diff options
82 files changed, 86446 insertions, 0 deletions
diff --git a/iburg/briggs/Makefile.in b/iburg/briggs/Makefile.in new file mode 100644 index 00000000000..5e3c4c5e237 --- /dev/null +++ b/iburg/briggs/Makefile.in @@ -0,0 +1,4916 @@ +# Makefile for GNU Compiler Collection +# Run 'configure' to generate Makefile from Makefile.in + +# Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, +# 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +# 2008 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 +#<http://www.gnu.org/licenses/>. + +# The targets for external use include: +# all, doc, proto, install, install-cross, install-cross-rest, +# uninstall, TAGS, mostlyclean, clean, distclean, maintainer-clean. + +# This is the default target. +# Set by autoconf to "all.internal" for a native build, or +# "all.cross" to build a cross compiler. +all: @ALL@ + +# Depend on this to specify a phony target portably. +force: + +# This tells GNU make version 3 not to export the variables +# defined in this file into the environment (and thus recursive makes). +.NOEXPORT: +# And this tells it not to automatically pass command-line variables +# to recursive makes. +MAKEOVERRIDES = + +# Suppress smart makes who think they know how to automake yacc and flex file +.y.c: +.l.c: + +# The only suffixes we want for implicit rules are .c and .o, so clear +# the list and add them. This speeds up GNU Make, and allows -r to work. +# For i18n support, we also need .gmo, .po, .pox. +# This must come before the language makefile fragments to allow them to +# add suffixes and rules of their own. +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo + +# ------------------------------- +# Standard autoconf-set variables +# ------------------------------- + +build=@build@ +host=@host@ +target=@target@ +target_noncanonical:=@target_noncanonical@ + +# Sed command to transform gcc to installed name. +program_transform_name := @program_transform_name@ + +# ----------------------------- +# Directories used during build +# ----------------------------- + +# Directory where sources are, from where we are. +srcdir = @srcdir@ +gcc_docdir = @srcdir@/doc + +# Directory where sources are, absolute. +abs_srcdir = @abs_srcdir@ +abs_docdir = @abs_srcdir@/doc + +# Top build directory for this package, relative to here. +top_builddir = . + +# The absolute path to the current directory. +objdir := $(shell pwd) + +host_subdir=@host_subdir@ +build_subdir=@build_subdir@ +target_subdir=@target_subdir@ +build_libsubdir=@build_libsubdir@ + +# Top build directory for the "Cygnus tree", relative to $(top_builddir). +ifeq ($(host_subdir),.) +toplevel_builddir := .. +else +toplevel_builddir := ../.. +endif + +build_objdir := $(toplevel_builddir)/$(build_subdir) +build_libobjdir := $(toplevel_builddir)/$(build_libsubdir) +target_objdir := $(toplevel_builddir)/$(target_subdir) + +# -------- +# Defined vpaths +# -------- + +# Directory where sources are, from where we are. +VPATH = @srcdir@ + +# We define a vpath for the sources of the .texi files here because they +# are split between multiple directories and we would rather use one implicit +# pattern rule for everything. +# This vpath could be extended within the Make-lang fragments. + +vpath %.texi $(gcc_docdir) +vpath %.texi $(gcc_docdir)/include + +# -------- +# UNSORTED +# -------- + +# Variables that exist for you to override. +# See below for how to change them for certain systems. + +# List of language subdirectories. +SUBDIRS =@subdirs@ build + +# Selection of languages to be made. +CONFIG_LANGUAGES = @all_selected_languages@ +LANGUAGES = c gcov$(exeext) gcov-dump$(exeext) $(CONFIG_LANGUAGES) + +# Default values for variables overridden in Makefile fragments. +# CFLAGS is for the user to override to, e.g., do a cross build with -O2. +# TCFLAGS is used for compilations with the GCC just built. +# T_CFLAGS is used for all compilations and is overridden by t-* files. +T_CFLAGS = +TCFLAGS = +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ + +# Flags to determine code coverage. When coverage is disabled, this will +# contain the optimization flags, as you normally want code coverage +# without optimization. +COVERAGE_FLAGS = @coverage_flags@ +coverageexts = .{gcda,gcno} + +# The warning flags are separate from CFLAGS because people tend to +# override optimization flags and we'd like them to still have warnings +# turned on. These flags are also used to pass other stage dependent +# flags from configure. The user is free to explicitly turn these flags +# off if they wish. +# LOOSE_WARN are the warning flags to use when compiling something +# which is only compiled with gcc, such as libgcc. +# STRICT_WARN are the additional warning flags to +# apply to the back end and some front ends, which may be compiled +# with other compilers. +LOOSE_WARN = @loose_warn@ +STRICT_WARN = @strict_warn@ + +# This is set by --enable-checking. The idea is to catch forgotten +# "extern" tags in header files. +NOCOMMON_FLAG = @nocommon_flag@ + +# This is set by --disable-maintainer-mode (default) to "#" +MAINT := @MAINT@ + +# These are set by --enable-checking=valgrind. +RUN_GEN = @valgrind_command@ +VALGRIND_DRIVER_DEFINES = @valgrind_path_defines@ + +# This is how we control whether or not the additional warnings are applied. +.-warn = $(STRICT_WARN) +build-warn = $(STRICT_WARN) +GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn) + +# These files are to have specific diagnostics suppressed, or are not to +# be subject to -Werror: +# flex output may yield harmless "no previous prototype" warnings +build/gengtype-lex.o-warn = -Wno-error +# SYSCALLS.c misses prototypes +SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error +# dfp.c contains alias violations +dfp.o-warn = -Wno-error +# bitmap.c contains -Wc++compat warnings. +bitmap.o-warn = -Wno-error +# dominance.c contains a -Wc++compat warning. +dominance.o-warn = -Wno-error +# mips-tfile.c contains -Wcast-qual warnings. +mips-tfile.o-warn = -Wno-error + +# All warnings have to be shut off in stage1 if the compiler used then +# isn't gcc; configure determines that. WARN_CFLAGS will be either +# $(GCC_WARN_CFLAGS), or nothing. +WARN_CFLAGS = @warn_cflags@ + +CPPFLAGS = @CPPFLAGS@ + +AWK = @AWK@ +CC = @CC@ +BISON = @BISON@ +BISONFLAGS = +FLEX = @FLEX@ +FLEXFLAGS = +AR = @AR@ +AR_FLAGS = rc +NM = @NM@ +RANLIB = @RANLIB@ +RANLIB_FLAGS = @ranlib_flags@ + +# ------------------------------------------- +# Programs which operate on the build machine +# ------------------------------------------- + +SHELL = @SHELL@ +# pwd command to use. Allow user to override default by setting PWDCMD in +# the environment to account for automounters. The make variable must not +# be called PWDCMD, otherwise the value set here is passed to make +# subprocesses and overrides the setting from the user's environment. +# Don't use PWD since it is a common shell environment variable and we +# don't want to corrupt it. +PWD_COMMAND = $${PWDCMD-pwd} +# on sysV, define this as cp. +INSTALL = @INSTALL@ +# Some systems may be missing symbolic links, regular links, or both. +# Allow configure to check this and use "ln -s", "ln", or "cp" as appropriate. +LN=@LN@ +LN_S=@LN_S@ +# These permit overriding just for certain files. +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL@ +MAKEINFO = @MAKEINFO@ +MAKEINFOFLAGS = --no-split +TEXI2DVI = texi2dvi +TEXI2PDF = texi2pdf +TEXI2HTML = $(MAKEINFO) --html +TEXI2POD = perl $(srcdir)/../contrib/texi2pod.pl +POD2MAN = pod2man --center="GNU" --release="gcc-$(version)" +# Some versions of `touch' (such as the version on Solaris 2.8) +# do not correctly set the timestamp due to buggy versions of `utime' +# in the kernel. So, we use `echo' instead. +STAMP = echo timestamp > +# If necessary (e.g., when using the MSYS shell on Microsoft Windows) +# translate the shell's notion of absolute pathnames to the native +# spelling. +build_file_translate = @build_file_translate@ + +# Make sure the $(MAKE) variable is defined. +@SET_MAKE@ + +# Locate mkinstalldirs. +mkinstalldirs=$(SHELL) $(srcdir)/../mkinstalldirs + +# write_entries_to_file - writes each entry in a list +# to the specified file. Entries are written in chunks of +# $(write_entries_to_file_split) to accomodate systems with +# severe command-line-length limitations. +# Parameters: +# $(1): variable containing entries to iterate over +# $(2): output file +write_entries_to_file_split = 50 +write_entries_to_file = $(shell rm -f $(2) || :) $(shell touch $(2)) \ + $(foreach range, \ + $(shell i=1; while test $$i -le $(words $(1)); do \ + echo $$i; i=`expr $$i + $(write_entries_to_file_split)`; done), \ + $(shell echo "$(wordlist $(range), \ + $(shell expr $(range) + $(write_entries_to_file_split) - 1), $(1))" \ + | tr ' ' '\n' >> $(2))) + +# -------- +# UNSORTED +# -------- + +# Some compilers can't handle cc -c blah.c -o foo/blah.o. +# In stage2 and beyond, we force this to "-o $@" since we know we're using gcc. +OUTPUT_OPTION = @OUTPUT_OPTION@ + +# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is +# -I../zlib, unless we were configured with --with-system-zlib, in which +# case both are empty. +ZLIB = @zlibdir@ -lz +ZLIBINC = @zlibinc@ + +# How to find GMP +GMPLIBS = @GMPLIBS@ +GMPINC = @GMPINC@ + +# How to find PPL +PPLLIBS = @PPLLIBS@ +PPLINC = @PPLINC@ + +# How to find CLOOG +CLOOGLIBS = @CLOOGLIBS@ +CLOOGINC = @CLOOGINC@ + +CPPLIB = ../libcpp/libcpp.a +CPPINC = -I$(srcdir)/../libcpp/include + +# Where to find decNumber +enable_decimal_float = @enable_decimal_float@ +DECNUM = $(srcdir)/../libdecnumber +DECNUMFMT = $(srcdir)/../libdecnumber/$(enable_decimal_float) +DECNUMINC = -I$(DECNUM) -I$(DECNUMFMT) -I../libdecnumber +LIBDECNUMBER = ../libdecnumber/libdecnumber.a + +# Substitution type for target's getgroups 2nd arg. +TARGET_GETGROUPS_T = @TARGET_GETGROUPS_T@ + +# Target to use when installing include directory. Either +# install-headers-tar, install-headers-cpio or install-headers-cp. +INSTALL_HEADERS_DIR = @build_install_headers_dir@ + +# Header files that are made available under the same name +# to programs compiled with GCC. +USER_H = $(srcdir)/ginclude/float.h \ + $(srcdir)/ginclude/iso646.h \ + $(srcdir)/ginclude/stdarg.h \ + $(srcdir)/ginclude/stdbool.h \ + $(srcdir)/ginclude/stddef.h \ + $(srcdir)/ginclude/varargs.h \ + $(srcdir)/ginclude/stdfix.h \ + $(EXTRA_HEADERS) + +UNWIND_H = $(srcdir)/unwind-generic.h + +# The GCC to use for compiling crt*.o. +# Usually the one we just built. +# Don't use this as a dependency--use $(GCC_PASSES). +GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./xgcc -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include -L$(objdir)/../ld + +# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. +# It specifies -B./. +# It also specifies -isystem ./include to find, e.g., stddef.h. +GCC_CFLAGS=$(CFLAGS_FOR_TARGET) $(INTERNAL_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -Wold-style-definition $($@-warn) -isystem ./include $(TCFLAGS) + +# --------------------------------------------------- +# Programs which produce files for the target machine +# --------------------------------------------------- + +AR_FOR_TARGET := $(shell \ + if [ -f $(objdir)/../binutils/ar ] ; then \ + echo $(objdir)/../binutils/ar ; \ + else \ + if [ "$(host)" = "$(target)" ] ; then \ + echo $(AR); \ + else \ + t='$(program_transform_name)'; echo ar | sed -e $$t ; \ + fi; \ + fi) +AR_FLAGS_FOR_TARGET = +AR_CREATE_FOR_TARGET = $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) rc +AR_EXTRACT_FOR_TARGET = $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) x +LIPO_FOR_TARGET = lipo +ORIGINAL_AS_FOR_TARGET = @ORIGINAL_AS_FOR_TARGET@ +RANLIB_FOR_TARGET := $(shell \ + if [ -f $(objdir)/../binutils/ranlib ] ; then \ + echo $(objdir)/../binutils/ranlib ; \ + else \ + if [ "$(host)" = "$(target)" ] ; then \ + echo $(RANLIB); \ + else \ + t='$(program_transform_name)'; echo ranlib | sed -e $$t ; \ + fi; \ + fi) +ORIGINAL_LD_FOR_TARGET = @ORIGINAL_LD_FOR_TARGET@ +ORIGINAL_NM_FOR_TARGET = @ORIGINAL_NM_FOR_TARGET@ +NM_FOR_TARGET = ./nm +STRIP_FOR_TARGET := $(shell \ + if [ -f $(objdir)/../binutils/strip ] ; then \ + echo $(objdir)/../binutils/strip ; \ + else \ + if [ "$(host)" = "$(target)" ] ; then \ + echo strip; \ + else \ + t='$(program_transform_name)'; echo strip | sed -e $$t ; \ + fi; \ + fi) + +# -------- +# UNSORTED +# -------- + +# Where to find some libiberty headers. +HASHTAB_H = $(srcdir)/../include/hashtab.h +OBSTACK_H = $(srcdir)/../include/obstack.h +SPLAY_TREE_H= $(srcdir)/../include/splay-tree.h +FIBHEAP_H = $(srcdir)/../include/fibheap.h +PARTITION_H = $(srcdir)/../include/partition.h +MD5_H = $(srcdir)/../include/md5.h + +# Default native SYSTEM_HEADER_DIR, to be overridden by targets. +NATIVE_SYSTEM_HEADER_DIR = /usr/include +# Default cross SYSTEM_HEADER_DIR, to be overridden by targets. +CROSS_SYSTEM_HEADER_DIR = @CROSS_SYSTEM_HEADER_DIR@ + +# autoconf sets SYSTEM_HEADER_DIR to one of the above. +# Purge it of unneccessary internal relative paths +# to directories that might not exist yet. +# The sed idiom for this is to repeat the search-and-replace until it doesn't match, using :a ... ta. +# Use single quotes here to avoid nested double- and backquotes, this +# macro is also used in a double-quoted context. +SYSTEM_HEADER_DIR = `echo @SYSTEM_HEADER_DIR@ | sed -e :a -e 's,[^/]*/\.\.\/,,' -e ta` + +# Control whether to run fixproto and fixincludes. +STMP_FIXPROTO = @STMP_FIXPROTO@ +STMP_FIXINC = @STMP_FIXINC@ + +# Test to see whether <limits.h> exists in the system header files. +LIMITS_H_TEST = [ -f $(SYSTEM_HEADER_DIR)/limits.h ] + +# Directory for prefix to system directories, for +# each of $(system_prefix)/usr/include, $(system_prefix)/usr/lib, etc. +TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@ + +xmake_file=@xmake_file@ +tmake_file=@tmake_file@ +out_file=$(srcdir)/config/@out_file@ +out_object_file=@out_object_file@ +md_file=$(srcdir)/config/@md_file@ +tm_file_list=@tm_file_list@ +tm_include_list=@tm_include_list@ +tm_defines=@tm_defines@ +tm_p_file_list=@tm_p_file_list@ +tm_p_include_list=@tm_p_include_list@ +build_xm_file_list=@build_xm_file_list@ +build_xm_include_list=@build_xm_include_list@ +build_xm_defines=@build_xm_defines@ +host_xm_file_list=@host_xm_file_list@ +host_xm_include_list=@host_xm_include_list@ +host_xm_defines=@host_xm_defines@ +xm_file_list=@xm_file_list@ +xm_include_list=@xm_include_list@ +xm_defines=@xm_defines@ +lang_checks=check-gcc +lang_checks_parallelized=check-gcc +# This lists a couple of test files that take most time during check-gcc. +# When doing parallelized check-gcc, these can run in parallel with the +# remaining tests. Each word in this variable stands for work for one +# make goal and one extra make goal is added to handle all the *.exp +# files not handled explicitly already. If multiple *.exp files +# should be run in the same runtest invocation (usually if they aren't +# very long running, but still should be split of from the check-parallel-$lang +# remaining tests runtest invocation), they should be concatenated with commas. +# Note that [a-zA-Z] wildcards need to have []s prefixed with \ (needed +# by tcl) and as the *.exp arguments are mached both as is and with +# */ prefixed to it in runtest_file_p, it is usually desirable to include +# a subdirectory name. +check_gcc_parallelize=execute.exp=execute/2* \ + execute.exp=execute/\[013-9a-zA-Z\]* \ + compile.exp dg.exp \ + struct-layout-1.exp,unsorted.exp,stackalign.exp,i386.exp +lang_opt_files=@lang_opt_files@ $(srcdir)/c.opt $(srcdir)/common.opt +lang_specs_files=@lang_specs_files@ +lang_tree_files=@lang_tree_files@ +target_cpu_default=@target_cpu_default@ +GCC_THREAD_FILE=@thread_file@ +OBJC_BOEHM_GC=@objc_boehm_gc@ +GTHREAD_FLAGS=@gthread_flags@ +extra_modes_file=@extra_modes_file@ +extra_opt_files=@extra_opt_files@ +host_hook_obj=@out_host_hook_obj@ + +# ------------------------ +# Installation directories +# ------------------------ + +# Common prefix for installation directories. +# NOTE: This directory must exist when you start installation. +prefix = @prefix@ +# Directory in which to put localized header files. On the systems with +# gcc as the native cc, `local_prefix' may not be `prefix' which is +# `/usr'. +# NOTE: local_prefix *should not* default from prefix. +local_prefix = @local_prefix@ +# Directory in which to put host dependent programs and libraries +exec_prefix = @exec_prefix@ +# Directory in which to put the executable for the command `gcc' +bindir = @bindir@ +# Directory in which to put the directories used by the compiler. +libdir = @libdir@ +# Directory in which GCC puts its executables. +libexecdir = @libexecdir@ + +# -------- +# UNSORTED +# -------- + +# Directory in which the compiler finds libraries etc. +libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(version) +# Directory in which the compiler finds executables +libexecsubdir = $(libexecdir)/gcc/$(target_noncanonical)/$(version) +# Used to produce a relative $(gcc_tooldir) in gcc.o +unlibsubdir = ../../.. +# $(prefix), expressed as a path relative to $(libsubdir). +# +# An explanation of the sed strings: +# -e 's|^$(prefix)||' matches and eliminates 'prefix' from 'exec_prefix' +# -e 's|/$$||' match a trailing forward slash and eliminates it +# -e 's|^[^/]|/|' forces the string to start with a forward slash (*) +# -e 's|/[^/]*|../|g' replaces each occurrence of /<directory> with ../ +# +# (*) Note this pattern overwrites the first character of the string +# with a forward slash if one is not already present. This is not a +# problem because the exact names of the sub-directories concerned is +# unimportant, just the number of them matters. +# +# The practical upshot of these patterns is like this: +# +# prefix exec_prefix result +# ------ ----------- ------ +# /foo /foo/bar ../ +# /foo/ /foo/bar ../ +# /foo /foo/bar/ ../ +# /foo/ /foo/bar/ ../ +# /foo /foo/bar/ugg ../../ +libsubdir_to_prefix := \ + $(unlibsubdir)/$(shell echo "$(libdir)" | \ + sed -e 's|^$(prefix)||' -e 's|/$$||' -e 's|^[^/]|/|' \ + -e 's|/[^/]*|../|g') +# $(exec_prefix), expressed as a path relative to $(prefix). +prefix_to_exec_prefix := \ + $(shell echo "$(exec_prefix)" | \ + sed -e 's|^$(prefix)||' -e 's|^/||' -e '/./s|$$|/|') +# Directory in which to find other cross-compilation tools and headers. +dollar = @dollar@ +# Used in install-cross. +gcc_tooldir = @gcc_tooldir@ +# Used to install the shared libgcc. +slibdir = @slibdir@ +# Since gcc_tooldir does not exist at build-time, use -B$(build_tooldir)/bin/ +build_tooldir = $(exec_prefix)/$(target_noncanonical) +# Directory in which the compiler finds target-independent g++ includes. +gcc_gxx_include_dir = @gcc_gxx_include_dir@ +# Directory to search for site-specific includes. +local_includedir = $(local_prefix)/include +includedir = $(prefix)/include +# where the info files go +infodir = @infodir@ +# Where cpp should go besides $prefix/bin if necessary +cpp_install_dir = @cpp_install_dir@ +# where the locale files go +datadir = @datadir@ +localedir = $(datadir)/locale +# Extension (if any) to put in installed man-page filename. +man1ext = .1 +man7ext = .7 +objext = .o +exeext = @host_exeext@ +build_exeext = @build_exeext@ + +# Directory in which to put man pages. +mandir = @mandir@ +man1dir = $(mandir)/man1 +man7dir = $(mandir)/man7 +# Dir for temp files. +tmpdir = /tmp + +datarootdir = @datarootdir@ +docdir = @docdir@ +# Directory in which to build HTML +build_htmldir = $(objdir)/HTML/gcc-$(version) +# Directory in which to put HTML +htmldir = @htmldir@ + +# Whether we were configured with NLS. +USE_NLS = @USE_NLS@ + +# Internationalization library. +LIBINTL = @LIBINTL@ +LIBINTL_DEP = @LIBINTL_DEP@ + +# Character encoding conversion library. +LIBICONV = @LIBICONV@ +LIBICONV_DEP = @LIBICONV_DEP@ + +# The GC method to be used on this system. +GGC=@GGC@.o + +# If a supplementary library is being used for the GC. +GGC_LIB= + +# "true" if the target C library headers are unavailable; "false" +# otherwise. +inhibit_libc = @inhibit_libc@ +ifeq ($(inhibit_libc),true) +INHIBIT_LIBC_CFLAGS = -Dinhibit_libc +endif + +# Options to use when compiling libgcc2.a. +# +LIBGCC2_DEBUG_CFLAGS = -g +LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \ + $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \ + -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \ + $(INHIBIT_LIBC_CFLAGS) + +# Additional options to use when compiling libgcc2.a. +# Some targets override this to -isystem include +LIBGCC2_INCLUDES = + +# Additional target-dependent options for compiling libgcc2.a. +TARGET_LIBGCC2_CFLAGS = + +# Options to use when compiling crtbegin/end. +CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ + -finhibit-size-directive -fno-inline-functions -fno-exceptions \ + -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ + $(INHIBIT_LIBC_CFLAGS) + +# Additional sources to handle exceptions; overridden by targets as needed. +LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ + $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c +LIB2ADDEHSTATIC = $(LIB2ADDEH) +LIB2ADDEHSHARED = $(LIB2ADDEH) +LIB2ADDEHDEP = $(UNWIND_H) unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h + +# Don't build libunwind by default. +LIBUNWIND = +LIBUNWINDDEP = +SHLIBUNWIND_LINK = +SHLIBUNWIND_INSTALL = + +# nm flags to list global symbols in libgcc object files. +SHLIB_NM_FLAGS = -pg + +# List of extra executables that should be compiled for this target machine +# that are used for compiling from source code to object code. +# The rules for compiling them should be in the t-* file for the machine. +EXTRA_PASSES =@extra_passes@ + +# Like EXTRA_PASSES, but these are used when linking. +EXTRA_PROGRAMS = @extra_programs@ + +# List of extra object files that should be compiled for this target machine. +# The rules for compiling them should be in the t-* file for the machine. +EXTRA_PARTS = @extra_parts@ + +# List of extra object files that should be compiled and linked with +# compiler proper (cc1, cc1obj, cc1plus). +EXTRA_OBJS = @extra_objs@ + +# List of extra object files that should be compiled and linked with +# the gcc driver. +EXTRA_GCC_OBJS =@extra_gcc_objs@ + +# List of additional header files to install. +EXTRA_HEADERS =@extra_headers_list@ + +# The configure script will set this to collect2$(exeext), except on a +# (non-Unix) host which can not build collect2, for which it will be +# set to empty. +COLLECT2 = @collect2@ + +# List of extra C and assembler files to add to static and shared libgcc2. +# Assembler files should have names ending in `.asm'. +LIB2FUNCS_EXTRA = + +# List of extra C and assembler files to add to static libgcc2. +# Assembler files should have names ending in `.asm'. +LIB2FUNCS_STATIC_EXTRA = + +# List of functions not to build from libgcc2.c. +LIB2FUNCS_EXCLUDE = + +# Target sfp-machine.h file. +SFP_MACHINE = + +# Program to convert libraries. +LIBCONVERT = + +# Control whether header files are installed. +INSTALL_HEADERS=install-headers install-mkheaders + +# Control whether Info documentation is built and installed. +BUILD_INFO = @BUILD_INFO@ + +# Control whether manpages generated by texi2pod.pl can be rebuilt. +GENERATED_MANPAGES = @GENERATED_MANPAGES@ + +# Additional directories of header files to run fixincludes on. +# These should be directories searched automatically by default +# just as /usr/include is. +# *Do not* use this for directories that happen to contain +# header files, but are not searched automatically by default. +# On most systems, this is empty. +OTHER_FIXINCLUDES_DIRS= + +# A list of all the language-specific executables. +COMPILERS = cc1$(exeext) @all_compilers@ + +# List of things which should already be built whenever we try to use xgcc +# to compile anything (without linking). +GCC_PASSES=xgcc$(exeext) cc1$(exeext) specs $(EXTRA_PASSES) + +# Directory to link to, when using the target `maketest'. +DIR = ../gcc + +# Native compiler for the build machine and its switches. +CC_FOR_BUILD = @CC_FOR_BUILD@ +BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE + +# Native linker and preprocessor flags. For x-fragment overrides. +BUILD_LDFLAGS=@BUILD_LDFLAGS@ +BUILD_CPPFLAGS=$(ALL_CPPFLAGS) + +# Actual name to use when installing a native compiler. +GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)') +GCC_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcc|sed '$(program_transform_name)') +CPP_INSTALL_NAME := $(shell echo cpp|sed '$(program_transform_name)') +PROTOIZE_INSTALL_NAME := $(shell echo protoize|sed '$(program_transform_name)') +UNPROTOIZE_INSTALL_NAME := $(shell echo unprotoize|sed '$(program_transform_name)') +GCOV_INSTALL_NAME := $(shell echo gcov|sed '$(program_transform_name)') +GCCBUG_INSTALL_NAME := $(shell echo gccbug|sed '$(program_transform_name)') + +# Setup the testing framework, if you have one +EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \ + echo $${rootme}/../expect/expect ; \ + else echo expect ; fi` + +RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \ + echo $${srcdir}/../dejagnu/runtest ; \ + else echo runtest; fi` +RUNTESTFLAGS = + +# Extra symbols for fixproto to define when parsing headers. +FIXPROTO_DEFINES = + +# Extra flags to use when compiling crt{begin,end}.o. +CRTSTUFF_T_CFLAGS = + +# Extra flags to use when compiling [m]crt0.o. +CRT0STUFF_T_CFLAGS = + +# "t" or nothing, for building multilibbed versions of, say, crtbegin.o. +T = + +# Should T contain a `=', libgcc/Makefile will make T_TARGET, setting +# $(T_TARGET) to the name of the actual target filename. +T_TARGET = +T_TARGET : $(T_TARGET) + +# This should name the specs file that we're going to install. Target +# Makefiles may override it and name another file to be generated from +# the built-in specs and installed as the default spec, as long as +# they also introduce a rule to generate a file name specs, to be used +# at build time. +SPECS = specs + +# End of variables for you to override. + +# GTM_H lists the config files that the generator files depend on, +# while TM_H lists the ones ordinary gcc files depend on, which +# includes several files generated by those generators. +BCONFIG_H = bconfig.h $(build_xm_file_list) +CONFIG_H = config.h $(host_xm_file_list) +TCONFIG_H = tconfig.h $(xm_file_list) +TM_P_H = tm_p.h $(tm_p_file_list) +GTM_H = tm.h $(tm_file_list) +TM_H = $(GTM_H) insn-constants.h insn-flags.h options.h + +# Variables for version information. +BASEVER := $(srcdir)/BASE-VER # 4.x.y +DEVPHASE := $(srcdir)/DEV-PHASE # experimental, prerelease, "" +DATESTAMP := $(srcdir)/DATESTAMP # YYYYMMDD or empty +REVISION := $(srcdir)/REVISION # [BRANCH revision XXXXXX] + +BASEVER_c := $(shell cat $(BASEVER)) +DEVPHASE_c := $(shell cat $(DEVPHASE)) +DATESTAMP_c := $(shell cat $(DATESTAMP)) + +ifeq (,$(wildcard $(REVISION))) +REVISION_c := +else +REVISION_c := $(shell cat $(REVISION)) +endif + +version := $(BASEVER_c) + +# For use in version.c - double quoted strings, with appropriate +# surrounding punctuation and spaces, and with the datestamp and +# development phase collapsed to the empty string in release mode +# (i.e. if DEVPHASE_c is empty). The space immediately after the +# comma in the $(if ...) constructs is significant - do not remove it. +BASEVER_s := "\"$(BASEVER_c)\"" +DEVPHASE_s := "\"$(if $(DEVPHASE_c), ($(DEVPHASE_c)))\"" +DATESTAMP_s := "\"$(if $(DEVPHASE_c), $(DATESTAMP_c))\"" +PKGVERSION_s:= "\"@PKGVERSION@\"" +BUGURL_s := "\"@REPORT_BUGS_TO@\"" + +PKGVERSION := @PKGVERSION@ +BUGURL_TEXI := @REPORT_BUGS_TEXI@ + +ifdef REVISION_c +REVISION_s := "\"$(if $(DEVPHASE_c), $(REVISION_c))\"" +else +REVISION_s := +endif + +# Shorthand variables for dependency lists. +TOPLEV_H = toplev.h input.h +TARGET_H = $(TM_H) target.h insn-modes.h +MACHMODE_H = machmode.h mode-classes.def insn-modes.h +HOOKS_H = hooks.h $(MACHMODE_H) +HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H) +LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H) +TARGET_DEF_H = target-def.h $(HOOKS_H) targhooks.h +RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \ + $(INPUT_H) $(REAL_H) statistics.h vec.h $(FIXED_VALUE_H) alias.h +FIXED_VALUE_H = fixed-value.h $(MACHMODE_H) double-int.h +RTL_H = $(RTL_BASE_H) genrtl.h +PARAMS_H = params.h params.def +BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def +TREE_H = tree.h all-tree.def tree.def c-common.def $(lang_tree_files) \ + $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \ + $(INPUT_H) statistics.h vec.h treestruct.def $(HASHTAB_H) \ + double-int.h alias.h $(SYMTAB_H) options.h +BASIC_BLOCK_H = basic-block.h $(BITMAP_H) sbitmap.h varray.h $(PARTITION_H) \ + hard-reg-set.h $(PREDICT_H) vec.h $(FUNCTION_H) \ + cfghooks.h $(OBSTACK_H) +GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \ + $(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h +GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h +COVERAGE_H = coverage.h $(GCOV_IO_H) +DEMANGLE_H = $(srcdir)/../include/demangle.h +RECOG_H = recog.h +ALIAS_H = alias.h coretypes.h +EMIT_RTL_H = emit-rtl.h +FLAGS_H = flags.h options.h +FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) varray.h +EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H) +OPTABS_H = optabs.h insn-codes.h +REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H) +RA_H = ra.h $(REGS_H) +RESOURCE_H = resource.h hard-reg-set.h +SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) $(DF_H) vecprim.h +SEL_SCHED_IR_H = sel-sched-ir.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) \ + $(GGC_H) $(SCHED_INT_H) +SEL_SCHED_DUMP_H = sel-sched-dump.h $(SEL_SCHED_IR_H) +INTEGRATE_H = integrate.h $(VARRAY_H) +CFGLAYOUT_H = cfglayout.h $(BASIC_BLOCK_H) +CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $(RTL_H) vecprim.h double-int.h +IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H) +IPA_REFERENCE_H = ipa-reference.h $(BITMAP_H) $(TREE_H) +IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H) +CGRAPH_H = cgraph.h $(TREE_H) $(BASIC_BLOCK_H) +DF_H = df.h $(BITMAP_H) $(BASIC_BLOCK_H) alloc-pool.h +RESOURCE_H = resource.h hard-reg-set.h $(DF_H) +DDG_H = ddg.h sbitmap.h $(DF_H) +GCC_H = gcc.h version.h +GGC_H = ggc.h gtype-desc.h statistics.h +TIMEVAR_H = timevar.h timevar.def +INSN_ATTR_H = insn-attr.h $(INSN_ADDR_H) $(srcdir)/varray.h +INSN_ADDR_H = $(srcdir)/insn-addr.h vecprim.h +C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H) $(GGC_H) +C_PRAGMA_H = c-pragma.h $(CPPLIB_H) +C_TREE_H = c-tree.h $(C_COMMON_H) $(TOPLEV_H) $(DIAGNOSTIC_H) +SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h \ + $(srcdir)/../include/safe-ctype.h $(srcdir)/../include/filenames.h +PREDICT_H = predict.h predict.def +CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ + $(srcdir)/../libcpp/include/cpplib.h +INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h +DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \ + $(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \ + $(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h +MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h +SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h $(OBSTACK_H) +CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h +CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H) +TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) tree-pass.h +TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \ + $(BITMAP_H) $(BASIC_BLOCK_H) hard-reg-set.h $(GIMPLE_H) \ + $(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) +TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) vecprim.h +PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H) +DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h +C_PRETTY_PRINT_H = c-pretty-print.h $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H) +SCEV_H = tree-scalar-evolution.h $(GGC_H) tree-chrec.h $(PARAMS_H) +LAMBDA_H = lambda.h $(TREE_H) vec.h $(GGC_H) +TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h graphds.h tree-chrec.h +VARRAY_H = varray.h $(MACHMODE_H) $(SYSTEM_H) coretypes.h $(TM_H) +TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h +REAL_H = real.h $(MACHMODE_H) +IRA_INT_H = ira.h ira-int.h $(CFGLOOP_H) alloc-pool.h +DBGCNT_H = dbgcnt.h dbgcnt.def +EBIMAP_H = ebitmap.h sbitmap.h +IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H) +GSTAB_H = gstab.h stab.def +BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h + +# +# Now figure out from those variables how to compile and link. + +# IN_GCC distinguishes between code compiled into GCC itself and other +# programs built during a bootstrap. +# autoconf inserts -DCROSS_DIRECTORY_STRUCTURE if we are building a +# cross compiler which does not use the native headers and libraries. +INTERNAL_CFLAGS = -DIN_GCC @CROSS@ + +# This is the variable actually used when we compile. If you change this, +# you probably want to update BUILD_CFLAGS in configure.ac +ALL_CFLAGS = $(T_CFLAGS) \ + $(CFLAGS) $(INTERNAL_CFLAGS) $(COVERAGE_FLAGS) $(WARN_CFLAGS) @DEFS@ + +# Likewise. Put INCLUDES at the beginning: this way, if some autoconf macro +# puts -I options in CPPFLAGS, our include files in the srcdir will always +# win against random include files in /usr/include. +ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS) + +# Build and host support libraries. +LIBIBERTY = ../libiberty/libiberty.a +BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/libiberty.a + +# Dependencies on the intl and portability libraries. +LIBDEPS= $(CPPLIB) $(LIBIBERTY) $(LIBINTL_DEP) $(LIBICONV_DEP) $(LIBDECNUMBER) + +# Likewise, for use in the tools that must run on this machine +# even if we are cross-building GCC. +BUILD_LIBDEPS= $(BUILD_LIBIBERTY) + +# How to link with both our special library facilities +# and the system's installed libraries. +LIBS = @LIBS@ $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBIBERTY) $(LIBDECNUMBER) +BACKENDLIBS = $(GMPLIBS) $(CLOOGLIBS) $(PPLLIBS) +# Any system libraries needed just for GNAT. +SYSLIBS = @GNAT_LIBEXC@ + +# Used from ada/Make-lang.in +GNATBIND = @GNATBIND@ +GNATMAKE = @GNATMAKE@ + +# Libs needed (at present) just for jcf-dump. +LDEXP_LIB = @LDEXP_LIB@ + +# Likewise, for use in the tools that must run on this machine +# even if we are cross-building GCC. +BUILD_LIBS = $(BUILD_LIBIBERTY) + +BUILD_RTL = build/rtl.o build/read-rtl.o build/ggc-none.o build/vec.o \ + build/min-insn-modes.o build/gensupport.o build/print-rtl.o +BUILD_ERRORS = build/errors.o + +# Specify the directories to be searched for header files. +# Both . and srcdir are used, in that order, +# so that *config.h will be found in the compilation +# subdirectory rather than in the source directory. +# -I$(@D) and -I$(srcdir)/$(@D) cause the subdirectory of the file +# currently being compiled, in both source trees, to be examined as well. +# libintl.h will be found in ../intl if we are using the included libintl. +INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \ + -I$(srcdir)/../include @INCINTL@ \ + $(CPPINC) $(GMPINC) $(DECNUMINC) \ + $(PPLINC) $(CLOOGINC) + +.c.o: + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION) + +# +# Support for additional languages (other than C). +# C can be supported this way too (leave for later). + +LANG_MAKEFRAGS = @all_lang_makefrags@ +LANG_MAKEFILES = @all_lang_makefiles@ + +# Flags to pass to recursive makes. +# CC is set by configure. +# ??? The choices here will need some experimenting with. + +export AR_FOR_TARGET +export AR_CREATE_FOR_TARGET +export AR_FLAGS_FOR_TARGET +export AR_EXTRACT_FOR_TARGET +export AWK +export DESTDIR +export GCC_FOR_TARGET +export INCLUDES +export INSTALL_DATA +export LIB1ASMSRC +export LIBGCC2_CFLAGS +export LIPO_FOR_TARGET +export MACHMODE_H +export NM_FOR_TARGET +export STRIP_FOR_TARGET +export RANLIB_FOR_TARGET +export libsubdir +export slibdir + +FLAGS_TO_PASS = \ + "ADA_CFLAGS=$(ADA_CFLAGS)" \ + "BISON=$(BISON)" \ + "BISONFLAGS=$(BISONFLAGS)" \ + "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \ + "LDFLAGS=$(LDFLAGS)" \ + "FLEX=$(FLEX)" \ + "FLEXFLAGS=$(FLEXFLAGS)" \ + "LN=$(LN)" \ + "LN_S=$(LN_S)" \ + "MAKEINFO=$(MAKEINFO)" \ + "MAKEINFOFLAGS=$(MAKEINFOFLAGS)" \ + "MAKEOVERRIDES=" \ + "SHELL=$(SHELL)" \ + "exeext=$(exeext)" \ + "build_exeext=$(build_exeext)" \ + "objext=$(objext)" \ + "exec_prefix=$(exec_prefix)" \ + "prefix=$(prefix)" \ + "local_prefix=$(local_prefix)" \ + "gxx_include_dir=$(gcc_gxx_include_dir)" \ + "build_tooldir=$(build_tooldir)" \ + "gcc_tooldir=$(gcc_tooldir)" \ + "bindir=$(bindir)" \ + "libexecsubdir=$(libsubdir)" \ + "datarootdir=$(datarootdir)" \ + "datadir=$(datadir)" \ + "localedir=$(localedir)" +# +# Lists of files for various purposes. + +# All option source files +ALL_OPT_FILES=$(lang_opt_files) $(extra_opt_files) + +# Target specific, C specific object file +C_TARGET_OBJS=@c_target_objs@ + +# Target specific, C++ specific object file +CXX_TARGET_OBJS=@cxx_target_objs@ + +# Target specific, Fortran specific object file +FORTRAN_TARGET_OBJS=@fortran_target_objs@ + +# Object files for gcc driver. +GCC_OBJS = gcc.o opts-common.o gcc-options.o + +# Language-specific object files for C and Objective C. +C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \ + c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \ + c-ppoutput.o c-cppbuiltin.o \ + c-objc-common.o c-dump.o c-pch.o c-parser.o $(C_TARGET_OBJS) \ + c-gimplify.o tree-mudflap.o c-pretty-print.o c-omp.o + +# Language-specific object files for C. +C_OBJS = c-lang.o stub-objc.o $(C_AND_OBJC_OBJS) + +# Language-independent object files. +# We put the insn-*.o files first so that a parallel make will build +# them sooner, because they are large and otherwise tend to be the +# last objects to finish building. +OBJS-common = \ + insn-attrtab.o \ + insn-automata.o \ + insn-emit.o \ + insn-extract.o \ + insn-modes.o \ + insn-opinit.o \ + insn-output.o \ + insn-peep.o \ + insn-preds.o \ + insn-recog.o \ + $(GGC) \ + alias.o \ + alloc-pool.o \ + auto-inc-dec.o \ + bb-reorder.o \ + bitmap.o \ + bt-load.o \ + builtins.o \ + caller-save.o \ + calls.o \ + cfg.o \ + cfganal.o \ + cfgbuild.o \ + cfgcleanup.o \ + cfgexpand.o \ + cfghooks.o \ + cfglayout.o \ + cfgloop.o \ + cfgloopanal.o \ + cfgloopmanip.o \ + cfgrtl.o \ + combine.o \ + combine-stack-adj.o \ + convert.o \ + coverage.o \ + cse.o \ + cselib.o \ + dbxout.o \ + dbgcnt.o \ + dce.o \ + ddg.o \ + debug.o \ + df-byte-scan.o \ + df-core.o \ + df-problems.o \ + df-scan.o \ + dfp.o \ + diagnostic.o \ + dojump.o \ + dominance.o \ + domwalk.o \ + double-int.o \ + dse.o \ + dwarf2asm.o \ + dwarf2out.o \ + ebitmap.o \ + emit-rtl.o \ + et-forest.o \ + except.o \ + explow.o \ + expmed.o \ + expr.o \ + final.o \ + fixed-value.o \ + fold-const.o \ + function.o \ + fwprop.o \ + gcse.o \ + genrtl.o \ + ggc-common.o \ + gimple.o \ + gimple-iterator.o \ + gimple-low.o \ + gimple-pretty-print.o \ + gimplify.o \ + global.o \ + graph.o \ + graphds.o \ + graphite.o \ + gtype-desc.o \ + haifa-sched.o \ + hooks.o \ + icg.o \ + icg-build-tree.o \ + icg-combine.o \ + icg-debug.o \ + icg-filter.o \ + icg-final.o \ + icg-forward-prop.o \ + icg-graph.o \ + icg-reassociate.o \ + icg-remat.o \ + icg-rewrite.o \ + icg-spill.o \ + icg-supairs.o \ + icg-color.o \ + icg-costs.o \ + icg-emit.o \ + icg-names.o \ + icg-select.o \ + icg-ssa.o \ + icg-burg.o \ + icg-opcode-names.o \ + icg-rulemaps.o \ + ifcvt.o \ + init-regs.o \ + integrate.o \ + intl.o \ + ira.o \ + ira-build.o \ + ira-costs.o \ + ira-conflicts.o \ + ira-color.o \ + ira-emit.o \ + ira-lives.o \ + jump.o \ + lambda-code.o \ + lambda-mat.o \ + lambda-trans.o \ + langhooks.o \ + lcm.o \ + lists.o \ + local-alloc.o \ + loop-doloop.o \ + loop-init.o \ + loop-invariant.o \ + loop-iv.o \ + loop-unroll.o \ + loop-unswitch.o \ + lower-subreg.o \ + mcf.o \ + mode-switching.o \ + modulo-sched.o \ + omega.o \ + omp-low.o \ + optabs.o \ + options.o \ + opts-common.o \ + opts.o \ + params.o \ + passes.o \ + pointer-set.o \ + postreload-gcse.o \ + postreload.o \ + predict.o \ + pretty-print.o \ + print-rtl.o \ + print-tree.o \ + profile.o \ + ra-conflict.o \ + real.o \ + recog.o \ + reg-stack.o \ + regclass.o \ + regmove.o \ + regrename.o \ + regstat.o \ + reload.o \ + reload1.o \ + reorg.o \ + resource.o \ + rtl-error.o \ + rtl-factoring.o \ + rtl.o \ + rtlanal.o \ + rtlhooks.o \ + sbitmap.o \ + sched-deps.o \ + sched-ebb.o \ + sched-rgn.o \ + sched-vis.o \ + sdbout.o \ + see.o \ + sel-sched-ir.o \ + sel-sched-dump.o \ + sel-sched.o \ + simplify-rtx.o \ + sparseset.o \ + sreal.o \ + stack-ptr-mod.o \ + statistics.o \ + stmt.o \ + stor-layout.o \ + stringpool.o \ + targhooks.o \ + timevar.o \ + toplev.o \ + tracer.o \ + tree-affine.o \ + tree-call-cdce.o \ + tree-cfg.o \ + tree-cfgcleanup.o \ + tree-chrec.o \ + tree-complex.o \ + tree-data-ref.o \ + tree-dfa.o \ + tree-dump.o \ + tree-eh.o \ + tree-if-conv.o \ + tree-into-ssa.o \ + tree-iterator.o \ + tree-loop-distribution.o \ + tree-loop-linear.o \ + tree-nested.o \ + tree-nrv.o \ + tree-object-size.o \ + tree-optimize.o \ + tree-outof-ssa.o \ + tree-parloops.o \ + tree-phinodes.o \ + tree-predcom.o \ + tree-pretty-print.o \ + tree-profile.o \ + tree-scalar-evolution.o \ + tree-sra.o \ + tree-switch-conversion.o \ + tree-ssa-address.o \ + tree-ssa-alias.o \ + tree-ssa-ccp.o \ + tree-ssa-coalesce.o \ + tree-ssa-copy.o \ + tree-ssa-copyrename.o \ + tree-ssa-dce.o \ + tree-ssa-dom.o \ + tree-ssa-dse.o \ + tree-ssa-forwprop.o \ + tree-ssa-ifcombine.o \ + tree-ssa-live.o \ + tree-ssa-loop-ch.o \ + tree-ssa-loop-im.o \ + tree-ssa-loop-ivcanon.o \ + tree-ssa-loop-ivopts.o \ + tree-ssa-loop-manip.o \ + tree-ssa-loop-niter.o \ + tree-ssa-loop-prefetch.o \ + tree-ssa-loop-unswitch.o \ + tree-ssa-loop.o \ + tree-ssa-math-opts.o \ + tree-ssa-operands.o \ + tree-ssa-phiopt.o \ + tree-ssa-phiprop.o \ + tree-ssa-pre.o \ + tree-ssa-propagate.o \ + tree-ssa-reassoc.o \ + tree-ssa-sccvn.o \ + tree-ssa-sink.o \ + tree-ssa-structalias.o \ + tree-ssa-ter.o \ + tree-ssa-threadedge.o \ + tree-ssa-threadupdate.o \ + tree-ssa-uncprop.o \ + tree-ssa.o \ + tree-ssanames.o \ + tree-stdarg.o \ + tree-tailcall.o \ + tree-vect-analyze.o \ + tree-vect-generic.o \ + tree-vect-patterns.o \ + tree-vect-transform.o \ + tree-vectorizer.o \ + tree-vrp.o \ + tree.o \ + value-prof.o \ + var-tracking.o \ + varasm.o \ + varray.o \ + vec.o \ + version.o \ + vmsdbgout.o \ + web.o \ + xcoffout.o + +# Target object files. +OBJS-md = $(out_object_file) + +# Language independent object files which are not used by all languages. +OBJS-archive = \ + $(EXTRA_OBJS) \ + $(host_hook_obj) \ + cgraph.o \ + cgraphbuild.o \ + cgraphunit.o \ + cppdefault.o \ + incpath.o \ + ipa-cp.o \ + ipa-inline.o \ + ipa-prop.o \ + ipa-pure-const.o \ + ipa-reference.o \ + ipa-struct-reorg.o \ + ipa-type-escape.o \ + ipa-utils.o \ + ipa.o \ + matrix-reorg.o \ + prefix.o \ + tree-inline.o \ + tree-nomudflap.o \ + varpool.o + +OBJS = $(OBJS-common) $(OBJS-md) $(OBJS-archive) + +OBJS-onestep = libbackend.o $(OBJS-archive) + +# This lists all host object files, whether they are included in this +# compilation or not. +ALL_HOST_OBJS = $(GCC_OBJS) $(C_OBJS) $(OBJS) libbackend.o \ + @TREEBROWSER@ main.o gccspec.o version.o intl.o prefix.o cppspec.o \ + $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS)) \ + $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) \ + mips-tfile.o mips-tdump.o \ + $(PROTO_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) + +BACKEND = main.o @TREEBROWSER@ libbackend.a $(CPPLIB) $(LIBDECNUMBER) + +MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \ + insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \ + insn-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.h \ + tm-preds.h tm-constrs.h \ + tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \ + genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \ + xgcc$(exeext) cpp$(exeext) cc1$(exeext) cc1*-dummy$(exeext) $(EXTRA_PASSES) \ + $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \ + protoize$(exeext) unprotoize$(exeext) \ + $(SPECS) collect2$(exeext) \ + gcov-iov$(build_exeext) gcov$(exeext) gcov-dump$(exeext) \ + *.[0-9][0-9].* *.[si] *-checksum.c libbackend.a libgcc.mk + +# Defined in libgcc2.c, included only in the static library. +LIB2FUNCS_ST = _eprintf __gcc_bcmp + +# Defined in libgcov.c, included only in gcov library +LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \ + _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \ + _gcov_execv _gcov_execvp _gcov_execve \ + _gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \ + _gcov_indirect_call_profiler _gcov_average_profiler _gcov_ior_profiler \ + _gcov_merge_ior + +FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ + _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ + _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ + _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf + +DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ + _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \ + _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \ + _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df + +TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \ + _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \ + _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \ + _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf + +D32PBIT_FUNCS = _addsub_sd _div_sd _mul_sd _plus_sd _minus_sd \ + _eq_sd _ne_sd _lt_sd _gt_sd _le_sd _ge_sd \ + _sd_to_si _sd_to_di _sd_to_usi _sd_to_udi \ + _si_to_sd _di_to_sd _usi_to_sd _udi_to_sd \ + _sd_to_sf _sd_to_df _sd_to_xf _sd_to_tf \ + _sf_to_sd _df_to_sd _xf_to_sd _tf_to_sd \ + _sd_to_dd _sd_to_td _unord_sd _conv_sd + +D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \ + _eq_dd _ne_dd _lt_dd _gt_dd _le_dd _ge_dd \ + _dd_to_si _dd_to_di _dd_to_usi _dd_to_udi \ + _si_to_dd _di_to_dd _usi_to_dd _udi_to_dd \ + _dd_to_sf _dd_to_df _dd_to_xf _dd_to_tf \ + _sf_to_dd _df_to_dd _xf_to_dd _tf_to_dd \ + _dd_to_sd _dd_to_td _unord_dd _conv_dd + +D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \ + _eq_td _ne_td _lt_td _gt_td _le_td _ge_td \ + _td_to_si _td_to_di _td_to_usi _td_to_udi \ + _si_to_td _di_to_td _usi_to_td _udi_to_td \ + _td_to_sf _td_to_df _td_to_xf _td_to_tf \ + _sf_to_td _df_to_td _xf_to_td _tf_to_td \ + _td_to_sd _td_to_dd _unord_td _conv_td + +# These might cause a divide overflow trap and so are compiled with +# unwinder info. +LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4 + +# +# Language makefile fragments. + +# The following targets define the interface between us and the languages. +# +# all.cross, start.encap, rest.encap, +# install-common, install-info, install-man, +# uninstall, +# mostlyclean, clean, distclean, maintainer-clean, +# +# Each language is linked in with a series of hooks. The name of each +# hooked is "lang.${target_name}" (eg: lang.info). Configure computes +# and adds these here. We use double-colon rules for some of the hooks; +# double-colon rules should be preferred for any new hooks. + +# language hooks, generated by configure +@language_hooks@ + +# per-language makefile fragments +ifneq ($(LANG_MAKEFRAGS),) +include $(LANG_MAKEFRAGS) +endif + +# target and host overrides must follow the per-language makefile fragments +# so they can override or augment language-specific variables + +# target overrides +ifneq ($(tmake_file),) +include $(tmake_file) +endif + +# host overrides +ifneq ($(xmake_file),) +include $(xmake_file) +endif + +# all-tree.def includes all the tree.def files. +all-tree.def: s-alltree; @true +s-alltree: Makefile + rm -f tmp-all-tree.def + echo '#include "tree.def"' > tmp-all-tree.def + echo 'END_OF_BASE_TREE_CODES' >> tmp-all-tree.def + echo '#include "c-common.def"' >> tmp-all-tree.def + ltf="$(lang_tree_files)"; for f in $$ltf; do \ + echo "#include \"$$f\""; \ + done | sed 's|$(srcdir)/||' >> tmp-all-tree.def + $(SHELL) $(srcdir)/../move-if-change tmp-all-tree.def all-tree.def + $(STAMP) s-alltree + +# + +# ----------------------------- +# Rebuilding this configuration +# ----------------------------- + +# On the use of stamps: +# Consider the example of tree-check.h. It is constructed with build/gencheck. +# A simple rule to build tree-check.h would be +# tree-check.h: build/gencheck$(build_exeext) +# $(RUN_GEN) build/gencheck$(build_exeext) > tree-check.h +# +# but tree-check.h doesn't change every time gencheck changes. It would the +# nice if targets that depend on tree-check.h wouldn't be rebuild +# unnecessarily when tree-check.h is unchanged. To make this, tree-check.h +# must not be overwritten with a identical copy. One solution is to use a +# temporary file +# tree-check.h: build/gencheck$(build_exeext) +# $(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h +# $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h +# +# This solution has a different problem. Since the time stamp of tree-check.h +# is unchanged, make will try to update tree-check.h every time it runs. +# To prevent this, one can add a stamp +# tree-check.h: s-check +# s-check : build/gencheck$(build_exeext) +# $(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h +# $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h +# $(STAMP) s-check +# +# The problem with this solution is that make thinks that tree-check.h is +# always unchanged. Make must be deceived into thinking that tree-check.h is +# rebuild by the "tree-check.h: s-check" rule. To do this, add a dummy command: +# tree-check.h: s-check; @true +# s-check : build/gencheck$(build_exeext) +# $(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h +# $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h +# $(STAMP) s-check +# +# This is what is done in this makefile. Note that mkconfig.sh has a +# move-if-change built-in + +Makefile: config.status $(srcdir)/Makefile.in $(LANG_MAKEFRAGS) + LANGUAGES="$(CONFIG_LANGUAGES)" \ + CONFIG_HEADERS= \ + CONFIG_SHELL="$(SHELL)" \ + CONFIG_FILES=$@ $(SHELL) config.status + +config.h: cs-config.h ; @true +bconfig.h: cs-bconfig.h ; @true +tconfig.h: cs-tconfig.h ; @true +tm.h: cs-tm.h ; @true +tm_p.h: cs-tm_p.h ; @true + +cs-config.h: Makefile + TARGET_CPU_DEFAULT="" \ + HEADERS="$(host_xm_include_list)" DEFINES="$(host_xm_defines)" \ + $(SHELL) $(srcdir)/mkconfig.sh config.h + +cs-bconfig.h: Makefile + TARGET_CPU_DEFAULT="" \ + HEADERS="$(build_xm_include_list)" DEFINES="$(build_xm_defines)" \ + $(SHELL) $(srcdir)/mkconfig.sh bconfig.h + +cs-tconfig.h: Makefile + TARGET_CPU_DEFAULT="" \ + HEADERS="$(xm_include_list)" DEFINES="USED_FOR_TARGET $(xm_defines)" \ + $(SHELL) $(srcdir)/mkconfig.sh tconfig.h + +cs-tm.h: Makefile + TARGET_CPU_DEFAULT="$(target_cpu_default)" \ + HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ + $(SHELL) $(srcdir)/mkconfig.sh tm.h + +cs-tm_p.h: Makefile + TARGET_CPU_DEFAULT="" \ + HEADERS="$(tm_p_include_list)" DEFINES="" \ + $(SHELL) $(srcdir)/mkconfig.sh tm_p.h + +# Don't automatically run autoconf, since configure.ac might be accidentally +# newer than configure. Also, this writes into the source directory which +# might be on a read-only file system. If configured for maintainer mode +# then do allow autoconf to be run. + +$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(srcdir)/aclocal.m4 \ + $(srcdir)/acinclude.m4 + (cd $(srcdir) && autoconf) + +gccbug: $(srcdir)/gccbug.in + CONFIG_FILES=gccbug CONFIG_HEADERS= ./config.status + +# cstamp-h.in controls rebuilding of config.in. +# It is named cstamp-h.in and not stamp-h.in so the mostlyclean rule doesn't +# delete it. A stamp file is needed as autoheader won't update the file if +# nothing has changed. +# It remains in the source directory and is part of the distribution. +# This follows what is done in shellutils, fileutils, etc. +# "echo timestamp" is used instead of touch to be consistent with other +# packages that use autoconf (??? perhaps also to avoid problems with patch?). +# ??? Newer versions have a maintainer mode that may be useful here. + +# Don't run autoheader automatically either. +# Only run it if maintainer mode is enabled. +@MAINT@ $(srcdir)/config.in: $(srcdir)/cstamp-h.in +@MAINT@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.ac +@MAINT@ (cd $(srcdir) && autoheader) +@MAINT@ @rm -f $(srcdir)/cstamp-h.in +@MAINT@ echo timestamp > $(srcdir)/cstamp-h.in +auto-host.h: cstamp-h ; @true +cstamp-h: config.in config.status + CONFIG_HEADERS=auto-host.h:config.in \ + CONFIG_FILES= \ + LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status + +# Really, really stupid make features, such as SUN's KEEP_STATE, may force +# a target to build even if it is up-to-date. So we must verify that +# config.status does not exist before failing. +config.status: $(srcdir)/configure $(srcdir)/config.gcc + @if [ ! -f config.status ] ; then \ + echo You must configure gcc. Look at http://gcc.gnu.org/install/ for details.; \ + false; \ + else \ + LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \ + fi + +# -------- +# UNSORTED +# -------- + +# Provide quickstrap as a target that people can type into the gcc directory, +# and that fails if you're not into it. +quickstrap: all + cd $(toplevel_builddir) && $(MAKE) all-target-libgcc + +all.internal: start.encap rest.encap doc +# This is what to compile if making a cross-compiler. +all.cross: native gcc-cross$(exeext) cpp$(exeext) specs \ + libgcc-support lang.all.cross doc @GENINSRC@ srcextra +# This is what must be made before installing GCC and converting libraries. +start.encap: native xgcc$(exeext) cpp$(exeext) specs \ + libgcc-support lang.start.encap @GENINSRC@ srcextra +# These can't be made until after GCC can run. +rest.encap: $(STMP_FIXPROTO) lang.rest.encap +# This is what is made with the host's compiler +# whether making a cross compiler or not. +native: config.status auto-host.h build-@POSUB@ $(LANGUAGES) \ + $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(COLLECT2) + +# Define the names for selecting languages in LANGUAGES. +c: cc1$(exeext) + +# Tell GNU make these are phony targets. +.PHONY: c proto + +# On the target machine, finish building a cross compiler. +# This does the things that can't be done on the host machine. +rest.cross: specs + +# Recompile all the language-independent object files. +# This is used only if the user explicitly asks for it. +compilations: $(BACKEND) + +# This archive is strictly for the host. +libbackend.a: $(OBJS@onestep@) + -rm -rf libbackend.a + $(AR) $(AR_FLAGS) libbackend.a $(OBJS@onestep@) + -$(RANLIB) $(RANLIB_FLAGS) libbackend.a + +# We call this executable `xgcc' rather than `gcc' +# to avoid confusion if the current directory is in the path +# and CC is `gcc'. It is renamed to `gcc' when it is installed. +xgcc$(exeext): $(GCC_OBJS) gccspec.o version.o intl.o prefix.o \ + version.o $(LIBDEPS) $(EXTRA_GCC_OBJS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) gccspec.o \ + intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS) + +# cpp is to cpp0 as gcc is to cc1. +# The only difference from xgcc is that it's linked with cppspec.o +# instead of gccspec.o. +cpp$(exeext): $(GCC_OBJS) cppspec.o version.o intl.o prefix.o \ + version.o $(LIBDEPS) $(EXTRA_GCC_OBJS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) cppspec.o \ + intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS) + +# Dump a specs file to make -B./ read these specs over installed ones. +$(SPECS): xgcc$(exeext) + $(GCC_FOR_TARGET) -dumpspecs > tmp-specs + mv tmp-specs $(SPECS) + +# We do want to create an executable named `xgcc', so we can use it to +# compile libgcc2.a. +# Also create gcc-cross, so that install-common will install properly. +gcc-cross$(exeext): xgcc$(exeext) + cp xgcc$(exeext) gcc-cross$(exeext) + +dummy-checksum.o : dummy-checksum.c + +cc1-dummy$(exeext): $(C_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) dummy-checksum.o \ + $(BACKEND) $(LIBS) $(BACKENDLIBS) + +cc1-checksum.c : cc1-dummy$(exeext) build/genchecksum$(build_exeext) + build/genchecksum$(build_exeext) cc1-dummy$(exeext) > $@ + +cc1-checksum.o : cc1-checksum.c + +cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) cc1-checksum.o \ + $(BACKEND) $(LIBS) $(BACKENDLIBS) + +# icg + +# ICG object files from "real" (non-generated) source files. +ICG_OBJS = icg.o icg-build-tree.o icg-color.o icg-costs.o icg-debug.o \ + icg-emit.o icg-final.o icg-graph.o icg-names.o icg-remat.o \ + icg-reassociate.o icg-rewrite.o icg-select.o icg-spill.o icg-ssa.o \ + icg-supairs.o icg-forward-prop.o + +# ICG headers required for _any_ of the ICG_OBJS files. +ICG_COMMON_H = $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(BASIC_BLOCK_H) $(FUNCTION_H) tree-pass.h hard-reg-set.h \ + insn-config.h $(RECOG_H) $(FLAGS_H) $(BASIC_BLOCK_H) $(DF_H) \ + tree-flow.h domwalk.h vec.h vecprim.h sparseset.h + +PLUG_DIR = icg-tools/plug +plug: $(PLUG_DIR)/plug.c + $(CC) -g -Wall -o $@ $< + +PLUGSPEC_PYOUT = \ + icg-grammars/x86-64.gr.pyout \ + icg-grammars/x86-64.float.pyout \ + icg-grammars/x86-64.int.pyout \ + icg-grammars/x86-64.misc.pyout \ + icg-grammars/x86-64.string.pyout \ + icg-grammars/x86-64.asm.pyout \ +# +PLUGSPEC_INPUT = \ + $(PLUGSPEC_PYOUT) \ + $(ICG_COMMON_H) \ + icg.h \ +# + +PLUGSPEC_OUTPUT = \ + icg.burg \ + icg-opcode.h \ + icg-ruleinfo.h \ + icg-rulemaps.c \ + icg-opcode-names.c \ + icg-names.cases \ + icg-kinds.cases \ + icg-supairs.cases \ + icg-build.cases \ + icg-coalesce.cases \ + icg-costs.cases \ + icg-remat.cases \ + icg-spill.cases \ + icg-debug.cases \ + icg-final.cases \ + icg-emit.cases \ + icg-targeting.cases \ +# + +# This bit of Makefile trickery forces all plug output files except +# icg.burg to depend upon icg.burg. This ensures that plug is only +# run once. +$(filter-out icg.burg, $(PLUGSPEC_OUTPUT)): icg.burg + +# Object files built from plug-generated sources. +icg-rulemaps.o: icg-rulemaps.c icg-ruleinfo.h +icg-opcode-names.o: icg-opcode-names.c icg-opcode.h + +icg.burg: icg-grammars/x86-64.gr $(PLUGSPEC_INPUT) $(PLUGSPEC_PYOUT) plug + cat \ + $(srcdir)/icg-grammars/x86-64.gr \ + $(PLUGSPEC_PYOUT:%=$(srcdir)/%) \ + | ./plug \ + > icg.burg + +# +# TODO: this writes into the srcdir, which is a BIG no no. +# the weird include semantics and weird line number tracing in plug +# probably preclude using ./ to put the pyout files. +# +icg-grammars/%.pyout: icg-grammars/%.py icg-grammars/plug.py + python $< > $(srcdir)/$@ + +IBURG_DIR = icg-tools/iburg +iburg: pluggram.c $(IBURG_DIR)/iburg.c + $(CC) -g -o $@ -iquote $(srcdir)/$(IBURG_DIR) $+ +pluggram.c: $(IBURG_DIR)/gram.y + $(YACC) -o $@ $< + +icg-burg.c: icg.burg iburg + ./iburg -I -p icg_burm icg.burg > icg-burg.c + +$(ICG_OBJS): icg.h icg-opcode.h $(ICG_COMMON_H) $(PLUGSPEC_OUTPUT) + +# +# Build libgcc.a. + +LIB2ADD = $(LIB2FUNCS_EXTRA) +LIB2ADD_ST = $(LIB2FUNCS_STATIC_EXTRA) + +# All source files for libgcc are either in the source directory (in +# which case they will start with $(srcdir)), or generated into the build +# directory (in which case they will be relative paths). +srcdirify = $(patsubst $(srcdir)%,$$(gcc_srcdir)%,$(filter $(srcdir)%,$(1))) \ + $(patsubst %,$$(gcc_objdir)/%,$(filter-out $(srcdir)%,$(1))) + +# The distinction between these two variables is no longer relevant, +# so we combine them. Sort removes duplicates. +GCC_EXTRA_PARTS := $(sort $(EXTRA_MULTILIB_PARTS) $(EXTRA_PARTS)) + +libgcc-support: libgcc.mvars stmp-int-hdrs $(STMP_FIXPROTO) $(TCONFIG_H) \ + $(MACHMODE_H) $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \ + $(LIB2ADD_ST) $(LIB2ADDEH) $(srcdir)/emutls.c gcov-iov.h $(SFP_MACHINE) + +libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \ + xgcc$(exeext) + : > tmp-libgcc.mvars + echo LIB1ASMFUNCS = '$(LIB1ASMFUNCS)' >> tmp-libgcc.mvars + echo LIB1ASMSRC = '$(LIB1ASMSRC)' >> tmp-libgcc.mvars + echo LIB2FUNCS_ST = '$(LIB2FUNCS_ST)' >> tmp-libgcc.mvars + echo LIB2FUNCS_EXCLUDE = '$(LIB2FUNCS_EXCLUDE)' >> tmp-libgcc.mvars + echo LIBGCOV = '$(LIBGCOV)' >> tmp-libgcc.mvars + echo LIB2ADD = '$(call srcdirify,$(LIB2ADD))' >> tmp-libgcc.mvars + echo LIB2ADD_ST = '$(call srcdirify,$(LIB2ADD_ST))' >> tmp-libgcc.mvars + echo LIB2ADDEH = '$(call srcdirify,$(LIB2ADDEH) $(srcdir)/emutls.c)' >> tmp-libgcc.mvars + echo LIB2ADDEHSTATIC = '$(call srcdirify,$(LIB2ADDEHSTATIC) $(srcdir)/emutls.c)' >> tmp-libgcc.mvars + echo LIB2ADDEHSHARED = '$(call srcdirify,$(LIB2ADDEHSHARED) $(srcdir)/emutls.c)' >> tmp-libgcc.mvars + echo LIB2_SIDITI_CONV_FUNCS = '$(LIB2_SIDITI_CONV_FUNCS)' >> tmp-libgcc.mvars + echo LIBUNWIND = '$(call srcdirify,$(LIBUNWIND))' >> tmp-libgcc.mvars + echo SHLIBUNWIND_LINK = '$(SHLIBUNWIND_LINK)' >> tmp-libgcc.mvars + echo SHLIBUNWIND_INSTALL = '$(SHLIBUNWIND_INSTALL)' >> tmp-libgcc.mvars + echo FPBIT = '$(FPBIT)' >> tmp-libgcc.mvars + echo FPBIT_FUNCS = '$(FPBIT_FUNCS)' >> tmp-libgcc.mvars + echo LIB2_DIVMOD_FUNCS = '$(LIB2_DIVMOD_FUNCS)' >> tmp-libgcc.mvars + echo DPBIT = '$(DPBIT)' >> tmp-libgcc.mvars + echo DPBIT_FUNCS = '$(DPBIT_FUNCS)' >> tmp-libgcc.mvars + echo TPBIT = '$(TPBIT)' >> tmp-libgcc.mvars + echo TPBIT_FUNCS = '$(TPBIT_FUNCS)' >> tmp-libgcc.mvars + echo DFP_ENABLE = '$(DFP_ENABLE)' >> tmp-libgcc.mvars + echo DFP_CFLAGS='$(DFP_CFLAGS)' >> tmp-libgcc.mvars + echo D32PBIT='$(D32PBIT)' >> tmp-libgcc.mvars + echo D32PBIT_FUNCS='$(D32PBIT_FUNCS)' >> tmp-libgcc.mvars + echo D64PBIT='$(D64PBIT)' >> tmp-libgcc.mvars + echo D64PBIT_FUNCS='$(D64PBIT_FUNCS)' >> tmp-libgcc.mvars + echo D128PBIT='$(D128PBIT)' >> tmp-libgcc.mvars + echo D128PBIT_FUNCS='$(D128PBIT_FUNCS)' >> tmp-libgcc.mvars + echo GCC_EXTRA_PARTS = '$(GCC_EXTRA_PARTS)' >> tmp-libgcc.mvars + echo SHLIB_LINK = '$(subst $(GCC_FOR_TARGET),$$(GCC_FOR_TARGET),$(SHLIB_LINK))' >> tmp-libgcc.mvars + echo SHLIB_INSTALL = '$(SHLIB_INSTALL)' >> tmp-libgcc.mvars + echo SHLIB_EXT = '$(SHLIB_EXT)' >> tmp-libgcc.mvars + echo SHLIB_MKMAP = '$(call srcdirify,$(SHLIB_MKMAP))' >> tmp-libgcc.mvars + echo SHLIB_MKMAP_OPTS = '$(SHLIB_MKMAP_OPTS)' >> tmp-libgcc.mvars + echo SHLIB_MAPFILES = '$(call srcdirify,$(SHLIB_MAPFILES))' >> tmp-libgcc.mvars + echo SHLIB_NM_FLAGS = '$(SHLIB_NM_FLAGS)' >> tmp-libgcc.mvars + echo LIBGCC2_CFLAGS = '$(LIBGCC2_CFLAGS)' >> tmp-libgcc.mvars + echo TARGET_LIBGCC2_CFLAGS = '$(TARGET_LIBGCC2_CFLAGS)' >> tmp-libgcc.mvars + echo LIBGCC_SYNC = '$(LIBGCC_SYNC)' >> tmp-libgcc.mvars + echo LIBGCC_SYNC_CFLAGS = '$(LIBGCC_SYNC_CFLAGS)' >> tmp-libgcc.mvars + echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars + echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars + echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars + + mv tmp-libgcc.mvars libgcc.mvars + +# Use the genmultilib shell script to generate the information the gcc +# driver program needs to select the library directory based on the +# switches. +multilib.h: s-mlib; @true +s-mlib: $(srcdir)/genmultilib Makefile + if test @enable_multilib@ = yes \ + || test -n "$(MULTILIB_OSDIRNAMES)"; then \ + $(SHELL) $(srcdir)/genmultilib \ + "$(MULTILIB_OPTIONS)" \ + "$(MULTILIB_DIRNAMES)" \ + "$(MULTILIB_MATCHES)" \ + "$(MULTILIB_EXCEPTIONS)" \ + "$(MULTILIB_EXTRA_OPTS)" \ + "$(MULTILIB_EXCLUSIONS)" \ + "$(MULTILIB_OSDIRNAMES)" \ + "@enable_multilib@" \ + > tmp-mlib.h; \ + else \ + $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \ + > tmp-mlib.h; \ + fi + $(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h + $(STAMP) s-mlib + +# Compile two additional files that are linked with every program +# linked using GCC on systems using COFF or ELF, for the sake of C++ +# constructors. +$(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN \ + -o $(T)crtbegin$(objext) + +$(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_END \ + -o $(T)crtend$(objext) + +# These are versions of crtbegin and crtend for shared libraries. +$(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O \ + -o $(T)crtbeginS$(objext) + +$(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \ + -c $(srcdir)/crtstuff.c -DCRT_END -DCRTSTUFFS_O \ + -o $(T)crtendS$(objext) + +# This is a version of crtbegin for -static links. +$(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \ + -o $(T)crtbeginT$(objext) + +# Compile the start modules crt0.o and mcrt0.o that are linked with +# every program +$(T)crt0.o: s-crt0 ; @true +$(T)mcrt0.o: s-crt0; @true + +s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \ + -o $(T)crt0.o -c $(CRT0_S) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \ + -o $(T)mcrt0.o -c $(MCRT0_S) + $(STAMP) s-crt0 +# +# Compiling object files from source files. + +# Note that dependencies on obstack.h are not written +# because that file is not part of GCC. + +# C language specific files. + +c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(C_TREE_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TM_P_H) +c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \ + $(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \ + vec.h $(TARGET_H) $(CGRAPH_H) + +srcextra: gcc.srcextra lang.srcextra + +gcc.srcextra: gengtype-lex.c + -cp -p $^ $(srcdir) + +incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \ + intl.h prefix.h coretypes.h $(TM_H) cppdefault.h $(TARGET_H) \ + $(MACHMODE_H) + +c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) $(FLAGS_H) $(FUNCTION_H) output.h \ + $(EXPR_H) debug.h $(TOPLEV_H) intl.h $(TM_P_H) $(TREE_INLINE_H) $(TIMEVAR_H) \ + opts.h $(C_PRAGMA_H) gt-c-decl.h $(CGRAPH_H) $(HASHTAB_H) libfuncs.h \ + except.h $(LANGHOOKS_DEF_H) $(TREE_DUMP_H) $(C_COMMON_H) $(CPPLIB_H) \ + $(DIAGNOSTIC_H) $(INPUT_H) langhooks.h $(GIMPLE_H) tree-mudflap.h \ + pointer-set.h $(BASIC_BLOCK_H) $(GIMPLE_H) tree-iterator.h +c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h output.h $(EXPR_H) \ + $(RTL_H) $(TOPLEV_H) $(TM_P_H) langhooks.h $(GGC_H) $(TREE_FLOW_H) \ + $(GIMPLE_H) tree-iterator.h +c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(C_TREE_H) $(DIAGNOSTIC_H) \ + $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h \ + c-objc-common.h $(C_PRAGMA_H) c-common.def $(TREE_INLINE_H) +stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ + $(C_COMMON_H) +c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) debug.h $(C_TREE_H) $(C_COMMON_H) $(REAL_H) $(SPLAY_TREE_H) \ + $(C_PRAGMA_H) $(INPUT_H) intl.h $(FLAGS_H) $(TOPLEV_H) output.h \ + $(CPPLIB_H) $(TARGET_H) $(TIMEVAR_H) $(TM_P_H) +c-ppoutput.o : c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(C_COMMON_H) $(TREE_H) $(CPPLIB_H) $(CPP_INTERNAL_H) $(C_PRAGMA_H) +c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(C_TREE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \ + $(FUNCTION_H) $(FLAGS_H) $(TOPLEV_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(VARRAY_H) \ + langhooks.h $(GGC_H) $(TARGET_H) $(C_PRETTY_PRINT_H) c-objc-common.h \ + tree-mudflap.h +c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(C_TREE_H) $(FLAGS_H) $(TOPLEV_H) +c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(FLAGS_H) $(TOPLEV_H) $(C_COMMON_H) convert.h $(C_TREE_H) \ + langhooks.h $(TARGET_H) +c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FUNCTION_H) $(C_PRAGMA_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \ + $(C_COMMON_H) $(TARGET_H) gt-c-pragma.h $(CPPLIB_H) $(FLAGS_H) $(DIAGNOSTIC_H) \ + opts.h +graph.o: graph.c $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) $(FLAGS_H) output.h \ + $(RTL_H) $(FUNCTION_H) hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(OBSTACK_H) \ + $(CONFIG_H) +sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) +ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(EBITMAP_H) $(RTL_H) $(FLAGS_H) $(OBSTACK_H) +sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H) + +COLLECT2_OBJS = collect2.o tlink.o intl.o version.o +COLLECT2_LIBS = @COLLECT2_LIBS@ +collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) +# Don't try modifying collect2 (aka ld) in place--it might be linking this. + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o T$@ \ + $(COLLECT2_OBJS) $(LIBS) $(COLLECT2_LIBS) + mv -f T$@ $@ + +collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \ + $(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DTARGET_MACHINE=\"$(target_noncanonical)\" \ + -c $(srcdir)/collect2.c $(OUTPUT_OPTION) + +tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(OBSTACK_H) collect2.h intl.h + +# A file used by all variants of C. + +c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) output.h $(C_PRAGMA_H) \ + $(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \ + $(DIAGNOSTIC_H) gt-c-common.h langhooks.h $(VARRAY_H) $(RTL_H) \ + $(TARGET_H) $(C_TREE_H) tree-iterator.h langhooks.h tree-mudflap.h \ + intl.h opts.h $(REAL_H) $(CPPLIB_H) $(TREE_INLINE_H) $(HASHTAB_H) \ + $(BUILTINS_DEF) $(CGRAPH_H) $(BASIC_BLOCK_H) $(TARGET_DEF_H) \ + $(GIMPLE_H) + +c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \ + $(C_TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(REAL_H) \ + $(DIAGNOSTIC_H) tree-iterator.h fixed-value.h + +c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) langhooks.h \ + $(TREE_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) \ + opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \ + $(TM_P_H) $(VARRAY_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@ + +c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) $(FLAGS_H) \ + $(TOPLEV_H) output.h except.h $(REAL_H) $(TARGET_H) $(TM_P_H) \ + $(BASEVER) debug.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) -DBASEVER=$(BASEVER_s) \ + $< $(OUTPUT_OPTION) + +# A file used by all variants of C and some other languages. + +attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) $(TM_P_H) \ + $(TARGET_H) langhooks.h $(CPPLIB_H) + +c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) langhooks.h \ + $(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) alloc-pool.h \ + c-format.h + +c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) \ + $(PREDICT_H) $(TREE_INLINE_H) $(C_COMMON_H) except.h $(FUNCTION_H) \ + langhooks.h $(SPLAY_TREE_H) $(TIMEVAR_H) $(GIMPLE_H) \ + $(VARRAY_H) tree-iterator.h + +c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(C_TREE_H) $(TREE_DUMP_H) + +c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \ + $(C_COMMON_H) output.h $(TOPLEV_H) $(C_PRAGMA_H) $(GGC_H) debug.h \ + langhooks.h $(FLAGS_H) hosthooks.h version.h $(TARGET_H) opts.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \ + $< $(OUTPUT_OPTION) + +c-omp.o : c-omp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(FUNCTION_H) $(C_COMMON_H) $(TOPLEV.H) $(GIMPLE_H) $(BITMAP_H) \ + langhooks.h + +# Language-independent files. + +DRIVER_DEFINES = \ + -DSTANDARD_STARTFILE_PREFIX=\"$(unlibsubdir)/\" \ + -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc/\" \ + -DSTANDARD_LIBEXEC_PREFIX=\"$(libexecdir)/gcc/\" \ + -DDEFAULT_TARGET_VERSION=\"$(version)\" \ + -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" \ + -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \ + -DTOOLDIR_BASE_PREFIX=\"$(libsubdir_to_prefix)$(prefix_to_exec_prefix)\" \ + @TARGET_SYSTEM_ROOT_DEFINE@ \ + $(VALGRIND_DRIVER_DEFINES) \ + `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"` + +gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h multilib.h \ + Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H) $(FLAGS_H) \ + configargs.h $(OBSTACK_H) opts.h + (SHLIB_LINK='$(SHLIB_LINK)'; \ + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(DRIVER_DEFINES) \ + -c $(srcdir)/gcc.c $(OUTPUT_OPTION)) + +gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) + (SHLIB_LINK='$(SHLIB_LINK)'; \ + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(DRIVER_DEFINES) \ + -c $(srcdir)/gccspec.c $(OUTPUT_OPTION)) + +cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) + +specs.h : s-specs ; @true +s-specs : Makefile + lsf="$(lang_specs_files)"; for f in $$lsf; do \ + echo "#include \"$$f\""; \ + done | sed 's|$(srcdir)/||' > tmp-specs.h + $(SHELL) $(srcdir)/../move-if-change tmp-specs.h specs.h + $(STAMP) s-specs + +optionlist: s-options ; @true +s-options: $(ALL_OPT_FILES) Makefile $(srcdir)/opt-gather.awk + $(AWK) -f $(srcdir)/opt-gather.awk $(ALL_OPT_FILES) > tmp-optionlist + $(SHELL) $(srcdir)/../move-if-change tmp-optionlist optionlist + $(STAMP) s-options + +options.c: optionlist $(srcdir)/opt-functions.awk $(srcdir)/optc-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/optc-gen.awk \ + -v header_name="config.h system.h coretypes.h tm.h" < $< > $@ + +options.h: s-options-h ; @true +s-options-h: optionlist $(srcdir)/opt-functions.awk $(srcdir)/opth-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/opth-gen.awk \ + < $< > tmp-options.h + $(SHELL) $(srcdir)/../move-if-change tmp-options.h options.h + $(STAMP) $@ + +options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) $(FLAGS_H) \ + $(TM_H) opts.h intl.h + +gcc-options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) opts.h intl.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(OUTPUT_OPTION) -DGCC_DRIVER options.c + +dumpvers: dumpvers.c + +ifdef REVISION_s +version.o: version.c version.h $(REVISION) $(DATESTAMP) $(BASEVER) $(DEVPHASE) +else +version.o: version.c version.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) +endif + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ + -DREVISION=$(REVISION_s) \ + -DDEVPHASE=$(DEVPHASE_s) -DPKGVERSION=$(PKGVERSION_s) \ + -DBUGURL=$(BUGURL_s) -c $(srcdir)/version.c $(OUTPUT_OPTION) + +gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) $(OBSTACK_H) $(BITMAP_H) \ + input.h $(TREE_H) $(RTL_H) $(FUNCTION_H) insn-config.h $(EXPR_H) \ + hard-reg-set.h $(BASIC_BLOCK_H) cselib.h $(INSN_ADDR_H) $(OPTABS_H) \ + libfuncs.h debug.h $(GGC_H) $(CGRAPH_H) $(TREE_FLOW_H) reload.h \ + $(CPP_ID_DATA_H) tree-chrec.h $(CFGLAYOUT_H) except.h output.h \ + $(CFGLOOP_H) + +ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \ + $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h $(HOSTHOOKS_DEF_H) + +ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ + $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) $(TREE_FLOW_H) + +ggc-zone.o: ggc-zone.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) \ + $(PARAMS_H) $(BITMAP_H) $(VARRAY_H) + +ggc-none.o: ggc-none.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \ + $(BCONFIG_H) + +stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(GGC_H) gt-stringpool.h $(CPPLIB_H) $(SYMTAB_H) + +prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) prefix.h \ + Makefile $(BASEVER) + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DPREFIX=\"$(prefix)\" -DBASEVER=$(BASEVER_s) \ + -c $(srcdir)/prefix.c $(OUTPUT_OPTION) + +convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(FLAGS_H) convert.h $(TOPLEV_H) langhooks.h $(REAL_H) fixed-value.h + +double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) + +langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \ + langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \ + intl.h $(GIMPLE_H) +tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \ + $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \ + $(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ + $(OBSTACK_H) pointer-set.h fixed-value.h +tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \ + tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h +tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \ + $(VARRAY_H) $(HASHTAB_H) $(TOPLEV_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \ + intl.h $(FUNCTION_H) $(GGC_H) $(GIMPLE_H) \ + debug.h $(DIAGNOSTIC_H) except.h $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \ + $(IPA_PROP_H) value-prof.h tree-pass.h $(TARGET_H) $(INTEGRATE_H) +print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) +stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) output.h $(RTL_H) \ + $(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \ + $(TOPLEV_H) +tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \ + $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \ + $(FLAGS_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) output.h \ + $(DIAGNOSTIC_H) $(TREE_H) $(C_COMMON_H) $(TREE_FLOW_H) $(TREE_INLINE_H) varray.h \ + $(C_TREE_H) $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) tree-pass.h \ + $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) gt-tree-ssa-structalias.h \ + $(CGRAPH_H) $(ALIAS_H) pointer-set.h +tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) $(BITMAP_H) \ + $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \ + $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) +tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ + $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + langhooks.h domwalk.h tree-pass.h $(GGC_H) $(PARAMS_H) $(BASIC_BLOCK_H) \ + $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \ + $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h +tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(TREE_SSA_LIVE_H) $(BITMAP_H) +tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) $(TOPLEV_H) +tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) $(TOPLEV_H) +tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \ + $(DIAGNOSTIC_H) $(TIMEVAR_H) +tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ + langhooks.h $(FLAGS_H) $(GIMPLE_H) +tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ + langhooks.h $(FLAGS_H) +tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) +tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \ + $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h +tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(RTL_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(EXPR_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \ + langhooks.h +tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ + $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(BASIC_BLOCK_H) tree-pass.h langhooks.h tree-ssa-propagate.h $(FLAGS_H) +tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \ + $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \ + tree-ssa-propagate.h vec.h value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \ + $(VARRAY_H) $(GIMPLE_H) +tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ + $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(BASIC_BLOCK_H) domwalk.h tree-pass.h $(FLAGS_H) langhooks.h \ + tree-ssa-propagate.h $(CFGLOOP_H) $(PARAMS_H) $(REAL_H) +tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \ + $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) $(BASIC_BLOCK_H) domwalk.h tree-pass.h $(FLAGS_H) \ + langhooks.h tree-ssa-propagate.h $(REAL_H) +tree-ssa-threadedge.o : tree-ssa-threadedge.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(FLAGS_H) $(RTL_H) $(TM_P_H) $(GGC_H) \ + $(BASIC_BLOCK_H) $(CFGLOOP_H) output.h $(EXPR_H) \ + $(FUNCTION_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TREE_DUMP_H) $(TREE_FLOW_H) \ + domwalk.h $(REAL_H) tree-pass.h tree-ssa-propagate.h langhooks.h $(PARAMS_H) +tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \ + $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(BASIC_BLOCK_H) $(FLAGS_H) tree-pass.h $(CFGLOOP_H) +tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(TREE_FLOW_H) +tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ + gt-tree-phinodes.h $(RTL_H) $(TOPLEV.H) $(GIMPLE_H) +domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H) +tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(TREE_SSA_LIVE_H) $(BITMAP_H) $(TOPLEV_H) debug.h $(FLAGS_H) +tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) tree-pass.h \ + $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \ + $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) langhooks.h $(GIMPLE_H) \ + $(TREE_INLINE_H) $(GIMPLE_H) +tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \ + $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) langhooks.h $(CFGLOOP_H) \ + alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \ + $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \ + $(DBGCNT_H) +tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \ + $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \ + alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) langhooks.h $(HASHTAB_H) $(GIMPLE_H) \ + $(TREE_INLINE_H) tree-iterator.h tree-ssa-propagate.h tree-ssa-sccvn.h \ + $(PARAMS_H) +tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(GGC_H) \ + $(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \ + $(CFGLOOP_H) tree-chrec.h $(TIMEVAR_H) $(TOPLEV_H) intl.h +tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \ + $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \ + $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(TOPLEV_H) \ + value-prof.h tree-ssa-propagate.h $(TREE_INLINE_H) +tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \ + $(DIAGNOSTIC_H) $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \ + $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) $(TOPLEV_H) \ + tree-ssa-propagate.h tree-scalar-evolution.h +rtl-factoring.o : rtl-factoring.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ + coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(RESOURCE_H) $(GGC_H) $(REGS_H) \ + $(PARAMS_H) $(EXPR_H) addresses.h $(TM_P_H) tree-pass.h $(TREE_FLOW_H) \ + $(TIMEVAR_H) output.h $(DF_H) +tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) $(DIAGNOSTIC_H) except.h tree-pass.h $(FLAGS_H) langhooks.h \ + $(BASIC_BLOCK_H) hard-reg-set.h $(DBGCNT_H) +tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ + $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) alloc-pool.h \ + $(BASIC_BLOCK_H) $(BITMAP_H) $(CFGLOOP_H) $(FIBHEAP_H) $(HASHTAB_H) \ + langhooks.h $(REAL_H) $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h +tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \ + $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(TREE_DUMP_H) $(TREE_INLINE_H) \ + tree-iterator.h $(GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \ + $(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h +tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ + $(CFGLOOP_H) $(RTL_H) $(C_COMMON_H) tree-chrec.h $(TREE_DATA_REF_H) \ + $(SCEV_H) tree-pass.h $(DIAGNOSTIC_H) $(TARGET_H) $(TREE_DUMP_H) \ + $(VARRAY_H) +tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + coretypes.h $(GGC_H) tree-iterator.h $(GIMPLE_H) gt-tree-iterator.h +tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ + $(TREE_INLINE_H) $(HASHTAB_H) pointer-set.h $(FLAGS_H) $(FUNCTION_H) \ + $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h $(TREE_DUMP_H) \ + tree-pass.h $(PARAMS_H) $(CGRAPH_H) $(BASIC_BLOCK_H) hard-reg-set.h \ + $(GIMPLE_H) +tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ + $(FLAGS_H) $(FUNCTION_H) $(TM_H) $(TIMEVAR_H) tree-pass.h $(TOPLEV_H) \ + coretypes.h langhooks.h $(IPA_REFERENCE_H) +tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) except.h langhooks.h \ + $(GGC_H) tree-pass.h coretypes.h $(TIMEVAR_H) $(TM_P_H) pointer-set.h \ + $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h $(TOPLEV_H) +tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) output.h \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) tree-pass.h $(TIMEVAR_H) \ + $(CFGLOOP_H) $(FLAGS_H) $(TREE_INLINE_H) tree-scalar-evolution.h +tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) \ + $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \ + domwalk.h $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \ + coretypes.h $(TREE_DUMP_H) tree-pass.h $(BASIC_BLOCK_H) hard-reg-set.h \ + $(TREE_INLINE_H) +tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \ + output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + tree-pass.h $(FLAGS_H) $(TREE_INLINE_H) $(RECOG_H) insn-config.h $(EXPR_H) \ + gt-tree-ssa-address.h $(GGC_H) tree-affine.h +tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \ + $(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(TOPLEV_H) $(FLAGS_H) tree-pass.h $(SCEV_H) $(TREE_DATA_REF_H) $(BASIC_BLOCK_H) \ + $(GGC_H) hard-reg-set.h tree-chrec.h intl.h +tree-ssa-loop-ivcanon.o : tree-ssa-loop-ivcanon.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \ + $(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(FLAGS_H) tree-pass.h $(SCEV_H) $(BASIC_BLOCK_H) $(GGC_H) hard-reg-set.h \ + tree-chrec.h +tree-ssa-loop-ch.o : tree-ssa-loop-ch.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(TREE_INLINE_H) \ + output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) hard-reg-set.h +tree-ssa-loop-prefetch.o: tree-ssa-loop-prefetch.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \ + output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \ + $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \ + tree-chrec.h $(TOPLEV_H) langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \ + $(OPTABS_H) +tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ + $(CFGLOOP_H) $(TREE_FLOW_H) $(GGC_H) $(TREE_DATA_REF_H) $(SCEV_H) \ + $(PARAMS_H) $(DIAGNOSTIC_H) tree-pass.h $(TM_H) coretypes.h tree-affine.h \ + $(TREE_INLINE_H) +tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \ + output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \ + $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \ + tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H) +tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \ + output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H) +tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h \ + $(BASIC_BLOCK_H) output.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \ + $(TIMEVAR_H) $(CFGLOOP_H) tree-pass.h $(CFGLAYOUT_H) tree-scalar-evolution.h \ + $(PARAMS_H) $(TREE_INLINE_H) +tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \ + $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(REAL_H) $(BASIC_BLOCK_H) \ + hard-reg-set.h pointer-set.h tree-affine.h tree-ssa-propagate.h +tree-ssa-math-opts.o : tree-ssa-math-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_FLOW_H) $(REAL_H) $(TIMEVAR_H) tree-pass.h \ + alloc-pool.h $(BASIC_BLOCK_H) $(TARGET_H) +tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(TREE_INLINE_H) $(FLAGS_H) \ + $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \ + $(TREE_DUMP_H) tree-pass.h $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + hard-reg-set.h $(GIMPLE_H) vec.h tree-ssa-structalias.h \ + $(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h +tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ + $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\ + $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) vec.h langhooks.h \ + alloc-pool.h pointer-set.h $(CFGLOOP_H) +tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(EXPR_H) $(GGC_H) output.h \ + $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h $(FLAGS_H) $(CGRAPH_H) \ + $(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) tree-pass.h \ + $(CFGLOOP_H) except.h + +c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(C_TREE_H) $(C_COMMON_H) $(DIAGNOSTIC_H) $(GIMPLE_H) $(VARRAY_H) \ + $(FLAGS_H) langhooks.h $(TOPLEV_H) $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \ + $(TM_H) coretypes.h $(C_PRETTY_PRINT_H) $(CGRAPH_H) $(BASIC_BLOCK_H) \ + hard-reg-set.h $(TREE_DUMP_H) $(TREE_INLINE_H) +gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \ + $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \ + $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \ + coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \ + $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \ + $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h +gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h +gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \ + $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) tree-pass.h \ + $(HASHTAB_H) $(TOPLEV.H) tree-iterator.h +omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_H) \ + $(TREE_FLOW_H) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) $(TOPLEV_H) tree-pass.h \ + $(GGC_H) except.h $(SPLAY_TREE_H) $(OPTABS_H) $(CFGLOOP_H) \ + tree-iterator.h +tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \ + $(TM_H) coretypes.h +omega.o : omega.c omega.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + errors.h $(GGC_H) $(TREE_H) $(DIAGNOSTIC_H) varray.h tree-pass.h $(PARAMS_H) +tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(REAL_H) $(SCEV_H) tree-pass.h $(PARAMS_H) \ + $(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H) +tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \ + $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \ + $(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h \ + gt-tree-scalar-evolution.h +tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + $(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h langhooks.h +graphite.o: graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TOPLEV_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(GIMPLE_H) domwalk.h \ + $(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h graphite.h pointer-set.h \ + value-prof.h +tree-vect-analyze.o: tree-vect-analyze.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RECOG_H) $(BASIC_BLOCK_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) tree-chrec.h \ + $(TOPLEV_H) $(RECOG_H) +tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \ + $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(EXPR_H) \ + $(OPTABS_H) $(PARAMS_H) $(TREE_DATA_REF_H) tree-vectorizer.h $(RECOG_H) $(TOPLEV_H) +tree-vect-transform.o: tree-vect-transform.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(GGC_H) $(OPTABS_H) $(RECOG_H) $(TREE_H) $(RTL_H) \ + $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \ + $(TIMEVAR_H) $(CFGLOOP_H) $(TARGET_H) tree-pass.h $(EXPR_H) \ + tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) langhooks.h $(TOPLEV_H) \ + tree-chrec.h +tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + tree-pass.h $(EXPR_H) $(RECOG_H) tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) \ + $(INPUT_H) $(TARGET_H) $(CFGLAYOUT_H) $(TOPLEV_H) tree-chrec.h langhooks.h +tree-loop-linear.o: tree-loop-linear.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) $(LAMBDA_H) \ + $(TARGET_H) tree-chrec.h $(OBSTACK_H) +tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) \ + $(TARGET_H) tree-chrec.h langhooks.h tree-vectorizer.h +tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_FLOW_H) $(TREE_H) $(RTL_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GGC_H) \ + $(DIAGNOSTIC_H) tree-pass.h $(SCEV_H) langhooks.h gt-tree-parloops.h \ + tree-vectorizer.h +tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(FUNCTION_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \ + tree-stdarg.h $(TARGET_H) langhooks.h +tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(TOPLEV_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \ + tree-ssa-propagate.h +gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ + $(GGC_H) $(GIMPLE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) gt-gimple.h \ + $(TREE_FLOW_H) value-prof.h $(FLAGS_H) +gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \ + $(TM_H) coretypes.h tree-pass.h $(GIMPLE_H) value-prof.h +tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ + $(GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \ + $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(CGRAPH_H) $(GGC_H) \ + gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) hard-reg-set.h \ + $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(TOPLEV.H) $(GIMPLE_H) tree-iterator.h +tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ + $(C_TREE_H) $(C_COMMON_H) $(GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \ + output.h $(VARRAY_H) langhooks.h tree-mudflap.h $(TM_H) coretypes.h \ + $(GGC_H) gt-tree-mudflap.h tree-pass.h $(TOPLEV_H) +tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \ + $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h \ + value-prof.h fixed-value.h output.h +fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(FLAGS_H) $(REAL_H) $(TOPLEV_H) $(HASHTAB_H) $(EXPR_H) $(RTL_H) \ + $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h fixed-value.h $(TARGET_H) \ + $(GIMPLE_H) +diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) version.h $(TM_P_H) $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) intl.h \ + $(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h +opts.o : opts.c opts.h options.h $(TOPLEV_H) $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ + output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ + $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h varray.h +opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h intl.h +targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ + $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ + $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ + $(OPTABS_H) $(RECOG_H) reload.h + +toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) \ + $(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) debug.h insn-config.h intl.h \ + $(RECOG_H) Makefile $(TOPLEV_H) dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \ + hard-reg-set.h $(BASIC_BLOCK_H) graph.h except.h $(REGS_H) $(TIMEVAR_H) \ + value-prof.h $(PARAMS_H) $(TM_P_H) reload.h ira.h dwarf2asm.h $(TARGET_H) \ + langhooks.h insn-flags.h $(CFGLAYOUT_H) $(CFGLOOP_H) hosthooks.h \ + $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \ + opts.h params.def tree-mudflap.h $(REAL_H) tree-pass.h $(GIMPLE_H) + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DTARGET_NAME=\"$(target_noncanonical)\" \ + -c $(srcdir)/toplev.c $(OUTPUT_OPTION) + +passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) $(INSN_ATTR_H) output.h \ + $(DIAGNOSTIC_H) debug.h insn-config.h intl.h $(RECOG_H) $(TOPLEV_H) \ + dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \ + graph.h except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \ + $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \ + langhooks.h insn-flags.h $(CFGLAYOUT_H) $(REAL_H) $(CFGLOOP_H) \ + hosthooks.h $(CGRAPH_H) $(COVERAGE_H) tree-pass.h $(TREE_DUMP_H) \ + $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h $(TREE_FLOW_H) $(TREE_INLINE_H) \ + gt-passes.h $(DF_H) $(PREDICT_H) + +main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) + +host-default.o : host-default.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + hosthooks.h $(HOSTHOOKS_DEF_H) + +rtl-error.o: rtl-error.c $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(INSN_ATTR_H) insn-config.h $(INPUT_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) \ + $(CONFIG_H) varray.h + +rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def $(TOPLEV_H) $(REAL_H) + +print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \ + $(BCONFIG_H) $(REAL_H) +rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \ + $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \ + $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \ + $(DF_H) + +varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \ + output.h $(C_PRAGMA_H) $(TOPLEV_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ + $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \ + $(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h $(REAL_H) tree-iterator.h +function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(CFGLAYOUT_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \ + $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ + output.h $(TOPLEV_H) except.h $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \ + gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) $(PREDICT_H) \ + tree-pass.h $(DF_H) $(TIMEVAR_H) vecprim.h +statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + tree-pass.h $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(TM_H) $(FUNCTION_H) +stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \ + libfuncs.h except.h $(RECOG_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \ + langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H) $(MACHMODE_H) \ + $(REGS_H) alloc-pool.h +except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) except.h $(FUNCTION_H) $(EXPR_H) libfuncs.h \ + langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ + dwarf2asm.h dwarf2out.h $(TOPLEV_H) $(HASHTAB_H) intl.h $(GGC_H) \ + gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \ + $(TARGET_H) $(TM_P_H) tree-pass.h $(TIMEVAR_H) +expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ + libfuncs.h $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ + typeclass.h hard-reg-set.h $(TOPLEV_H) hard-reg-set.h except.h reload.h \ + $(GGC_H) langhooks.h intl.h $(TM_P_H) $(REAL_H) $(TARGET_H) \ + tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ + tree-pass.h $(DF_H) $(DIAGNOSTIC_H) vecprim.h +dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ + $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \ + langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) +builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(TARGET_H) $(FUNCTION_H) $(REGS_H) \ + $(EXPR_H) $(OPTABS_H) insn-config.h $(RECOG_H) output.h typeclass.h \ + hard-reg-set.h $(TOPLEV_H) hard-reg-set.h except.h $(TM_P_H) $(PREDICT_H) \ + libfuncs.h $(REAL_H) langhooks.h $(BASIC_BLOCK_H) tree-mudflap.h \ + $(BUILTINS_DEF) $(MACHMODE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) value-prof.h +calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \ + libfuncs.h $(REGS_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_P_H) \ + $(CGRAPH_H) except.h sbitmap.h $(DBGCNT_H) $(TREE_FLOW_H) +expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ + $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(REAL_H) \ + $(TOPLEV_H) $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H) +explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ + $(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \ + $(TOPLEV_H) except.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \ + $(TARGET_H) output.h +optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \ + $(RECOG_H) reload.h $(TOPLEV_H) $(GGC_H) $(REAL_H) $(TM_P_H) except.h \ + gt-optabs.h $(BASIC_BLOCK_H) $(TARGET_H) $(FUNCTION_H) +dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(FLAGS_H) $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) $(FUNCTION_H) \ + langhooks.h insn-config.h reload.h $(GSTAB_H) xcoffout.h output.h dbxout.h \ + $(TOPLEV_H) $(GGC_H) $(OBSTACK_H) $(EXPR_H) gt-dbxout.h +debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) +sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) debug.h \ + $(TREE_H) $(GGC_H) $(RTL_H) $(REGS_H) $(FLAGS_H) insn-config.h \ + output.h $(TOPLEV_H) $(TM_P_H) gsyms.h langhooks.h $(TARGET_H) sdbout.h \ + gt-sdbout.h reload.h $(VARRAY_H) +dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) version.h $(RTL_H) dwarf2.h debug.h $(FLAGS_H) insn-config.h \ + output.h $(DIAGNOSTIC_H) $(REAL_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \ + libfuncs.h $(TOPLEV_H) dwarf2out.h reload.h $(GGC_H) except.h dwarf2asm.h \ + $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) \ + $(MD5_H) $(INPUT_H) $(FUNCTION_H) $(VARRAY_H) +dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \ + gt-dwarf2asm.h dwarf2.h $(SPLAY_TREE_H) $(TARGET_H) +vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) version.h \ + $(FLAGS_H) $(RTL_H) output.h vmsdbg.h debug.h langhooks.h $(FUNCTION_H) $(TARGET_H) +xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(RTL_H) xcoffout.h $(FLAGS_H) $(TOPLEV_H) output.h dbxout.h \ + $(GGC_H) $(TARGET_H) debug.h $(GSTAB_H) xcoff.h +emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \ + $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \ + $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h tree-pass.h gt-emit-rtl.h \ + $(REAL_H) $(DF_H) +real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h +dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(TOPLEV_H) $(TM_P_H) $(REAL_H) $(DECNUM_H) +fixed-value.o: fixed-value.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) fixed-value.h $(REAL_H) $(TOPLEV_H) +integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TREE_H) $(FLAGS_H) debug.h $(INTEGRATE_H) insn-config.h \ + $(EXPR_H) $(REAL_H) $(REGS_H) intl.h $(FUNCTION_H) output.h $(RECOG_H) \ + except.h $(TOPLEV_H) $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h \ + gt-integrate.h $(GGC_H) tree-pass.h $(DF_H) +jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) \ + $(REAL_H) except.h $(FUNCTION_H) tree-pass.h $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H) \ + $(TIMEVAR_H) $(TARGET_H) +simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h \ + $(RECOG_H) $(EXPR_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \ + $(TREE_H) $(TARGET_H) +cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \ + gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ + $(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h +cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \ + $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ + $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \ + $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \ + gt-cgraphunit.h tree-iterator.h +cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \ + $(TREE_FLOW_H) tree-pass.h +varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_H) $(HASHTAB_H) \ + $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \ + $(TREE_FLOW_H) gt-varpool.h +ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ + tree-pass.h $(TIMEVAR_H) +ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ + $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(TREE_INLINE_H) \ + $(TIMEVAR_H) +ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) tree-pass.h \ + $(FLAGS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(TREE_INLINE_H) +matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) $(TREE_INLINE_H) $(TREE_FLOW_H) \ + tree-flow-inline.h langhooks.h $(HASHTAB_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \ + debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(PARAMS_H) \ + $(FIBHEAP_H) $(C_COMMON_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \ + tree-iterator.h tree-pass.h opts.h $(TREE_DATA_REF_H) tree-chrec.h \ + tree-scalar-evolution.h +ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ + $(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TIMEVAR_H) tree-pass.h \ + $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) +ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + pointer-set.h $(GGC_H) $(C_COMMON_H) $(GIMPLE_H) \ + $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(TIMEVAR_H) $(DIAGNOSTIC_H) +ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(C_COMMON_H) \ + $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \ + $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) + +ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(C_COMMON_H) $(TARGET_H) \ + $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(TIMEVAR_H) \ + $(DIAGNOSTIC_H) +ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(C_COMMON_H) \ + $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \ + $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) +ipa-struct-reorg.o: ipa-struct-reorg.c ipa-struct-reorg.h $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(GIMPLE_H) tree-inline.h \ + $(TREE_FLOW_H) langhooks.h pointer-set.h $(HASHTAB_H) $(C_TREE_H) $(TOPLEV_H) \ + $(FLAGS_H) debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ + $(PARAMS_H) $(FIBHEAP_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) tree-iterator.h \ + tree-pass.h opts.h $(IPA_TYPE_ESCAPE_H) $(TREE_DUMP_H) $(C_COMMON_H) \ + $(GIMPLE_H) + +coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \ + $(FUNCTION_H) $(TOPLEV_H) $(GGC_H) langhooks.h $(COVERAGE_H) gt-coverage.h \ + $(HASHTAB_H) tree-iterator.h $(CGRAPH_H) tree-pass.h gcov-io.c $(TM_P_H) +cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(RECOG_H) \ + $(EMIT_RTL_H) $(TOPLEV_H) output.h $(FUNCTION_H) cselib.h $(GGC_H) $(TM_P_H) \ + gt-cselib.h $(PARAMS_H) alloc-pool.h $(HASHTAB_H) $(TARGET_H) +cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ + hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) $(TOPLEV_H) \ + output.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \ + except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h $(REAL_H) \ + $(DF_H) $(DBGCNT_H) +dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \ + $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H) +dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) $(TIMEVAR_H) tree-pass.h \ + alloc-pool.h $(ALIAS_H) dse.h $(OPTABS_H) +fwprop.o : fwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TOPLEV_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \ + output.h $(DF_H) alloc-pool.h $(TIMEVAR_H) tree-pass.h $(TARGET_H) $(TM_P_H) \ + $(CFGLOOP_H) $(EMIT_RTL_H) +web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ + $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h +see.o : see.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h \ + $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(RECOG_H) $(EXPR_H) $(SPLAY_TREE_H) \ + $(HASHTAB_H) $(REGS_H) dce.h +gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \ + $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ + $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h $(TREE_H) cselib.h $(TIMEVAR_H) \ + intl.h $(OBSTACK_H) tree-pass.h $(DF_H) $(DBGCNT_H) +resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \ + coretypes.h $(TM_H) $(REGS_H) $(FLAGS_H) output.h $(RESOURCE_H) $(DF_H) \ + $(FUNCTION_H) $(TOPLEV_H) $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H) +lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ + hard-reg-set.h $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(RECOG_H) \ + $(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) output.h $(REAL_H) +mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) \ + output.h tree-pass.h $(TIMEVAR_H) $(REAL_H) $(DF_H) +tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \ + coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \ + $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(GIMPLE_H) $(CFGLOOP_H) \ + tree-scalar-evolution.h +tree-call-cdce.o : tree-call-cdce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \ + coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \ + $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(GIMPLE_H) +tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \ + $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \ + tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H) +tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \ + $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ + $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \ + langhooks.h tree-pass.h $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \ + $(BITMAP_H) $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(PARAMS_H) $(TARGET_H) +tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ + $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \ + tree-pass.h $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \ + $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) +tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ + $(TM_H) $(RTL_H) $(REAL_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \ + tree-iterator.h tree-pass.h tree-ssa-propagate.h $(DIAGNOSTIC_H) +tree-vect-generic.o : tree-vect-generic.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h tree-pass.h \ + $(FLAGS_H) $(OPTABS_H) $(RTL_H) $(MACHMODE_H) $(EXPR_H) \ + langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \ + coretypes.h insn-codes.h +df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \ + hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \ + $(TM_P_H) $(FLAGS_H) output.h tree-pass.h $(PARAMS_H) +df-problems.o : df-problems.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \ + hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \ + $(TM_P_H) $(FLAGS_H) output.h except.h dce.h vecprim.h +df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \ + hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \ + $(TM_P_H) $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h \ + tree-pass.h +df-byte-scan.o : df-byte-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + tm_p.h $(DF_H) output.h $(DBGCNT_H) +regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TM_P_H) $(FLAGS_H) $(REGS_H) output.h except.h hard-reg-set.h \ + $(BASIC_BLOCK_H) $(TIMEVAR_H) $(DF_H) +var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \ + $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \ + $(REGS_H) $(EXPR_H) $(TIMEVAR_H) tree-pass.h +profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \ + $(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \ + $(CFGLOOP_H) $(TIMEVAR_H) tree-pass.h profile.h +mcf.o : mcf.c profile.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h \ + $(BASIC_BLOCK_H) output.h langhooks.h $(GCOV_IO_H) $(TREE_H) +tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \ + $(FUNCTION_H) $(TOPLEV_H) $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \ + tree-pass.h $(TREE_FLOW_H) $(TIMEVAR_H) $(GGC_H) gt-tree-profile.h $(CGRAPH_H) +value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h $(FLAGS_H) \ + $(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H) $(GGC_H) $(DIAGNOSTIC_H) \ + $(TREE_H) $(COVERAGE_H) $(RTL_H) $(GCOV_IO_H) $(TREE_FLOW_H) \ + tree-flow-inline.h $(TIMEVAR_H) tree-pass.h $(TOPLEV_H) pointer-set.h +loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \ + $(TOPLEV_H) $(CFGLOOP_H) output.h $(PARAMS_H) $(TARGET_H) +alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H) +auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \ + $(REGS_H) $(FLAGS_H) output.h $(FUNCTION_H) except.h $(TOPLEV_H) $(RECOG_H) \ + $(EXPR_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H) +cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \ + $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(GGC_H) \ + $(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h \ + $(HASHTAB_H) $(DF_H) $(CFGLOOP_H) $(TREE_FLOW_H) tree-pass.h +cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TOPLEV_H) $(CFGLOOP_H) +cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) \ + coretypes.h $(TREE_DUMP_H) except.h langhooks.h tree-pass.h $(RTL_H) \ + $(DIAGNOSTIC_H) $(TOPLEV_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \ + value-prof.h $(TREE_INLINE_H) $(TARGET_H) +cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ + output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(TM_P_H) insn-config.h $(EXPR_H) \ + $(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \ + tree-pass.h $(DF_H) $(GGC_H) +cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \ + $(TIMEVAR_H) $(OBSTACK_H) $(TOPLEV_H) vecprim.h +cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) \ + $(FUNCTION_H) except.h $(TIMEVAR_H) $(TREE_H) +cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TIMEVAR_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \ + $(TOPLEV_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \ + $(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h $(CFGLOOP_H) $(EXPR_H) \ + $(DF_H) $(DBGCNT_H) dce.h +cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \ + $(OBSTACK_H) $(TOPLEV_H) $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h \ + $(GGC_H) +cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \ + $(OBSTACK_H) output.h graphds.h $(PARAMS_H) +graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) $(BITMAP_H) $(OBSTACK_H) \ + coretypes.h vec.h vecprim.h +loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \ + hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) \ + output.h intl.h $(TOPLEV_H) $(DF_H) $(HASHTAB_H) +loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) coretypes.h \ + $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(OBSTACK_H) output.h \ + $(HASHTAB_H) except.h +cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) output.h \ + coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H) $(TREE_FLOW_H) +loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(GGC_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) \ + coretypes.h $(TM_H) $(OBSTACK_H) tree-pass.h $(TIMEVAR_H) $(FLAGS_H) $(DF_H) +loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \ + output.h $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) +loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \ + $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \ + output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \ + $(OBSTACK_H) +dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \ + $(TIMEVAR_H) graphds.h vecprim.h pointer-set.h +et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + et-forest.h alloc-pool.h $(BASIC_BLOCK_H) +combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) $(FUNCTION_H) insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \ + rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) $(REAL_H) hard-reg-set.h \ + $(TOPLEV_H) $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \ + insn-codes.h $(TIMEVAR_H) tree-pass.h $(DF_H) vecprim.h $(CGRAPH_H) +regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) addresses.h $(REGS_H) insn-config.h \ + $(RECOG_H) reload.h $(REAL_H) $(TOPLEV_H) $(FUNCTION_H) output.h $(GGC_H) \ + $(TM_P_H) $(EXPR_H) $(TIMEVAR_H) gt-regclass.h $(HASHTAB_H) \ + $(TARGET_H) tree-pass.h $(DF_H) +local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ + output.h $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) except.h reload.h $(TM_P_H) \ + $(GGC_H) $(INTEGRATE_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H) +bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H) +global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \ + insn-config.h output.h $(TOPLEV_H) $(TM_P_H) $(MACHMODE_H) tree-pass.h \ + $(TIMEVAR_H) vecprim.h $(DF_H) $(DBGCNT_H) $(RA_H) +ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \ + insn-config.h output.h $(TOPLEV_H) $(TM_P_H) $(MACHMODE_H) tree-pass.h \ + $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h sparseset.h +varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \ + $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) $(TOPLEV_H) +vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \ + $(TOPLEV_H) +reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \ + hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) real.h $(TOPLEV_H) \ + addresses.h $(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H) $(DF_H) +reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \ + $(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) $(TOPLEV_H) $(TM_P_H) \ + addresses.h except.h $(TREE_H) $(REAL_H) $(FLAGS_H) $(MACHMODE_H) \ + $(OBSTACK_H) $(DF_H) $(TARGET_H) $(EMIT_RTL_H) ira.h +rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + rtlhooks-def.h $(EXPR_H) $(RECOG_H) +postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(REAL_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) \ + hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) output.h \ + $(FUNCTION_H) $(TOPLEV_H) cselib.h $(TM_P_H) except.h $(TREE_H) $(MACHMODE_H) \ + $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H) +postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ + $(TM_P_H) except.h $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \ + $(PARAMS_H) $(TIMEVAR_H) tree-pass.h $(REAL_H) $(DBGCNT_H) +caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \ + addresses.h $(RECOG_H) reload.h $(EXPR_H) $(TOPLEV_H) $(TM_P_H) $(DF_H) \ + output.h ira.h gt-caller-save.h $(GGC_H) +bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \ + $(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \ + $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h $(TOPLEV_H) \ + $(DF_H) vecprim.h $(RECOG_H) +reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + conditions.h hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \ + $(INSN_ATTR_H) except.h $(RECOG_H) $(FUNCTION_H) $(FLAGS_H) output.h \ + $(EXPR_H) $(TOPLEV_H) $(PARAMS_H) $(TM_P_H) $(OBSTACK_H) $(RESOURCE_H) \ + $(TIMEVAR_H) $(TARGET_H) tree-pass.h +alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \ + $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \ + langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \ + $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) tree-pass.h +stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) tree-pass.h \ + $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H) +init-regs.o : init-regs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) tree-pass.h \ + $(BASIC_BLOCK_H) $(FLAGS_H) $(DF_H) +ira-build.o: ira-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) \ + $(PARAMS_H) $(DF_H) sparseset.h $(IRA_INT_H) +ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) insn-config.h $(RECOG_H) \ + $(REGS_H) hard-reg-set.h $(FLAGS_H) errors.h \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TM_P_H) \ + $(IRA_INT_H) +ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ + $(DF_H) sparseset.h $(IRA_INT_H) +ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ + $(DF_H) $(SPLAY_TREE_H) $(IRA_INT_H) +ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ + $(IRA_INT_H) +ira-lives.o: ira-lives.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \ + $(DF_H) sparseset.h $(IRA_INT_H) +ira.o: ira.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TARGET_H) $(TM_H) $(RTL_H) $(RECOG_H) \ + $(REGS_H) hard-reg-set.h $(FLAGS_H) $(OBSTACK_H) \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) \ + $(DF_H) $(IRA_INT_H) $(PARAMS_H) $(TIMEVAR_H) $(INTEGRATE_H) \ + tree-pass.h output.h +regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + insn-config.h $(TIMEVAR_H) tree-pass.h $(DF_H)\ + $(RECOG_H) output.h $(REGS_H) hard-reg-set.h $(FLAGS_H) $(FUNCTION_H) \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) except.h reload.h +combine-stack-adj.o : combine-stack-adj.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) insn-config.h $(TIMEVAR_H) tree-pass.h \ + $(RECOG_H) output.h $(REGS_H) hard-reg-set.h $(FLAGS_H) $(FUNCTION_H) \ + $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(DF_H) except.h reload.h +ddg.o : ddg.c $(DDG_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) \ + $(TOPLEV_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \ + $(FLAGS_H) insn-config.h $(INSN_ATTR_H) except.h $(RECOG_H) \ + $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(BITMAP_H) \ + hard-reg-set.h sbitmap.h $(TM_H) +modulo-sched.o : modulo-sched.c $(DDG_H) $(CONFIG_H) $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TARGET_H) $(TOPLEV_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \ + $(FLAGS_H) insn-config.h $(INSN_ATTR_H) except.h $(RECOG_H) \ + $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \ + cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) tree-pass.h \ + $(DF_H) $(DBGCNT_H) +haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \ + $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(TM_P_H) $(TARGET_H) output.h \ + $(PARAMS_H) $(DBGCNT_H) +sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h cselib.h \ + $(PARAMS_H) $(TM_P_H) +sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(PARAMS_H) \ + $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) tree-pass.h \ + $(DBGCNT_H) +sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(TM_P_H) \ + $(PARAMS_H) $(CFGLAYOUT_H) $(TARGET_H) output.h +sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(SCHED_INT_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) \ + $(REAL_H) tree-pass.h $(INSN_ATTR_H) +sel-sched.o : sel-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(PARAMS_H) \ + $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) tree-pass.h \ + $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) \ + $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h +sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(PARAMS_H) \ + $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) tree-pass.h \ + $(SEL_SCHED_DUMP_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) $(SEL_SCHED_IR_H) +sel-sched-ir.o : sel-sched-ir.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ + $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(PARAMS_H) \ + $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) tree-pass.h \ + $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) $(SEL_SCHED_IR_H) +final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) intl.h $(REGS_H) $(RECOG_H) conditions.h \ + insn-config.h $(INSN_ATTR_H) $(FUNCTION_H) output.h hard-reg-set.h \ + except.h debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h tree-pass.h \ + $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(CFGLAYOUT_H) dbxout.h \ + $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) $(DF_H) vecprim.h $(GGC_H) \ + $(CFGLOOP_H) $(PARAMS_H) +recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \ + $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \ + addresses.h $(TM_P_H) $(TIMEVAR_H) tree-pass.h hard-reg-set.h $(REAL_H) \ + $(DF_H) $(DBGCNT_H) $(TARGET_H) +reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + insn-config.h $(TOPLEV_H) reload.h $(FUNCTION_H) $(TM_P_H) $(GGC_H) \ + $(BASIC_BLOCK_H) $(CFGLAYOUT_H) output.h $(VARRAY_H) $(TIMEVAR_H) \ + tree-pass.h $(TARGET_H) vecprim.h $(DF_H) +sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h +predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \ + hard-reg-set.h output.h $(TOPLEV_H) $(RECOG_H) $(FUNCTION_H) except.h \ + $(TM_P_H) $(PREDICT_H) sreal.h $(PARAMS_H) $(TARGET_H) $(CFGLOOP_H) \ + $(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def $(TIMEVAR_H) $(TREE_DUMP_H) \ + $(TREE_FLOW_H) tree-pass.h $(EXPR_H) pointer-set.h +lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \ + $(RTL_H) $(GGC_H) gt-lists.h +bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \ + $(TARGET_H) $(FUNCTION_H) $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) \ + $(PARAMS_H) $(TOPLEV_H) tree-pass.h $(DF_H) +tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(TREE_H) $(BASIC_BLOCK_H) hard-reg-set.h output.h $(CFGLAYOUT_H) \ + $(FLAGS_H) $(TIMEVAR_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H) \ + tree-pass.h $(TREE_FLOW_H) $(TREE_INLINE_H) +cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \ + $(FUNCTION_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(TARGET_H) gt-cfglayout.h \ + $(GGC_H) alloc-pool.h $(FLAGS_H) $(OBSTACK_H) tree-pass.h vecprim.h \ + $(DF_H) +timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TIMEVAR_H) $(FLAGS_H) intl.h $(TOPLEV_H) $(RTL_H) timevar.def +regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ + output.h $(RECOG_H) $(FUNCTION_H) $(OBSTACK_H) $(FLAGS_H) $(TM_P_H) \ + addresses.h reload.h $(TOPLEV_H) $(TIMEVAR_H) tree-pass.h $(DF_H) +ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + $(REGS_H) $(TOPLEV_H) $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \ + $(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \ + $(REAL_H) $(OPTABS_H) $(CFGLOOP_H) hard-reg-set.h $(TIMEVAR_H) tree-pass.h \ + $(DF_H) $(DBGCNT_H) +lambda-mat.o : lambda-mat.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \ + $(TM_H) coretypes.h $(TREE_H) $(TREE_FLOW_H) +lambda-trans.o: lambda-trans.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \ + $(TM_H) coretypes.h $(TARGET_H) $(TREE_H) $(TREE_FLOW_H) +lambda-code.o: lambda-code.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \ + $(TM_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \ + $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \ + $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) coretypes.h $(TARGET_H) \ + tree-chrec.h tree-pass.h vec.h vecprim.h $(OBSTACK_H) pointer-set.h +params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) $(TOPLEV_H) +pointer-set.o: pointer-set.c pointer-set.h $(CONFIG_H) $(SYSTEM_H) +hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H) +pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \ + $(TREE_H) +errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(BCONFIG_H) +dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h errors.h $(DBGCNT_H) \ + $(TM_H) $(RTL_H) output.h +lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \ + insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) $(BITMAP_H) \ + $(EXPR_H) except.h $(REGS_H) tree-pass.h $(DF_H) +icg-combine.o: icg-combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(BASIC_BLOCK_H) tree-pass.h $(DF_H) +icg-filter.o: icg-combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(BASIC_BLOCK_H) tree-pass.h errors.h + +$(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \ + $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \ + output.h $(INSN_ATTR_H) $(SYSTEM_H) $(TOPLEV_H) $(TARGET_H) libfuncs.h \ + $(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) $(TM_P_H) $(EXPR_H) \ + langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h $(GIMPLE_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(out_file) $(OUTPUT_OPTION) + +# Build auxiliary files that support ecoff format. +mips-tfile: mips-tfile.o version.o $(LIBDEPS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS) + +mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) version.h $(srcdir)/../include/getopt.h $(GSTAB_H) intl.h + +mips-tdump: mips-tdump.o version.o $(LIBDEPS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS) + +mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) version.h $(srcdir)/../include/getopt.h stab.def + +# FIXME: writing proper dependencies for this is a *LOT* of work. +libbackend.o : $(OBJS-common:.o=.c) $(out_file) \ + insn-config.h insn-flags.h insn-codes.h insn-constants.h \ + insn-attr.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) gcov-iov.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DTARGET_NAME=\"$(target_noncanonical)\" \ + -DLOCALEDIR=\"$(localedir)\" \ + -c $(filter %.c,$^) -o $@ \ + -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ + -DREVISION=$(REVISION_s) \ + -DDEVPHASE=$(DEVPHASE_s) -DPKGVERSION=$(PKGVERSION_s) \ + -DBUGURL=$(BUGURL_s) -combine + +# +# Generate header and source files from the machine description, +# and compile them. + +.PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \ + insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \ + insn-attr.h insn-attrtab.c insn-preds.c + +# Dependencies for the md file. The first time through, we just assume +# the md file itself and the generated dependency file (in order to get +# it built). The second time through we have the dependency file. +-include mddeps.mk +MD_DEPS = s-mddeps $(md_file) $(MD_INCLUDES) + +s-mddeps: $(md_file) $(MD_INCLUDES) build/genmddeps$(build_exeext) + $(RUN_GEN) build/genmddeps$(build_exeext) $(md_file) > tmp-mddeps + $(SHELL) $(srcdir)/../move-if-change tmp-mddeps mddeps.mk + $(STAMP) s-mddeps + +# Header dependencies for generated source files. +genrtl.o : genrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H)\ + $(GGC_H) $(OBSTACK_H) +insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \ + insn-config.h $(TOPLEV_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) +insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \ + insn-config.h $(TOPLEV_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) +insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(REAL_H) \ + dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H) \ + $(RESOURCE_H) reload.h $(TOPLEV_H) $(REGS_H) tm-constrs.h $(GGC_H) \ + $(BASIC_BLOCK_H) $(INTEGRATE_H) +insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(TOPLEV_H) insn-config.h $(RECOG_H) +insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(MACHMODE_H) $(REAL_H) +insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h $(FLAGS_H) $(RECOG_H) \ + $(EXPR_H) $(OPTABS_H) reload.h +insn-output.o : insn-output.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(GGC_H) $(REGS_H) $(REAL_H) conditions.h \ + hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) output.h \ + $(RECOG_H) $(FUNCTION_H) $(TOPLEV_H) $(FLAGS_H) insn-codes.h $(TM_P_H) \ + $(TARGET_H) tm-constrs.h +insn-peep.o : insn-peep.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + insn-config.h $(RTL_H) $(TM_P_H) $(REGS_H) output.h $(REAL_H) \ + $(RECOG_H) except.h $(FUNCTION_H) $(TOPLEV_H) $(FLAGS_H) tm-constrs.h +insn-preds.o : insn-preds.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(TREE_H) insn-config.h $(RECOG_H) output.h \ + $(FLAGS_H) $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) \ + $(TOPLEV_H) reload.h $(REGS_H) $(REAL_H) tm-constrs.h +insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) insn-config.h $(RECOG_H) output.h $(FLAGS_H) \ + $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) $(TOPLEV_H) \ + reload.h $(REAL_H) $(REGS_H) tm-constrs.h + +# For each of the files generated by running a generator program over +# the machine description, the following pair of static pattern rules +# runs the generator program only if the machine description has changed, +# but touches the target file only when its contents actually change. +# The "; @true" construct forces Make to recheck the timestamp on the +# target file. + +simple_generated_h = insn-attr.h insn-codes.h insn-config.h insn-flags.h + +simple_generated_c = insn-attrtab.c insn-automata.c insn-emit.c \ + insn-extract.c insn-opinit.c insn-output.c \ + insn-peep.c insn-recog.c + +$(simple_generated_h): insn-%.h: s-%; @true + +$(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) \ + $(MD_DEPS) insn-conditions.md + $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ + insn-conditions.md > tmp-$*.h + $(SHELL) $(srcdir)/../move-if-change tmp-$*.h insn-$*.h + $(STAMP) s-$* + +$(simple_generated_c): insn-%.c: s-%; @true +$(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) \ + $(MD_DEPS) insn-conditions.md + $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ + insn-conditions.md > tmp-$*.c + $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c + $(STAMP) s-$* + +generated_files = config.h tm.h $(TM_P_H) $(TM_H) multilib.h \ + $(simple_generated_h) $(simple_generated_c) specs.h \ + tree-check.h genrtl.h insn-modes.h tm-preds.h tm-constrs.h \ + $(ALL_GTFILES_H) gtype-desc.c gtype-desc.h gcov-iov.h + +# In order for parallel make to really start compiling the expensive +# objects from $(OBJS-common) as early as possible, build all their +# prerequisites strictly before all objects. +$(ALL_HOST_OBJS) : | $(generated_files) + +# genconstants needs to run before insn-conditions.md is available +# (because the constants may be used in the conditions). +insn-constants.h: s-constants; @true +s-constants: build/genconstants$(build_exeext) $(MD_DEPS) + $(RUN_GEN) build/genconstants$(build_exeext) $(md_file) \ + > tmp-constants.h + $(SHELL) $(srcdir)/../move-if-change tmp-constants.h insn-constants.h + $(STAMP) s-constants + +# gencheck doesn't read the machine description, and the file produced +# doesn't use the insn-* convention. +tree-check.h: s-check ; @true +s-check : build/gencheck$(build_exeext) + $(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h + $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h + $(STAMP) s-check + +# gencondmd doesn't use the standard naming convention. +build/gencondmd.c: s-conditions; @true +s-conditions: $(MD_DEPS) build/genconditions$(build_exeext) + $(RUN_GEN) build/genconditions$(build_exeext) $(md_file) > tmp-condmd.c + $(SHELL) $(srcdir)/../move-if-change tmp-condmd.c build/gencondmd.c + $(STAMP) s-conditions + +insn-conditions.md: s-condmd; @true +s-condmd: build/gencondmd$(build_exeext) + $(RUN_GEN) build/gencondmd$(build_exeext) > tmp-cond.md + $(SHELL) $(srcdir)/../move-if-change tmp-cond.md insn-conditions.md + $(STAMP) s-condmd + + +# These files are generated by running the same generator more than +# once with different options, so they have custom rules. The +# stampfile idiom is the same. +genrtl.c: s-genrtl; @true +genrtl.h: s-genrtl-h; @true + +s-genrtl: build/gengenrtl$(build_exeext) + $(RUN_GEN) build/gengenrtl$(build_exeext) > tmp-genrtl.c + $(SHELL) $(srcdir)/../move-if-change tmp-genrtl.c genrtl.c + $(STAMP) s-genrtl + +s-genrtl-h: build/gengenrtl$(build_exeext) + $(RUN_GEN) build/gengenrtl$(build_exeext) -h > tmp-genrtl.h + $(SHELL) $(srcdir)/../move-if-change tmp-genrtl.h genrtl.h + $(STAMP) s-genrtl-h + +insn-modes.c: s-modes; @true +insn-modes.h: s-modes-h; @true +min-insn-modes.c: s-modes-m; @true + +s-modes: build/genmodes$(build_exeext) + $(RUN_GEN) build/genmodes$(build_exeext) > tmp-modes.c + $(SHELL) $(srcdir)/../move-if-change tmp-modes.c insn-modes.c + $(STAMP) s-modes + +s-modes-h: build/genmodes$(build_exeext) + $(RUN_GEN) build/genmodes$(build_exeext) -h > tmp-modes.h + $(SHELL) $(srcdir)/../move-if-change tmp-modes.h insn-modes.h + $(STAMP) s-modes-h + +s-modes-m: build/genmodes$(build_exeext) + $(RUN_GEN) build/genmodes$(build_exeext) -m > tmp-min-modes.c + $(SHELL) $(srcdir)/../move-if-change tmp-min-modes.c min-insn-modes.c + $(STAMP) s-modes-m + +insn-preds.c: s-preds; @true +tm-preds.h: s-preds-h; @true +tm-constrs.h: s-constrs-h; @true + +s-preds: $(MD_DEPS) build/genpreds$(build_exeext) + $(RUN_GEN) build/genpreds$(build_exeext) $(md_file) > tmp-preds.c + $(SHELL) $(srcdir)/../move-if-change tmp-preds.c insn-preds.c + $(STAMP) s-preds + +s-preds-h: $(MD_DEPS) build/genpreds$(build_exeext) + $(RUN_GEN) build/genpreds$(build_exeext) -h $(md_file) > tmp-preds.h + $(SHELL) $(srcdir)/../move-if-change tmp-preds.h tm-preds.h + $(STAMP) s-preds-h + +s-constrs-h: $(MD_DEPS) build/genpreds$(build_exeext) + $(RUN_GEN) build/genpreds$(build_exeext) -c $(md_file) > tmp-constrs.h + $(SHELL) $(srcdir)/../move-if-change tmp-constrs.h tm-constrs.h + $(STAMP) s-constrs-h + +GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ + $(host_xm_file_list) \ + $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \ + $(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \ + $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/varray.h $(srcdir)/libfuncs.h $(SYMTAB_H) \ + $(srcdir)/real.h $(srcdir)/function.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \ + $(srcdir)/fixed-value.h \ + $(srcdir)/ipa-reference.h $(srcdir)/output.h $(srcdir)/cfgloop.h \ + $(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \ + $(srcdir)/reload.h $(srcdir)/caller-save.c \ + $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \ + $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c $(srcdir)/matrix-reorg.c \ + $(srcdir)/dbxout.c $(srcdir)/ipa-struct-reorg.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \ + $(srcdir)/tree-vect-generic.c \ + $(srcdir)/dojump.c \ + $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \ + $(srcdir)/function.c $(srcdir)/except.h \ + $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \ + $(srcdir)/profile.c $(srcdir)/regclass.c $(srcdir)/mcf.c \ + $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \ + $(srcdir)/sdbout.c $(srcdir)/stor-layout.c \ + $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \ + $(srcdir)/gimple.h $(srcdir)/gimple.c \ + $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \ + $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \ + $(srcdir)/tree-cfg.c \ + $(srcdir)/tree-dfa.c \ + $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \ + $(srcdir)/tree-chrec.h \ + $(srcdir)/tree-scalar-evolution.c \ + $(srcdir)/tree-ssa-operands.h \ + $(srcdir)/tree-profile.c $(srcdir)/tree-nested.c \ + $(srcdir)/varpool.c \ + $(srcdir)/tree-parloops.c \ + $(srcdir)/omp-low.c \ + $(srcdir)/targhooks.c $(out_file) $(srcdir)/passes.c $(srcdir)/cgraphunit.c \ + $(srcdir)/tree-ssa-propagate.c \ + $(srcdir)/tree-phinodes.c \ + $(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \ + $(srcdir)/tree-ssa-structalias.c \ + @all_gtfiles@ + +# Compute the list of GT header files from the corresponding C sources, +# possibly nested within config or language subdirectories. Match gengtype's +# behavior in this respect: gt-LANG-file.h for "file" anywhere within a LANG +# language subdir, gt-file.h otherwise (no subdir indication for config/ +# related sources). + +GTFILES_H = $(subst /,-, \ + $(shell echo $(patsubst $(srcdir)/%,gt-%, \ + $(patsubst %.c,%.h, \ + $(filter %.c, $(GTFILES)))) \ + | sed -e "s|/[^ ]*/|/|g" -e "s|gt-config/|gt-|g")) + +GTFILES_LANG_H = $(patsubst [%], gtype-%.h, $(filter [%], $(GTFILES))) +ALL_GTFILES_H := $(sort $(GTFILES_H) $(GTFILES_LANG_H)) + +# $(GTFILES) may be too long to put on a command line, so we have to +# write it out to a file (taking care not to do that in a way that +# overflows a command line!) and then have gengtype read the file in. + +$(ALL_GTFILES_H) gtype-desc.c gtype-desc.h : s-gtype ; @true + +gtyp-input.list: s-gtyp-input ; @true +s-gtyp-input: Makefile + @: $(call write_entries_to_file,$(GTFILES),tmp-gi.list) + $(SHELL) $(srcdir)/../move-if-change tmp-gi.list gtyp-input.list + $(STAMP) s-gtyp-input + +s-gtype: build/gengtype$(build_exeext) $(filter-out [%], $(GTFILES)) \ + gtyp-input.list + $(RUN_GEN) build/gengtype$(build_exeext) $(srcdir) gtyp-input.list + $(STAMP) s-gtype + +# +# How to compile object files to run on the build machine. + +build/%.o : # dependencies provided by explicit rule later + $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -o $@ $< + +# Header dependencies for the programs that generate source code. +# These are library modules... +build/errors.o : errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h +build/gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) errors.h $(HASHTAB_H) \ + gensupport.h +build/ggc-none.o : ggc-none.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GGC_H) +build/min-insn-modes.o : min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) \ + $(MACHMODE_H) +build/print-rtl.o: print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GTM_H) $(RTL_BASE_H) +build/read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) $(HASHTAB_H) gensupport.h +build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \ + $(RTL_H) $(REAL_H) $(GGC_H) errors.h +build/vec.o : vec.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h vec.h \ + $(GGC_H) $(TOPLEV_H) +build/gencondmd.o : build/gencondmd.c $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) insn-constants.h $(RTL_H) $(TM_P_H) \ + $(FUNCTION_H) $(REGS_H) $(RECOG_H) $(REAL_H) output.h $(FLAGS_H) \ + $(RESOURCE_H) $(TOPLEV_H) reload.h except.h tm-constrs.h +# This pulls in tm-pred.h which contains inline functions wrapping up +# predicates from the back-end so those functions must be discarded. +# No big deal since gencondmd.c is a dummy file for non-GCC compilers. +build/gencondmd.o : \ + BUILD_CFLAGS := $(filter-out -fkeep-inline-functions, $(BUILD_CFLAGS)) + +# ...these are the programs themselves. +build/genattr.o : genattr.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genattrtab.o : genattrtab.c $(RTL_BASE_H) $(OBSTACK_H) \ + $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(GGC_H) \ + gensupport.h +build/genautomata.o : genautomata.c $(RTL_BASE_H) $(OBSTACK_H) \ + $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h vec.h \ + $(HASHTAB_H) gensupport.h +build/gencheck.o : gencheck.c tree.def $(BCONFIG_H) $(GTM_H) \ + $(SYSTEM_H) coretypes.h $(lang_tree_files) gimple.def +build/genchecksum.o : genchecksum.c $(BCONFIG_H) $(SYSTEM_H) $(MD5_H) +build/gencodes.o : gencodes.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genconditions.o : genconditions.c $(RTL_BASE_H) $(BCONFIG_H) \ + $(SYSTEM_H) coretypes.h $(GTM_H) errors.h +build/genconfig.o : genconfig.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genconstants.o : genconstants.c $(RTL_BASE_H) $(BCONFIG_H) \ + $(SYSTEM_H) coretypes.h $(GTM_H) errors.h +build/genemit.o : genemit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H) \ + $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h vecprim.h +build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H) \ + $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h +build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def +build/gengtype-lex.o : gengtype-lex.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) +build/gengtype-parse.o : gengtype-parse.c gengtype.h $(BCONFIG_H) \ + $(SYSTEM_H) +build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) gengtype.h \ + rtl.def insn-notes.def errors.h double-int.h +build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GTM_H) $(RTL_BASE_H) errors.h gensupport.h +build/genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h \ + $(HASHTAB_H) machmode.def $(extra_modes_file) +build/genopinit.o : genopinit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genoutput.o : genoutput.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h +build/genpeep.o : genpeep.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h $(TOPLEV_H) +build/genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h $(OBSTACK_H) +build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h $(GTM_H) errors.h gensupport.h + +# Compile the programs that generate insn-* from the machine description. +# They are compiled with $(CC_FOR_BUILD), and associated libraries, +# since they need to run on this machine +# even if GCC is being compiled to run on some other machine. + +# As a general rule... +build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS) + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \ + $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS) + +# All these programs use the MD reader ($(BUILD_RTL)). +genprogmd = attr attrtab automata codes conditions config constants emit \ + extract flags mddeps opinit output peep preds recog +$(genprogmd:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_ERRORS) + +# These programs need libs over and above what they get from the above list. +build/genautomata$(build_exeext) : BUILD_LIBS += -lm + +# These programs are not linked with the MD reader. +build/gengenrtl$(build_exeext) : $(BUILD_ERRORS) +build/genmodes$(build_exeext) : $(BUILD_ERRORS) +build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \ + $(BUILD_ERRORS) + +# Generated source files for gengtype. +gengtype-lex.c : gengtype-lex.l + -$(FLEX) $(FLEXFLAGS) -o$@ $< + +# +# Remake internationalization support. +intl.o: intl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h Makefile + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DLOCALEDIR=\"$(localedir)\" \ + -c $(srcdir)/intl.c $(OUTPUT_OPTION) + +# +# Remake cpp and protoize. + +PREPROCESSOR_DEFINES = \ + -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \ + -DFIXED_INCLUDE_DIR=\"$(libsubdir)/include-fixed\" \ + -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \ + -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_noncanonical)\" \ + -DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/backward\" \ + -DLOCAL_INCLUDE_DIR=\"$(local_includedir)\" \ + -DCROSS_INCLUDE_DIR=\"$(CROSS_SYSTEM_HEADER_DIR)\" \ + -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \ + -DPREFIX=\"$(prefix)/\" \ + -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc/\" \ + @TARGET_SYSTEM_ROOT_DEFINE@ + +cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + cppdefault.h Makefile + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(PREPROCESSOR_DEFINES) \ + -c $(srcdir)/cppdefault.c $(OUTPUT_OPTION) + +# Note for the stamp targets, we run the program `true' instead of +# having an empty command (nothing following the semicolon). + +proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X + +PROTO_OBJS = intl.o version.o cppdefault.o errors.o + +protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS) + +unprotoize$(exeext): unprotoize.o $(PROTO_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ unprotoize.o $(PROTO_OBJS) $(LIBS) + +protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) Makefile version.h cppdefault.h intl.h + (SHLIB_LINK='$(SHLIB_LINK)'; \ + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(DRIVER_DEFINES) \ + $(srcdir)/protoize.c $(OUTPUT_OPTION)) + +unprotoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) Makefile version.h cppdefault.h intl.h + (SHLIB_LINK='$(SHLIB_LINK)'; \ + $(CC) -c -DUNPROTOIZE $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + $(DRIVER_DEFINES) \ + $(srcdir)/protoize.c $(OUTPUT_OPTION)) + +# This info describes the target machine, so compile with GCC just built. +SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \ + stmp-int-hdrs + -rm -f SYSCALLS.c tmp-SYSCALLS.s + sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \ + $(srcdir)/sys-types.h $(srcdir)/sys-protos.h > SYSCALLS.c + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) \ + -aux-info $@ -S -o tmp-SYSCALLS.s SYSCALLS.c + -rm -f SYSCALLS.c tmp-SYSCALLS.s + + +test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES) + -rm -f tmp-proto.[cso] + cp $(srcdir)/protoize.c tmp-proto.c + chmod u+w tmp-proto.c + ./protoize -N -B ./ -x getopt.h -c "-B./ -Wall -Wwrite-strings \ + $(GCC_CFLAGS) $(INCLUDES) \ + -DGCC_INCLUDE_DIR=0 \ + -DFIXED_INCLUDE_DIR=0 \ + -DGPLUSPLUS_INCLUDE_DIR=0 \ + -DCROSS_INCLUDE_DIR=0 \ + -DTOOL_INCLUDE_DIR=0 \ + -DSTANDARD_EXEC_PREFIX=0 \ + -DDEFAULT_TARGET_MACHINE=0 \ + -DDEFAULT_TARGET_VERSION=0" tmp-proto.c + @echo '**********' Expect 400 lines of differences. + -diff $(srcdir)/protoize.c tmp-proto.c > tmp-proto.diff + -wc -l tmp-proto.diff + ./unprotoize -N -x getopt.h -c "-B./ -Wall -Wwrite-strings \ + $(GCC_CFLAGS) $(INCLUDES) \ + -DGCC_INCLUDE_DIR=0 \ + -DFIXED_INCLUDE_DIR=0 \ + -DGPLUSPLUS_INCLUDE_DIR=0 \ + -DCROSS_INCLUDE_DIR=0 \ + -DTOOL_INCLUDE_DIR=0 \ + -DSTANDARD_EXEC_PREFIX=0 \ + -DDEFAULT_TARGET_MACHINE=0 \ + -DDEFAULT_TARGET_VERSION=0" tmp-proto.c + @echo Expect zero differences. + diff $(srcdir)/protoize.c tmp-proto.c | cat + -rm -f tmp-proto.[cs] tmp-proto$(objext) + +# gcov-iov.c is run on the build machine to generate gcov-iov.h from version.c +build/gcov-iov.o: gcov-iov.c $(BCONFIG_H) coretypes.h $(GTM_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) + +build/gcov-iov$(build_exeext): build/gcov-iov.o + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) build/gcov-iov.o -o $@ + +gcov-iov.h: s-iov +s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE) + build/gcov-iov$(build_exeext) '$(BASEVER_c)' '$(DEVPHASE_c)' \ + > tmp-gcov-iov.h + $(SHELL) $(srcdir)/../move-if-change tmp-gcov-iov.h gcov-iov.h + $(STAMP) s-iov + +gcov.o: gcov.c gcov-io.c $(GCOV_IO_H) intl.h $(SYSTEM_H) coretypes.h $(TM_H) \ + $(CONFIG_H) version.h +gcov-dump.o: gcov-dump.c gcov-io.c $(GCOV_IO_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(CONFIG_H) version.h + +GCOV_OBJS = gcov.o intl.o version.o errors.o +gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@ +GCOV_DUMP_OBJS = gcov-dump.o version.o errors.o +gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) $(LIBS) -o $@ +# +# Build the include directories. The stamp files are stmp-* rather than +# s-* so that mostlyclean does not force the include directory to +# be rebuilt. + +# Build the include directories. +stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) $(UNWIND_H) fixinc_list +# Copy in the headers provided with gcc. +# The sed command gets just the last file name component; +# this is necessary because VPATH could add a dirname. +# Using basename would be simpler, but some systems don't have it. +# The touch command is here to workaround an AIX/Linux NFS bug. + -if [ -d include ] ; then true; else mkdir include; chmod a+rx include; fi + -if [ -d include-fixed ] ; then true; else mkdir include-fixed; chmod a+rx include-fixed; fi + for file in .. $(USER_H); do \ + if [ X$$file != X.. ]; then \ + realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \ + $(STAMP) include/$$realfile; \ + rm -f include/$$realfile; \ + cp $$file include; \ + chmod a+r include/$$realfile; \ + fi; \ + done + rm -f include/unwind.h + cp $(UNWIND_H) include/unwind.h + set -e; for ml in `cat fixinc_list`; do \ + sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \ + multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \ + fix_dir=include-fixed$${multi_dir}; \ + if $(LIMITS_H_TEST) ; then \ + cat $(srcdir)/limitx.h $(srcdir)/glimits.h $(srcdir)/limity.h > tmp-xlimits.h; \ + else \ + cat $(srcdir)/glimits.h > tmp-xlimits.h; \ + fi; \ + $(mkinstalldirs) $${fix_dir}; \ + chmod a+rx $${fix_dir} || true; \ + rm -f $${fix_dir}/limits.h; \ + mv tmp-xlimits.h $${fix_dir}/limits.h; \ + chmod a+r $${fix_dir}/limits.h; \ + done +# Install the README + rm -f include-fixed/README + cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README + chmod a+r include-fixed/README + $(STAMP) $@ + +.PHONY: install-gcc-tooldir +install-gcc-tooldir: + $(mkinstalldirs) $(DESTDIR)$(gcc_tooldir) + +macro_list: s-macro_list; @true +s-macro_list : $(GCC_PASSES) + echo | $(GCC_FOR_TARGET) -E -dM - | \ + sed -n -e 's/^#define \([^_][a-zA-Z0-9_]*\).*/\1/p' \ + -e 's/^#define \(_[^_A-Z][a-zA-Z0-9_]*\).*/\1/p' | \ + sort -u > tmp-macro_list + $(SHELL) $(srcdir)/../move-if-change tmp-macro_list macro_list + $(STAMP) s-macro_list + +fixinc_list: s-fixinc_list; @true +s-fixinc_list : $(GCC_PASSES) +# Build up a list of multilib directories and corresponding sysroot +# suffixes, in form sysroot;multilib. + if $(GCC_FOR_TARGET) -print-sysroot-headers-suffix > /dev/null 2>&1; then \ + set -e; for ml in `$(GCC_FOR_TARGET) -print-multi-lib`; do \ + multi_dir=`echo $${ml} | sed -e 's/;.*$$//'`; \ + flags=`echo $${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \ + sfx=`$(GCC_FOR_TARGET) $${flags} -print-sysroot-headers-suffix`; \ + if [ "$${multi_dir}" = "." ]; \ + then multi_dir=""; \ + else \ + multi_dir=/$${multi_dir}; \ + fi; \ + echo "$${sfx};$${multi_dir}"; \ + done; \ + else \ + echo ";"; \ + fi > tmp-fixinc_list + $(SHELL) $(srcdir)/../move-if-change tmp-fixinc_list fixinc_list + $(STAMP) s-fixinc_list + +# The line below is supposed to avoid accidentally matching the +# built-in suffix rule `.o:' to build fixincl out of fixincl.o. You'd +# expect fixincl to be newer than fixincl.o, such that this situation +# would never come up. As it turns out, if you use ccache with +# CCACHE_HARDLINK enabled, the compiler doesn't embed the current +# working directory in object files (-g absent, or -fno-working-dir +# present), and build and host are the same, fixincl for the host will +# build after fixincl for the build machine, getting a cache hit, +# thereby updating the timestamp of fixincl.o in the host tree. +# Because of CCACHE_HARDLINK, this will also update the timestamp in +# the build tree, and so fixincl in the build tree will appear to be +# out of date. Yuck. +../$(build_subdir)/fixincludes/fixincl: ; @ : + +# Build fixed copies of system files. +# Abort if no system headers available, unless building a crosscompiler. +# FIXME: abort unless building --without-headers would be more accurate and less ugly +stmp-fixinc: gsyslimits.h macro_list fixinc_list \ + $(build_objdir)/fixincludes/fixincl \ + $(build_objdir)/fixincludes/fixinc.sh + rm -rf include-fixed; mkdir include-fixed + -chmod a+rx include-fixed + if [ -d ../prev-gcc ]; then \ + cd ../prev-gcc && \ + $(MAKE) real-$(INSTALL_HEADERS_DIR) DESTDIR=`pwd`/../gcc/ \ + libsubdir=. ; \ + else \ + set -e; for ml in `cat fixinc_list`; do \ + sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \ + multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \ + fix_dir=include-fixed$${multi_dir}; \ + if ! $(inhibit_libc) && test ! -d ${SYSTEM_HEADER_DIR}; then \ + echo The directory that should contain system headers does not exist: >&2 ; \ + echo " ${SYSTEM_HEADER_DIR}" >&2 ; \ + tooldir_sysinc=`echo "${gcc_tooldir}/sys-include" | sed -e :a -e "s,[^/]*/\.\.\/,," -e ta`; \ + if test "x${SYSTEM_HEADER_DIR}" = "x$${tooldir_sysinc}"; \ + then sleep 1; else exit 1; fi; \ + fi; \ + $(mkinstalldirs) $${fix_dir}; \ + chmod a+rx $${fix_dir} || true; \ + (TARGET_MACHINE='$(target)'; srcdir=`cd $(srcdir); ${PWD_COMMAND}`; \ + SHELL='$(SHELL)'; MACRO_LIST=`${PWD_COMMAND}`/macro_list ; \ + export TARGET_MACHINE srcdir SHELL MACRO_LIST && \ + cd $(build_objdir)/fixincludes && \ + $(SHELL) ./fixinc.sh ../../gcc/$${fix_dir} \ + $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS) ); \ + rm -f $${fix_dir}/syslimits.h; \ + if [ -f $${fix_dir}/limits.h ]; then \ + mv $${fix_dir}/limits.h $${fix_dir}/syslimits.h; \ + else \ + cp $(srcdir)/gsyslimits.h $${fix_dir}/syslimits.h; \ + fi; \ + chmod a+r $${fix_dir}/syslimits.h; \ + done; \ + fi + $(STAMP) stmp-fixinc + +# Files related to the fixproto script. +# gen-protos and fix-header are compiled with CC_FOR_BUILD, but they are only +# used in native and host-x-target builds, so it's safe to link them with +# libiberty.a. + +deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs + if [ -d "$(SYSTEM_HEADER_DIR)" ]; \ + then \ + CC="$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) -I. -I$(srcdir) -isystem include -isystem ${SYSTEM_HEADER_DIR}"; \ + export CC; \ + $(SHELL) $(srcdir)/scan-types.sh "$(srcdir)" >tmp-deduced.h; \ + mv tmp-deduced.h deduced.h; \ + else \ + $(STAMP) deduced.h; \ + fi + +GEN_PROTOS_OBJS = build/gen-protos.o build/scan.o $(BUILD_ERRORS) +build/gen-protos$(build_exeext): $(GEN_PROTOS_OBJS) + ${CC_FOR_BUILD} $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \ + $(GEN_PROTOS_OBJS) $(BUILD_LIBS) + +build/gen-protos.o: gen-protos.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ + $(GTM_H) errors.h + +build/scan.o: scan.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) + +xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h \ + build/gen-protos$(build_exeext) Makefile + sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \ + deduced.h $(srcdir)/sys-protos.h > tmp-fixtmp.c + mv tmp-fixtmp.c fixtmp.c + $(GCC_FOR_TARGET) fixtmp.c -w -U__SIZE_TYPE__ -U__PTRDIFF_TYPE__ -U__WCHAR_TYPE__ -E \ + | sed -e 's/ / /g' -e 's/ *(/ (/g' -e 's/ [ ]*/ /g' -e 's/( )/()/' \ + | $(RUN_GEN) build/gen-protos >xsys-protos.hT + mv xsys-protos.hT xsys-protos.h + rm -rf fixtmp.c + +# This is nominally a 'build' program, but it's run only when host==build, +# so we can (indeed, must) use $(LIBDEPS) and $(LIBS). +build/fix-header$(build_exeext): build/fix-header.o build/scan-decls.o \ + build/scan.o xsys-protos.h \ + $(BUILD_ERRORS) $(LIBDEPS) + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \ + build/fix-header.o incpath.o cppdefault.o build/scan-decls.o prefix.o \ + build/scan.o $(BUILD_ERRORS) $(LIBS) + +build/fix-header.o: fix-header.c $(OBSTACK_H) scan.h errors.h \ + xsys-protos.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(CPPLIB_H) + +build/scan-decls.o: scan-decls.c scan.h $(CPPLIB_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) + +# stmp-fixproto depends on this, not on fix-header directly. +# The idea is to make sure fix-header gets built, +# but not rerun fixproto after each stage +# just because fix-header's mtime has changed. +fixhdr.ready: build/fix-header$(build_exeext) + -if [ -f fixhdr.ready ] ; then \ + true; \ + else \ + $(STAMP) fixhdr.ready; \ + fi + +# stmp-int-hdrs is to make sure fixincludes has already finished. +# The if statement is so that we don't run fixproto a second time +# if it has already been run on the files in `include-fixed'. +stmp-fixproto: fixhdr.ready fixproto fixinc_list stmp-int-hdrs + set -e; for ml in `cat fixinc_list`; do \ + sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \ + multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \ + fix_dir=include-fixed$${multi_dir}; \ + if [ -f $${fix_dir}/fixed ] ; then true; \ + else \ + : This line works around a 'make' bug in BSDI 1.1.; \ + FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \ + FIX_HEADER="build/fix-header$(build_exeext)"; export FIX_HEADER; \ + mkinstalldirs="$(mkinstalldirs)"; \ + export mkinstalldirs; \ + if [ -d "$(SYSTEM_HEADER_DIR)" ]; then \ + $(SHELL) ${srcdir}/fixproto $${fix_dir} $${fix_dir} $(SYSTEM_HEADER_DIR); \ + if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \ + else true; fi; \ + $(STAMP) $${fix_dir}/fixed; \ + fi; \ + done + $(STAMP) stmp-fixproto + +# We can't run fixproto (it's being built for a different host), but we still +# need to install it so that the user can run it when the compiler is +# installed. +stmp-install-fixproto: fixproto + $(STAMP) $@ +# +# Remake the info files. + +doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug + +INFOFILES = doc/cpp.info doc/gcc.info doc/gccint.info \ + doc/gccinstall.info doc/cppinternals.info + +info: $(INFOFILES) lang.info @GENINSRC@ srcinfo lang.srcinfo + +srcinfo: $(INFOFILES) + -cp -p $^ $(srcdir)/doc + +TEXI_CPP_FILES = cpp.texi fdl.texi cppenv.texi cppopts.texi \ + gcc-common.texi gcc-vers.texi + +TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \ + standards.texi invoke.texi extend.texi md.texi objc.texi \ + 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 \ + implement-c.texi arm-neon-intrinsics.texi + +TEXI_GCCINT_FILES = gccint.texi gcc-common.texi gcc-vers.texi \ + contribute.texi makefile.texi configterms.texi options.texi \ + portability.texi interface.texi passes.texi c-tree.texi \ + rtl.texi md.texi tm.texi hostconfig.texi fragments.texi \ + configfiles.texi collect2.texi headerdirs.texi funding.texi \ + gnu.texi gpl_v3.texi fdl.texi contrib.texi languages.texi \ + sourcebuild.texi gty.texi libgcc.texi cfg.texi tree-ssa.texi \ + loop.texi generic.texi gimple.texi + +TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi \ + gcc-common.texi gcc-vers.texi + +TEXI_CPPINT_FILES = cppinternals.texi gcc-common.texi gcc-vers.texi + +# gcc-vers.texi is generated from the version files. +gcc-vers.texi: $(BASEVER) $(DEVPHASE) + (echo "@set version-GCC $(BASEVER_c)"; \ + if [ "$(DEVPHASE_c)" = "experimental" ]; \ + then echo "@set DEVELOPMENT"; \ + else echo "@clear DEVELOPMENT"; \ + fi) > $@T + $(build_file_translate) echo @set srcdir $(abs_srcdir) >> $@T + if [ -n "$(PKGVERSION)" ]; then \ + echo "@set VERSION_PACKAGE $(PKGVERSION)" >> $@T; \ + fi + echo "@set BUGURL $(BUGURL_TEXI)" >> $@T; \ + mv -f $@T $@ + + +# The *.1, *.7, *.info, *.dvi, and *.pdf files are being generated from implicit +# patterns. To use them, put each of the specific targets with its +# specific dependencies but no build commands. + +doc/cpp.info: $(TEXI_CPP_FILES) +doc/gcc.info: $(TEXI_GCC_FILES) +doc/gccint.info: $(TEXI_GCCINT_FILES) +doc/cppinternals.info: $(TEXI_CPPINT_FILES) + +doc/%.info: %.texi + if [ x$(BUILD_INFO) = xinfo ]; then \ + $(MAKEINFO) $(MAKEINFOFLAGS) -I . -I $(gcc_docdir) \ + -I $(gcc_docdir)/include -o $@ $<; \ + fi + +# Duplicate entry to handle renaming of gccinstall.info +doc/gccinstall.info: $(TEXI_GCCINSTALL_FILES) + if [ x$(BUILD_INFO) = xinfo ]; then \ + $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \ + -I $(gcc_docdir)/include -o $@ $<; \ + fi + +doc/cpp.dvi: $(TEXI_CPP_FILES) +doc/gcc.dvi: $(TEXI_GCC_FILES) +doc/gccint.dvi: $(TEXI_GCCINT_FILES) +doc/cppinternals.dvi: $(TEXI_CPPINT_FILES) + +doc/cpp.pdf: $(TEXI_CPP_FILES) +doc/gcc.pdf: $(TEXI_GCC_FILES) +doc/gccint.pdf: $(TEXI_GCCINT_FILES) +doc/cppinternals.pdf: $(TEXI_CPPINT_FILES) + +$(build_htmldir)/cpp/index.html: $(TEXI_CPP_FILES) +$(build_htmldir)/gcc/index.html: $(TEXI_GCC_FILES) +$(build_htmldir)/gccint/index.html: $(TEXI_GCCINT_FILES) +$(build_htmldir)/cppinternals/index.html: $(TEXI_CPPINT_FILES) + +dvi:: doc/gcc.dvi doc/gccint.dvi doc/gccinstall.dvi doc/cpp.dvi \ + doc/cppinternals.dvi lang.dvi + +doc/%.dvi: %.texi + $(TEXI2DVI) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< + +# Duplicate entry to handle renaming of gccinstall.dvi +doc/gccinstall.dvi: $(TEXI_GCCINSTALL_FILES) + $(TEXI2DVI) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< + +PDFFILES = doc/gcc.pdf doc/gccint.pdf doc/gccinstall.pdf doc/cpp.pdf \ + doc/cppinternals.pdf + +pdf:: $(PDFFILES) lang.pdf + +doc/%.pdf: %.texi + $(TEXI2PDF) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< + +# Duplicate entry to handle renaming of gccinstall.pdf +doc/gccinstall.pdf: $(TEXI_GCCINSTALL_FILES) + $(TEXI2PDF) -I . -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< + +# List the directories or single hmtl files which are installed by +# install-html. The lang.html file triggers language fragments to build +# html documentation. Installing language fragment documentation is not +# yet supported. +HTMLS_INSTALL=$(build_htmldir)/cpp $(build_htmldir)/gcc \ + $(build_htmldir)/gccinstall $(build_htmldir)/gccint \ + $(build_htmldir)/cppinternals + +# List the html file targets. +HTMLS_BUILD=$(build_htmldir)/cpp/index.html $(build_htmldir)/gcc/index.html \ + $(build_htmldir)/gccinstall/index.html $(build_htmldir)/gccint/index.html \ + $(build_htmldir)/cppinternals/index.html lang.html + +html:: $(HTMLS_BUILD) + +$(build_htmldir)/%/index.html: %.texi + $(mkinstalldirs) $(@D) + rm -f $(@D)/* + $(TEXI2HTML) -I $(abs_docdir) -I $(abs_docdir)/include -o $(@D) $< + +# Duplicate entry to handle renaming of gccinstall +$(build_htmldir)/gccinstall/index.html: $(TEXI_GCCINSTALL_FILES) + $(mkinstalldirs) $(@D) + echo rm -f $(@D)/* + SOURCEDIR=$(abs_docdir) \ + DESTDIR=$(@D) \ + $(SHELL) $(srcdir)/doc/install.texi2html + +MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 doc/fsf-funding.7 + +generated-manpages: man + +man: $(MANFILES) lang.man @GENINSRC@ srcman lang.srcman + +srcman: $(MANFILES) + -cp -p $^ $(srcdir)/doc + +doc/%.1: %.pod + $(STAMP) $@ + -($(POD2MAN) --section=1 $< > $(@).T$$$$ && \ + mv -f $(@).T$$$$ $@) || \ + (rm -f $(@).T$$$$ && exit 1) + +doc/%.7: %.pod + $(STAMP) $@ + -($(POD2MAN) --section=7 $< > $(@).T$$$$ && \ + mv -f $(@).T$$$$ $@) || \ + (rm -f $(@).T$$$$ && exit 1) + +%.pod: %.texi + $(STAMP) $@ + -$(TEXI2POD) -DBUGURL="$(BUGURL_TEXI)" $< > $@ + +.INTERMEDIATE: cpp.pod gcc.pod gfdl.pod fsf-funding.pod +cpp.pod: cpp.texi cppenv.texi cppopts.texi + +# These next rules exist because the output name is not the same as +# the input name, so our implicit %.pod rule will not work. + +gcc.pod: invoke.texi cppenv.texi cppopts.texi + $(STAMP) $@ + -$(TEXI2POD) $< > $@ +gfdl.pod: fdl.texi + $(STAMP) $@ + -$(TEXI2POD) $< > $@ +fsf-funding.pod: funding.texi + $(STAMP) $@ + -$(TEXI2POD) $< > $@ +gpl.pod: gpl_v3.texi + $(STAMP) $@ + -$(TEXI2POD) $< > $@ + +# +# Deletion of files made during compilation. +# There are four levels of this: +# `mostlyclean', `clean', `distclean' and `maintainer-clean'. +# `mostlyclean' is useful while working on a particular type of machine. +# It deletes most, but not all, of the files made by compilation. +# It does not delete libgcc.a or its parts, so it won't have to be recompiled. +# `clean' deletes everything made by running `make all'. +# `distclean' also deletes the files made by config. +# `maintainer-clean' also deletes everything that could be regenerated +# automatically, except for `configure'. +# We remove as much from the language subdirectories as we can +# (less duplicated code). + +mostlyclean: lang.mostlyclean + -rm -f $(MOSTLYCLEANFILES) + -rm -f *$(objext) + -rm -f *$(coverageexts) +# Delete build programs + -rm -f build/* + -rm -f mddeps.mk +# Delete other built files. + -rm -f xsys-protos.hT + -rm -f specs.h options.c options.h +# Delete the stamp and temporary files. + -rm -f s-* tmp-* stamp-* stmp-* + -rm -f */stamp-* */tmp-* +# Delete debugging dump files. + -rm -f *.[0-9][0-9].* */*.[0-9][0-9].* +# Delete some files made during installation. + -rm -f specs $(SPECS) SYSCALLS.c.X SYSCALLS.c + -rm -f collect collect2 mips-tfile mips-tdump +# Delete files generated for fixproto + -rm -rf $(build_exeext) xsys-protos.h deduced.h tmp-deduced.h \ + gen-protos$(build_exeext) fixproto.list fixtmp.* fixhdr.ready +# Delete unwanted output files from TeX. + -rm -f *.toc *.log *.vr *.fn *.cp *.tp *.ky *.pg + -rm -f */*.toc */*.log */*.vr */*.fn */*.cp */*.tp */*.ky */*.pg +# Delete sorted indices we don't actually use. + -rm -f gcc.vrs gcc.kys gcc.tps gcc.pgs gcc.fns +# Delete core dumps. + -rm -f core */core +# Delete file generated for gengtype + -rm -f gtyp-input.list +# Delete files generated by gengtype.c + -rm -f gtype-* + -rm -f gt-* +# Delete genchecksum outputs + -rm -f *-checksum.c + +# Delete all files made by compilation +# that don't exist in the distribution. +clean: mostlyclean lang.clean + -rm -f libgcc.a libgcc_eh.a libgcov.a + -rm -f libgcc_s* + -rm -f libunwind* + -rm -f config.h tconfig.h bconfig.h tm_p.h tm.h + -rm -f options.c options.h optionlist + -rm -f cs-* + -rm -f doc/*.dvi + -rm -f doc/*.pdf +# Delete the include directories. + -rm -rf include include-fixed +# Delete files used by the "multilib" facility (including libgcc subdirs). + -rm -f multilib.h tmpmultilib* + -rm -f $(PLUGSPEC_OUTPUT) icg.burg plug iburg icg-burg.c pluggram.c + -if [ "x$(MULTILIB_DIRNAMES)" != x ] ; then \ + rm -rf $(MULTILIB_DIRNAMES); \ + else if [ "x$(MULTILIB_OPTIONS)" != x ] ; then \ + rm -rf `echo $(MULTILIB_OPTIONS) | sed -e 's/\// /g'`; \ + fi ; fi + +# Delete all files that users would normally create +# while building and installing GCC. +distclean: clean lang.distclean + -rm -f auto-host.h auto-build.h + -rm -f cstamp-h + -rm -f config.status config.run config.cache config.bak + -rm -f Make-lang Make-hooks Make-host Make-target + -rm -f Makefile *.oaux + -rm -f gthr-default.h + -rm -f TAGS */TAGS + -rm -f *.asm + -rm -f site.exp site.bak testsuite/site.exp testsuite/site.bak + -rm -f testsuite/*.log testsuite/*.sum + -cd testsuite && rm -f x *.x *.x? *.exe *.rpo *.o *.s *.S *.c + -cd testsuite && rm -f *.out *.gcov *$(coverageexts) + -rm -rf ${QMTEST_DIR} stamp-qmtest + -rm -f cxxmain.c + -rm -f gccbug .gdbinit configargs.h + -rm -f gcov.pod +# Delete po/*.gmo only if we are not building in the source directory. + -if [ ! -f po/exgettext ]; then rm -f po/*.gmo; fi + -rmdir ada cp f java objc intl po testsuite 2>/dev/null + +# Get rid of every file that's generated from some other file, except for `configure'. +# Most of these files ARE PRESENT in the GCC distribution. +maintainer-clean: + @echo 'This command is intended for maintainers to use; it' + @echo 'deletes files that may need special tools to rebuild.' + $(MAKE) lang.maintainer-clean distclean + -rm -f cpp.??s cpp.*aux + -rm -f gcc.??s gcc.*aux + -rm -f $(gcc_docdir)/*.info $(gcc_docdir)/*.1 $(gcc_docdir)/*.7 $(gcc_docdir)/*.dvi $(gcc_docdir)/*.pdf +# +# Entry points `install' and `uninstall'. +# Also use `install-collect2' to install collect2 when the config files don't. + +# Copy the compiler files into directories where they will be run. +# Install the driver last so that the window when things are +# broken is small. +install: install-common $(INSTALL_HEADERS) \ + install-cpp install-man install-info install-@POSUB@ \ + install-driver + +# Handle cpp installation. +install-cpp: installdirs cpp$(exeext) + -rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext) + -$(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext) + -if [ x$(cpp_install_dir) != x ]; then \ + rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \ + else true; fi + +# Create the installation directories. +# $(libdir)/gcc/include isn't currently searched by cpp. +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libsubdir) + $(mkinstalldirs) $(DESTDIR)$(libexecsubdir) + $(mkinstalldirs) $(DESTDIR)$(bindir) + $(mkinstalldirs) $(DESTDIR)$(includedir) + $(mkinstalldirs) $(DESTDIR)$(infodir) + $(mkinstalldirs) $(DESTDIR)$(slibdir) + $(mkinstalldirs) $(DESTDIR)$(man1dir) + $(mkinstalldirs) $(DESTDIR)$(man7dir) + +# Install the compiler executables built during cross compilation. +install-common: native lang.install-common installdirs + for file in $(COMPILERS); do \ + if [ -f $$file ] ; then \ + rm -f $(DESTDIR)$(libexecsubdir)/$$file; \ + $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libexecsubdir)/$$file; \ + else true; \ + fi; \ + done + for file in $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(COLLECT2) ..; do \ + if [ x"$$file" != x.. ]; then \ + rm -f $(DESTDIR)$(libexecsubdir)/$$file; \ + $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libexecsubdir)/$$file; \ + else true; fi; \ + done +# We no longer install the specs file because its presence makes the +# driver slower, and because people who need it can recreate it by +# using -dumpspecs. We remove any old version because it would +# otherwise override the specs built into the driver. + rm -f $(DESTDIR)$(libsubdir)/specs +# Install protoize if it was compiled. + -if [ -f protoize$(exeext) ]; then \ + rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \ + rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \ + rm -f $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \ + $(INSTALL_DATA) SYSCALLS.c.X $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \ + chmod a-x $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \ + fi +# Install gcov if it was compiled. + -if [ -f gcov$(exeext) ]; \ + then \ + rm -f $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) gcov$(exeext) $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \ + fi + $(INSTALL_SCRIPT) gccbug $(DESTDIR)$(bindir)/$(GCCBUG_INSTALL_NAME) + +# Install the driver program as $(target_noncanonical)-gcc, +# $(target_noncanonical)-gcc-$(version) +# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc. +install-driver: installdirs xgcc$(exeext) + -rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) + -$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) + -rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)$(exeext) + -( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version)$(exeext) ) + -if [ -f gcc-cross$(exeext) ] ; then \ + if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \ + rm -f $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \ + $(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \ + else true; fi; \ + else \ + rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-tmp$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-tmp$(exeext) && \ + mv -f $(target_noncanonical)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \ + fi + +# Install the info files. +# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir +# to do the install. +install-info:: doc installdirs \ + $(DESTDIR)$(infodir)/cpp.info \ + $(DESTDIR)$(infodir)/gcc.info \ + $(DESTDIR)$(infodir)/cppinternals.info \ + $(DESTDIR)$(infodir)/gccinstall.info \ + $(DESTDIR)$(infodir)/gccint.info \ + lang.install-info + +$(DESTDIR)$(infodir)/%.info: doc/%.info installdirs + rm -f $@ + if [ -f $< ]; then \ + for f in $(<)*; do \ + realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \ + $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$realfile; \ + chmod a-x $(DESTDIR)$(infodir)/$$realfile; \ + done; \ + else true; fi + -if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ + if [ -f $@ ]; then \ + install-info --dir-file=$(DESTDIR)$(infodir)/dir $@; \ + else true; fi; \ + else true; fi; + +pdf__strip_dir = `echo $$p | sed -e 's|^.*/||'`; + +install-pdf: $(PDFFILES) lang.install-pdf + @$(NORMAL_INSTALL) + test -z "$(pdfdir)/gcc" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)/gcc" + @list='$(PDFFILES)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(pdf__strip_dir) \ + echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/gcc/$$f'"; \ + $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/gcc/$$f"; \ + done + +html__strip_dir = `echo $$p | sed -e 's|^.*/||'`; + +install-html: $(HTMLS_BUILD) + @$(NORMAL_INSTALL) + test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)" + @list='$(HTMLS_INSTALL)'; for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \ + f=$(html__strip_dir) \ + if test -d "$$d$$p"; then \ + echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \ + else \ + echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \ + fi; \ + done + +# Install the man pages. +install-man: lang.install-man \ + $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) \ + $(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext) \ + $(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext) \ + $(DESTDIR)$(man7dir)/fsf-funding$(man7ext) \ + $(DESTDIR)$(man7dir)/gfdl$(man7ext) \ + $(DESTDIR)$(man7dir)/gpl$(man7ext) + +$(DESTDIR)$(man7dir)/%$(man7ext): doc/%.7 installdirs + -rm -f $@ + -$(INSTALL_DATA) $< $@ + -chmod a-x $@ + +$(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext): doc/gcc.1 installdirs + -rm -f $@ + -$(INSTALL_DATA) $< $@ + -chmod a-x $@ + +$(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext): doc/cpp.1 installdirs + -rm -f $@ + -$(INSTALL_DATA) $< $@ + -chmod a-x $@ + +$(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext): doc/gcov.1 installdirs + -rm -f $@ + -$(INSTALL_DATA) $< $@ + -chmod a-x $@ + +# Install all the header files built in the include subdirectory. +install-headers: $(INSTALL_HEADERS_DIR) +# Fix symlinks to absolute paths in the installed include directory to +# point to the installed directory, not the build directory. +# Don't need to use LN_S here since we really do need ln -s and no substitutes. + -files=`cd $(DESTDIR)$(libsubdir)/include-fixed; find . -type l -print 2>/dev/null`; \ + if [ $$? -eq 0 ]; then \ + dir=`cd include-fixed; ${PWD_COMMAND}`; \ + for i in $$files; do \ + dest=`ls -ld $(DESTDIR)$(libsubdir)/include-fixed/$$i | sed -n 's/.*-> //p'`; \ + if expr "$$dest" : "$$dir.*" > /dev/null; then \ + rm -f $(DESTDIR)$(libsubdir)/include-fixed/$$i; \ + ln -s `echo $$i | sed "s|/[^/]*|/..|g" | sed 's|/..$$||'``echo "$$dest" | sed "s|$$dir||"` $(DESTDIR)$(libsubdir)/include-fixed/$$i; \ + fi; \ + done; \ + fi + +# Create or recreate the gcc private include file directory. +install-include-dir: installdirs + $(mkinstalldirs) $(DESTDIR)$(libsubdir)/include + -rm -rf $(DESTDIR)$(libsubdir)/include-fixed + mkdir $(DESTDIR)$(libsubdir)/include-fixed + -chmod a+rx $(DESTDIR)$(libsubdir)/include-fixed + +# Create or recreate the install-tools include file directory. +itoolsdir = $(libexecsubdir)/install-tools +itoolsdatadir = $(libsubdir)/install-tools +install-itoolsdirs: installdirs + $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include + $(mkinstalldirs) $(DESTDIR)$(itoolsdir) + +# Install the include directory using tar. +install-headers-tar: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir +# We use `pwd`/include instead of just include to problems with CDPATH +# Unless a full pathname is provided, some shells would print the new CWD, +# found in CDPATH, corrupting the output. We could just redirect the +# output of `cd', but some shells lose on redirection within `()'s + (cd `${PWD_COMMAND}`/include ; \ + tar -cf - .; exit 0) | (cd $(DESTDIR)$(libsubdir)/include; tar xpf - ) + (cd `${PWD_COMMAND}`/include-fixed ; \ + tar -cf - .; exit 0) | (cd $(DESTDIR)$(libsubdir)/include-fixed; tar xpf - ) +# /bin/sh on some systems returns the status of the first tar, +# and that can lose with GNU tar which always writes a full block. +# So use `exit 0' to ignore its exit status. + +# Install the include directory using cpio. +install-headers-cpio: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir +# See discussion about the use of `pwd` above + cd `${PWD_COMMAND}`/include ; \ + find . -print | cpio -pdum $(DESTDIR)$(libsubdir)/include + cd `${PWD_COMMAND}`/include-fixed ; \ + find . -print | cpio -pdum $(DESTDIR)$(libsubdir)/include-fixed + +# Install the include directory using cp. +install-headers-cp: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir + cp -p -r include $(DESTDIR)$(libsubdir) + cp -p -r include-fixed $(DESTDIR)$(libsubdir) + +# Targets without dependencies, for use in prev-gcc during bootstrap. +real-install-headers-tar: + (cd `${PWD_COMMAND}`/include-fixed ; \ + tar -cf - .; exit 0) | (cd $(DESTDIR)$(libsubdir)/include-fixed; tar xpf - ) + +real-install-headers-cpio: + cd `${PWD_COMMAND}`/include-fixed ; \ + find . -print | cpio -pdum $(DESTDIR)$(libsubdir)/include-fixed + +real-install-headers-cp: + cp -p -r include-fixed $(DESTDIR)$(libsubdir) + +# Install supporting files for fixincludes to be run later. +install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-itoolsdirs \ + macro_list fixinc_list + $(INSTALL_DATA) $(srcdir)/gsyslimits.h \ + $(DESTDIR)$(itoolsdatadir)/gsyslimits.h + $(INSTALL_DATA) macro_list $(DESTDIR)$(itoolsdatadir)/macro_list + $(INSTALL_DATA) fixinc_list $(DESTDIR)$(itoolsdatadir)/fixinc_list + set -e; for ml in `cat fixinc_list`; do \ + multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \ + $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}; \ + $(INSTALL_DATA) include-fixed$${multidir}/limits.h $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}/limits.h; \ + done + $(INSTALL_SCRIPT) $(srcdir)/../mkinstalldirs \ + $(DESTDIR)$(itoolsdir)/mkinstalldirs ; \ + if [ x$(STMP_FIXPROTO) != x ] ; then \ + $(INSTALL_SCRIPT) $(srcdir)/fixproto $(DESTDIR)$(itoolsdir)/fixproto ; \ + $(INSTALL_PROGRAM) build/fix-header$(build_exeext) \ + $(DESTDIR)$(itoolsdir)/fix-header$(build_exeext) ; \ + else :; fi + sysroot_headers_suffix='$${sysroot_headers_suffix}'; \ + echo 'SYSTEM_HEADER_DIR="'"$(SYSTEM_HEADER_DIR)"'"' \ + > $(DESTDIR)$(itoolsdatadir)/mkheaders.conf + echo 'OTHER_FIXINCLUDES_DIRS="$(OTHER_FIXINCLUDES_DIRS)"' \ + >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf + echo 'FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"' \ + >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf + echo 'STMP_FIXPROTO="$(STMP_FIXPROTO)"' \ + >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf + echo 'STMP_FIXINC="$(STMP_FIXINC)"' \ + >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf + +# Use this target to install the program `collect2' under the name `collect2'. +install-collect2: collect2 installdirs + $(INSTALL_PROGRAM) collect2$(exeext) $(DESTDIR)$(libexecsubdir)/collect2$(exeext) +# Install the driver program as $(libsubdir)/gcc for collect2. + $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(libexecsubdir)/gcc$(exeext) + +# Cancel installation by deleting the installed files. +uninstall: lang.uninstall + -rm -rf $(DESTDIR)$(libsubdir) + -rm -rf $(DESTDIR)$(libexecsubdir) + -rm -rf $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) + -rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext) + -if [ x$(cpp_install_dir) != x ]; then \ + rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \ + else true; fi + -rm -rf $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/cpp$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/protoize$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/unprotoize$(man1ext) + -rm -f $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info* + -rm -f $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info* +# +# These targets are for the dejagnu testsuites. The file site.exp +# contains global variables that all the testsuites will use. + +target_subdir = @target_subdir@ + +site.exp: ./config.status Makefile + @echo "Making a new config file..." + -@rm -f ./tmp? + @$(STAMP) site.exp + -@mv site.exp site.bak + @echo "## these variables are automatically generated by make ##" > ./tmp0 + @echo "# Do not edit here. If you wish to override these values" >> ./tmp0 + @echo "# add them to the last section" >> ./tmp0 + @echo "set rootme \"`${PWD_COMMAND}`\"" >> ./tmp0 + @echo "set srcdir \"`cd ${srcdir}; ${PWD_COMMAND}`\"" >> ./tmp0 + @echo "set host_triplet $(host)" >> ./tmp0 + @echo "set build_triplet $(build)" >> ./tmp0 + @echo "set target_triplet $(target)" >> ./tmp0 + @echo "set target_alias $(target_noncanonical)" >> ./tmp0 + @echo "set libiconv \"$(LIBICONV)\"" >> ./tmp0 +# CFLAGS is set even though it's empty to show we reserve the right to set it. + @echo "set CFLAGS \"\"" >> ./tmp0 + @echo "set CXXFLAGS \"\"" >> ./tmp0 + @echo "set HOSTCC \"$(CC)\"" >> ./tmp0 + @echo "set HOSTCFLAGS \"$(CFLAGS)\"" >> ./tmp0 + @echo "set TESTING_IN_BUILD_TREE 1" >> ./tmp0 + @echo "set HAVE_LIBSTDCXX_V3 1" >> ./tmp0 + @echo "set GCC_EXEC_PREFIX \"$(libdir)/gcc/\"" >> ./tmp0 +# If newlib has been configured, we need to pass -B to gcc so it can find +# newlib's crt0.o if it exists. This will cause a "path prefix not used" +# message if it doesn't, but the testsuite is supposed to ignore the message - +# it's too difficult to tell when to and when not to pass -B (not all targets +# have crt0's). We could only add the -B if ../newlib/crt0.o exists, but that +# seems like too selective a test. +# ??? Another way to solve this might be to rely on linker scripts. Then +# theoretically the -B won't be needed. +# We also need to pass -L ../ld so that the linker can find ldscripts. + @if [ -d $(objdir)/../$(target_subdir)/newlib ] \ + && [ "${host}" != "${target}" ]; then \ + echo "set newlib_cflags \"-I$(objdir)/../$(target_subdir)/newlib/targ-include -I\$$srcdir/../newlib/libc/include\"" >> ./tmp0; \ + echo "set newlib_ldflags \"-B$(objdir)/../$(target_subdir)/newlib/\"" >> ./tmp0; \ + echo "append CFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \ + echo "append CXXFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \ + echo "append LDFLAGS \" \$$newlib_ldflags\"" >> ./tmp0; \ + else true; \ + fi + @if [ -d $(objdir)/../ld ] ; then \ + echo "append LDFLAGS \" -L$(objdir)/../ld\"" >> ./tmp0; \ + else true; \ + fi + echo "set tmpdir $(objdir)/testsuite" >> ./tmp0 + @echo "set srcdir \"\$${srcdir}/testsuite\"" >> ./tmp0 + @if [ "X$(ALT_CC_UNDER_TEST)" != "X" ] ; then \ + echo "set ALT_CC_UNDER_TEST \"$(ALT_CC_UNDER_TEST)\"" >> ./tmp0; \ + else true; \ + fi + @if [ "X$(ALT_CXX_UNDER_TEST)" != "X" ] ; then \ + echo "set ALT_CXX_UNDER_TEST \"$(ALT_CXX_UNDER_TEST)\"" >> ./tmp0; \ + else true; \ + fi + @if [ "X$(COMPAT_OPTIONS)" != "X" ] ; then \ + echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./tmp0; \ + else true; \ + fi + @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0 + @cat ./tmp0 > site.exp + @cat site.bak | sed \ + -e '1,/^## All variables above are.*##/ d' >> site.exp + -@rm -f ./tmp? + +CHECK_TARGETS = check-gcc @check_languages@ + +check: $(CHECK_TARGETS) + +check-subtargets: $(patsubst %,%-subtargets,$(CHECK_TARGETS)) + +# The idea is to parallelize testing of multilibs, for example: +# make -j3 check-gcc//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu} +# will run 3 concurrent sessions of check-gcc, eventually testing +# all 10 combinations. GNU make is required, as is a shell that expands +# alternations within braces. +lang_checks_parallel = $(lang_checks:=//%) +$(lang_checks_parallel): site.exp + target=`echo "$@" | sed 's,//.*,,'`; \ + variant=`echo "$@" | sed 's,^[^/]*//,,'`; \ + vardots=`echo "$$variant" | sed 's,/,.,g'`; \ + $(MAKE) TESTSUITEDIR="testsuite.$$vardots" \ + RUNTESTFLAGS="--target_board=$$variant $(RUNTESTFLAGS)" \ + "$$target" + +TESTSUITEDIR = testsuite + +$(TESTSUITEDIR)/site.exp: site.exp + -test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) + -rm -f $@ + sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)|' < site.exp > $@ + +# This is only used for check-% targets that aren't parallelized. +$(filter-out $(lang_checks_parallelized),$(lang_checks)): check-% : site.exp + -test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) + test -d $(TESTSUITEDIR)/$* || mkdir $(TESTSUITEDIR)/$* + -(rootme=`${PWD_COMMAND}`; export rootme; \ + srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \ + cd $(TESTSUITEDIR)/$*; \ + rm -f tmp-site.exp; \ + sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)/$*|' \ + < ../../site.exp > tmp-site.exp; \ + $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../expect/expect ] ; then \ + TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \ + export TCL_LIBRARY ; fi ; \ + GCC_EXEC_PREFIX="$(libdir)/gcc/" ; export GCC_EXEC_PREFIX ; \ + $(RUNTEST) --tool $* $(RUNTESTFLAGS)) + +$(patsubst %,%-subtargets,$(filter-out $(lang_checks_parallelized),$(lang_checks))): check-%-subtargets: + @echo check-$* + +check_p_tool=$(firstword $(subst _, ,$*)) +check_p_vars=$(check_$(check_p_tool)_parallelize) +check_p_subno=$(word 2,$(subst _, ,$*)) +check_p_comma=, +check_p_subwork=$(subst $(check_p_comma), ,$(if $(check_p_subno),$(word $(check_p_subno),$(check_p_vars)))) +check_p_numbers=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +check_p_subdir=$(subst _,,$*) +check_p_subdirs=$(wordlist 1,$(words $(check_$*_parallelize)),$(check_p_numbers)) + +# For parallelized check-% targets, this decides whether parallelization +# is desirable (if -jN is used and RUNTESTFLAGS doesn't contain anything +# but optionally --target_board argument). If it is desirable, +# recursive make is run with check-parallel-$lang{,1,2,3,4,5} etc. goals, +# which can be executed in parallel, as they are run in separate directories. +# check-parallel-$lang{1,2,3,4,5} etc. goals invoke runtest with the longest +# running *.exp files from the testsuite, as determined by check_$lang_parallelize +# variable. The check-parallel-$lang goal in that case invokes runtest with +# all the remaining *.exp files not handled by the separate goals. +# Afterwards contrib/dg-extract-results.sh is used to merge the sum and log +# files. If parallelization isn't desirable, only one recursive make +# is run with check-parallel-$lang goal and check_$lang_parallelize variable +# cleared to say that no additional arguments beyond $(RUNTESTFLAGS) +# should be passed to runtest. +# +# To parallelize some language check, add the corresponding check-$lang +# to lang_checks_parallelized variable and define check_$lang_parallelize +# variable (see above check_gcc_parallelize description). +$(lang_checks_parallelized): check-% : site.exp + @if [ -z "$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \ + && [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \ + $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \ + check-parallel-$* \ + $(patsubst %,check-parallel-$*_%, $(check_p_subdirs)); \ + for file in $(TESTSUITEDIR)/$*/$* \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*,$(check_p_subdirs));\ + do \ + mv -f $$file.sum $$file.sum.sep; mv -f $$file.log $$file.log.sep; \ + done; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh \ + $(TESTSUITEDIR)/$*/$*.sum.sep \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*.sum.sep,$(check_p_subdirs)) \ + > $(TESTSUITEDIR)/$*/$*.sum; \ + $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L \ + $(TESTSUITEDIR)/$*/$*.log.sep \ + $(patsubst %,$(TESTSUITEDIR)/$*%/$*.log.sep,$(check_p_subdirs)) \ + > $(TESTSUITEDIR)/$*/$*.log; \ + else \ + $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \ + check_$*_parallelize= check-parallel-$*; \ + fi + +# Just print the parallelized subtargets for those that want to split +# the testing across machines. +$(patsubst %,%-subtargets,$(lang_checks_parallelized)): check-%-subtargets: + @echo check-parallel-$* \ + $(patsubst %,check-parallel-$*_%, $(check_p_subdirs)) + +# In the if [ -n "$(check_p_subno)" ] case runtest should be given the name of +# the given *.exp file(s). See comment above check_gcc_parallelize variable +# for details on the content of these variables. +# +# In the elif [ -n "$(check_p_vars)" ] case runtest should be given +# names of all the *.exp files for this tool that aren't already handled by +# other goals. First it finds all the *.exp files for this tool, then +# prunes those already specified in check_$lang_parallelize or duplicates. +# +# Otherwise check-$lang isn't parallelized and runtest is invoked just with +# the $(RUNTESTFLAGS) arguments. +check-parallel-% : site.exp + -test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) + test -d $(TESTSUITEDIR)/$(check_p_subdir) || mkdir $(TESTSUITEDIR)/$(check_p_subdir) + -(rootme=`${PWD_COMMAND}`; export rootme; \ + srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \ + cd $(TESTSUITEDIR)/$(check_p_subdir); \ + rm -f tmp-site.exp; \ + sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)/$(check_p_subdir)|' \ + < ../../site.exp > tmp-site.exp; \ + $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../expect/expect ] ; then \ + TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \ + export TCL_LIBRARY ; fi ; \ + GCC_EXEC_PREFIX="$(libdir)/gcc/" ; export GCC_EXEC_PREFIX ; \ + runtestflags= ; \ + if [ -n "$(check_p_subno)" ] ; then \ + runtestflags="$(check_p_subwork)"; \ + elif [ -n "$(check_p_vars)" ] ; then \ + parts="`echo ' $(strip $(subst $(check_p_comma), ,$(check_p_vars))) ' \ + | sed 's/=[^ ]* / /g'`"; \ + for part in `find $$srcdir/testsuite/$(check_p_tool)* -name \*.exp` ; do \ + part=`basename $$part` ; \ + case " $$parts $$runtestflags " in \ + *" $$part "*) ;; \ + *) runtestflags="$$runtestflags $$part" ;; \ + esac ; \ + done ; \ + fi ; \ + $(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS) $$runtestflags) + +check-consistency: testsuite/site.exp + -rootme=`${PWD_COMMAND}`; export rootme; \ + srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \ + cd testsuite; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../expect/expect ] ; then \ + TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \ + export TCL_LIBRARY ; fi ; \ + GCC_EXEC_PREFIX="$(libdir)/gcc/" ; export GCC_EXEC_PREFIX ; \ + $(RUNTEST) --tool consistency $(RUNTESTFLAGS) + +.PHONY: check-icg icg-test +ICG_TEST_RUNDIR = icg-tests +ICG_TEST_SRCDIR = $(srcdir)/icg-tests +ICG_TESTS = *.test + +icg-test: check-icg +check-icg: + -test -d $(ICG_TEST_RUNDIR) || mkdir $(ICG_TEST_RUNDIR) + $(ICG_TEST_SRCDIR)/run_icg_tests.py \ + --src_dir=$(ICG_TEST_SRCDIR) \ + --run_dir=$(ICG_TEST_RUNDIR) \ + --compiler=. \ + $(ICG_TEST_SRCDIR)/$(ICG_TESTS) + +# QMTest targets + +# The path to qmtest. +QMTEST_PATH=qmtest + +# The flags to pass to qmtest. +QMTESTFLAGS= + +# The flags to pass to "qmtest run". +QMTESTRUNFLAGS=-f none --result-stream dejagnu_stream.DejaGNUStream + +# The command to use to invoke qmtest. +QMTEST=${QMTEST_PATH} ${QMTESTFLAGS} + +# The tests (or suites) to run. +QMTEST_GPP_TESTS=g++ + +# The subdirectory of the OBJDIR that will be used to store the QMTest +# test database configuration and that will be used for temporary +# scratch space during QMTest's execution. +QMTEST_DIR=qmtestsuite + +# Create the QMTest database configuration. +${QMTEST_DIR} stamp-qmtest: + ${QMTEST} -D ${QMTEST_DIR} create-tdb \ + -c gcc_database.GCCDatabase \ + -a srcdir=`cd ${srcdir}/testsuite && ${PWD_COMMAND}` && \ + $(STAMP) stamp-qmtest + +# Create the QMTest context file. +${QMTEST_DIR}/context: stamp-qmtest + rm -f $@ + echo "CompilerTable.languages=c cplusplus" >> $@ + echo "CompilerTable.c_kind=GCC" >> $@ + echo "CompilerTable.c_path=${objdir}/xgcc" >> $@ + echo "CompilerTable.c_options=-B${objdir}/" >> $@ + echo "CompilerTable.cplusplus_kind=GCC" >> $@ + echo "CompilerTable.cplusplus_path=${objdir}/g++" >> $@ + echo "CompilerTable.cplusplus_options=-B${objdir}/" >> $@ + echo "DejaGNUTest.target=${target_noncanonical}" >> $@ + +# Run the G++ testsuite using QMTest. +qmtest-g++: ${QMTEST_DIR}/context + cd ${QMTEST_DIR} && ${QMTEST} run ${QMTESTRUNFLAGS} -C context \ + -o g++.qmr ${QMTEST_GPP_TESTS} + +# Use the QMTest GUI. +qmtest-gui: ${QMTEST_DIR}/context + cd ${QMTEST_DIR} && ${QMTEST} gui -C context + +.PHONY: qmtest-g++ + +# Run Paranoia on real.c. + +paranoia.o: $(srcdir)/../contrib/paranoia.cc $(CONFIG_H) $(SYSTEM_H) \ + $(REAL_H) $(TREE_H) + g++ -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION) + +paranoia: paranoia.o real.o $(LIBIBERTY) + g++ -o $@ paranoia.o real.o $(LIBIBERTY) + +# These exist for maintenance purposes. + +# Update the tags table. +TAGS: lang.tags + (cd $(srcdir); \ + incs= ; \ + list='$(SUBDIRS)'; for dir in $$list; do \ + if test -f $$dir/TAGS; then \ + incs="$$incs --include $$dir/TAGS.sub"; \ + fi; \ + done; \ + etags -o TAGS.sub *.y *.h *.c; \ + etags --include TAGS.sub $$incs) + +# ----------------------------------------------------- +# Rules for generating translated message descriptions. +# Disabled by autoconf if the tools are not available. +# ----------------------------------------------------- + +XGETTEXT = @XGETTEXT@ +GMSGFMT = @GMSGFMT@ +MSGMERGE = msgmerge +CATALOGS = $(patsubst %,po/%,@CATALOGS@) + +.PHONY: build- install- build-po install-po update-po + +# Dummy rules to deal with dependencies produced by use of +# "build-@POSUB@" and "install-@POSUB@" above, when NLS is disabled. +build-: ; @true +install-: ; @true + +build-po: $(CATALOGS) + +# This notation should be acceptable to all Make implementations used +# by people who are interested in updating .po files. +update-po: $(CATALOGS:.gmo=.pox) + +# N.B. We do not attempt to copy these into $(srcdir). The snapshot +# script does that. +.po.gmo: + -test -d po || mkdir po + $(GMSGFMT) --statistics -o $@ $< + +# The new .po has to be gone over by hand, so we deposit it into +# build/po with a different extension. +# If build/po/gcc.pot exists, use it (it was just created), +# else use the one in srcdir. +.po.pox: + -test -d po || mkdir po + $(MSGMERGE) $< `if test -f po/gcc.pot; \ + then echo po/gcc.pot; \ + else echo $(srcdir)/po/gcc.pot; fi` -o $@ + +# This rule has to look for .gmo modules in both srcdir and +# the cwd, and has to check that we actually have a catalog +# for each language, in case they weren't built or included +# with the distribution. +install-po: + $(mkinstalldirs) $(DESTDIR)$(datadir) + cats="$(CATALOGS)"; for cat in $$cats; do \ + lang=`basename $$cat | sed 's/\.gmo$$//'`; \ + if [ -f $$cat ]; then :; \ + elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \ + else continue; \ + fi; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + echo $(mkinstalldirs) $(DESTDIR)$$dir; \ + $(mkinstalldirs) $(DESTDIR)$$dir || exit 1; \ + echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc.mo; \ + $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc.mo; \ + done + +# Rule for regenerating the message template (gcc.pot). +# Instead of forcing everyone to edit POTFILES.in, which proved impractical, +# this rule has no dependencies and always regenerates gcc.pot. This is +# relatively harmless since the .po files do not directly depend on it. +# Note that exgettext has an awk script embedded in it which requires a +# fairly modern (POSIX-compliant) awk. +# The .pot file is left in the build directory. +gcc.pot: po/gcc.pot +po/gcc.pot: force + -test -d po || mkdir po + $(MAKE) srcextra + AWK=$(AWK) $(SHELL) $(srcdir)/po/exgettext \ + $(XGETTEXT) gcc $(srcdir) diff --git a/iburg/briggs/doc/BurgProcessor.html b/iburg/briggs/doc/BurgProcessor.html new file mode 100644 index 00000000000..e14f8301395 --- /dev/null +++ b/iburg/briggs/doc/BurgProcessor.html @@ -0,0 +1,258 @@ +<p> +</p><h1><a name="Plug_a_Preprocessor_for_Burg"> </a> Plug, a Preprocessor for Burg </h1> +<p> +Burg and iburg take a common input language that's designed to be +produced by another tool, a preprocessor. Plug is a tool I designed to +act as such a preprocessor. Its main addition to the burg input +language is a way to specify semantic actions to be carried out during +the reduce phase. Actually, I envision many possible reduce phases, so +plug allows us to specify many different named actions for each rule. +In addition, plug performs a variety of consistency checks on the +input. +</p><p> +</p><h2><a name="The_Command_Line"> </a> The Command Line </h2> +<p> +By default, plug reads from <code>stdin</code> and writes to <code>stdout</code>. +This default behavior can be overridden at the command line. +</p><p> +<code>plug</code> [ <code>-o</code> <em>output-pathname</em> ] [ <em>input_pathname</em> ] +</p><p> +</p><p> +</p><h2><a name="Syntax"> </a> Syntax </h2> +<p> +A machine description looks like +</p><p> +[ <em>prologue</em> ] <code>%%</code> <em>decls</em> <em>rules</em> [ <code>%%</code> <em>epilogue</em> ] +</p><p> +where the prologue and epilogue are simply lines of C code and +the <code>%%</code> token must appear on a line by itself. +Typically, the prologue contains declarations and the epilogue +will consist of C routines. +</p><p> +</p><p> +</p><p> +<table border="0" cellpadding="2" cellspacing="1"> +<tbody><tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>decls</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> { <em>decl</em> <code>;</code> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>decl</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <code>start</code> <em>nonterm-id</em> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td align="center" bgcolor="#f4f4f4"> | </td><td bgcolor="#f4f4f4"> <code>nonterm</code> <em>nonterm-id</em> { <code>,</code> <em>nonterm-id</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td align="center" bgcolor="#eeeeee"> | </td><td bgcolor="#eeeeee"> <code>term</code> <em>term-equate</em> { <code>,</code> <em>term-equate</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td align="center" bgcolor="#f4f4f4"> | </td><td bgcolor="#f4f4f4"> <code>reduce</code> <em>reduce-equate</em> { <code>,</code> <em>reduce-equate</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>term-equate</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>term-id</em> [ <code>=</code> <em>number</em> ] </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td align="center" bgcolor="#eeeeee"> | </td><td bgcolor="#eeeeee"> <code>term_align</code> <code>(</code> <em>number</em> <code>)</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td align="center" bgcolor="#f4f4f4"> | </td><td bgcolor="#f4f4f4"> <code>term_incr</code> <code>(</code> <em>number</em> <code>)</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>reduce-equate</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>reduce-id</em> <code>=</code> <em>path</em> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>rules</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> { <em>rule</em> | <em>include</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>include</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <code>include</code> <em>path</em> <code>;</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>rule</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>specs</em> [ <em>reductions</em> ] <code>;</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>specs</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>spec</em> { <code>,</code> spec } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>spec</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>nonterm-id</em> <code>:</code> <em>pattern</em> <em>cost</em> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td><td bgcolor="#eeeeee"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#f4f4f4"> <em>pattern</em> </td><td align="center" bgcolor="#f4f4f4"> = </td><td bgcolor="#f4f4f4"> <em>nonterm-id</em> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td align="center" bgcolor="#eeeeee"> | </td><td bgcolor="#eeeeee"> <em>term-id</em> [ <code>(</code> <em>patterns</em> <code>)</code> ] </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>patterns</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <em>pattern</em> [ <code>,</code> <em>pattern</em> ] </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td align="center" bgcolor="#f4f4f4"> | </td><td bgcolor="#f4f4f4"> <em>pattern</em> { <code>|</code> <em>pattern</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#eeeeee"> </td><td align="center" bgcolor="#eeeeee"> | </td><td bgcolor="#eeeeee"> <em>pattern</em> [ <code>@</code> <em>pattern</em> ] </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>cost</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> [ <code>[</code> <em>number</em> <code>,</code> <em>number</em> <code>]</code> ] </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>reductions</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <em>reduction</em> { <code>,</code> <em>reduction</em> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>reduction</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <em>reduce-id</em> <code>{</code> <em>code</em> <code>}</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>id</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <em>alpha</em> { <em>alphanum</em> | <code>_</code> } </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>path</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <code>"</code> { <em>char</em> } <code>"</code> </td></tr> +<tr><td class="twikiFirstCol" bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td><td bgcolor="#f4f4f4"> </td></tr> +<tr><td class="twikiFirstCol" align="right" bgcolor="#eeeeee"> <em>number</em> </td><td align="center" bgcolor="#eeeeee"> = </td><td bgcolor="#eeeeee"> <em>digit</em> { <em>digit</em> } </td></tr> +</tbody></table> +</p><p> +where code is C code with balanced curly braces. +</p><p> +Comments are started by <code>//</code> and extend to the end of line. +</p><p> +There are six keywords: <code>reduce</code>, <code>term</code>, <code>term_align</code>, <code>term_incr</code>, <code>nonterm</code>, and <code>start</code>. +</p><p> +Other tokens +</p><pre> ; , = : ( ) [ ] { } | + path id number + done +</pre> +<p> +</p><h2><a name="Checking"> </a> Checking </h2> +<p> +Make sure all id's are declared and used appropriately. +</p><p> +Make sure term numbers (in the term-equates) are unique. +</p><p> +Make sure file names (in reduce-equates) are unique. +</p><p> +Make sure each use of a particular term-id has the same number of children (0, 1, or 2). +</p><p> +Make sure there aren't too many leaves (limit is 9). +</p><p> +</p><p> +</p><p> +</p><h2><a name="An_Example"> </a> An Example </h2> +<p> +You'll need to understand the input language for burg and iburg. +The tool, plug, lets us write patterns using a similar syntax to drive the <em>label</em> phase +and specify a number of reductions (or actions) to be performed during (potentially multiple) <em>reduce</em> phases. +</p><p> +Here's a simple example specifying how to implement the plus:DI operation from gcc's RTL on the Opteron. +</p><pre>regx : PLUS_DI(regx, reg) [1, 3] + name { + $$->reg = $1->reg; + }, + debug { + dumpRR("addq", $2->reg, $$->reg); + }; +</pre> +<code>PLUS_DI</code> is a terminal; +<code>reg</code> and <code>regx</code> are non-terminals. +All need to be declared appropriately. +My intention is that both <code>reg</code> and <code>regx</code> indicate registers, +with <code>regx</code> indicating a register whose value need not be preserved. +The cost <code>[1, 3]</code> shows that the instruction has a 1-cycle latency +and will require 3-bytes to encode. +<p> +In this case, there are two reductions. The first, <code>name</code>, causes the reg +field associated with the result to be set to the reg field associated with +the first leaf (they are numbered left to right in the pattern, starting from 1). +The 2nd reduction calls a routine to print out the desired assembly. +Generally, the reductions can contain any arbitrary C code. +<code>$$</code> refers to the result and <code>$1</code>, <code>$2</code>, ... refer to the leaves. +</p><p> +When we run this through plug (along with appropriate declarations), +it'll spit out (at least) 3 different file. The main result is intended +for burg (or iburg) and is written to <code>stdout</code> (may be redirected via <code>-o</code>). +In this case, plug will spit out a line something like +</p><pre>regx : PLUS_DI(regx, reg) = 1 (259); +</pre> +where the <code>1</code> is the rule number and <code>259</code> is the cost = 256*latency + bytes. +<p> +In the file <code>name.cases</code>, it would add the lines +</p><pre>case 1: { + p->reg = p->kid[0]->reg; + } + break; +</pre> +The idea is that the appropriate reduce pass would include this file +into a case statement, switching on the label of a node. The iburg paper +has a pretty nice example. +<p> +</p><h2><a name="Fancier_Patterns"> </a> Fancier Patterns </h2> +<p> +I've found it useful to extend the basic style in a couple of ways. +First, I noticed that several patterns might share the same set of reductions. +For example, consider the rules +</p><pre>r64x : imm32 [1, 3] + names { + $$->rx = new_reg(); + }, + debug { + dumpIR("movq", $1->val, $$->rx); + }; +</pre> +and +<pre>r64x : imm64 [1, 2] + names { + $$->rx = new_reg(); + }, + debug { + dumpIR("movq", $1->val, $$->rx); + }; +</pre> +In both cases we're loading a constant into a register, but the cost +of doing so depends on the size of the constant. Since the reductions in each case are identical, +we can combine them into a single rule, like so +<pre>r64x : imm32 [1, 3], +r64x : imm64 [1, 2] + names { + $$->rx = new_reg(); + }, + debug { + dumpIR("movq", $1->val, $$->rx); + }; +</pre> +Second, I added a way to take advantage of operations that commute and associate to reduce +the size of the specification. For example, instead of two rules +<pre>regx : PLUS_DI(regx, reg) [1, 3] + name { + $$->reg = $1->reg; + }, + debug { + dumpRR("addq", $2->reg, $$->reg); + }; +</pre> +and +<pre>regx : PLUS_DI(reg, regx) [1, 3] + name { + $$->reg = $2->reg; + }, + debug { + dumpRR("addq", $1->reg, $$->reg); + }; +</pre> +we can achieve exactly the same effect like this +<pre>regx : PLUS_DI(regx | reg) [1, 3] + name { + $$->reg = $1->reg; + }, + debug { + dumpRR("addq", $2->reg, $$->reg); + }; +</pre> +In this case, it was only a small savings in initial typing and ongoing maintenance (factor of 2); +in some case, the savings is really substantial. Consider the pattern +<pre>rx : plus(r | mem(plus(base | index | imm))) +</pre> +describing an add-from-memory instruction on the Opteron. +In this case, plug expands it into 24 cases. +<pre>rx : plus(r,mem(plus(plus(base,index),imm))) +rx : plus(r,mem(plus(plus(base,imm),index))) +rx : plus(r,mem(plus(plus(index,base),imm))) +rx : plus(r,mem(plus(plus(index,imm),base))) +rx : plus(r,mem(plus(plus(imm,base),index))) +rx : plus(r,mem(plus(plus(imm,index),base))) +rx : plus(r,mem(plus(base,plus(index,imm)))) +rx : plus(r,mem(plus(base,plus(imm,index)))) +rx : plus(r,mem(plus(index,plus(base,imm)))) +rx : plus(r,mem(plus(index,plus(imm,base)))) +rx : plus(r,mem(plus(imm,plus(base,index)))) +rx : plus(r,mem(plus(imm,plus(index,base)))) +rx : plus(mem(plus(plus(base,index),imm)),r) +rx : plus(mem(plus(plus(base,imm),index)),r) +rx : plus(mem(plus(plus(index,base),imm)),r) +rx : plus(mem(plus(plus(index,imm),base)),r) +rx : plus(mem(plus(plus(imm,base),index)),r) +rx : plus(mem(plus(plus(imm,index),base)),r) +rx : plus(mem(plus(base,plus(index,imm))),r) +rx : plus(mem(plus(base,plus(imm,index))),r) +rx : plus(mem(plus(index,plus(base,imm))),r) +rx : plus(mem(plus(index,plus(imm,base))),r) +rx : plus(mem(plus(imm,plus(base,index))),r) +rx : plus(mem(plus(imm,plus(index,base))),r) +</pre> +This last extension was surprisingly hard to implement, so please take advantage! +<p> +</p><h2><a name="Ideas_for_the_future"> </a> Ideas for the future </h2> +<p> +I'd like to redesign the plug language a bit, aiming for more error checking. +In my experience to date, the biggest source of errors +is the inconsistent use of attributes between reductions. +One scheme might reply on C's type system so that inconsistent +uses are detected as type errors. +</p><p> +This area wants some thought. +</p><p> +</p><hr> +<p> diff --git a/iburg/briggs/doc/DescriptionOfTheBigPicture.html b/iburg/briggs/doc/DescriptionOfTheBigPicture.html new file mode 100644 index 00000000000..fc329a864cf --- /dev/null +++ b/iburg/briggs/doc/DescriptionOfTheBigPicture.html @@ -0,0 +1,134 @@ +<h1><a name="The_Big_Picture_Described"> </a> The Big Picture Described </h1> +<p> + <img src="icg.jpg" alt="icg.jpg" height="538" width="840"> +</p><p> +The input is <em>loose</em> RTL from gcc, siphoned off just before gcc's register allocator. +The output is <em>strict</em> RTL, fed back into gcc just after gcc's reload phase. +</p><p> +Everything in black is intended to be machine independent (someday). +Thus, the only machine-dependent portion is the grammar specification. +The proportions of things in the picture are misleading though, +since the grammar specification is quite large. +</p><p> +</p><h2><a name="Build_Time"> </a> Build Time </h2> +<p> +The dashed lines are intended to indicate processing that happens when the compiler is being built. +</p><ul> +<li> The grammar specification is machine dependent. It specifies how +different combinations of RTL are to be handled by the many parts of +the code generator. +</li> +<li> There's a preprocessor for plug, written by Robert Henry in +Python. It supports named attributes, does some checking, and enables a +lot more compression of the spec. +</li> +<li> <a href="BurgProcessor.html" target="_top">Plug</a> is mostly a preprocessor for <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/iburg.pdf" target="_top">iburg</a>. +In addition, plug splits of pieces of the grammar specification, +feeding them into include files to be included as part of the source +for the various phases of the code generator. In all cases, the +generated include files are simply long sequences of case arms, where +the case selection is controlled by a tree walk of the IL and the state +generated by iburg. +</li> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/iburg.pdf" target="_top">iburg</a> is a tool written by Dave Hanson, a fellow Googler, back when he was just a kid. +</li> +</ul> +<p> +</p><h2><a name="Compile_Time"> </a> Compile Time </h2> +<p> +Solid lines indicate phases that run during compile time. +There are three preliminary phases: +</p><ul> +<li> <em>foward prop</em> does a form of forward propagation within +basic blocks to build large expression trees. The RTL coming into the +allocator is made up of many, very small expression trees, basically +one tree per instruction. We prefer maximal trees, to give iburg and +the SU-numbering as much scope as possible. Trees that define a single +register with a single use are combine with the tree that uses the +register. Note that we run <em>forward prop</em> twice, because <em>find updates</em> can expose new opportunities. +</li> +<li> <em>side tree</em> constructs an icg-private version of each rtl +expression using our own data structures. We chose to do this for our +prototype, to allow us to easily add and delete fields without +affecting the rest of gcc's passes. +</li> +<li> <em>SSA</em> finds the live ranges by converting to SSA form, then unioning together all the names that reach phi nodes. +</li> +<li> <em>find updates</em> studies expression trees, looking for +opportunities to rewrite them with explicit update operation +(add-to-memory, etc). Note that we run this phase in two places: +initially and just after adding spill code. +</li> +</ul> +<p>The bulk of the code generator is in the form of a large loop that +repeatedly does instruction selection and attempts register allocation +until no additional spill code is required. Many of these phases work +over expression trees. Initially all expression trees are examined. As +spill code is added, the modified trees are marked <em>dirty</em> +and later passes will only examine the dirty trees. Generally, the +phases dealing with register allocation are global and must examine all +expression trees, dirty or not. +</p><ul> +<li> <em>reassoc</em> examines each dirty expression tree, computing <a href="ExtendedSUNumbering.html" target="_top">SU pairs</a> and reassociating to minimize register usage. This won't do a perfect job because we haven't yet done instruction selection. +</li> +<li> <em>select</em> does the labeling phase of iburg, walking over +dirty expression trees and computing the best cover. The result for +each subtree is stored in the <em>state_label</em> field. The value here is not examined directly; instead, it's referred to by iburg code when doing the various reduce passes. +</li> +<li> <em>names</em> walks over all expression trees, propagating +register names up from the leaves to interior nodes, adding new +register names when required. Also propagates the various parts of +addressing modes (base, index, displacement). +</li> +<li> <em>Sethi Ullman</em> examines each dirty expression tree, computing <a href="ExtendedSUNumbering.html" target="_top">SU pairs</a> +and choosing a preferred order of evaluation. This time, we've +completed instruction selection, so the SU pairs are accurate, though +we're not able to reassociate. +</li> +<li> <em>bit matrix</em> walks over all the expression trees, building +the bit matrix representation of the interference graph and computing +the degree of each live range. +</li> +<li> <em>build AVs</em> uses the computed degree and allocates +adjacency vectors for each live range, then walks over all the +expression trees, filling in the adjacency vectors. +</li> +<li> <em>coalesce</em> attempts to coalesce live ranges connected by a +copy. If any live ranges are coalesced, we need to recompute the +adjacency vectors. Additional coalescing opportunities may be exposed +whenever a coalesce is performed, so we iterate until no more changes +are found. +</li> +<li> <em>spill costs</em> walks over all expression trees, computing +spill costs for all the live ranges. Note that we divide the set of +live ranges into three parts: the machine registers, the SSA names, and +the interior live ranges. Each interior live range appears inside a +single expression tree and may not be spilled (has an infinite spill +cost). +</li> +<li> <em>color</em> tries to color the live ranges following the scheme +in Preston's thesis. If some live ranges can't be colored, then we'll +need to introduce spill code. +</li> +<li> <em>spill code</em> does a pretty simplistic job of introducing +spill code. If a spilled live range is referenced by an expression +tree, the tree is rewritten to reference memory and is marked as dirty. +Similarly, if the tree defines a spilled live range, the tree is +rewritten to store to memory and the tree is marked as dirty. +</li> +</ul> +<p> +There are a couple of final phases: +</p><ul> +<li> <em>final</em> (not shown, but runs right before emit). Propagates +the final register names/colors up the expression trees. Should perhaps +be replaced by a lookup during <em>emit</em>. +</li> +<li> <em>emit</em> makes calls into existing gcc infrastructure to +generate rtl for the new instructions and registers chosen during icg's +code generation. This was very tedious to write and is probably quite +brittle. +</li> +</ul> +<p> +There's another phase, <em>debug</em>, that dumps an assembly language version of the routine to dump_file. It can be run anytime after <em>names</em>. diff --git a/iburg/briggs/doc/ExtendedSUNumbering.html b/iburg/briggs/doc/ExtendedSUNumbering.html new file mode 100644 index 00000000000..6ab3211fbc3 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering.html @@ -0,0 +1,404 @@ +<h1><a name="Extended_Sethi_Ullman_Numbering"> </a> Extended Sethi-Ullman Numbering </h1> +<p> +<a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/sethi-ullman.pdf" target="_top">Sethi-Ullman numbering</a> +is a technique for scheduling the evaluation of expression trees for +minimum register usage. We all learned it in our first optimizer class +'cause it's so simple and clean. However, it's not really adequate for +an optimizing compiler. Classical SU-numbering assumes all the values +(the leaves of the expression tree) are in memory locations. While it's +possible to simply assert that the leaves may be in registers, the +traditional formulation misses an important opportunity, namely the +chance to reuse registers after they've gone dead. +</p><p> +Let's consider this example from the paper: +</p><pre>a/(b + c) - d*(e + f) +</pre> +The expression tree for this expression looks like +<p> + <img src="ExtendedSUNumbering_files/tree0.jpg" alt="tree0.jpg" height="364" width="408"> +</p><p> +Assigning classical SU numbers to this tree yields +</p><p> + <img src="ExtendedSUNumbering_files/tree1.jpg" alt="tree1.jpg" height="364" width="415"> +</p><p> +Here we're assuming that <code>a</code> through <code>f</code> +are all values in registers that must be preserved and that the machine +has 2-address instructions rather like the x86. The numbers associated +with each node indicate the number of additional registers required to +evaluate the associated subtree. In this case, we can evaluate the +entire tree with 3 temporary registers, emitting code like this +</p><pre>r0 = ra +r1 = rb +r1 += rc +r0 /= r1 +r1 = rd +r2 = re +r2 += rf +r1 *= r2 +r0 -= r1 +</pre> +While other code sequences are feasible, none are cheaper, in terms of instructions or registers. +<p>Note that we had to make copies of many of the source registers; +since they must all be preserved, we need to be careful to avoid +overwriting them. We number the tree during a depth-first walk +according to the following rules +</p><ul> +<li> If a node is a left leaf, it is numbered 1. +</li> +<li> If a node is a right leaf, it is number 0. +</li> +<li> If a non-leaf node has children with equal numbers <em>n</em>, it is numbered <em>n+1</em> +</li> +<li> If a non-leaf node has children with non-equal numbers <em>m</em> and <em>n</em>, it is numbered <em>max(m, n)</em> +</li> +</ul>Sethi and Ullman give extensions for handling commutative and +associative operators and it's easy to imagine extensions for +load-store architectures. Here, we explore a different idea: <em>How do we take advantage of leaf values in registers that need not be preserved?</em> +<p> +</p><p> +</p><h2><a name="The_problem"> </a> The problem </h2> +<p> +Let's reconsider our example tree, but with a few modifications. +</p><p> + <img src="ExtendedSUNumbering_files/tree2.jpg" alt="tree2.jpg" height="364" width="408"> +</p><p> +Here I've introduced a new bit of notation, an apostrophe after a +register name to indicate that the register need not be preserved; in +other words, this expression is the last use of <code>a</code> and <code>b</code>. After this expression, they will be <em>dead</em> in a data-flow sense. +</p><p> +Since we're allowed to overwrite some registers, we can achieve a +shorter schedule, using fewer temporaries. For instance, we might +evaluate the entire tree like this +</p><pre>rb += rc +ra /= rb +r0 = rd +rb = re +rb += rf +r0 *= rb +ra -= r0 +</pre> +So, the problem is: <em>Given an expression tree with leaf +values in registers, where some of the registers must be preserved and +others may be overwritten, find an order of evaluation that minimizes +the number of extra registers required.</em> +<p> +</p><p> +</p><h2><a name="Names"> </a> Names </h2> +<p> +We're going to be a bit less abstract than Sethi and Ullman, so I'd like to start afresh and define a some useful names. +We'll be manipulating expression trees. Nodes in the trees will have one or two children. If a node has two children, +we'll distinguish between the left and right child. +</p><p> +We'll further distinguish certain nodes as <em>r-nodes</em> (where the <em>r</em> might stand for <em>right</em> or <em>restricted</em>). These nodes +</p><ul> +<li> constants +</li> +<li> loads (memory references) +</li> +<li> references to registers that must be preserved +</li> +</ul> +are all r-nodes and we will <em>prefer</em> to have them as right children (while they can appear as left children, +it will cost an extra register). This notion is machine dependent, since many machines won't allow, for instance, +adding directly from a memory location. +<p> +Other nodes (including register references that may be overwritten) may +appear as either the left or right child of another node without +penalty. +</p><p> +</p><h2><a name="SU_pairs"> </a> SU-pairs </h2> +<p> +While I'm not completely sure of this result, my approach for now is as as follows... +</p><p> +We'll compute two non-negative integers at each node, a pair: the number of extra registers required, <code>extra</code>, and the number last uses, <code>freed</code>. The <code>extra</code> value corresponds to the traditional SU-number, though it won't always have the same value. We can call them <em>SU-pairs</em> and they'll have the form <code>(extra, freed)</code>. Our example tree would be labeled like this +</p><p> + <img src="ExtendedSUNumbering_files/tree3.jpg" alt="tree3.jpg" height="364" width="427"> +</p><p> +In this case, I've labeled the tree by inspection. We want an algorithm to achieve the same result. +</p><p> +</p><h2><a name="Leaves"> </a> Leaves </h2> +<p> +We number leaves as follows: +</p><ul> +<li> Constants get the pair <code>(0,0)</code> +</li> +<li> Registers which must be preserved get the pair <code>(0,0)</code> +</li> +<li> Registers which may be overwritten get the pair <code>(0,1)</code> +</li> +</ul> +<p> +</p><h2><a name="Unary_operations"> </a> Unary operations </h2> +<p> +Before we can determine the SU-pair for a unary operation, we must examine its child. If it's an r-node with the SU-pair <code>(0,0)</code>, +we adjust it to <code>(1,0)</code>. After any necessary adjustment, the SU-pair for a unary operation equals the SU-pair of its operand. +</p><p> +</p><h2><a name="Binary_operations"> </a> Binary operations </h2> +<p> +Before we can determine the SU-pair for a binary operation, we must examine its <em>left</em> child. +If it's an r-node with the SU-pair <code>(0,0)</code>, we adjust it to <code>(1,0)</code>. +</p><p> +Next, we need to choose which subtree (the <code>left</code> or <code>right</code>) +to evaluate first, then compute the associated SU-pair. To find this, +we consider the cost of the entire tree assuming the left subtree is +evaluated first versus the cost of evaluating the entire tree if the +right subtree is evaluated first. +</p><pre>cost.left = left.extra + left.freed > right.extra ? left.extra : right.extra - left.freed + 1 +cost.right = right.extra + right.freed > left.extra ? right.extra : left.extra - right.freed + 1 +</pre> +The result's SU-pair will equal <code>(min(cost.left, cost.right), left.freed + right.freed)</code>. +<p> +<em>A challenge is to simplify the computation of costs. Another challenge is to prove that it's correct!</em> +</p><p> +Consider the computation of <code>const.left</code>. There are two cases: +</p><ol> +<li> The number of registers free after the evaluation of the left +subtree is enough to evaluate the right subtree; that is, we won't need +any more registers than <code>left.extra</code> if <pre>left.extra + left.freed - 1 >= right.extra</pre> +</li> +<li> The number of registers free after evaluation of the left subtree +is inadequate to cover the needs of the right subtree, so more will be +required. In this case, we need <pre>right.extra - (left.extra + left.free - 1) + left.extra</pre> which simplifies to <pre>right.extra - left.freed + 1</pre> +</li> +</ol> +<p> +A way to start the proof of correctness is to compare with ordinary SU +numbering for examples where it applies (i.e., none of the input +registers are freed). +</p><p> +</p><h2><a name="Commutative_operations"> </a> Commutative operations </h2> +<p>For operations that are commutative but not associative (such as +floating-point addition or multiplications), it's sometimes worthwhile +to interchange the operands. Consider the example above. If we notice +that the left child of the multiply operation is an r-node, we can +interchange the left and right children and achieve a better result +</p><p> + <img src="ExtendedSUNumbering_files/tree9.jpg" alt="tree9.jpg" height="364" width="473"> +</p><p> +which yields the following code +</p><pre>rb += rc +ra /= rb +rb = re +rb += rf +rb *= rd +ra -= rb +</pre>Generally, if we have a commutative operation where the left +child is an r-node and the right child is not, we should interchange +the children, then compute the SU-pair in the same way as other binary +operations. +<p> +</p><h2><a name="Associative_operations"> </a> Associative operations </h2> +<p>While I know of operations that are associative but not commutative +(matrix multiplication and quaternion multiplication), few machines +have such things. Though the Tera MTA does have a bitwise +matrix-multiplication instruction. Perhaps I should think about this +problem in the future. +</p><p> +</p><h2><a name="Operations_that_are_associative_"> </a> Operations that are associative and commutative </h2> +<p> +Suppose we're given a more interesting tree, like this +</p><p> + <img src="ExtendedSUNumbering_files/tree4.jpg" alt="tree4.jpg" height="540" width="768"> +</p><p>It's useful to note and take advantage of operations that are +associative and commutative (e.g., integer multiplication and +addition). In this case, we can note the 4 subexpressions that are +summed and rewrite the tree, temporarily, with a special operator for +easier manipulation. +</p><p> + <img src="ExtendedSUNumbering_files/tree5.jpg" alt="tree5.jpg" height="436" width="724"> +</p><p> +I will call this form an <em>associative tree</em>. That is, we start with a binary tree and rewrite it as an associative tree. +Later, we'll rewrite it again as a binary tree. +</p><p> +Since we're going to focus on the sum, I'll abstract away the details, like this +</p><p> + <img src="ExtendedSUNumbering_files/tree6.jpg" alt="tree6.jpg" height="168" width="378"> +</p><p>The opportunity here is that we might implement the summation in +any one of a number of ways, with different register requirements. +My solution (I hope it's a solution) proceeds in two steps: +</p><ol> +<li> <em>Sorting</em>, and +</li> +<li> <em>Placement</em>. +</li> +</ol> +We begin by computing SU-pairs for all the subexpressions, as shown above. Then we <em>sort</em> all the subexpressions, first by <code>extra</code> (ascending), resolving ties by <code>freed</code> (descending). In our example, we'd get +<p> + <img src="ExtendedSUNumbering_files/tree7.jpg" alt="tree7.jpg" height="168" width="442"> +</p><p> +Next, we do <em>placement</em>. The key here is that we've +sorted so that the subexpression with the greatest need for extra +registers (Y), is on the right. We look at all the subexpressions to +its left (W, X, and Z). If none of them free any registers, we'll move +our right-most subexpression to the left end, where it will be +evaluated first. On the other hand, if some registers are freed during +the evaluation of the other subexpressions, then we'll leave the +rightmost expression in place, where the maximum number of registers +will be available for its evaluation. In this second case, we need to +recursively consider the placement of the rest of the subexpressions. +</p><p>In our example, since the evaluation of W will free some +registers, consideration of Y, Z, and X leaves each in place and the +summation would be implemented like this +</p><p> + <img src="ExtendedSUNumbering_files/tree8.jpg" alt="tree8.jpg" height="380" width="358"> +</p><p> +</p><h3><a name="Placement_examples"> </a> Placement examples </h3> +<p> +Here are a few more exampes to help illustrate the <em>placement</em> step. +In each case, I'll show the associative tree after sorting and after placement. +</p><p> +</p><hr> +<h4><a name="Example_1"> </a> Example 1 </h4> +<p> + <img src="ExtendedSUNumbering_files/tree10.jpg" alt="tree10.jpg" height="168" width="376"> +</p><p> +We consider the right-most subtree, D. Looking at all the subtrees to its left, we see that none free any registers, +so we move D to the left-most position where it will be evaluated first and we're done. +</p><p> + <img src="ExtendedSUNumbering_files/tree11.jpg" alt="tree11.jpg" height="168" width="439"> +</p><p> +</p><hr> +<h4><a name="Example_2"> </a> Example 2 </h4> +<p> + <img src="ExtendedSUNumbering_files/tree12.jpg" alt="tree12.jpg" height="168" width="439"> +</p><p>We consider the right-most subtree, H. Looking at all the +subtree to its left, we see that they free some registers, so we leave +it in place. +</p><p> +Next, we consider G. Looking at all the subtrees to its left, we see that none free any registers, +so we move G to the left-most position where it will be evaluated first and we're done. +</p><p> + <img src="ExtendedSUNumbering_files/tree13.jpg" alt="tree13.jpg" height="168" width="439"> +</p><p> +</p><p> +</p><hr> +<h4><a name="Example_3"> </a> Example 3 </h4> +<p> + <img src="ExtendedSUNumbering_files/tree14.jpg" alt="tree14.jpg" height="168" width="439"> +</p><p>We consider the right-most subtree, L. Looking at all the +subtree to its left, we see that they free some registers, so we leave +it in place. +</p><p>Next, we consider the right-most subtree, K. Looking at all the +subtree to its left, we see that they free some registers, so we leave +it in place. +</p><p> +Finally, we consider J. Looking at all the subtrees to its left, we see that none free any registers, +so we move J to the left-most position where it will be evaluated first and we're done. +Note that it's unimportant that J freed some registers. +</p><p> +</p><p> + <img src="ExtendedSUNumbering_files/tree15.jpg" alt="tree15.jpg" height="168" width="439"> +</p><p> +</p><h2><a name="Subtraction"> </a> Subtraction </h2> +<p> +While subtraction is not commutative or associative, it sometimes presents opportunities. +If we rewrite subtraction operations as addition and negation (where negate will be an r-node), +then we can perhaps reassociate. Furthermore, we can collapse pairs of negates. +</p><p> +The opportunity to collapse pairs of negates makes this worth doing for floating-point computation. +</p><p> +<em>What about division?</em> +</p><p> +</p><h2><a name="Optimality"> </a> Optimality </h2> +<p>This approach doesn't give an optimal scheduling, at least in terms +of register usage. Here's an example (thanks to Mark) where any +contiguous evaluation is not optimal. +</p><p> + <img src="ExtendedSUNumbering_files/tree16.jpg" alt="tree16.jpg" height="446" width="792"> +</p><p> +My approach to this tree would require 1 extra register for evaluation; better than Sethi-Ullman but not perfect. +Mark pointed out that it's better to evaluate <code>a + b</code> and <code>f + g</code> first, since each will free a register. +Given a spare free register, we can evaluate the rest of the expression in any convenient order, with no additional registers. +</p><p> +</p><h2><a name="Loads_and_stores"> </a> Loads and stores </h2> +<p>I'm not entirely sure what to do here. Complex addressing modes +allow more to be done with fewer registers, so my scheme will tend to +overestimate register requirements and will, as a result, get some of +the ordering incorrect. This may not be important. +</p><p> +</p><h2><a name="Very_complex_expression_trees"> </a> Very complex expression trees </h2> +<p>A very complex expression tree will require more registers than +we've got. This scheme doesn't account for that possibility. Given 16 +integer registers and 16 floating-point registers, I don't think it'll +be a problem very often, but it would be smart to have a fallback +position. +</p><p> +</p><p> +</p><p> +</p><h2><a name="Questions"> </a> Questions </h2> +<p> +<em>Prove that this is the best way to handle operations that are associative and commutative.</em> +</p><p> +<em>Is there a simpler approach to achieve the same effect?</em> +</p><p> +<em>Can we describe, precisely, the effect we're trying to achieve?</em> +</p><p> +</p><p> +<em>What about a value that appears in, for example, two leaves and then goes dead?</em> +</p><p> +<em>Can we express this approach in a BURG grammar, so that it's handled at the same time as instruction selection?</em> +</p><p> +</p><p> +</p><h1><a name="Remember"> </a> Remember </h1> +<p>ideas about using burg (iburg really) to run after extended SU +numbering to do a more precise job. Still need SU numbering to do the +reassociation. Here's my email note +</p><p>Recall that I've been talking about SU numbering. One of the +open questions wondered about what's lost by doing SU-numbering before +running BURG. That is, we recognized that there would be some +imprecision caused by running BURG late, since the SU numbering would +be slightly off on it's register requirements. +</p><p>The latest idea recognizes that it's possible to do some parts +of SU numbering during the label pass of BURG. Thinking about it, I +think I need to run the extended SU numbering first, 'cause I want to +be able to reassociate where it helps. But then, during the label pass, +pay attention to register usage and my extended cost accounting for +dead registers, and choose the correct ordering for subtree evaluation. +It might be the same as the order picked during the initial SU +numbering, but it might be improved due to refined info about actual +register requirements. +</p><p> +The cool part is that it's very easy to express using BURG (well, almost easy). +Imagine the grammar rule +</p><p> + reg : ADD(reg, reg) +</p><p>So here's a simple rule saying that the non-terminal reg can be +defined by an ADD of two other regs. To do SU numbering at the same +time, we just provide two rules that look identical, but may have +different costs, where one evaluated the left subtree first and the +other evaluates the right subtree first. +</p><p> +<em>It's not actually easy because the BURG input language doesn't +allow us to express this. Perhaps we could fix it using some +combination of hacking on iburg and plug. I'm going to leave this for +future work.</em> +</p><p> +Recall also that Robert asked about the costs we assign to each rule. +Well (!), BURG allows us to have a vector of costs for each rules. I'm +thinking 3 components: The first is the number of extra registers, the +2nd is an estimate of the bytes of instructions, and the 3rd is the +number of registers freed. I'll use the extra and freed components as +the SU pairs, as described in my wiki page. We'd make burg resolve +decisions based on minimizing extra registers as the 1st priority, +resolving ties by minimizing instruction size. If it's possible to get +cycle estimates (and sometimes it is), then maybe that should be the +most important criteria. +</p><p> +I hope this is clear, but I understand that it may not be. I'll recap. +</p><p> +1st, do extended SU numbering, because this is our opportunity to reassociate. +2nd, do BURG, with extra rules to to extended SU numbering (though not reassociation). +</p><p>Return a vector of costs for each rule reflecting the SU pairs, +total instruction size, and total cycle count and resolve ties using +some formula that might be tunable. +</p><p> +To handle the more interesting costs, we'll probably have to use IBURG, since it's more flexible in this area. +</p><p> +</p><hr> +<p> +The above note is a crock. +</p><p> +Well, there's the germ of a good idea. The good idea is to use burg to do a normal labeling, +then write a reduce pass that does SU numbering (over the actual instructions) +and establishes the order of evaluation for the other reduce passes. +We'll still want the ordinary SU numbering to do reassociation. diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree0.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree0.jpg Binary files differnew file mode 100644 index 00000000000..cb094abd8c9 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree0.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree1.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree1.jpg Binary files differnew file mode 100644 index 00000000000..56c89038d0c --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree1.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree10.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree10.jpg Binary files differnew file mode 100644 index 00000000000..77cf7c4f647 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree10.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree11.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree11.jpg Binary files differnew file mode 100644 index 00000000000..5480271f7e0 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree11.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree12.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree12.jpg Binary files differnew file mode 100644 index 00000000000..c835f983560 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree12.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree13.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree13.jpg Binary files differnew file mode 100644 index 00000000000..7343d048002 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree13.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree14.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree14.jpg Binary files differnew file mode 100644 index 00000000000..dcb605b91ad --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree14.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree15.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree15.jpg Binary files differnew file mode 100644 index 00000000000..00755ebd2dc --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree15.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree16.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree16.jpg Binary files differnew file mode 100644 index 00000000000..e6fa9dd1f2e --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree16.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree2.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree2.jpg Binary files differnew file mode 100644 index 00000000000..ae5a941640d --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree2.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree3.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree3.jpg Binary files differnew file mode 100644 index 00000000000..ae20015d139 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree3.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree4.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree4.jpg Binary files differnew file mode 100644 index 00000000000..7b5a1ddd486 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree4.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree5.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree5.jpg Binary files differnew file mode 100644 index 00000000000..b3d36a60b1b --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree5.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree6.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree6.jpg Binary files differnew file mode 100644 index 00000000000..0d286e4923d --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree6.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree7.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree7.jpg Binary files differnew file mode 100644 index 00000000000..526d28a4ceb --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree7.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree8.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree8.jpg Binary files differnew file mode 100644 index 00000000000..d296511e292 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree8.jpg diff --git a/iburg/briggs/doc/ExtendedSUNumbering_files/tree9.jpg b/iburg/briggs/doc/ExtendedSUNumbering_files/tree9.jpg Binary files differnew file mode 100644 index 00000000000..95251061830 --- /dev/null +++ b/iburg/briggs/doc/ExtendedSUNumbering_files/tree9.jpg diff --git a/iburg/briggs/doc/ICGAssemblyEvaluation.html b/iburg/briggs/doc/ICGAssemblyEvaluation.html new file mode 100644 index 00000000000..96246f60b74 --- /dev/null +++ b/iburg/briggs/doc/ICGAssemblyEvaluation.html @@ -0,0 +1,424 @@ +<h1><a name="Results_of_Assembly_Comparisons"> </a> Results of Assembly Comparisons </h1> +<p> +For these comparisons, we are always using the same basic compiler, gcc +4.4, but with different register allocators. X refers to the +allocator used in X; Y refers to the allocator that will be used in +Y (aka IRA). +</p><p>I've been comparing the assembly code produced by ICG with that +produced by Y, based on many of the hottest Google3 routines. In +many, many cases, the code is basically identical. Where there are +differences, I've tried to figure out why the differences arise. Where +Y is making inferior code, I've tried to describe the problem +carefully so that the maintainers of Y can perhaps fix the problem. +Where the ICG code looks inferior, I've tried to figure out how it +could be made better. In many of these latter cases, it may be worth +instrumenting ICG itself to look for these possibilities before going +to the effort of fixing them. +</p><p> +</p><h2><a name="ICG_Wins"> </a> ICG Wins </h2> +<p> +</p><h3><a name="Handling_of_memset"> </a> Handling of memset </h3> +<p>For some reason, Y mis-handles the inlined version of memset. +Here's an example, with ICG code on the left and Y code on the right +</p><pre>movl 12(%rbx), %edx movl 12(%rbx), %edx +salq $2, %rdx salq $2, %rdx +movq 40(%rbx), %rdi movq 40(%rbx), %rdi +xorl %esi, %esi xorl %esi, %esi +call memset call memset +movl 28(%rbx), %ecx movl 28(%rbx), %ecx +movl $4, %edx movl $4, %eax + > movq %rax, %rdx +salq %cl, %rdx salq %cl, %rdx +movq 32(%rbx), %rdi movq 32(%rbx), %rdi +xorl %esi, %esi xorl %esi, %esi +call memset call memset +xorl %eax, %eax xorl %eax, %eax +movl $512, %ecx movl $512, %ecx +leaq 4144(%rbx), %rdi | leaq 4144(%rbx), %rdx + > movq %rdx, %rdi +rep stosq rep stosq +movw $512, %cx movw $512, %cx +leaq 48(%rbx), %rdi | addq $48, %rbx + > movq %rbx, %rdi +rep stosq rep stosq +</pre>In these cases (a series of 4 memsets, where two have been +inlined), we see Y repeatedly computing a value into 1 register, then +moving immediately into another. It's the sort of problem normally +avoided by coalescing. The first case may be an example of Y +mis-handling the shift by a variable amount. Perhaps more experiments +will shed more light. +<p> +</p><h3><a name="Handling_of_variable_shift"> </a> Handling of variable shift </h3> +<p>OK, here's another example of Y messing up a variable shift, this +time without the distraction of a memset. Again, the ICG code is on the +left, Y code on the right. +</p><pre>pushq %r15 pushq %r15 +pushq %r14 pushq %r14 +pushq %r13 pushq %r13 +pushq %r12 pushq %r12 +pushq %rbp pushq %rbp +pushq %rbx pushq %rbx +subq $8, %rsp | subq $24, %rsp +movq %rdi, %r13 | movq %rdi, %rbx +movl 12380(%r13), %ecx | movl 12380(%rdi), %ecx + > movl %esi, %ebp +sall %cl, %esi | sall %cl, %ebp +</pre>Sometimes there seem to be 2 extra copies in this area. +Note also that Y is reserving more stack space; that's because it +spills a register in this routine (beyond those mentioned in the +prologue), whereas ICG doesn't. +<p> +</p><h3><a name="Missed_coalesce_provokes_extra_s"> </a> Missed coalesce provokes extra spill </h3> +<p>In the case above, I mentioned that Y spills a register. Looking +at the code, I discovered that another unnecessary mov instruction, +such that two copies of a value are carried of several basic blocks and +a call. ICG coalesces the two values, saving a register and avoid the +spill. I can't see why Y would miss it; doesn't look unusual. +</p><p> +</p><h3><a name="Updating_spilled_values_in_memor"> </a> Updating spilled values in memory </h3> +<p> +It appears that Y missed some opportunities to update spilled values directly in memory, +versus loading, updating, storing. +</p><pre>movl $-1, %edx | movl 24(%rsp), %eax +subl %r13d, %edx | subl $1, %eax +addl %edx, 40(%rsp) | subl %r13d, %eax + > movl %eax, 24(%rsp) +</pre> +I can't promise this is a fair criticism; I need to look for other examples. +<p> +</p><p> +</p><h3><a name="Poor_instruction_selection_aroun"> </a> Poor instruction selection around spilled values </h3> +<p> +Here's a particularly good one: +</p><pre>cmpl $0, 64(%rsp) | movl 64(%rsp), %edx + > testl %edx, %edx +je .L494 | je .L494 +</pre> +This illustrates exactly the sort of problem that ICG was designed to avoid. +Here Y has wasted an instruction and chewed an extra register. +Now, we wonder if this happens a lot, or it it somehow particular to conditional branches. +<p> +</p><p> +</p><h3><a name="Stupid_spilling_around_calls"> </a> Stupid spilling around calls </h3> +<p> +When I see calls in the code produced by ICG, it seems that registers are spilled around in the in a remarkably naive fashion. +Here's an example: +</p><pre>movl %ecx, 16(%rsp) +movq %r8, 8(%rsp) +movl %r9d, 24(%rsp) +movl %r10d, 40(%rsp) +movl %r11d, 32(%rsp) +call *16(%rax) +testb %al, %al +movl 16(%rsp), %ecx +movq 8(%rsp), %r8 +movl 24(%rsp), %r9d +movl 40(%rsp), %r10d +movl 32(%rsp), %r11d +je .L813 +</pre> +I was surprised to see each value reloaded back into its original register. +Now this can happen, of course, especially in loops, but it seems as though every example I see has this same form. +Makes me wonder... +<p> +Here's a more complex example where they seem to be doing the same thing and getting bit: +</p><pre>movq %rax, 32(%rsp) +movq %rdx, 40(%rsp) +movq %rcx, 24(%rsp) +movq %r8, 48(%rsp) +movl %r9d, 56(%rsp) +call _ZL9nextchainPN12_GLOBAL__N_16ChainsEi +movl 56(%rsp), %r9d ******* dumb move +movl %r9d, %esi ******* dumb move +movq %rbx, %rdi +call _ZL9nextchainPN12_GLOBAL__N_16ChainsEi +movq 48(%rsp), %r8 +movb $0, 7(%r8) +movq 24(%rsp), %rcx +movq 40(%rsp), %rdx +movq 32(%rsp), %rax +</pre> +The instructions marked <code>dumb move</code> should have been a simple load into <code>%esi</code>. +Looking at the same code as handled by ICG, I see nothing like this pattern. +Gives me hope that they are indeed beatable. +<p> +See <a href="ICGOurFirstBigWin.html">ICGOurFirstBigWin</a> for more discussion. +</p><p> +</p><h2><a name="ICG_Loses"> </a> ICG Loses </h2> +<p> +</p><h3><a name="Imperfect_handling_of_commutativ"> </a> Imperfect handling of commutative, two-address operations </h3> +<p> +Described <a href="ICGawkwardness.html">here</a>. Most of the observed instances are simple and could be handled trivially after register allocation. +</p><p> +</p><h3><a name="Parameter_passing"> </a> Parameter passing </h3> +<p> +Here's an example where coalescing isn't adequate to clean up all the register-register copies around procedure calls +</p><pre>movq %rbx, -16(%rsp) +movq %rbp, -8(%rsp) +subq $24, %rsp +movq %rdi, %rbx +movl %edx, %ebp -- we copy the parameter in %edx into %ebp +testl %ebp, %ebp +je .L10 +movq 12392(%rbx), %rdi +testq %rdi, %rdi +je .L10 +movl %ebp, %edx -- this copy is unnecessary, since %edx hasn't changed +movq (%rdi), %rax +call *16(%rax) -- as part of the call, %edx is killed +testb %al, %al +je .L12 +movslq %ebp,%rax -- %ebp is still live +... +</pre> +We can't simply coalesce %ebp and %edx because %edx is killed across the call, and we need the value after the call. +<p>Variations of this seem to happen a lot. The observed instances are +simple and could be handled trivially after register allocation. I +don't see a way to handle it naturally as part of the existing ICG +framework. +</p><p> +</p><h3><a name="Addressing_modes_for_memory_upda"> </a> Addressing modes for memory updates </h3> +<p> +We've planned for this from the beginning, but haven't yet finished the implementation. +</p><p> +</p><h3><a name="Another_DAG"> </a> Another DAG </h3> +<p> +The need to handle updates to memory was anticipated from the beginning; +the following disaster was a surprise. +</p><pre>leal -8(%ebp), %eax < +movl %eax, %edx < +andl $-8, %edx < +negl %edx < +leal (%eax,%edx), %ebp | andl $7, %r13d +</pre> +Can this be true? It is! What happened? +Here's the provoking IL: +<pre>insn 66: SET_ALL + REGX_SI:79 + PLUS_SI + REGX_SI:61 + CONST5N:-8 +insn 72: SET_ALL + REGX_SI:61 + PLUS_SI + REG_SI:79 + NEG_SI + ASHIFT_SI + LSHIFTRT_SI + REG_SI:79 + CONST_P3:3 + CONST_P3:3 +</pre>While we're doing something right (recognizing that the +right-shift, left-shift sequence can be replaced by an and-immediate), +there are many things going wrong. The basic problem is that we've got +a DAG, with r79 being used in two places in the 2nd expression; burg +patterns only describe trees. We ran into the same problem with updates +to memory and added a couple of passes to recognize them +systematically. Seems a basic weakness of our approach. I'd hate to add +a new pass for every new pattern, but perhaps it's justified in this +case? Certainly more study is required first. +<p> +Looking at the assembly, other questions arise, primarily: <em>Why the final</em> <code>leal</code> <em>over a negate instead of a simple subtract?</em>Again, +this is related to the DAGness of the problem. We see two uses of r79 +in the 2nd expression, and since we're uncertain of the order of +evaluation, we don't mark either as the "last use" (i.e., a REGX). And +since burg doesn't see a last use, it must carefully preserve r79 (if +we'd used a subtract instruction, r79 would be overwritten). Of course, +we could make a copy and then subtract, but the cost would be the same. +</p><p>We can do a better job here, even if we don't handle the DAG. +Given the structure of the expression tree, we can be certain that the +"deeper" reference to r79 will be complete before the subtract. +Therefore, we could safely mark the outer reference to r79 as a last +use and burg would choose the subtract, saving an instruction. I'll +have to see if this insight can be easily implemented. <em>Is this really true? Think carefully!</em> +</p><p> +And the source code for this slop? Well, there's actually nothing particularly interesting; it's just the epilogue of a loop. +I believe there's been some strength reduction going on and the optimizer has inserted this +code to recover a final value from an induction variable. I further speculate that gcc developers +added this as a special peephole optimization to clean a commonly occurring ugliness. +</p><p> +</p><h3><a name="Rematerialization"> </a> Rematerialization </h3> +<p> +When spilling, ICG should pay attention to <em>rematerializable values</em> +(e.g., constants) that don't need to be stored in memory, but can +instead be loaded immediately when they are needed. Here's an example: +</p><pre>movl $715827883, 32(%rsp) < +jmp .L33 jmp .L33 +... +addl 16(%rsp), %r13d | movl 28(%rsp), %ebx +movl %r13d, %ebx | addl %r13d, %ebx +cmpl $1, 40(%rsp) | cmpl $1, 24(%rsp) +jle .L32 jle .L32 +cmpl $10, 40(%rsp) | cmpl $10, 24(%rsp) +jle .L15 jle .L15 +movslq 40(%rsp),%rcx | movl $715827883, %eax +</pre> +I know how to do this, but there's some implementation effort required. +I believe it will fit in nicely with the overall structure. +<p> +</p><h3><a name="Need_more_local_smarts_when_spil"> </a> Need more local smarts when spilling </h3> +<p> +Here's an embarrassment: +</p><pre>movq 24(%rsp), %rdx +movzwl (%rdx), %edx +movq 24(%rsp), %rcx +</pre> +If we were more careful, this could be expressed +<pre>movq 24(%rsp), %rcx +movzwl (%rcx), %edx +</pre> +One of Chaitin's refinements was to exercise a little care when spilling (and computing spill costs) +and avoid situations like this. We've been lazy about implementing this detail; I should fix it. +<p> +</p><p> +</p><h3><a name="Avoiding_a_zero_extension"> </a> Avoiding a zero extension </h3> +<p> +We do some work to avoid unnecessary sign- and zero-extensions within expression trees. +Nevertheless, here's a mistake: +</p><pre>movzbl %cl, %ecx | movzbl %sil, %esi +movzbl %al, %eax < +sall $24, %eax | sall $24, %ecx +orl %ecx, %eax | orl %ecx, %esi +</pre>Clearly the left shift by 24 of a 32-bit value means that we +don't care about anything but the lowest 8 bits. We ought to be able to +catch these with burg patterns. <em>Fixed</em> +<p> +</p><h3><a name="Unnecessary_test_instruction"> </a> Unnecessary test instruction </h3> +<p> +We work hard to avoid these and appear to be successful for the most part; nevertheless, this one crept in. +</p><pre>subl %r12d, %r15d | subl %r15d, %ecx +testl %r15d, %r15d < +je .L112 | je .L112 +</pre> +This turns out to be beyond our scheme because <code>r15</code> is live downstream (burg's expression trees have only a single result). +It's clearly an easy peephole for a later pass. A more sophisticated matcher based on Ertl's work could also catch it, I think. +<p> +</p><h3><a name="Missed_peephole_optimization"> </a> Missed peephole optimization </h3> +<p> +There are many peephole optimizations that can be expressed via burg grammar rules. +Here's one we missed +</p><pre>addq $1, %rax | leaq 4(,%rax,4), %rax +salq $2, %rax < +</pre> +I'm afraid there will be many of these and they'll only be revealed over a long, tedious tuning period. +I have ideas about collecting semi or even fully automatically, but it'll still take a while to implement. +<p> +Hmmm, this actually is not a problem. On the Opteron, both sequences have exactly the same cost, latency and size. +But it does remind me that I should specify the correct target machine for these comparisons. +</p><p> +</p><h3><a name="Another_missed_peephole_optimiza"> </a> Another missed peephole optimization </h3> +<p> +The addressing modes are a source of all kinds of surprising +opportunities. Here's another that happens to show up twice in a row: +</p><pre>movslq %ebx,%r8 | movslq %r14d,%rsi +leaq 60(%r8), %r9 < +movl %edi, 32(%rsp,%r9,4) | movl %edi, 272(%rsp,%rsi,4) +leaq 696(%r8), %rdi < +movw %si, 32(%rsp,%rdi,2) | movw %cx, 1424(%rsp,%rsi,2) +</pre> +Basically, we want to rewrite <code>A*(rX + B) + rY + C</code> as <code>A*rX + rY + (A*B + C)</code>. +It's easy enough to recognize the opportunity using grammar rules, but care is required. +For this to work in a single addressing mode (and therefore be worth doing), +the constant <code>A*B + C</code> must fit within 4 bytes. This generally isn't the sort of thing we can +recognize in a context-free fashion. +<p> +There are a couple of ways we can deal with this. +</p><ol> +<li> Add a fancy cost function that's called with the values A, B, and +C. If the resulting constant doesn't fit in 32 bits, returns an +infinite cost; otherwise, returns the appropriate finite cost. We'd +have to extend plug and iburg to handle this sort of thing, but there's +no theoretical reason we can't manage. +</li> +<li> Since A is limited to the small constants 2, 4, or 8, we can +conservatively limit the size of B and C and be able to manage within +the context of the current implementations of plug and iburg. While it +won't catch as much as the more aggressive solution above, it'll get +all the small cases and degrade gracefully. +</li> +</ol> +<p> +Thinking more about it, I believe approach 2 can be very good. +Since we want A*B + C to be less than 2^31, we can ensure (syntactically) +that both A*B and C are less than 2^30. While it won't catch quite every case, +it will be quite good. Looking at it, I think I can express it (and all its variations, +accounting for different integer types and such) as 42 plug rules, which will expand by +another factor of 48 to yield over 2300 iburg rules. Cool! This idea <em>doubles</em> the the number of iburg +rules in one fell swoop. +</p><p> +While it helps show the power of the tools, it also helps illustrate their weakness. +Doing all this recognition in a pure syntactic fashion requires a <em>lot</em> of syntax. +It may be that a fairly small amount of clever C could achieve the same effect +in a much simpler fashion, perhaps by normalizing the expression somehow. +</p><p> +For completeness, here's the basic pattern we need to recognize. +</p><pre>r64x : PLUS_DI(MULT_DI(PLUS_DI(r64.index | imm29.const1) | CONST_P4) | imm31.const2 | r64.base) +</pre> +Here <code>imm29</code> indicates some constant (named <code>const1</code>) that can be represented in 29 bits or less, <code>imm31</code> +is some constant that can be represented in 31 bits or less, <code>CONST_P4</code> is the constant 4, and <code>r64</code> indicates a 64-bit register. +<p> +Plug will take this one rule and generate the 48 variations implied by the commutativity and associativity of +addition and multiplication. By hand, I'll produce the 42 variations that account for different integer types, +shift instead of multiplication, the three possible shift amounts, and the different costs for 1-byte and 32-byte displacements. +</p><p> +In any case, <em>Fixed</em> +</p><p> +</p><h2><a name="A_mixed_bag"> </a> A mixed bag </h2> +<p> +Here's a sequence of blocks where both appear to be making mistakes, though ICG gets the better result: +</p><pre>movswl (%rax,%r8),%ecx | movswl (%r9,%rax),%ecx +testl %ecx, %ecx testl %ecx, %ecx +je .L77 je .L77 +movslq %ecx,%rsi | movslq %ecx,%rdi +movl 0(%rsp,%rsi,4), %edi | movl 16(%rsp,%rdi,4), %r8d +movl %edi, %r9d | movl %r10d, %r11d +negl %ecx | subl %ecx, %r11d (1) +leal (%edx,%ecx), %ecx | movl %r11d, %ecx + > movl %r8d, %r13d (2) +sall %cl, %r9d | sall %cl, %r13d + > movl %r13d, %ecx +testl $-65536, %r9d | testl $-65536, %r13d +jne .L73 jne .L73 +addl $1, %edi | addl $1, %r8d +movl %edi, 0(%rsp,%rsi,4) | movl %r8d, 16(%rsp,%rdi,4) +movl %r9d, %ecx | movzbl %r13b, %edi (3) +andl $255, %ecx < +movzbl _ZN12_GLOBAL__N_1L6revtabE(%rcx), %ecx | movzbl _ZN12_GLOBAL__N_1L6revtabE(%rdi), %edi +sall $8, %ecx | sall $8, %edi +shrl $8, %r9d | shrl $8, %ecx + > mov %ecx, %ecx (4) +movzbl _ZN12_GLOBAL__N_1L6revtabE(%r9), %esi | movzbl _ZN12_GLOBAL__N_1L6revtabE(%rcx), %ecx +orw %cx, %si | orl %edi, %ecx (5) +movw %si, 2(%r8,%rax) | movw %cx, 2(%r9,%rax) +</pre> +I'm not completely confident of my explanations; some things will bear closer investigation. +<ol> +<li> ICG will sometimes emit the sequence <code>negate-lea</code> instead of <code>move-subtract</code>; in this case, preserving <code>rdx</code>. But I'm not certain <code>rdx</code> is actually live (I get lost in the control flow); if not, then a simple subtract would be better. Should be examined. +</li> +<li> Y has the usual mistake of an extra move instruction before the +variable shift. But this time there might be one after the shift too. +</li> +<li> ICG uses a <code>movl-and</code> sequence instead of a <code>movzbl</code>. I expect this is an easy peephole-like pattern to express in burg. <em>Fixed</em> +</li> +<li> Why does Y do this? It has the effect of zeroing the upper 32 +bits of the register, but they're already zero as a side effect of the +previous instruction. +</li> +<li> ICG should have used <code>orl</code> here, to save a byte in the instruction coding. We usually get these; there may be a typo to fix. <em>Fixed</em> +</li> +</ol> +<p> +</p><h2><a name="Comparing_to_X"> </a> Comparing to X </h2> +<p> +X is our name for the register allocator gcc was using when we started, just before IRA was introduced. +Looking in a limited way +</p><ul> +<li> it appears to generate slightly bulkier code than Y +</li> +<li> it avoids some of the small mistakes Y made (extra copies around variable shifts and calls to memset) +</li> +<li> has the same approach to (mis)handling caller-saves registers. +</li> +</ul> +This last point is a little scary. Implies that they may be handled in reload versus the allocator proper. +While it won't matter to ICG, it suggests that it won't be so easy to fix Y diff --git a/iburg/briggs/doc/ICGOurFirstBigWin.html b/iburg/briggs/doc/ICGOurFirstBigWin.html new file mode 100644 index 00000000000..4461abc2f68 --- /dev/null +++ b/iburg/briggs/doc/ICGOurFirstBigWin.html @@ -0,0 +1,123 @@ +<h1><a name="ICG_handles_calling_conventions_"> </a> ICG handles calling conventions <em>much</em> better than IRA </h1> +<p> +So here's a place where IRA seems to fall down badly. +Faced with code that has lots of live registers and lots of procedure calls, +they handle the caller-saves registers in a very naive fashion. +Here's an extended example +</p><pre> subl 40(%rsp), %r9d + je .L252 + movq 12392(%rbx), %rdi + testq %rdi, %rdi + je .L252 + movq (%rdi), %rax + movl %r9d, %edx + movq %r8, %rsi + movl %ecx, 8(%rsp) + movq %r8, 16(%rsp) + movl %r9d, 24(%rsp) + call *16(%rax) + testb %al, %al + movl 8(%rsp), %ecx + movq 16(%rsp), %r8 + movl 24(%rsp), %r9d + je .L302 + movslq %r9d,%r9 + addq %r9, 12408(%rbx) +.L252: + movq %r8, 12360(%rbx) + movq %r8, %r9 + jmp .L251 +.L298: + subl 40(%rsp), %r9d + je .L270 + movq 12392(%rbx), %rdi + testq %rdi, %rdi + je .L270 + movq (%rdi), %rax + movl %r9d, %edx + movq %r8, %rsi + movl %ecx, 8(%rsp) + movq %r8, 16(%rsp) + movl %r9d, 24(%rsp) + call *16(%rax) + testb %al, %al + movl 8(%rsp), %ecx + movq 16(%rsp), %r8 + movl 24(%rsp), %r9d + je .L303 +</pre> +The only thing really interesting here is the pattern of spills and reloads +around each call. It looks like it was inserted at the last minute, +not as an integral part of register allocation. +<p> +I think the right way to handle caller-saves registers in a coloring allocator is to treat +them as <em>callee-killed</em> registers. It's an old idea for me, and I'm certain +others (e.g., Callahan and Koblenz had the same idea); I probably +should have written more clearly about this in my thesis. +</p><p> +Anyway, when I come across a call, I treat it like any other instruction. +It references some registers (the parameters) and kills some registers +(those not guaranteed to be preserved across the call). In this fashion, +the interference graph will reflect the needs of each call and the +code will be globally adapted to avoid keeping values in those registers +across calls. +</p><p> +Here's what ICG makes for the same two calls: +</p><pre> subl 40(%rsp), %r15d + testl %r15d, %r15d **** + je .L251 + movq 12392(%rbx), %rdi + testq %rdi, %rdi + je .L251 + movl %r15d, %edx + movq 40(%rsp), %rsi + movq (%rdi), %rax + call *16(%rax) + testb %al, %al + je .L300 + movslq %r15d,%rdx + addq %rdx, 12408(%rbx) +.L251: + movq 40(%rsp), %rdx + movq %rdx, 12360(%rbx) + movq 40(%rsp), %r15 **** + jmp .L250 +.L299: + subl 40(%rsp), %r15d + testl %r15d, %r15d **** + je .L269 + movq 12392(%rbx), %rdi + testq %rdi, %rdi + je .L269 + movl %r15d, %edx + movq 40(%rsp), %rsi + movq (%rdi), %rax + call *16(%rax) + testb %al, %al + je .L301 +</pre> +30 instructions versus 39, which is a nice savings. +Now, there are some obvious problems with the ICG code too, +marked with stars. But all three are easily fixed with a peephole +pass. The problems with IRA's codes aren't so easily cleaned up. +<p> +(After making fixups, we see ICG with 27 instructions, versus IRA's 39. +More importantly, ICG would have 11 memory refs versus IRA's 20.) +</p><p> +I should say that two of ICG's extra refs should have been handled as part +of the ordinary process of allocation. Chaitin taught us how to avoid them, +and it's better to avoid them up front, because such things affect spill costs +and therefore the decisions about which registers to spill. +</p><p> +So maybe the headroom calculation should be ICG + cleanup phase, +MAO or something else. ICG is getting things in pretty good shape globally, +but has some locally rough spots. +</p><p> +Another idea that should probably be done in any case is to write +Vladamir, the guy who wrote most of IRA, and show him our idea. +I met him last year and I think he'd be amenable. It may take a while +for changes to percolate through the whole gcc process, but I don't think +they'd be that difficult for him to make and it's bound to be faster than +trying to replace the entire code generator. + +Heh! He was not ammenable. diff --git a/iburg/briggs/doc/ICGawkwardness.html b/iburg/briggs/doc/ICGawkwardness.html new file mode 100644 index 00000000000..5558ebfd254 --- /dev/null +++ b/iburg/briggs/doc/ICGawkwardness.html @@ -0,0 +1,143 @@ +<h1><a name="An_awkwardness"> </a> An awkwardness </h1> +<p> +Consider the following contrived example +</p><pre>int zip(int); + +int zap(int a, int b) { + return a * zip(a) * b; +} +</pre> +When we compile it, we get +<pre>movq %rbx, -16(%rsp) +movq %rbp, -8(%rsp) +subq $24, %rsp +movl %edi, %ebx +movl %esi, %ebp +call zip +imull %ebx, %eax +imull %eax, %ebp -- these two lines +movl %ebp, %eax -- are interesting +movq 8(%rsp), %rbx +movq 16(%rsp), %rbp +addq $24, %rsp +ret +</pre> +The problem is that the multiply could be rewritten as +<pre> imull %ebp, %eax +</pre> +saving the copy. Why didn't coalescing or something fix it? How did his happen? +<p> +Coming into icg, the relevant expressions look like this +</p><pre>SET_ALL + REGX_SI:55 + REGX_SI:0[ax] +SET_ALL + REGX_SI:56 + MULT_SI + MULT_SI + REGX_SI:53 + REGX_SI:55 + REGX_SI:54 +SET_ALL + REGX_SI:0[ax] + REGX_SI:56 +</pre> +After instruction selection, we see +<pre>movl %eax,%r55d -- copy 1 +imull %r53,%r55 +imull %r55,%r54 +movl %r54d,%r56d -- copy 2 +movl %r56d,%eax -- copy 3 +</pre> +At this point, we're already stuck. Coalescing can either remove copies 1 and 2 or copies 2 and 3, but not all three. +To get all three, we need to rewrite the second multiply as +<pre>imull %r54,%r55 +</pre> +which is legal. Iburg <em>arbitrarily</em> selected r54 *= r55, but it could just as well have selected r55 *= r54. +Unfortunately, there was no information to guide it. +The question is: How can we guide iburg to prefer this choice? +Or how can we fix it later? +<p> +I originally noted this problem with integer addition. +Luckily, the x86 has a 3-address form of integer addition (using the <code>lea</code> instruction), +so I used that to avoid the entire issue. That is, I generate something like r100 = r99 + r98. +Then, if r100 happens to be coalesced with either r99 or r98, or nothing at all, I always have +a plausible alternative. +</p><p> +The IBM guys used to handle this sort of situation by pretending the multiply was +a 3-address instruction. Then, during coalescing, they'd try to coalesce the destination +with either of the sources. If that worked, great. If not, they'd introduce a copy +at the last minute. +</p><p> +This approach may work for us too. I need to ponder it a bit more, but I guess I'd try +recognizing the pattern +</p><pre>stmt : SET_ALL(r32d, MULT_SI(r32x, r32x)) +</pre> +and attempting to coalesce the destination with either of the sources. +Hmmm, I think this will work. Well, maybe. What if this is the very first coalesce we try? +Then we might choose the wrong one, unluckily, and be stuck again. We could do better, +perhaps, by deferring these sorts of coalesces, since we have a choice. +So have 2 stages of coalescing (1 for copies, 1 for these things)? +<p> +This will require careful testing as there are a number of cases to cover. +</p><p> +</p><h3><a name="Targeting"> </a> Targeting </h3> +<p> +The ideas above are inadequate for complex expressions. +Consider +</p><pre>SET_ALL + REGX_SI:0 + MULT_SI + MULT_SI + REGX_SI:0 + REGX_SI:1 + MULT_SI + REGX_SI:2 + REGX_SI:3 +</pre> +There are 4 ways we can implement this expression tree using 2-address +multiply instructions, but only one of the ways avoids the need for a +copy. +Clearly we want to find that particular implementation. I propose to do +this in a single iburg reduction, very late in the code generation +process (just before emit). +I think it can be accomplished by percolating the required register top +down, through instructions that can be commuted. Similar transforms are +sometimes called <em>targeting</em>, +so I'll steal that name here. On the other hand, I've never seen the +problem discussed this thoroughly, so perhaps we've got something new. +<p> +I'm still not entirely happy. I'll continue to play with it. +</p><p> +</p><h3><a name="Better"> </a> Better </h3> +<p> +Rather than look for identical registers, it's more general to look for opportunities +to coalesce. For example, given +</p><pre>SET_ALL + REGX_SI:100 + MULT_SI + MULT_SI + REGX_SI:101 + REGX_SI:102 + MULT_SI + REGX_SI:103 + REGX_SI:104 +</pre> +we want to try coalescing r100 with the entire set of r101 through r104. +If any succeed, then we need to commute to make it work out. +This suggests perhaps traversing each expression tree, bottom up, +collecting a set of <em>coalescing candidates</em>. Then, as part of normal coalescing, +try coalescing the target of the copy with each of the candidates. +<p> +I'll ponder this idea. +</p><p> +</p><h3><a name="A_simpler_exampler_for_later"> </a> A simpler exampler for later </h3> +<p> +</p><pre>int zap(int a, int b) { + return a*b; +} +</pre> +yields +<pre>imull %esi, %edi +movl %edi, %eax +ret diff --git a/iburg/briggs/doc/ICGmisunderstandingSubreg.html b/iburg/briggs/doc/ICGmisunderstandingSubreg.html new file mode 100644 index 00000000000..fb81a121e19 --- /dev/null +++ b/iburg/briggs/doc/ICGmisunderstandingSubreg.html @@ -0,0 +1,104 @@ +<h1><a name="Misunderstanding_Subreg"> </a> Misunderstanding Subreg </h1> +<p> +I don't understand all the details of the <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgccint%2FRTL.html%23RTL" target="_top">RTL</a> +operation <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgccint%2FRegs-and-Memory.html%23Regs-and-Memory" target="_top">subreg</a>. +</p><p> +To date, the only subreg operations I've seen (for the x86-64) look something like this +</p><pre>(subreg:SI (reg:DI 63) 0) +</pre> +indicating that we're interested in the lower four bytes (a signed integer) of the +8-byte quantity (a double integer) in register 63. +<p> +This sort of cast may be the only sort of usage we'll ever see for the x86-64; +however, when I went to the gcc summit, many people pointed out that subreg is oh-so-much-more than +just a cast. At least it is on some processors. +</p><p> +The general form is +</p><pre>(subreg:<em>m1</em> reg:<em>m2 bytenum</em>) +</pre> +The sort I've seen so far are <em>normal</em> subregs (where the mode of the first operand is wider than the mode of the subreg). +Furthermore, all the ones I've seen have bytenum=0. +<p> +</p><h2><a name="Possible_problems"> </a> Possible problems </h2> +<p> +Currently, the translation to side-tree form handles subreg incorrectly, +dropping the <em>bytenum</em>. +</p><p> +Nothing in the grammar refers to the (missing) <em>bytenum</em>. +</p><p> +Need to be able to handle a subreg as an l-value. +Does this ever occur for the x86-64? If it does, then it's a sort of update instruction, +modifying part of the destination. Need to handle this correctly when computing SSA. +</p><p> +Paradoxical subregs? +</p><p> +</p><p> +</p><h2><a name="Understanding_Subreg"> </a> Understanding Subreg </h2> +<p> +Mark plowed through the existing documentation and came up with a better schema for +organizing the 4 interesting cases. We'll adopt it here. +</p><p> +</p><p> +</p><h3><a name="RHS_subregs"> </a> RHS subregs </h3> +<p> +These occur in expression trees, effectively on the right-hand-side of assignment statements. +Here's an example: +</p><pre>(set (reg:SI 56) + (plus:SI (reg:SI 70) + (subreg:SI (reg:DI 83) 0))) +</pre> +In this case, we assign the 32-bit sum of <code>r70</code> and the lower 32-bits of <code>r83</code> +to <code>r56</code>. +<p> +When we compare the modes of the <code>subreg</code> and its enclosed <code>reg</code>, there are two cases to be considered: <em>normal</em> and <em>paradoxical</em>. +</p><p> +</p><h5><a name="Normal_subregs"> </a> Normal subregs </h5> +<p> +The general format of a normal RHS subreg is +</p><pre>(subreg:<em>narrow</em> (reg:<em>wide n</em>) <em>bytenum</em>) +</pre> +This case is fairly straightforward. +<p> +</p><p> +</p><h5><a name="Paradoxical_subregs"> </a> Paradoxical subregs </h5> +<p> +The general format of a paradoxical RHS subreg is +</p><pre>(subreg:<em>wide</em> (reg:<em>narrow n</em>) 0) +</pre> +Note that the <em>bytenum</em> for paradoxical subregs is always 0. +<p> +Despite the name, paradoxical subregs are pretty straightforward. +The bits of register <em>n</em> are extended in some undefined fashion to +the width specified by <em>wide</em>. +</p><p> +</p><p> +</p><p> +</p><h3><a name="LHS_subregs"> </a> LHS subregs </h3> +<p> +These occur as the target of <code>set</code> forms, effectively on the left-hand-side of assignment statements. +Here's an example: +</p><pre>(set (subreg:DI (reg:SI 56) 0) + (plus:DI (reg:DI 70) + (reg:DI 83))) +</pre> +As above, there are two cases. +<p> +</p><h5><a name="Normal_subregs"> </a> Normal subregs </h5> +<p> +The general format of a normal LHS subreg is +</p><pre>(set (subreg:<em>narrow</em> (reg:<em>wide n</em>) <em>bytenum</em>) + <em>expr</em>) +</pre> +In this case the register is updated: a subset of bits of the register are written. +<p> +</p><h5><a name="Paradoxical_subregs"> </a> Paradoxical subregs </h5> +<p> +The general format of an paradoxical LHS subreg is +</p><pre>(set (subreg:<em>wide</em> (reg:<em>narrow n</em>) 0) + <em>expr</em>) +</pre> +Remember that the <em>bytenum</em> for paradoxical subregs is always 0. +<p> +Again, the paradoxical subreg is straightforward. +The low-order bits of <em>expr</em> overwrite register <em>n</em>; +the high-order bits of <em>expr</em> are ignored. diff --git a/iburg/briggs/doc/ICGmoreAccurateSpillCosts.html b/iburg/briggs/doc/ICGmoreAccurateSpillCosts.html new file mode 100644 index 00000000000..355caf4e7f1 --- /dev/null +++ b/iburg/briggs/doc/ICGmoreAccurateSpillCosts.html @@ -0,0 +1,139 @@ +<h1><a name="More_Accurate_Spill_Costs"> </a> More Accurate Spill Costs </h1> +<p> +There are a couple of new ideas we should explore +for computing more accurate spill costs. +</p><p> +</p><h2><a name="Looking_ahead"> </a> Looking ahead </h2> +<p> +While working on spilling, I wrote a simple test case, +my favorite kind. Looks like this +</p><pre>long zap(long *x, long i) { + long a0 = x[0]; + long a1 = x[1]; + long a2 = x[2]; + long a3 = x[3]; + long a4 = x[4]; + long a5 = x[5]; + long a6 = x[6]; + long a7 = x[7]; + long a8 = x[8]; + long a9 = x[9]; + long a10= x[10]; + long a11= x[11]; + long a12= x[12]; + long a13= x[13]; + + x[i] = 0; + + x[100] = a0; + x[101] = a1; + x[102] = a2; + x[103] = a3; + x[104] = a4; + x[105] = a5; + x[106] = a6; + x[107] = a7; + x[108] = a8; + x[109] = a9; + x[110] = a10; + x[111] = a11; + x[112] = a12; + x[113] = a13; +} +</pre> +Needs 17 integer registers ( <code>a0</code>, ..., <code>a13</code>, <code>x</code>, <code>i</code>, plus the stack pointer), +so we must spill one. Chaitin taught us to choose based on +spill cost and degree. He computed spill costs by counting uses and defs, +weighted by some estimate of execution frequency. +<p> +He also had a few tricks for better spilling within a single basic blocks, +but we'll ignore those here. +</p><p> +So, for all the live ranges, we count the number of defs and uses. +<code>x</code> has 1 def and many uses. Each of the others have exactly 1 def +and 1 use. +</p><p> +Looking at degree, we see that they all interfere with each other, +so they all have the same degree. +</p><p> +Therefore, when it comes time to choose 1 register to spill, +Chaitin will choose, arbitrarily, one of the registers from { <code>a0</code>, ..., <code>a13</code>, <code>i</code> } +(but not <code>x</code>, 'cause it's expensive) because they all seem identical. +</p><p> +But this is wrong. In this case, it's certainly worse to spill <code>i</code> or <code>a13</code>. +Why? Spilling either of those makes no progress; we'll have to spill +something else in addition. Consider what happens it we spill <code>a13</code>. +We make code something like +</p><pre>long zap(long *x, long i) { + long a0 = x[0]; + long a1 = x[1]; + long a2 = x[2]; + long a3 = x[3]; + long a4 = x[4]; + long a5 = x[5]; + long a6 = x[6]; + long a7 = x[7]; + long a8 = x[8]; + long a9 = x[9]; + long a10= x[10]; + long a11= x[11]; + long a12= x[12]; + long a13_1 = x[13]; + *sp = a13_1; + + x[i] = 0; + + x[100] = a0; + x[101] = a1; + x[102] = a2; + x[103] = a3; + x[104] = a4; + x[105] = a5; + x[106] = a6; + x[107] = a7; + x[108] = a8; + x[109] = a9; + x[110] = a10; + x[111] = a11; + x[112] = a12; + a13_2 = *sp; + x[113] = a13_2; +} +</pre> +Now we'll be able to allocate a register to <code>a13_1</code> because it +because it has no interferences. But <code>a13_1</code> has exactly the same +set of interferences as the original <code>a13</code>. We've made no progress at all. Damn! +(Not exactly true. We've simplified other areas of the code, but we're going to have to +spill something else.) +<p> +So, what to do? My idea is that we should examine all the spill points +for each live range (defs and uses) and note how many other live ranges are +live across each of those spill points. Keep the max for each live range. +</p><p> +So for our example, we note that the def point of <code>i</code> interferes with 2 things +(<code>x</code> and <code>sp</code>) and the use of <code>i</code> interferes with 16 things ( <code>x</code>, <code>sp</code>, <code>a0</code>, ..., <code>a13</code> ). +So the max for <code>i</code> is 16. But consider, say, <code>a4</code>. The def of <code>a4</code> interferes +with 7 things and the use of <code>a4</code> interferes with 11 things, so the max is 11. +My argument is that it's much better to spill <code>a4</code> than <code>i</code> and that the max we've +computed for each gives us the necessary clue. +</p><p> +I'm not sure of all the answers though. Should this just be a differentiator of last resort, +after examining spill cost and degree? Or perhaps, if the max is >= number of registers, +should I just make the spill cost infinite? (I think that's wrong) Or what? +</p><p> +I'll ponder some more. +</p><p> +</p><h2><a name="Looking_at_the_grammar"> </a> Looking at the grammar </h2> +<p> +This was inspired by conversation with David Li. +</p><p> +The basic idea is to note the difference between +</p><pre>r64x : ADD_DI(r64x | MEM_DI(addr)) +</pre> +and +<pre>r64x : ADD_DI(r64x | r64) +</pre> +In the first case, spilling the source register +will require a separate load instruction and an intermediate register. +In the second case, the add instruction can be modified to load from memory +and no intermediate register will be required. diff --git a/iburg/briggs/doc/NewCodeGenForGCC.html b/iburg/briggs/doc/NewCodeGenForGCC.html new file mode 100644 index 00000000000..14622ddc5ae --- /dev/null +++ b/iburg/briggs/doc/NewCodeGenForGCC.html @@ -0,0 +1,200 @@ +<h1><a name="ICG_A_new_code_generator_for_gcc"> </a> ICG: A new code generator for gcc </h1> +<p> +This wiki describes ICG, a new code generator for gcc. +</p><p> +We had a number of new ideas about code generation for CISC machines, like the x86 and x86-64. +Our goal was to explore these ideas in the context of <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fgcc.gnu.org%2Fwiki" target="_top">GCC</a>. +Our initial target was the <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FX86-64" target="_top">x86-64</a>, the 64-bit version of the x86 architecture. +</p><p> +</p><p> +</p><h2><a name="Status"> </a> Status </h2> +<p> +ICG produces correct code in most cases, though our level of correctness testing is still minimal. It also produces <em>good</em> code in most cases. + + +</p><h2><a name="The_big_picture"> </a> The big picture </h2> +<p> + <img src="icg.jpg" alt="icg.jpg" height="538" width="840"> +</p><p> +</p><p> +Pretty isn't it? Please see the <a href="DescriptionOfTheBigPicture.html">DescriptionOfTheBigPicture</a>. +</p><p> +</p><p> +</p><p> +</p><h2><a name="_http_gcc_gnu_org_onlinedocs_gcc"> </a> <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgccint%2FRTL.html%23RTL" target="_top">RTL</a> for Expression Trees </h2> +<p> +Our approach is to hook into gcc at the <a href="http://www.google.com/url?sa=D&q=http%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgccint%2FRTL.html%23RTL" target="_top">RTL</a> level. +RTL instructions currently roughly match machine instructions. We want the patterns to be as large as possible, +to make burg work better. We use the techniques used by combine to pull related RTL insns together into large RTL patterns. +</p><p> +</p><p> +</p><h2><a name="An_Example"> </a> An Example </h2> +<p> +Here's an example, in made up notation. +Imagine an RTL tree like this +</p><pre>(set (reg V) + (mult (reg Z) + (plus (reg Y) + (plus (reg X) + (reg W))))) +</pre> +where everything is 64-bit ints and we're aiming at +an x86-64. Thanks to the miracle of data-flow analysis, +we know that reg W has no more uses (but reg X and reg Y are still live). So the SU numbering +organizes the tree as above and burg figures out that it +would be cool to generate the following sequence +<pre>rW += rX +rW += rY +AX = rW +AX *= rZ +rV = AX +</pre> +but it doesn't actually rewriting the tree, 'cause that would +be expensive. Instead, when we build the IG, we notice that +AX (the hardware register) must interfere with rZ +and rW must interfere with rY and rZ. Furthermore, +we'd like to coalesce AX with rV and or rW. +And there's some other interferences, depending on +what's alive across the whole tree. +<p> +All normal stuff. +</p><p> +Then we try to allocate. For my example, imagine +we have to spill rW and rX. We rewrite the tree +to show the loads from the stack frame, then +give this tree back to SU numbering, yielding +</p><pre>(set (reg V) + (mult (reg Z) + (plus (load (plus (reg FP) + (const Woffset))) + (plus (load (plus (reg FP) + (const Xoffset))) + (reg Y)))) +</pre> +Notice the SU-numbering has reorganized things so that we can do +the adds directly from memory. Then we redo the burg labelling, +effectively finding the sequence +<pre>rT = rY -- because rY is still live +rT += Xoffset[FP] +rT += Woffset[FP] +AX = rT +AX *= rZ +rV = AX +</pre> +Again, we note interferences and potential coalesces, +and try to color. If we're lucky, we end up with +something like +<pre>AX += Xoffset[FP] +AX += Woffset[FP] +AX *= rZ +</pre> +Of course, we aren't always be so lucky, but that's ok. +The main thing is that the SU-numbering scheduled the +evaluation to minimize register usage and the BURG +stuff found a minimal instruction sequence, including +spill code. +<p> +</p><p> +</p><p> +</p><h2><a name="Benefits"> </a> Benefits </h2> +<p> +The main benefits arise around spill code. +When we spill, we do a better job, so code footprint is smaller and less registers are required, +leading to further savings. +</p><p> +All the spill code is inserted in a machine-independent form, +extending the expression trees, and is then exposed to burg so that it +fits, more-or-less optimally, into the instruction-selection process. +An especially good thing for ciscy machines. +</p><p> +By reconsidering instruction selection across the entire expression +tree after inserting spill code, we're able to get register usage +exactly correct; that is, no temporary registers are allocated where they +aren't necessary and no registers need to be reserved, "just in case". +This sort of thing is easy to get right on a RISC machine; CISC machines +are usually harder. +</p><p> +</p><p> +</p><p>Finally, assuming it can all be described neatly and cleanly, +having a neat and clean description will benefit future maintainers +(versus the current, situation where some passes (e.g., reload) are +considered so scary that maintainers aren't able to work on them +effectively). +</p><p> +</p><p> +</p><p> +</p><h2><a name="What_does_gcc_do_today_"> </a> What does gcc do today? </h2> +<p> +The RTL passes of <a href="http://wiki.corp.google.com/twiki/bin/view/Main/GCC">GCC</a> are described <a href="http://wiki.corp.google.com/twiki/bin/view/Main/ICGPreReloadPasses">here</a> (pre-reload) and <a href="http://wiki.corp.google.com/twiki/bin/view/Main/ICGPostReloadPasses">here</a> (post-reload). +</p><p> +</p><h2><a name="Extended_Sethi_Ullman_numbering"> </a> Extended Sethi-Ullman numbering </h2> +<p> +Part of our scheme is to use an extended form of Sethi-Ullman numbering to schedule evaluation of each RTL tree. See <a href="ExtendedSUNumbering.html">ExtendedSUNumbering</a>. +</p><p> +</p><h2><a name="A_Preprocessor_for_Burg"> </a> A Preprocessor for Burg </h2> +<p>Burg and iburg share an input language, but the input language isn't +really designed for use by humans. Instead, burg was envisioned as a +server with some sort of preprocessor. I built such a thing, called <a href="BurgProcessor.html">plug</a>. +</p><p> +</p><h2><a name="Register_allocation_for_byte_siz"> </a> Register allocation for byte-sized values </h2> +<p> +Vijay Menon reminded me that, on the x86-64, it's possible to +manipulate bytes in the AH, BH, CH, and DH registers and wondered if I +had a plan for them. After some thought, I remembered that I do have a +plan; it's right <a href="http://wiki.corp.google.com/twiki/bin/view/Main/RegisterPairs">here</a>. +</p><p> +</p><p> +</p><h2><a name="References"> </a> References </h2> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/codegen.pdf" target="_top">codegen.pdf</a>: slides for Preston's initial presentation on ideas for the new code generator +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/iburg.pdf" target="_top">iburg.pdf</a>: iburg paper +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/fraser91burg.pdf" target="_top">burg.pdf</a>: paper describing burg +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/p461-proebsting.pdf" target="_top">proebsting.pdf</a>: paper about how to implement burg +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/appel87concise.pdf" target="_top">appel.pdf</a>: how to use tools like burg, with lots of examples +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/ertl.pdf" target="_top">ertl.pdf</a>: a way to do burg-like matching on DAGs +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/sethi-ullman.pdf" target="_top">sethi-ullman.pdf</a>: sethi-ulman numbering +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/aho-johnson.pdf" target="_top">aho-johnson.pdf</a>: how to spill within expression trees +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/coloring.pdf" target="_top">briggs-cooper-torczon.pdf</a>: Improvements to Graph Coloring Register Allocation +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/p300-george.pdf" target="_top">george-appel.pdf</a>: Iterated Register Coalescing +</li> +</ul> +<p> +</p><ul> +<li> <a href="http://wiki.corp.google.com/twiki/pub/Main/NewCodeGenForGCC/p571-hailperin.pdf" target="_top">hailperin.pdf</a>: Comparing Conservative Coalescing Criteria diff --git a/iburg/briggs/doc/TrickyReassociationOfAddressingModes.html b/iburg/briggs/doc/TrickyReassociationOfAddressingModes.html new file mode 100644 index 00000000000..05a7fafac59 --- /dev/null +++ b/iburg/briggs/doc/TrickyReassociationOfAddressingModes.html @@ -0,0 +1,35 @@ +<h1><a name="Tricky_Reassociation_of_Addressi"> </a> Tricky Reassociation of Addressing Modes </h1> +<p> +Given an expression like +</p><pre>r1 + 2*(r2 + 1234) +</pre> +we can reorganize it to fit in a single addressing mode, like this +<pre>r1 + 2*r2 + 2*1234 +</pre> +Currently, I use four grammar rules to catch all the feasible cases: +<pre>addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm8) | mcon)) +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm32) | mcon)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm8), scon)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm32), scon)) +</pre> +where mcon = 1, 2, 4, or 8 and scon = 0, 1, 2, or 3. +<p> +This is a little sloppy, since a imm32*mcon may overflow it's 4-byte encoding. +To avoid this problem, we need to introduce 3 new non-terminals: imm29, imm30, and imm31, with associated rules +</p><pre>addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm29) | CONST_P8)) +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm30) | CONST_P4)) +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm31) | CONST_P2)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm29), CONST_P3)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm30), CONST_P2)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm31), CONST_P1)) +</pre> +We'll need to do something analogous for the imm8. While it can't +really overflow, the cost (size in bytes) can become incorrect if we're +not careful. Therefore, need to introduce 3 more non-terminals: imm5, +imm6, and imm7, with associated rules +<pre>addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm5) | CONST_P8)) +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm6) | CONST_P4)) +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm7) | CONST_P2)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm5), CONST_P3)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm6), CONST_P2)) +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm7), CONST_P1)) diff --git a/iburg/briggs/doc/icg.jpg b/iburg/briggs/doc/icg.jpg Binary files differnew file mode 100644 index 00000000000..696987b545b --- /dev/null +++ b/iburg/briggs/doc/icg.jpg diff --git a/iburg/briggs/icg-build-tree.c b/iburg/briggs/icg-build-tree.c new file mode 100644 index 00000000000..96b479d01ee --- /dev/null +++ b/iburg/briggs/icg-build-tree.c @@ -0,0 +1,1548 @@ +/* Build a side tree for every real INSN, for GNU compiler. + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include "obstack.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "icg.h" +#include "icg-opcode.h" +#include "insn-constants.h" +#include "output.h" + + +/*#define MAX_PARALLEL_KIDS 10*/ + +bool *icg_insn2dirty; +icg_node **icg_insn2tree; +int *icg_insn2goalNT; + +/* The works, setting the op field of icg_node to one of + * icg_opcodes + */ + + +/* Return true iff REG is dead at INSN. This implementation is + imperfect: all defs of registers will get type REGX. Probably less + confusing to give them REGX only if the def is unused. */ + +static +bool reg_dead_p (rtx reg, rtx insn) +{ + /* Register is not dead if the expression has more than one use despite the + * fact that it may be dead after, put in this code. + */ + if (count_occurrences(PATTERN(insn), reg, 0) > 1) + return false; + + /* Register is dead if either data flow says so (REG_DEAD) or if + INSN sets the register. */ + return (find_regno_note (insn, REG_DEAD, REGNO (reg)) != NULL_RTX + || reg_set_p (reg, insn)); + +} + +/* + * Given an rtx expression node, + * return the type modifier for the burg terminal symbol enumeration. + * + * This is where we map gcc types to iburg terminal types. + * The value returned here relies on the careful enumeration + * of the terminals in the x86-64.gr file. + * + * ICG_TSTEP=14 + * The terminal number%ICG_TSTEP is the type. + * The terminal number/ICG_TSTEP is the basic operator. + * + * For example, this is how the PLUS operators type variants + * might be enumerated: + */ +static +icg_opcodes get_operator_mode(rtx rtx_expr) +{ + const enum machine_mode expr_mode = GET_MODE(rtx_expr); + const enum rtx_code expr_code = GET_CODE(rtx_expr); + const bool scalar_equiv = + (expr_code == SET || expr_code == REG || expr_code == MEM); + + int mode; + switch (expr_mode) { + case CCmode: /* basic condition code mode */ + case CCGCmode: /* garbage in Carry flag */ + case CCGOCmode: /* garbage in Carry and Overflow flag */ + case CCNOmode: /* comp with 0 that require Overflow flag to be unset */ + case CCAmode: /* Above flag is valid */ + case CCCmode: /* Carry flag is valid */ + case CCOmode: /* Overflow flag is valid */ + case CCSmode: /* Sign flag is valid */ + case CCZmode: /* Zero flag is valid */ + mode = 0; + break; + + case CCFPmode: + case CCFPUmode: + mode = 0; + break; + + case VOIDmode: + mode = 0; + break; + case DImode : + mode = 0; /* eg _DI */ + break; + case SImode : + mode = 1; /* eg _SI */ + break; + case HImode : + mode = 2; /* eg _HI */ + break; + case QImode : + mode = 3; /* eg _QI */ + break; + + case TImode: /* int128 */ + mode = 4; /* eg _TI */ + break; + case OImode: /* int256 */ + mode = 5; /* eg _OI */ + break; + + case DFmode : + mode = 6; /* eg _DF */ + break; + case SFmode : + mode = 7; /* eg _SF */ + break; + + case V2DImode : /* vector of 2 double word ints (2*uint64) for SSE */ + mode = scalar_equiv ? 6 : 8; /* eg _DF or _VDI */ + break; + case V4SImode : /* vector of 4 single word ints (4*uint32) for SSE */ + mode = scalar_equiv ? 6 : 9; /* eg _DF or _VSI */ + break; + case V8HImode : /* vector of 8 half word ints (8*uint16) for SSE */ + mode = scalar_equiv ? 6 : 10; /* eg _DF or _VHI */ + break; + case V16QImode : /* vector of 16 quarter word ints (16*uint8) for SSE */ + mode = scalar_equiv ? 6 : 11; /* eg _DF or _VQI */ + break; + case V2DFmode : /* vector of 2 ieee64 double (2*double) for SSE */ + mode = scalar_equiv ? 6 : 12; /* eg _DF or _VDF */ + break; + case V4SFmode : /* vector of 4 ieee32 float (4*float) for SSE */ + mode = scalar_equiv ? 6 : 13; /* eg _DF or _VSF */ + break; + + case BLKmode: /* block of memory, as for example __builtin_memmove */ + /* TODO? where's the size information */ + mode = 0; /* only use DI (uint64) grammar encoding */ + break; + + default : + mode = 0; + icg_nyi("get_operator_mode: expr_code=%d/%s expr_mode=%d/%s unhandled", + expr_code, GET_RTX_NAME(expr_code), + expr_mode, GET_MODE_NAME(expr_mode)); + /*NOTREACHED*/ + break; + } + return (icg_opcodes)mode; +} + +struct unspec_code_def { + int unspec_code; + const char *unspec_name; + unsigned icg_terminal; + unsigned char is_type_encoded; +}; + +static +struct unspec_code_def *lookup_unspec_code(int unspec_code) +{ + static struct unspec_code_def *indexable = 0; + static int max_unspec_code = 0; + if (indexable == 0) { + /* + * This table is unsorted and dense. + * We'll lazily copy data in this table + * to a dynamically allocated directly indexable table + * the first time we need the table. + */ + static const struct unspec_code_def unspec_code_def [] = { + {UNSPEC_GOT, "UNSPEC_GOT", ICG_UNSPEC_GOT, 0}, + {UNSPEC_GOTOFF, "UNSPEC_GOTOFF", ICG_UNSPEC_GOTOFF, 0}, + {UNSPEC_GOTPCREL, "UNSPEC_GOTPCREL", ICG_UNSPEC_GOTPCREL, 0}, + {UNSPEC_GOTTPOFF, "UNSPEC_GOTTPOFF", ICG_UNSPEC_GOTTPOFF, 0}, + {UNSPEC_TPOFF, "UNSPEC_TPOFF", ICG_UNSPEC_TPOFF, 0}, + {UNSPEC_NTPOFF, "UNSPEC_NTPOFF", ICG_UNSPEC_NTPOFF, 0}, + {UNSPEC_DTPOFF, "UNSPEC_DTPOFF", ICG_UNSPEC_DTPOFF, 0}, + {UNSPEC_GOTNTPOFF, "UNSPEC_GOTNTPOFF", ICG_UNSPEC_GOTNTPOFF, 0}, + {UNSPEC_INDNTPOFF, "UNSPEC_INDNTPOFF", ICG_UNSPEC_INDNTPOFF, 0}, + {UNSPEC_PLTOFF, "UNSPEC_PLTOFF", ICG_UNSPEC_PLTOFF, 0}, + {UNSPEC_MACHOPIC_OFFSET, "UNSPEC_MACHOPIC_OFFSET", ICG_UNSPEC_MACHOPIC_OFFSET, 0}, + {UNSPEC_STACK_ALLOC, "UNSPEC_STACK_ALLOC", ICG_UNSPEC_STACK_ALLOC, 0}, + {UNSPEC_SET_GOT, "UNSPEC_SET_GOT", ICG_UNSPEC_SET_GOT, 0}, + {UNSPEC_SSE_PROLOGUE_SAVE, "UNSPEC_SSE_PROLOGUE_SAVE", ICG_UNSPEC_SSE_PROLOGUE_SAVE, 0}, + {UNSPEC_REG_SAVE, "UNSPEC_REG_SAVE", ICG_UNSPEC_REG_SAVE, 0}, + {UNSPEC_DEF_CFA, "UNSPEC_DEF_CFA", ICG_UNSPEC_DEF_CFA, 0}, + {UNSPEC_SET_RIP, "UNSPEC_SET_RIP", ICG_UNSPEC_SET_RIP, 0}, + {UNSPEC_SET_GOT_OFFSET, "UNSPEC_SET_GOT_OFFSET", ICG_UNSPEC_SET_GOT_OFFSET, 0}, + {UNSPEC_TP, "UNSPEC_TP", ICG_UNSPEC_TP, 0}, + {UNSPEC_TLS_GD, "UNSPEC_TLS_GD", ICG_UNSPEC_TLS_GD, 0}, + {UNSPEC_TLS_LD_BASE, "UNSPEC_TLS_LD_BASE", ICG_UNSPEC_TLS_LD_BASE, 0}, + {UNSPEC_TLSDESC, "UNSPEC_TLSDESC", ICG_UNSPEC_TLSDESC, 0}, + {UNSPEC_SCAS, "UNSPEC_SCAS", ICG_UNSPEC_SCAS, 0}, + {UNSPEC_FNSTSW, "UNSPEC_FNSTSW", ICG_UNSPEC_FNSTSW, 0}, + {UNSPEC_SAHF, "UNSPEC_SAHF", ICG_UNSPEC_SAHF, 0}, + {UNSPEC_FSTCW, "UNSPEC_FSTCW", ICG_UNSPEC_FSTCW, 0}, + {UNSPEC_ADD_CARRY, "UNSPEC_ADD_CARRY", ICG_UNSPEC_ADD_CARRY_DI, 1}, /* icg type specific */ + {UNSPEC_FLDCW, "UNSPEC_FLDCW", ICG_UNSPEC_FLDCW, 0}, + {UNSPEC_REP, "UNSPEC_REP", ICG_UNSPEC_REP, 0}, + {UNSPEC_EH_RETURN, "UNSPEC_EH_RETURN", ICG_UNSPEC_EH_RETURN, 0}, + {UNSPEC_LD_MPIC, "UNSPEC_LD_MPIC", ICG_UNSPEC_LD_MPIC, 0}, + {UNSPEC_TRUNC_NOOP, "UNSPEC_TRUNC_NOOP", ICG_UNSPEC_TRUNC_NOOP, 0}, + {UNSPEC_FIX_NOTRUNC, "UNSPEC_FIX_NOTRUNC", ICG_UNSPEC_FIX_NOTRUNC, 0}, + {UNSPEC_PFRCPIT1, "UNSPEC_PFRCPIT1", ICG_UNSPEC_PFRCPIT1, 0}, + {UNSPEC_MASKMOV, "UNSPEC_MASKMOV", ICG_UNSPEC_MASKMOV, 0}, + {UNSPEC_PFRCPIT2, "UNSPEC_PFRCPIT2", ICG_UNSPEC_PFRCPIT2, 0}, + {UNSPEC_MOVMSK, "UNSPEC_MOVMSK", ICG_UNSPEC_MOVMSK, 0}, + {UNSPEC_PFRSQRT, "UNSPEC_PFRSQRT", ICG_UNSPEC_PFRSQRT, 0}, + {UNSPEC_MOVNT, "UNSPEC_MOVNT", ICG_UNSPEC_MOVNT, 0}, + {UNSPEC_PFRSQIT1, "UNSPEC_PFRSQIT1", ICG_UNSPEC_PFRSQIT1, 0}, + {UNSPEC_MFENCE, "UNSPEC_MFENCE", ICG_UNSPEC_MFENCE, 0}, + {UNSPEC_MOVU, "UNSPEC_MOVU", ICG_UNSPEC_MOVU, 0}, + {UNSPEC_LFENCE, "UNSPEC_LFENCE", ICG_UNSPEC_LFENCE, 0}, + {UNSPEC_RCP, "UNSPEC_RCP", ICG_UNSPEC_RCP, 0}, + {UNSPEC_PSADBW, "UNSPEC_PSADBW", ICG_UNSPEC_PSADBW, 0}, + {UNSPEC_RSQRT, "UNSPEC_RSQRT", ICG_UNSPEC_RSQRT, 0}, + {UNSPEC_LDDQU, "UNSPEC_LDDQU", ICG_UNSPEC_LDDQU, 0}, + {UNSPEC_SFENCE, "UNSPEC_SFENCE", ICG_UNSPEC_SFENCE, 0}, + {UNSPEC_PFRCP, "UNSPEC_PFRCP", ICG_UNSPEC_PFRCP, 0}, + {UNSPEC_COPYSIGN, "UNSPEC_COPYSIGN", ICG_UNSPEC_COPYSIGN, 0}, + {UNSPEC_IEEE_MIN, "UNSPEC_IEEE_MIN", ICG_UNSPEC_IEEE_MIN_DI, 1}, /* icg type specific */ + {UNSPEC_IEEE_MAX, "UNSPEC_IEEE_MAX", ICG_UNSPEC_IEEE_MAX_DI, 1}, /* icg type specific */ + {UNSPEC_SIN, "UNSPEC_SIN", ICG_UNSPEC_SIN, 0}, + {UNSPEC_COS, "UNSPEC_COS", ICG_UNSPEC_COS, 0}, + {UNSPEC_FPATAN, "UNSPEC_FPATAN", ICG_UNSPEC_FPATAN, 0}, + {UNSPEC_FYL2X, "UNSPEC_FYL2X", ICG_UNSPEC_FYL2X, 0}, + {UNSPEC_FYL2XP1, "UNSPEC_FYL2XP1", ICG_UNSPEC_FYL2XP1, 0}, + {UNSPEC_FRNDINT, "UNSPEC_FRNDINT", ICG_UNSPEC_FRNDINT, 0}, + {UNSPEC_FIST, "UNSPEC_FIST", ICG_UNSPEC_FIST, 0}, + {UNSPEC_F2XM1, "UNSPEC_F2XM1", ICG_UNSPEC_F2XM1, 0}, + {UNSPEC_TAN, "UNSPEC_TAN", ICG_UNSPEC_TAN, 0}, + {UNSPEC_FXAM, "UNSPEC_FXAM", ICG_UNSPEC_FXAM, 0}, + {UNSPEC_FRNDINT_FLOOR, "UNSPEC_FRNDINT_FLOOR", ICG_UNSPEC_FRNDINT_FLOOR, 0}, + {UNSPEC_FRNDINT_CEIL, "UNSPEC_FRNDINT_CEIL", ICG_UNSPEC_FRNDINT_CEIL, 0}, + {UNSPEC_FRNDINT_TRUNC, "UNSPEC_FRNDINT_TRUNC", ICG_UNSPEC_FRNDINT_TRUNC, 0}, + {UNSPEC_FRNDINT_MASK_PM, "UNSPEC_FRNDINT_MASK_PM", ICG_UNSPEC_FRNDINT_MASK_PM, 0}, + {UNSPEC_FIST_FLOOR, "UNSPEC_FIST_FLOOR", ICG_UNSPEC_FIST_FLOOR, 0}, + {UNSPEC_FIST_CEIL, "UNSPEC_FIST_CEIL", ICG_UNSPEC_FIST_CEIL, 0}, + {UNSPEC_SINCOS_COS, "UNSPEC_SINCOS_COS", ICG_UNSPEC_SINCOS_COS, 0}, + {UNSPEC_SINCOS_SIN, "UNSPEC_SINCOS_SIN", ICG_UNSPEC_SINCOS_SIN, 0}, + {UNSPEC_XTRACT_FRACT, "UNSPEC_XTRACT_FRACT", ICG_UNSPEC_XTRACT_FRACT, 0}, + {UNSPEC_XTRACT_EXP, "UNSPEC_XTRACT_EXP", ICG_UNSPEC_XTRACT_EXP, 0}, + {UNSPEC_FSCALE_FRACT, "UNSPEC_FSCALE_FRACT", ICG_UNSPEC_FSCALE_FRACT, 0}, + {UNSPEC_FSCALE_EXP, "UNSPEC_FSCALE_EXP", ICG_UNSPEC_FSCALE_EXP, 0}, + {UNSPEC_FPREM_F, "UNSPEC_FPREM_F", ICG_UNSPEC_FPREM_F, 0}, + {UNSPEC_FPREM_U, "UNSPEC_FPREM_U", ICG_UNSPEC_FPREM_U, 0}, + {UNSPEC_FPREM1_F, "UNSPEC_FPREM1_F", ICG_UNSPEC_FPREM1_F, 0}, + {UNSPEC_FPREM1_U, "UNSPEC_FPREM1_U", ICG_UNSPEC_FPREM1_U, 0}, + {UNSPEC_C2_FLAG, "UNSPEC_C2_FLAG", ICG_UNSPEC_C2_FLAG, 0}, + {UNSPEC_SP_SET, "UNSPEC_SP_SET", ICG_UNSPEC_SP_SET, 0}, + {UNSPEC_SP_TEST, "UNSPEC_SP_TEST", ICG_UNSPEC_SP_TEST, 0}, + {UNSPEC_SP_TLS_SET, "UNSPEC_SP_TLS_SET", ICG_UNSPEC_SP_TLS_SET, 0}, + {UNSPEC_SP_TLS_TEST, "UNSPEC_SP_TLS_TEST", ICG_UNSPEC_SP_TLS_TEST, 0}, + {UNSPEC_PSHUFB, "UNSPEC_PSHUFB", ICG_UNSPEC_PSHUFB, 0}, + {UNSPEC_PSIGN, "UNSPEC_PSIGN", ICG_UNSPEC_PSIGN, 0}, + {UNSPEC_PALIGNR, "UNSPEC_PALIGNR", ICG_UNSPEC_PALIGNR, 0}, + {UNSPEC_EXTRQI, "UNSPEC_EXTRQI", ICG_UNSPEC_EXTRQI, 0}, + {UNSPEC_EXTRQ, "UNSPEC_EXTRQ", ICG_UNSPEC_EXTRQ, 0}, + {UNSPEC_INSERTQI, "UNSPEC_INSERTQI", ICG_UNSPEC_INSERTQI, 0}, + {UNSPEC_INSERTQ, "UNSPEC_INSERTQ", ICG_UNSPEC_INSERTQ, 0}, + {UNSPEC_BLENDV, "UNSPEC_BLENDV", ICG_UNSPEC_BLENDV, 0}, + {UNSPEC_INSERTPS, "UNSPEC_INSERTPS", ICG_UNSPEC_INSERTPS, 0}, + {UNSPEC_DP, "UNSPEC_DP", ICG_UNSPEC_DP, 0}, + {UNSPEC_MOVNTDQA, "UNSPEC_MOVNTDQA", ICG_UNSPEC_MOVNTDQA, 0}, + {UNSPEC_MPSADBW, "UNSPEC_MPSADBW", ICG_UNSPEC_MPSADBW, 0}, + {UNSPEC_PHMINPOSUW, "UNSPEC_PHMINPOSUW", ICG_UNSPEC_PHMINPOSUW, 0}, + {UNSPEC_PTEST, "UNSPEC_PTEST", ICG_UNSPEC_PTEST, 0}, + {UNSPEC_ROUND, "UNSPEC_ROUND", ICG_UNSPEC_ROUND, 0}, + {UNSPEC_CRC32, "UNSPEC_CRC32", ICG_UNSPEC_CRC32, 0}, + {UNSPEC_PCMPESTR, "UNSPEC_PCMPESTR", ICG_UNSPEC_PCMPESTR, 0}, + {UNSPEC_PCMPISTR, "UNSPEC_PCMPISTR", ICG_UNSPEC_PCMPISTR, 0}, + {UNSPEC_SSE5_INTRINSIC, "UNSPEC_SSE5_INTRINSIC", ICG_UNSPEC_SSE5_INTRINSIC, 0}, + {UNSPEC_SSE5_UNSIGNED_CMP, "UNSPEC_SSE5_UNSIGNED_CMP", ICG_UNSPEC_SSE5_UNSIGNED_CMP, 0}, + {UNSPEC_SSE5_TRUEFALSE, "UNSPEC_SSE5_TRUEFALSE", ICG_UNSPEC_SSE5_TRUEFALSE, 0}, + {UNSPEC_SSE5_PERMUTE, "UNSPEC_SSE5_PERMUTE", ICG_UNSPEC_SSE5_PERMUTE, 0}, + {UNSPEC_FRCZ, "UNSPEC_FRCZ", ICG_UNSPEC_FRCZ, 0}, + {UNSPEC_CVTPH2PS, "UNSPEC_CVTPH2PS", ICG_UNSPEC_CVTPH2PS, 0}, + {UNSPEC_CVTPS2PH, "UNSPEC_CVTPS2PH", ICG_UNSPEC_CVTPS2PH, 0}, + {UNSPEC_AESENC, "UNSPEC_AESENC", ICG_UNSPEC_AESENC, 0}, + {UNSPEC_AESENCLAST, "UNSPEC_AESENCLAST", ICG_UNSPEC_AESENCLAST, 0}, + {UNSPEC_AESDEC, "UNSPEC_AESDEC", ICG_UNSPEC_AESDEC, 0}, + {UNSPEC_AESDECLAST, "UNSPEC_AESDECLAST", ICG_UNSPEC_AESDECLAST, 0}, + {UNSPEC_AESIMC, "UNSPEC_AESIMC", ICG_UNSPEC_AESIMC, 0}, + {UNSPEC_AESKEYGENASSIST, "UNSPEC_AESKEYGENASSIST", ICG_UNSPEC_AESKEYGENASSIST, 0}, + {UNSPEC_PCLMUL, "UNSPEC_PCLMUL", ICG_UNSPEC_PCLMUL, 0}, + {UNSPEC_PCMP, "UNSPEC_PCMP", ICG_UNSPEC_PCMP, 0}, + {UNSPEC_VPERMIL, "UNSPEC_VPERMIL", ICG_UNSPEC_VPERMIL, 0}, + {UNSPEC_VPERMIL2, "UNSPEC_VPERMIL2", ICG_UNSPEC_VPERMIL2, 0}, + {UNSPEC_VPERMIL2F128, "UNSPEC_VPERMIL2F128", ICG_UNSPEC_VPERMIL2F128, 0}, + {UNSPEC_MASKLOAD, "UNSPEC_MASKLOAD", ICG_UNSPEC_MASKLOAD, 0}, + {UNSPEC_MASKSTORE, "UNSPEC_MASKSTORE", ICG_UNSPEC_MASKSTORE, 0}, + {UNSPEC_CAST, "UNSPEC_CAST", ICG_UNSPEC_CAST, 0}, + {UNSPEC_VTESTP, "UNSPEC_VTESTP", ICG_UNSPEC_VTESTP, 0}, + }; + size_t i; + for (i = 0; i < sizeof(unspec_code_def)/sizeof(unspec_code_def[0]); i++) { + if (unspec_code_def[i].unspec_code > max_unspec_code) { + max_unspec_code = unspec_code_def[i].unspec_code; + } + } + indexable = XNEWVEC(struct unspec_code_def, (max_unspec_code + 1)); + for (i = 0; i < sizeof(unspec_code_def)/sizeof(unspec_code_def[0]); i++) { + indexable[unspec_code_def[i].unspec_code] = unspec_code_def[i]; + } + } + gcc_assert(0 <= unspec_code); + gcc_assert(unspec_code <= max_unspec_code); + return &indexable[unspec_code]; +} + +/* + * This finds the icg_opcode based on a + * combination of machine mode and rtx code. + * See icg-opcode.h (in the build directory) + * for the list of icg_opcodes. + */ +static +icg_opcodes get_operator(rtx rtx_expr, rtx curr_insn) +{ + const enum rtx_code expr_code = GET_CODE(rtx_expr); + /* + * The variable op will start off in the range 0..9. + * For example, DI mode will have op==0; SI mode will have op==1, etc. + */ + icg_opcodes op = get_operator_mode(rtx_expr); + + /* + * TODO: Translation of floating point compares requires a bit of context + * in order to use the cmpsd instruction (double < double) ==> uint64 in xmm + */ + const enum machine_mode expr_mode = GET_MODE(rtx_expr); + const enum machine_mode insn_mode = GET_MODE(curr_insn); + + /* + * perhaps there is a macro in gcc rtl that already determines + * if a mode is floating point. + * This has been disabled, as determining whether or not to use FLT_BASE + * is context sensitive. + */ + const bool d2 = 0 && ((expr_mode == SFmode && insn_mode == SFmode) || + (expr_mode == DFmode && insn_mode == DFmode) + ) + ; + + switch (expr_code) + { + case PARALLEL : + op = PARALLEL_ALL; + break; + + case SET : + op = SET_ALL; + break; + + case USE : + op = USE_ALL; + break; + + case CALL : + op = CALL_ALL; + break; + + case CONST: + op += CONST_DI; + break; + + case CONST_DOUBLE: + if (expr_mode == DFmode) { + op = CONSTIEEE64; + } else { + op = CONSTIEEE32; + } + break; + + case CONST_INT : + { + /* + * Encode special values into specific terminal symbols. + */ + const long long number = INTVAL(rtx_expr); + op = icg_op_of_constant(number); + break; + } + + case REG : + { + /* + * Set REGX or REG depending on whether the rtx expression + * is dead or not + */ + switch (expr_mode) { + case CCmode: + case CCGCmode: + case CCGOCmode: + case CCNOmode: + case CCAmode: + case CCCmode: + case CCOmode: + case CCSmode: + case CCZmode: + if (reg_dead_p(rtx_expr, curr_insn)) { + op += REGCCX_DI; + } else { + op += REGCC_DI; + } + break; + case CCFPmode: + case CCFPUmode: + if (reg_dead_p(rtx_expr, curr_insn)) { + op += REGCCFPUX_DI; + } else { + op += REGCCFPU_DI; + } + break; + default: + if (reg_dead_p(rtx_expr, curr_insn)) { + op += REGX_DI; + } else { + op += REG_DI; + } + break; + } + break; + } + + case PREFETCH: + op += PREFETCH_DI; + break; + + case MEM : + if (expr_mode == BLKmode) { + op += MEMB_DI; + } else { + op += MEM_DI; + } + break; + + case ZERO_EXTEND : + op += ZERO_EXTEND_DI; + break; + case SIGN_EXTEND : + op += SIGN_EXTEND_DI; + break; + case SUBREG : + op += SUBREG_DI; + break; + case PLUS : + op += PLUS_DI; + break; + case MINUS : + op += MINUS_DI; + break; + case NEG : + op += NEG_DI; + break; + case MULT : + op += MULT_DI; + break; + case DIV : + op += DIV_DI; + break; + case UDIV : + op += UDIV_DI; + break; + case MOD : + op += MOD_DI; + break; + case UMOD : + op += UMOD_DI; + break; + case NOT : + op += NOT_DI; + break; + case AND : + op += AND_DI; + break; + case IOR : + op += IOR_DI; + break; + case XOR : + op += XOR_DI; + break; + case ASHIFT : /* arithmetic left shift */ + op += ASHIFT_DI; + break; + case LSHIFTRT : /* logical right shift */ + op += LSHIFTRT_DI; + break; + case ASHIFTRT : /* arithmetic right shift */ + op += ASHIFTRT_DI; + break; + case SMIN : + op += SMIN_DI; + break; + case SMAX : + op += SMAX_DI; + break; + case UMIN : + op += UMIN_DI; + break; + case UMAX : + op += UMAX_DI; + break; + case ROTATE : + op += ROTATE_DI; + break; + case ROTATERT : + op += ROTATERT_DI; + break; + case CLZ : + op += CLZ_DI; + break; + case POPCOUNT : + op += POPCOUNT_DI; + break; + + case FIX : + op += FIX_DI; + break; + case TRUNCATE: + op += TRUNCATE_DI; + break; + case FLOAT : + op += FLOAT_BASE; /* will get smashed to FLOAT_SF or FLOAT_DF */ + break; + case FLOAT_TRUNCATE: /* converting double to float */ + op += FLOAT_TRUNCATE_BASE; + break; + case FLOAT_EXTEND: /* converting float to double */ + op += FLOAT_EXTEND_BASE; + break; + case IF_THEN_ELSE : + /* Specially handled by looking at its 3 kids */ + break; + + case SYMBOL_REF : + /* From rtl.def: + Reference to a named label: + Operand 0: label name + Operand 1: flags (see SYMBOL_FLAG_* in rtl.h) + Operand 2: tree from which this symbol is derived, or null. + This is either a DECL node, or some kind of constant. */ + if (flag_pic) { + op += SYMBOL_REF_64; + } else { + op += SYMBOL_REF_32; + } + break; + + case LABEL_REF : + /* From rtl.def: + Reference to an assembler label in the code for this function. + The operand is a CODE_LABEL found in the insn chain. */ + op += LABEL_REF_DI; + break; + + /* + * scalar and floating point ordered comparisions, yielding condition code + * floating point ordered comparision, yielding xmm register (cmpsd) + * This was scaffolded in around 10Oct2008, and still needed work then. + */ + case EQ : + if (d2) { + op += FEQ_BASE; + } else { + op = EQ_ALL; + } + break; + case NE : + if (d2) { + op += FNEQ_BASE; + } else { + op = NE_ALL; + } + break; + + case GT : + if (d2) { + op += FGT_BASE; /* will be done as FLE with swapped operands */ + } else { + const rtx rtx_lchild = XEXP(rtx_expr, 0); + const enum machine_mode lmode = GET_MODE(rtx_lchild); + const bool is_ccfpu = (GET_CODE(rtx_lchild) == REG && lmode == CCFPUmode); + if (is_ccfpu) { + op = UNGT_ALL; + } else { + op = GT_ALL; + } + } + break; + case GTU : /* > unsigned */ + op = GTU_ALL; + break; + + case LT : + if (d2) { + op += FLT_BASE; + } else { + const rtx rtx_lchild = XEXP(rtx_expr, 0); + const enum machine_mode lmode = GET_MODE(rtx_lchild); + const bool is_ccfpu = (GET_CODE(rtx_lchild) == REG && lmode == CCFPUmode); + if (is_ccfpu) { + op = UNLT_ALL; + } else { + op = LT_ALL; + } + if (expr_mode == CCGOCmode) { + op = LTS_ALL; /* TODO: incomplete: added to support uint64->double conversion */ + } + } + break; + case LTU : /* < unsigned */ + op = LTU_ALL; + break; + + case GE : + if (d2) { + op += FGE_BASE; /* will be done as FLT with swapped operands */ + } else { + const rtx rtx_lchild = XEXP(rtx_expr, 0); + const enum machine_mode lmode = GET_MODE(rtx_lchild); + const bool is_ccfpu = (GET_CODE(rtx_lchild) == REG && lmode == CCFPUmode); + if (is_ccfpu) { + op = UNGE_ALL; /* do as an unordered floating compare */ + } else { + op = GE_ALL; /* TODO: in some cases, should be done as a unordered floating compare */ + } + } + break; + case GEU : /* >= unsigned */ + op = GEU_ALL; + break; + + case LE : + if (d2) { + op += FLE_BASE; + } else { + const rtx rtx_lchild = XEXP(rtx_expr, 0); + const enum machine_mode lmode = GET_MODE(rtx_lchild); + const bool is_ccfpu = (GET_CODE(rtx_lchild) == REG && lmode == CCFPUmode); + if (is_ccfpu) { + op = UNLE_ALL; + } else { + op = LE_ALL; + } + } + break; + case LEU : /* <= unsigned */ + op = LEU_ALL; + break; + + /* + * floating point unordered comparisions, yielding condition code + */ + case UNEQ: /* == unordered */ + op = UNEQ_ALL; + break; + case UNGE: /* >= unordered */ + op = UNGE_ALL; + break; + case UNGT: /* > unordered */ + op = UNGT_ALL; + break; + case UNLE: /* <= unordered */ + op = UNLE_ALL; + break; + case UNLT: /* < unordered */ + op = UNLT_ALL; + break; + case LTGT: /* <> unordered (aka? != unordered) */ + op = LTGT_ALL; + break; + case UNORDERED: + op = UNORDERED_ALL; + break; + case ORDERED: + op = ORDERED_ALL; + break; + + case PC : + op = PC_ALL; + break; + + case COMPARE : + op = COMPARE_CC; + break; + + case UNSPEC: + { + const int unspec_code = XINT(rtx_expr, 1); + const struct unspec_code_def *def = lookup_unspec_code(unspec_code); + switch (unspec_code) { + case UNSPEC_GOTPCREL: + op += flag_pic ? SYMBOL_REF_64 : SYMBOL_REF_32; + gcc_assert (XVECLEN (rtx_expr, 0) == 1); + gcc_assert (GET_CODE (XVECEXP (rtx_expr, 0, 0)) == SYMBOL_REF); + break; + default: + icg_nyi("unhandled unspec_code=%d/%s", + unspec_code, def->unspec_name); + break; + } + } + break; + + case ASM_OPERANDS: /* should be rewritten and never seen by now */ + case CONST_VECTOR: + case CONST_FIXED: + default : + if (dump_file) { + fprintf(dump_file, "\n"); + fprintf(dump_file, "Build-Tree Phase Error: In RTL instruction:\n"); + print_inline_rtx(dump_file, curr_insn, 2); + fprintf(dump_file, "\n"); + fprintf(dump_file, + "%s:%d: RTX Opcode: %s not matched in ICG grammar ... Quitting\n", + __FILE__, __LINE__, + GET_RTX_NAME(expr_code)); + fflush(dump_file); + } + icg_nyi("get_operator: expr_code=%d/%s unhandled", + expr_code, GET_RTX_NAME(expr_code)); + /*NOTREACHED*/ + break; + } + return op; +} + +static +bool set_unused_p (rtx set_expr, rtx curr_insn) +{ + rtx notes_rtx; + rtx reg_expr = XEXP(set_expr, 0); + if (GET_CODE(reg_expr)!=REG) { + return false; + } + for (notes_rtx=XEXP(curr_insn, 7); notes_rtx; notes_rtx=XEXP(notes_rtx, 1)) { + gcc_assert(GET_CODE(notes_rtx)==EXPR_LIST); + { + rtx reg_rtx = XEXP(notes_rtx, 0); + if (REG_NOTE_KIND(notes_rtx)==REG_UNUSED && REGNO(reg_rtx)==REGNO(reg_expr)) { + return true; + } + } + } + return false; +} + +/* Allocate a new icg_node. If expr is not NULL, then various fields + are filled in based on the RTL expression. */ +static +icg_node * icg_node_alloc (icg_opcodes op, rtx insn, rtx expr) +{ + icg_node *p; + p = (icg_node *)icg_calloc(sizeof(icg_node)); + p->op = op; + p->insn = insn; + if (expr != NULL) { + const enum rtx_code expr_code = GET_CODE(expr); + p->rtl = expr; + p->mode = GET_MODE (expr); /* TODO: deprecated; only used in one place in icg.c */ + /* Set specific fields for specific node types. */ + switch (expr_code) { + case REG: + p->r = REGNO (expr); + p->rx = REGNO (expr); + break; + + case CONST_INT: + p->val = INTVAL (expr); + p->a.string = NULL; + break; + + case CONST_DOUBLE: + { + /* + * This code is likely to be extremely fragile, + * and not survive rehosting to a host machine other than x86_64, + * or to a host machine with a different endianness than x86_64. + */ + const enum machine_mode expr_mode = GET_MODE(expr); + if (GET_MODE (expr) == DFmode) { + long vals[4]; + typedef unsigned long long uint64; + REAL_VALUE_TYPE rv = *CONST_DOUBLE_REAL_VALUE(expr); + REAL_VALUE_TO_TARGET_DOUBLE(rv, vals); + if (0) { + fprintf(stderr, "v[0]=%ld = 0x%016lx\n", vals[0], vals[0]); + fprintf(stderr, "v[1]=%ld = 0x%016lx\n", vals[1], vals[1]); + fprintf(stderr, "v[2]=%ld = 0x%016lx\n", vals[2], vals[2]); + fprintf(stderr, "v[3]=%ld = 0x%016lx\n", vals[3], vals[3]); + } + p->val = 0ULL + | (((uint64)(vals[1]) & 0xffffffffULL) << 32) + | (((uint64)(vals[0]) & 0xffffffffULL) << 00) + ; + } else if (GET_MODE (expr) == SFmode) { + long val; + typedef unsigned long long uint64; + REAL_VALUE_TYPE rv = *CONST_DOUBLE_REAL_VALUE(expr); + REAL_VALUE_TO_TARGET_SINGLE(rv, val); + p->val = val; + } else { + icg_nyi("get_operator: expr_code=%d/%s mode=%d/%s unhandled", + expr_code, GET_RTX_NAME(expr_code), + expr_mode, GET_MODE_NAME(expr_mode)); + /*NOTREACHED*/ + } + p->a.string = NULL; + } + break; + + case CONST_VECTOR: + case CONST_FIXED: + icg_nyi("get_operator: expr_code=%d/%s", + expr_code, GET_RTX_NAME(expr_code)); + /*NOTREACHED*/ + break; + + case SYMBOL_REF: + /* From rtl.def: + Reference to a named label: + Operand 0: label name + Operand 1: flags (see SYMBOL_FLAG_* in rtl.h) + Operand 2: tree from which this symbol is derived, or null. + This is either a DECL node, or some kind of constant. */ + if (flag_pic) { + op += SYMBOL_REF_64; + } else { + op += SYMBOL_REF_32; + } + p->a.string = XSTR (expr, 0); + p->val = 0; + break; + + case LABEL_REF: + /* From rtl.def: + Reference to an assembler label in the code for this function. + The operand is a CODE_LABEL found in the insn chain. */ + op += LABEL_REF_DI; + p->a.string = "???LABEL_REF???"; + p->a.string = 0; + p->val = CODE_LABEL_NUMBER (XEXP (expr, 0)); + break; + + default: + break; + } + } + return p; +} + +/* + * Return 1 if ICG can handle this asm somehow. + */ +int icg_analyze_asm(rtx expr, icg_analyze_asm_key how) +{ +/* This comment about ASM_OPERANDS accessor functions is lifted from rtl.def + An assembler instruction with operands. + 1st operand is the instruction template. + 2nd operand is the constraint for the output. + 3rd operand is the number of the output this expression refers to. + When an insn stores more than one value, a separate ASM_OPERANDS + is made for each output; this integer distinguishes them. + 4th is a vector of values of input operands. + 5th is a vector of modes and constraints for the input operands. + Each element is an ASM_INPUT containing a constraint string + and whose mode indicates the mode of the input operand. + 6th is the source line number. */ +#if 0 + 0 ASM_OPERANDS_TEMPLATE + 1 ASM_OPERANDS_OUTPUT_CONSTRAINT + 2 ASM_OPERANDS_OUTPUT_IDX + 3 ASM_OPERANDS_INPUT_VEC + 4 ASM_OPERANDS_INPUT_CONSTRAINT_VEC + 3,N ASM_OPERANDS_INPUT + 3 ASM_OPERANDS_INPUT_LENGTH + 4,N ASM_OPERANDS_INPUT_CONSTRAINT_EXP + 4,N ASM_OPERANDS_INPUT_CONSTRAINT + 4,N ASM_OPERANDS_INPUT_MODE + 5, ASM_OPERANDS_SOURCE_LOCATION + 1, ASM_INPUT_SOURCE_LOCATION +#endif + const enum rtx_code code = GET_CODE(expr); + gcc_assert (code == ASM_OPERANDS); + { + const char *template = ASM_OPERANDS_TEMPLATE(expr); + const char *output_constraint = ASM_OPERANDS_OUTPUT_CONSTRAINT(expr); + const int output_idx = ASM_OPERANDS_OUTPUT_IDX(expr); + const rtvec input_vec = ASM_OPERANDS_INPUT_VEC(expr); + const rtvec input_constraint_vec = ASM_OPERANDS_INPUT_CONSTRAINT_VEC(expr); + const int ninputs = ASM_OPERANDS_INPUT_LENGTH(expr); + const int line_source = ASM_OPERANDS_SOURCE_LOCATION(expr); + const int line_input = ASM_INPUT_SOURCE_LOCATION(expr); + rtx inputs[20]; + const char *input_constraint[20]; + int i; + const char *cp; + unsigned ok = 1; + + (void)line_input; + (void)line_source; + (void)input_constraint_vec; + (void)input_vec; + + memset(inputs, 0, sizeof(inputs)); + memset(input_constraint, 0, sizeof(input_constraint)); + for (i = 0; i < ninputs; i++) { + inputs[i] = ASM_OPERANDS_INPUT(expr, i); + input_constraint[i] = ASM_OPERANDS_INPUT_CONSTRAINT(expr, i); + } + + if (output_idx != 0) { + return 0; /* do not accept */ + } + + if (output_constraint == 0 || output_constraint[0] == 0) { + if (ninputs == 0) { + /* example: __asm__ __volatile___("mfence" : : : "memory"); */ + if (how == ICG_ASM_PHASE_DEBUG) { + fprintf(dump_file, "\t%s\t; %s\n", template, "crock: ICG_ASM_NULLARY"); + } + return 1; /* accept */ + } + return 0; /* do not accept */ + } + + /* + * We expect there to be one output and it should be modifiable + */ + if (*output_constraint != '=') { + return 0; + } + + if (0) { + /* + * look for multiple register source operands, single register destination operand + * Example: + * __asm__("bsr %1, %0\n\t" "cmovz %2, %0" : "=&r" (bits) : "ro" (v), "r" (neg1) : "cc"); + * + * We'll treat this as a 2 register src operand , 1 register dst operand instruction + * even though the "ro" says the 1st source operand can come from "o"ffsetable memory. + */ + ok = 1; + for (cp = output_constraint; *cp; cp++) { + switch (*cp) { + case '=': + case '&': + case 'r': + ok &= 1; + break; + default: + ok = 0; + break; + } + } + for (i = 0; i < ninputs; i++) { + unsigned input_ok = 0; + for (cp = input_constraint[i]; *cp; cp++) { + switch (*cp) { + case 'r': + input_ok = 1; + break; + default: + break; + } + } + ok &= input_ok; + } + + if (ok) { + return 2; /* accept, using generic binary operator ASM_BINARY_RRR */ + } + } + + } + + return 0; /* do not accept */ +} + +/* + * Return the number of subexpressions in X. + * We're peeking inside the structure of rtx (ugh), + * but there doesn't seem to be a better way. + */ +static +int count_subexpressions (rtx x) +{ + /* Count the number of 'e's in the format string. */ + const char *format_str = GET_RTX_FORMAT (GET_CODE (x)); + int i, n = 0; + for (i = 0; format_str[i]; i++) { + if (format_str[i] == 'e') { + /* + * If X has any 'e's, they should be all at the beginning of the + * string (I think). + */ + gcc_assert (n == i); + n++; + } + } + return n; +} + +/* + * Translate rtl subexpression EXPR of INSN and return a newly + * constructed icg node. + * This is where the bulk of the work gets done. + */ +static +icg_node *translate_expression (rtx expr, rtx insn) +{ + icg_node *inode = NULL; + enum rtx_code expr_code; + + gcc_assert (expr != NULL_RTX); + expr_code = GET_CODE (expr); + + /* Handle special cases explicitly (PARALLEL, CALL, etc) where there + is not a one-to-one mapping between rtx nodes and icg tree + nodes. */ + + if (expr_code == SET + && (GET_CODE (SET_DEST (expr)) == PARALLEL)) { + /* SET (PARALLEL(expr_list (a, X), expr_list(b, Y)...) , CALL (...) + => SET (LIST_ALL (DEF_ALL (a), LIST_ALL ...)) + CALL ( ... ) + + This structure appears if the function call returns a + structure. In this case the destination of the SET is a + PARALLEL of expr_list. Each expr_list has "mode" + REG_DEP_TRUE. */ + int i; + icg_node **tail; + rtx par_expr = SET_DEST (expr); + inode = icg_node_alloc (SET_ALL, insn, expr); + inode->right = translate_expression (SET_SRC (expr), insn); + tail = &(inode->left); + for (i = 0; i < XVECLEN (par_expr, 0); i ++) { + rtx vexpr = XVECEXP (par_expr, 0, i); + /* Verify that element is an expr_list of mode REG_DEP_TRUE. */ + gcc_assert (GET_CODE (vexpr) == EXPR_LIST); + gcc_assert (GET_MODE (vexpr) == REG_DEP_TRUE); + gcc_assert (REG_P (XEXP (vexpr, 0))); + *tail = icg_node_alloc (LIST_ALL, insn, NULL); + (*tail)->left = icg_node_alloc (DEF_ALL, insn, NULL); + (*tail)->left->left = translate_expression (XEXP (vexpr, 0), insn); + tail = &((*tail)->right); + } + /* Verify that at least one element is in the LIST_ALL. */ + gcc_assert (tail != &(inode->left)); + /* Terminate list. */ + *tail = icg_node_alloc (END_OF_LIST, insn, NULL); + + } else if (expr_code == PARALLEL) { + /* + * PARALLEL(a,b,c,..) => PARALLEL_ALL (a, PARALLEL_ALL(b, ... )) + * Only the used elements of PARALLEL are translated. + * If the number of used elements of PARALLEL is one, + * then just return the single element, + * and no PARALLEL_ALL node is constructed. + */ + int i = 0; + inode = NULL; + /* + * Tree is constructed bottom up, so iterate through vector in + * reverse. At any point, inode is the top of the partially + * constructed tree. + */ + for (i = XVECLEN (expr, 0) - 1; i >= 0; i--) { + icg_node *parent = NULL; + rtx vexp = XVECEXP (expr, 0, i); + if (GET_CODE (vexp) == CLOBBER) { + /* Ignore clobbers. */ +#ifdef OLD_STUFF + if (GET_CODE (vexp) == CLOBBER) + || (GET_CODE (vexp) == SET + && set_unused_p (vexp, insn))) { + /* Ignore clobbers and unused sets. */ +#endif + continue; + } + if (inode != NULL) { + /* + * Allocate parent and hang previous icg node on it. + */ + parent = icg_node_alloc (PARALLEL_ALL, insn, NULL); + parent->right = inode; + } + inode = translate_expression (vexp, insn); + if (parent) { + /* + * Hang inode on existing parent (filling it), + * and make it the new parent. + */ + parent->left = inode; + inode = parent; + parent = NULL; + } + } + /* + * A PARALLEL rtx must have at least one used operand. + */ + gcc_assert (inode); + + } else if (expr_code == IF_THEN_ELSE) { + /* IF_THEN_ELSE (a, b, c) => COND_MOVE (a, PAIR_ALL (b, c)) */ + inode = icg_node_alloc (COND_MOVE, insn, expr); + inode->left = translate_expression (XEXP (expr, 0), insn); + inode->right = icg_node_alloc (PAIR_ALL, insn, NULL); + inode->right->left = translate_expression (XEXP (expr, 1), insn); + inode->right->right = translate_expression (XEXP (expr, 2), insn); + + } else if (expr_code == CALL) { + /* CALL (f, o) EXPR_LIST (a, b, ...) + => CALL_ALL (PAIR_ALL (f, o), LIST_ALL (USE_ALL (a), LIST_ALL ...))) */ + icg_node *tail; + rtx link; + + current_function_is_leaf = 0; + + inode = icg_node_alloc (CALL_ALL, insn, expr); + inode->left = icg_node_alloc (PAIR_ALL, insn, NULL); + inode->left->left = translate_expression (XEXP (expr, 0), insn); + inode->left->right = translate_expression (XEXP (expr, 1), insn); + + /* Call parameters are stored in an expression list accessed via + CALL_INSN_FUNCTION_USAGE. This macro takes an insn, not an + expression which will cause problems if for whatever reason + (forward prop?) the CALL rtx is not the top level rtx (pattern) + or SET_SRC of the insn, so verify this before continuing + (although this really shouldn't happen). */ + gcc_assert (PATTERN (insn) == expr + || (GET_CODE (PATTERN (insn)) == SET + && SET_SRC (PATTERN (insn)) == expr)); + tail = inode; + for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) { + /* Extend list. */ + tail->right = icg_node_alloc (LIST_ALL, insn, NULL); + tail = tail->right; + /* Add element. */ + tail->left = translate_expression (XEXP (link, 0), insn); + } + /* Terminate list. */ + tail->right = icg_node_alloc (END_OF_LIST, insn, NULL); + + } else if (expr_code == ASM_OPERANDS) { + + const char *instr_template = ASM_OPERANDS_TEMPLATE(expr); + if (0 && strcmp(instr_template, "bsfq %1, %0") == 0) { + icg_node *inode = icg_node_alloc(BSF_DI, insn, expr); + const rtvec rtvec = ASM_OPERANDS_INPUT_VEC(expr); + const int nelements = ASM_OPERANDS_INPUT_LENGTH(expr); + gcc_assert(nelements == 1); + inode->left = translate_expression(RTVEC_ELT(rtvec, 0), insn); + inode->right = 0; + } else { + const int accept_code = icg_analyze_asm(expr, ICG_ASM_PHASE_BUILD); + if (accept_code) { + if (accept_code == 2) { + const int nelements = ASM_OPERANDS_INPUT_LENGTH(expr); + icg_opcodes op; + gcc_assert(nelements == 2); + op = ASM_BINARY_RRR_DI; /* base operator */ + op += get_operator_mode(expr); /* fold in type info */ + inode = icg_node_alloc(op, insn, expr); + inode->left = translate_expression(ASM_OPERANDS_INPUT(expr, 0), insn); + inode->right = translate_expression(ASM_OPERANDS_INPUT(expr, 1), insn); + } else { + inode = icg_node_alloc(ASM_NULLARY, insn, expr); + } + } else { + icg_nyi("asm template %s unhandled", instr_template); + /*NOTREACHED*/ + inode = 0; + } + } + + } else if ((expr_code == UNSPEC) || (expr_code == UNSPEC_VOLATILE)) { + const int unspec_code = XINT(expr, 1); + if (unspec_code == UNSPEC_GOTPCREL) { + rtx sym = 0; + gcc_assert (XVECLEN (expr, 0) == 1); + sym = XVECEXP (expr, 0, 0); + gcc_assert (GET_CODE (sym) == SYMBOL_REF); + inode = icg_node_alloc (get_operator (sym, insn), insn, sym); + if (0) { + inode->a.string = XSTR (expr, 0); + inode->val = 0; + } + } else { + /* + * Unravel the k kids of the UNSPEC node into a right recursive binary tree + * with k-1 nodes in the icg tree. + */ + const struct unspec_code_def *def = lookup_unspec_code(unspec_code); + const rtvec rtvec = XVEC(expr, 0); + const int num_elem = GET_NUM_ELEM(rtvec); + int i; + gcc_assert (num_elem >= 1); + inode = translate_expression(RTVEC_ELT(rtvec, num_elem-1), insn); + for (i = num_elem - 2; i >= 0; i--) { + icg_opcodes op = def->icg_terminal; + if (def->is_type_encoded) { + op += get_operator_mode(expr); + } + { + icg_node *interior = icg_node_alloc(op, insn, expr); + interior->left = translate_expression(RTVEC_ELT(rtvec, i), insn); + interior->right = inode; + inode = interior; + } + } + } + + } else if (expr_code == PREFETCH) { + /* From rtl.def: + * Memory prefetch, with attributes supported on some targets. + * Operand 1 is the address of the memory to fetch. + * Operand 2 is 1 for a write access, 0 otherwise. + * Operand 3 is the level of temporal locality; 0 means there is no + * temporal locality and 1, 2, and 3 are for increasing levels of temporal + * locality. + * The attributes specified by operands 2 and 3 are ignored for targets + * whose prefetch instructions do not support them. + * + * Our strategy is to encode kids 1 and 2 into a single integer + * and treat prefetch as a binary operator. + */ + const int k1 = XINT(expr, 1); + const int k2 = XINT(expr, 2); + inode = icg_node_alloc (get_operator (expr, insn), insn, expr); + inode->left = translate_expression(XEXP (expr, 0), insn); + inode->right = icg_node_alloc (icg_op_of_constant(k1*10+k2), insn, NULL); + return inode; + + } else { + /* "Normal" expression. */ + const int nsubs = count_subexpressions (expr); + gcc_assert (nsubs <= 2); + inode = icg_node_alloc (get_operator (expr, insn), insn, expr); + /* + * These ops should be "normal" binary, unary, or nul-ary + * expressions with a icg-tree structure which + * mirrors the RTL structure. + */ + if (nsubs > 0) { + inode->left = translate_expression (XEXP (expr, 0), insn); + } + if (nsubs > 1) { + inode->right = translate_expression (XEXP (expr, 1), insn); + } + } + + /* Add the offset part for subreg to the tree. */ + if (expr_code == SUBREG) { + /* + * (SUBREG (REG XX) OFFSET) + * REG is already added. OFFSET is an integer that + * should be separately added. + */ + const int offset = XINT(expr, 1); + icg_node *offset_node = + icg_node_alloc (icg_op_of_constant(offset), insn, NULL); + offset_node->val = offset; + offset_node->a.string = NULL; + inode->right = offset_node; + } + + if (expr_code == NEG && (GET_MODE(expr)==SFmode || GET_MODE(expr)==DFmode)) { + /* + * TODO: somehow we have to register the constant 1LL<<63 or 1LL<<31 + * into the constant pool so that it is retained across icg + * This comment was added whene exploring floating negates + * in the context of gcc4.3.1. + * Note: This may no longer be needed for gcc 4.4 + * Note that the RTL back end can not handle XOR_DF + * but has instead rules for NEG_DF, + * which it somehow converts to XOR_DF + */ + const icg_opcodes mode_offset = inode->op - NEG_DI; + const icg_opcodes new_label = XOR_DI + mode_offset; + icg_node *msb_node = icg_node_alloc(CONST_0, 0, NULL); /* TODO BOGUS */ + inode->op = new_label; /* xor */ + inode->right = msb_node; /* splice in bogus constant */ + } + + /* Do any post-construction transformations or optimizations */ + if (expr_code == MINUS) { + /* + * (MINUS_xx a b) => (PLUS_xx a (NEG_xx b)) + * This increases the scope of reassociation. + * + * There are special patterns in the grammar to turn this back into a MINUS. + */ + const int mode_offset = inode->op - MINUS_DI; + + /* Insert NEG_xx node in between inode and the right child. */ + icg_node *neg_node = icg_node_alloc (NEG_DI + mode_offset, insn, NULL); + neg_node->left = inode->right; + neg_node->mode = inode->mode; /* TODO: deprecaed */ + inode->right = neg_node; + + /* Convert MINUS_xx into PLUS_xx */ + inode->op = PLUS_DI + mode_offset; + } + + gcc_assert (inode != NULL); + return inode; +} + +/* + * Returns true if INSN should be translated into an icg tree. + * Some insns such as (CLOBBER (reg)) are dead wood in icg. + */ +static +bool translate_expression_p (rtx insn) +{ + if (0 + || (GET_CODE (PATTERN (insn)) == CLOBBER) + ) { + return false; + } + return true; +} + +/* + * This calls the recursive function translate_expression. + * It populates the op,left,right,val and (r,rx) fields of icg_node + * Results accumulate in the vector icg_insn2tree and icg_insn2dirty + */ +static +void build_insn_tree(rtx curr_insn) +{ + if (translate_expression_p (curr_insn)) { + icg_insn2tree[INSN_UID (curr_insn)] = + translate_expression (PATTERN (curr_insn), curr_insn); + icg_insn2dirty[INSN_UID (curr_insn)] = true; + } +} + + +static int print_icg_rtx_dot(FILE *, rtx); +static int print_icg_tree_dot(FILE *, icg_node *curr_insn); + + +/* + * This is the main driver function to build the side-tree for icg + * Results accumulate in the vector icg_insn2tree and icg_insn2dirty + */ +unsigned icg_create_side_tree(void) +{ + basic_block bb; + rtx curr_insn; + static int make_dotfiles_mask = 0; + FILE *dotfile = (make_dotfiles_mask & (1<<0)) + ? fopen("icg_orig_rtx.dot", "w") : 0; + FILE *icgdotfile = (make_dotfiles_mask & (1<<1)) + ? fopen("icg_side_tree.dot", "w") : 0; + + current_function_is_leaf = 1; /* we initialize it to 1, then clear it if we trip across a call */ + + icg_insn2dirty = (bool *) icg_calloc(get_max_uid() * sizeof(bool)); + icg_insn2tree = (icg_node **)icg_calloc(get_max_uid() * sizeof(icg_node *)); + icg_insn2goalNT = (int *) icg_calloc(get_max_uid() * sizeof(int)); + FOR_EACH_BB(bb) + { + FOR_BB_INSNS(bb, curr_insn) + { + if (!INSN_P(curr_insn)) { + /* + * includes notes, code_labels, and other non-insns + */ + continue; + } + build_insn_tree(curr_insn); + + if (dotfile) { + print_icg_rtx_dot(dotfile, curr_insn); + } + if (icgdotfile) { + print_icg_tree_dot(icgdotfile, icg_insn2tree[INSN_UID(curr_insn)]); + } + } + } + + if (dotfile) { + fclose(dotfile); dotfile = 0; + } + if (icgdotfile) { + fclose(icgdotfile); icgdotfile = 0; + } + + return 0; +} + + +/* The following functions are used to dump the original rtx trees + * and the side-trees as dot files. + */ + +static +int for_each_dot_icg_rtx(FILE *dotfile, rtx curr_insn, int parent) +{ + static int nodenum = 0; + enum rtx_code this_code; + int node; + int i = 0; + int j = 0; + const char *format_str; + + if (parent == 0) + nodenum = 0; + if (curr_insn == NULL_RTX) + return 0; + this_code= GET_CODE(curr_insn); + + nodenum++; + node = nodenum; + switch (this_code) + { + case REG : + fprintf(dotfile,"n%d [label=\"%s : %d\"];\n", node, + GET_RTX_NAME(this_code), XINT(curr_insn, 0)); + break; + case CONST_INT : + fprintf(dotfile,"n%d [label=\"%s : %lld\"];\n", node, + GET_RTX_NAME(this_code), XWINT(curr_insn, 0)); + break; + case SYMBOL_REF : + fprintf(dotfile,"n%d [label=\"%s : %s\"];\n", node, + GET_RTX_NAME(this_code), XSTR(curr_insn, 0)); + break; + default : + fprintf(dotfile,"n%d [label=\"%s\"];\n", node, GET_RTX_NAME(this_code)); + break; + } + if (parent >0) { + fprintf(dotfile,"n%d -- n%d [label=\"%d\"];\n", parent, node, node); + } + + format_str = GET_RTX_FORMAT(this_code); + if (!format_str) { + return 0; + } + i = 0; + while (format_str[i]) { + switch (format_str[i]) { + case 'E' : + if (this_code == (enum rtx_code)PARALLEL) { + for (j = 0; j< XVECLEN (curr_insn, i); j++) { + for_each_dot_icg_rtx(dotfile, XVECEXP(curr_insn, i, j), + node); + } + } + break; + + case 'e' : + for_each_dot_icg_rtx(dotfile, XEXP(curr_insn, i), + node); + break; + + default : + break; + } + i++; + } + return 0; +} + +static +int print_icg_rtx_dot(FILE *dotfile, rtx curr_insn) +{ + if (dotfile == 0) + dotfile = stdout; + fprintf(dotfile,"\n" "graph graph_%d {\n", INSN_UID(curr_insn)); + if (curr_insn) { + for_each_dot_icg_rtx(dotfile, PATTERN(curr_insn), 0); + } + fprintf(dotfile,"}\n"); + return 0; +} + +static +int for_each_dot_icg_tree(FILE *dotfile, icg_node *insn_node, int parent) +{ + static int nodenum = 0; + int node; + if (dotfile == 0) + dotfile = stdout; + + if (parent == 0) + nodenum= 0; + if (!insn_node) + return 0; + nodenum++; + node = nodenum; + if (insn_node->op >= REG_DI && insn_node->op <= REG_SF) { + fprintf(dotfile,"n%d [label=\"REG : %d\"];\n", node, insn_node->r); + } else if (insn_node->op >= REGX_DI && insn_node->op <= REGX_SF) { + fprintf(dotfile,"n%d [label=\"REGX : %d\"];\n", node, insn_node->r); + } else { + fprintf(dotfile,"n%d [label=\"%s\"];\n", node, get_icg_opcode_name(insn_node->op)); + } + if (parent) { + fprintf(dotfile,"n%d -- n%d;\n", parent, node); + } + for_each_dot_icg_tree(dotfile, insn_node->left, node); + for_each_dot_icg_tree(dotfile, insn_node->right, node); + return 0; +} + +static +int print_icg_tree_dot(FILE *dotfile, icg_node *insn_node) +{ + static int graphnum = 0; + if (dotfile == 0) + dotfile = stdout; + fprintf(dotfile,"\n" "graph graph_%d {\n", graphnum++); + if (insn_node) { + for_each_dot_icg_tree(dotfile, insn_node, 0); + } + fprintf(dotfile,"}\n"); + return 0; +} diff --git a/iburg/briggs/icg-color.c b/iburg/briggs/icg-color.c new file mode 100644 index 00000000000..0fec8645886 --- /dev/null +++ b/iburg/briggs/icg-color.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "sparseset.h" + +#include "icg.h" + +#define forall(i, s) EXECUTE_IF_SET_IN_SPARSESET(s, i) +#define k FIRST_PSEUDO_REGISTER + + +/* see Preston's thesis, Section 8.8 */ + + +static +unsigned simplify_graph(void) +{ + unsigned r; + unsigned sp = 0; + sparseset low = sparseset_alloc(icg_interior_regs); + sparseset high = sparseset_alloc(icg_interior_regs); + sparseset stacked = sparseset_alloc(icg_interior_regs); + + if (dump_file) fprintf(dump_file, "\n" "starting simplify {\n"); + + for (r = k; r < icg_interior_regs; r++) + if (icg_reg_vector[r].root == r) + { + if (icg_reg_vector[r].degree < k) + sparseset_set_bit(low, r); + else if (icg_reg_vector[r].cost < 1.0/0.0) + sparseset_set_bit(high, r); + } + if (dump_file) fprintf(dump_file, "\t" "finished init\n"); + while (1) + { + unsigned m, best; + float best_ratio; + while (sparseset_cardinality(low) > 0) + { + unsigned i; + icg_names *av; + + + /* + * in the future, choose i at random from [0 .. members) + * to reduce effect of arbitrary selection. + * probably want to control with a flag. + */ + + i = low->members - 1; + m = low->dense[i]; + low->members = i; + if (dump_file) fprintf(dump_file, "\t" "popping %3d\n", m); + + av = icg_reg_vector[m].av; + for (i = 0; i < av->size; i++) + { + unsigned n = av->name[i]; + if (n >= k) + { + icg_reg_vector[n].degree--; + if (n >= k && icg_reg_vector[n].degree < k && !sparseset_bit_p(stacked, n)) + { + sparseset_clear_bit(high, n); + sparseset_set_bit(low, n); + } + } + } + icg_reg_vector[m].stack = sp; + sparseset_set_bit(stacked, m); + sp = m; + } + if (sparseset_cardinality(high) == 0) break; + best_ratio = 1.0/0.0; + forall(m, high) + { + float ratio = icg_reg_vector[m].cost / icg_reg_vector[m].degree; + if (ratio < best_ratio) + { + best = m; + best_ratio = ratio; + } + } + if (dump_file) fprintf(dump_file, "\t" "spill possibility %d\n", best); + sparseset_clear_bit(high, best); + sparseset_set_bit(low, best); + } + sparseset_free(low); + sparseset_free(high); + sparseset_free(stacked); + + if (dump_file) fprintf(dump_file, "\n" "finished simplify }\n"); + + return sp; +} + +static +void dump_sparse_set(FILE *fp, const sparseset set, const char *name) +{ + unsigned r; + const size_t size = sparseset_size(set); + unsigned *p = (unsigned *)icg_alloc(size*sizeof(int)); + + size_t n = 0; /* number of items in the set */ + forall(r, set) { + p[n] = r; + n += 1; + } + if (fp == 0) { + fp = stdout; + } + fprintf(fp, "%s:\n", name); + icg_print_runs(fp, p, n); /* ends with a new line */ +} + +static +void select_colors(unsigned sp) +{ + unsigned m; + sparseset caller_saves = sparseset_alloc(k); + sparseset callee_saves = sparseset_alloc(k); + + if (dump_file) fprintf(dump_file, "\n" "starting select\n"); + + for (m = 0; m < k; m++) + sparseset_set_bit(caller_saves, m); + + sparseset_set_bit(callee_saves, 3); /* %rbx */ + sparseset_set_bit(callee_saves, 6); /* %rbp */ + sparseset_set_bit(callee_saves, 41); /* %r12 */ + sparseset_set_bit(callee_saves, 42); /* %r13 */ + sparseset_set_bit(callee_saves, 43); /* %r14 */ + sparseset_set_bit(callee_saves, 44); /* %r15 */ + + sparseset_and_compl(caller_saves, caller_saves, callee_saves); + + if (dump_file) { + dump_sparse_set(dump_file, caller_saves, "caller saves"); + dump_sparse_set(dump_file, callee_saves, "callee saves"); + } + + while (sp) + { + m = sp; + if (icg_reg_vector[m].cost > 0.0) + { + unsigned i; + icg_names *av; + bool used[k]; + unsigned c; + for (c = 0; c < k; c++) + used[c] = false; + av = icg_reg_vector[m].av; + for (i = 0; i < av->size; i++) + { + unsigned n = av->name[i]; + int c = icg_reg_vector[n].color; + if (c >= 0) + used[c] = true; + } + forall(c, caller_saves) + if (!used[c]) { + icg_reg_vector[m].color = c; + break; + } + if (icg_reg_vector[m].color < 0) + forall(c, callee_saves) + if (!used[c]) { + icg_reg_vector[m].color = c; + break; + } + } + sp = icg_reg_vector[sp].stack; + } + + sparseset_free(caller_saves); + sparseset_free(callee_saves); + + if (dump_file) fprintf(dump_file, "\n" "finished select\n"); + + if (dump_file) + for (m = k; m < icg_interior_regs; m++) + if (icg_reg_vector[m].root == m) + fprintf(dump_file, "live range %3d got %3d\n", m, icg_reg_vector[m].color); + + for (m = k; m < icg_live_ranges; m++) + if (icg_reg_vector[m].root == m && icg_reg_vector[m].color < 0) + return; + + /* check to be sure all interior registers got colors */ + for (m = icg_live_ranges; m < icg_interior_regs; m++) + if (icg_reg_vector[m].root == m && icg_reg_vector[m].color < 0) + { + fprintf(stderr, "\n" "an interior register didn't get colored\n"); + exit(0); + } +} + + + +void icg_color(void) +{ + unsigned r; + for (r = 0; r < k; r++) + icg_reg_vector[r].color = r; + for (r = k; r < icg_interior_regs; r++) + icg_reg_vector[r].color = -1; + + select_colors(simplify_graph()); +} diff --git a/iburg/briggs/icg-combine.c b/iburg/briggs/icg-combine.c new file mode 100644 index 00000000000..f792df55c9f --- /dev/null +++ b/iburg/briggs/icg-combine.c @@ -0,0 +1,1009 @@ +/* Combines insns via forward propagation to create maximally sized + RTL expressions for ICG. Copyright (C) 2008 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 + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "df.h" + + +/* Integrated code generator combine. + + Combines RTL insns in to maximally sized expression trees. These + expression trees are input to the combined instruction selector and + graph-coloring register allocator. */ + + +#ifdef DEBUG +/* Dump data for scraping via a script. */ +#define COMBINE_LOG_DATA(f, d) (dump_file ? fprintf (dump_file, "COMBINE_DATA %s: %d\n", (f), (d)) : 0) +#define COMBINE_LOG(s) (dump_file ? fprintf (dump_file, "COMBINE_LOG %s\n", (s)) : 0) +#else +#define COMBINE_LOG_DATA(f, d) (dump_file ? fprintf (dump_file, " %s: %d\n", (f), (d)) : 0) +#define COMBINE_LOG(s) (dump_file ? fprintf (dump_file, "%s\n", (s)) : 0) +#endif + + +/* Data structure for accumulating the number of leaves and types in + an insn. A leaf is a register, constant, or memory reference. + Does not count the register destination of a SET. This data + structure and related functions are only used for data collection, + not for an transformations. */ + +struct leaf_counts +{ + int leaves; + int mem; + int con; + int reg; + int reg_single_live; + int reg_single_dead; + int reg_mult_live; + int reg_mult_dead; +}; + +static void dump_def_use (FILE *, basic_block); +static void log_bb_data (basic_block, const char *); +static void insn_count_leaves (rtx, struct leaf_counts *); +static void log_leaves (const char *, struct leaf_counts *); + + +static bool +is_reg_or_subreg_p (rtx expr) +{ + return (REG_P (expr) || GET_CODE (expr) == SUBREG); +} + +static rtx +get_reg_rtx (rtx expr) +{ + gcc_assert (is_reg_or_subreg_p (expr)); + if (REG_P (expr)) + return expr; + else + return SUBREG_REG (expr); +} + +/* Returns true iff EXPR is a real register or subreg of real + register. If EXCEPT_CC is true, then doesn't count CC as a real + register. */ + +static bool +real_reg_or_subreg_p (rtx expr, bool except_cc) +{ + if (is_reg_or_subreg_p (expr)) + { + rtx reg = get_reg_rtx (expr); + return (REGNO (reg) < FIRST_PSEUDO_REGISTER + && !(except_cc && REGNO (reg) == FLAGS_REG)); + } + return false; +} + +/* Returns true iff INSN is a copy involving a machine register */ + +static bool +copy_mach_reg_p (rtx insn) +{ + /* The opcode of the insn is a register-to-register copy (reg or + subreg) and one of the operands is a machine reg (or subreg). */ + rtx insn_pat = PATTERN (insn); + if (GET_CODE (insn_pat) == SET) + { + rtx src = SET_SRC (insn_pat); + rtx dest = SET_DEST (insn_pat); + if (is_reg_or_subreg_p (src) && is_reg_or_subreg_p (dest) + && (real_reg_or_subreg_p (src, false) + || real_reg_or_subreg_p (dest, false))) + return true; + } + return false; +} + +/* Returns true iff REG is dead after INSN. */ + +static bool +reg_dead_p (rtx insn, rtx reg) +{ + /* Register is dead if either data flow says so (REG_DEAD) or if + INSN sets the register. */ + gcc_assert (REG_P (reg)); + return (find_regno_note (insn, REG_DEAD, REGNO (reg)) != NULL_RTX + || reg_set_p (reg, insn)); +} + +/* Returns true iff REG defined by INSN is never used. */ + +static bool +reg_unused_p (rtx insn, rtx reg) +{ + rtx note; + gcc_assert (REG_P (reg)); + for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) + { + if (REG_NOTE_KIND (note) == REG_UNUSED) + { + rtx x = XEXP (note, 0); + gcc_assert (REG_P (x)); + if (REGNO (reg) == REGNO (x)) + return true; + } + } + return false; +} + +/* Returns true iff the INSN is a conditional jump. Does it in a + rather hamfisted manner. Checks to see if INSN is a control flow + insn and if its basic block has more than one successor. */ + +static bool +conditional_jump_p (rtx insn) +{ + if (control_flow_insn_p (insn) && !CALL_P (insn) + && EDGE_COUNT (BLOCK_FOR_INSN (insn)->succs) > 1) + return true; + return false; +} + +/* Helper function which calls for_each_rtx on part of *X which + satisfies the conditions below in the comments for + for_each_ref_exp. */ + +static int +for_each_ref_exp_1 (rtx insn, rtx *x, rtx_function f, + bool only_used, void *data) +{ + if (GET_CODE (*x) == SET && is_reg_or_subreg_p (SET_DEST (*x))) + { + rtx reg = get_reg_rtx (SET_DEST (*x)); + if (only_used && reg_unused_p (insn, reg)) + return 0; + else + return for_each_rtx (&SET_SRC (*x), f, data); + } + else if (GET_CODE (*x) != CLOBBER) + return for_each_rtx (x, f, data); + return 0; +} + +/* Calls F on each non-destination (sort of) rtx in INSN. If + ONLY_USED is true, then skip SET expressions whose destinations are + not used. + + More precisely, calls F on each rtx of ISNS's pattern which + satisfies the following: + + - not the register destination of a SET or CLOBBER + + - if ONLY_USED is true, then not part of a SET (source or + destination) which is not used + + Uses for_each_rtx to traverse sub-expressions, so the return value + of F is treated as in for_each_rtx. */ + +static int +for_each_ref_exp (rtx insn, rtx_function f, bool only_used, void *data) +{ + rtx pat = PATTERN (insn); + if (GET_CODE (pat) == PARALLEL) + { + int i; + gcc_assert (GET_CODE (pat) == PARALLEL); + for (i = 0; i < XVECLEN (pat, 0); i++) + { + int rv = for_each_ref_exp_1 (insn, &XVECEXP (pat, 0, i), + f, only_used, data); + if (rv != 0) + return rv; + } + return 0; + } + else + return for_each_ref_exp_1 (insn, &PATTERN (insn), f, only_used, data); +} + +/* Returns number of references of EXPR in INSN. EXPR can be a REG or + SUBREG. If USED is true, then only count those which are actually + used. Better than directly using count_occurrences because + count_occurrences counts within sources of every SET, even if not + every SET is used. -1 is returned if register in EXPR is used but + in a different mode or in a way which cannot be forward propagated + into. This includes if EXPR is a subreg and the corresponding + register is referenced. */ + +struct occur_data +{ + rtx expr; + int n; + bool invalid; +}; + +static int +count_references_1 (rtx *x, void *data) +{ + struct occur_data *p = (struct occur_data *)data; + if (GET_CODE (p->expr) == SUBREG) + { + if (GET_CODE (*x) == SUBREG) + { + if (rtx_equal_p (*x, p->expr)) + { + p->n++; + return -1; /* Don't traverse subexpressions. */ + } + else if (REGNO (SUBREG_REG (*x)) == REGNO (SUBREG_REG (p->expr))) + { + /* SUBREGs share the same regno, but different modes. */ + p->invalid = true; + return 1; /* stop traversal */ + } + } + else if (REG_P (*x) && REGNO (*x) == REGNO (SUBREG_REG (p->expr))) + { + /* X shares the same register as SUBREG. */ + p->invalid = true; + return 1; /* stop traversal */ + } + } + else if (REG_P (p->expr)) + { + if (rtx_equal_p (*x, p->expr)) + p->n++; + else if (REGNO (p->expr) == REGNO (*x)) + { + /* Same regno but different mode. */ + p->invalid = true; + return 1; /* stop traversal */ + } + } + else + gcc_assert (0); + + return 0; +} + +/* Checks for a use rtx of the register defined by DATA. Sets invalid + field of DATA if one is found. */ + +static int +check_for_use_expr (rtx *x, void *data) +{ + struct occur_data *p = (struct occur_data *)data; + if (GET_CODE (*x) == USE) { + rtx use_reg = XEXP (*x, 0); + rtx data_reg; + gcc_assert (REG_P (use_reg)); + if (GET_CODE (p->expr) == SUBREG) + data_reg = SUBREG_REG (p->expr); + else + data_reg = p->expr; + if (REGNO (data_reg) == REGNO (use_reg)) + { + p->invalid = true; + return 1; + } + } + + return 0; +} + +static int +count_references (rtx insn, rtx expr, bool used) +{ + struct occur_data data; + data.expr = expr; + data.n = 0; + data.invalid = false; + for_each_ref_exp (insn, count_references_1, used, &data); + if (!data.invalid) + for_each_rtx (&PATTERN (insn), check_for_use_expr, &data); + return (data.invalid ? -1 : data.n); +} + +/* Helper function for store_aliases_p. */ + +static int +store_aliases_p_1 (rtx *x, void *p) +{ + rtx store = (rtx)p; + if (MEM_P (*x) && memory_modified_in_insn_p (*x, store)) + return 1; + return 0; +} + +/* Returns true iff STORE may write a memory location read or written + to by INSN. */ + +static bool +store_aliases_p (rtx store, rtx insn) +{ + return (for_each_rtx (&PATTERN (insn), store_aliases_p_1, store) != 0); +} + +static void +modifies_memory_p_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) +{ + bool *p = (bool *)data; + if (MEM_P (x)) + *p = true; +} + +/* Returns true iff INSN modifies memory. */ + +static bool +modifies_memory_p (rtx insn) +{ + bool mod = false; + note_stores (PATTERN (insn), modifies_memory_p_1, &mod); + return mod; +} + + +static int +references_memory_p_1 (rtx *x, void *data) +{ + bool *p = (bool *)data; + if (MEM_P (*x)) + *p = true; + return 0; +} +/* Returns true iff INSN modifies memory. */ + +static bool +references_memory_p (rtx insn) +{ + bool ref = false; + for_each_rtx (&PATTERN (insn), references_memory_p_1, &ref); + return ref; +} + +static int +uses_real_reg_except_cc_1 (rtx *x, void *data) +{ + bool *p = (bool *)data; + if (real_reg_or_subreg_p (*x, true)) + { + *p = true; + return -1; + } + return 0; +} + +/* Returns true iff INSN uses a real (hard) register except CC. */ + +static bool +uses_real_reg_except_cc_p (rtx insn) +{ + bool uses_reg = false; + for_each_ref_exp (insn, uses_real_reg_except_cc_1, false, &uses_reg); + return uses_reg; +} + +/* Helper struct and function for defines_real_reg_p. */ + +struct define_data +{ + rtx insn; + bool defines_reg; + bool except_cc; +}; + +static void +defines_used_real_reg_p_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) +{ + struct define_data *p = (struct define_data *)data; + if (REG_P (x) && real_reg_or_subreg_p (x, p->except_cc) + && !reg_dead_p (p->insn, x)) + p->defines_reg = true; +} + +/* Returns true iff INSN defines a real (hard) register except CC, and + definition is not dead. */ + +static bool +defines_used_real_reg_p (rtx insn, bool except_cc) +{ + struct define_data data; + data.insn = insn; + data.defines_reg = false; + data.except_cc = except_cc; + note_stores (PATTERN (insn), defines_used_real_reg_p_1, &data); + return data.defines_reg; +} + +struct merge_data +{ + rtx from; + rtx to; +}; + +/* Helper function for merge_def. */ + +static int +merge_def_1 (rtx *x, void *data) +{ + struct merge_data *p = (struct merge_data *)data; + if (rtx_equal_p (*x, p->from)) + { + *x = p->to; + return -1; /* Don't traverse below this point. */ + } + else if (REG_P (*x)) + /* All instances of the target register mustbe substituted. */ + gcc_assert (REGNO (*x) != REGNO (get_reg_rtx (p->from))); + return 0; +} + +/* Merge DEF_INSN into USE_INSN. Necessarily, DEF_INSN defines a + register or subreg used by USE_INSN. */ + +static void +merge_def (rtx def_insn, rtx use_insn, rtx expr) +{ + struct merge_data data; + const_rtx set = set_of (expr, def_insn); + + data.from = expr; + gcc_assert (set != NULL_RTX); + data.to = SET_SRC (set); + for_each_ref_exp (use_insn, merge_def_1, false, &data); + +/* /\* Fix up REG_DEAD reg notes in new combined insn. Add dead notes of */ +/* src insn to new insn and remove dead note of merged register. *\/ */ +/* for (rn = REG_NOTES (def_insn); rn; rn = XEXP (rn, 1)) */ +/* if (REG_NOTE_KIND (rn) == REG_DEAD) */ +/* REG_NOTES (use_insn) = gen_rtx_EXPR_LIST (REG_DEAD, */ +/* XEXP (rn, 0), */ +/* REG_NOTES (use_insn)); */ +/* rn = find_regno_note (use_insn, REG_DEAD, REGNO (reg)); */ +/* if (rn != NULL_RTX) */ +/* remove_note (use_insn, rn); */ + + delete_insn (def_insn); +} + +/* Simple-minded O(n^2) algorithm to combine insns together. + insn A is combined into insn B iff: + 1. A and B are in same BB + 2. A defines only one used reg (call it rA) + 3. B is only use of rA (rA is dead at B), and B only uses rA once + 4. A's dependences are available at B + This probably should be made O(n). */ + +static void +combine_insns (void) +{ + basic_block bb; + + df_note_add_problem (); + df_analyze (); + + COMBINE_LOG ("function"); + FOR_EACH_BB (bb) + { + rtx def_insn, use_insn, next; + + if (dump_file) + { + COMBINE_LOG ("bb"); + dump_def_use (dump_file, bb); + log_bb_data (bb, "bb-before"); + } + + FOR_BB_INSNS_SAFE (bb, def_insn, next) + { + df_ref *use_vec; + rtx def_expr; + bool merged = false; + + if (!INSN_P (def_insn)) + continue; + + if (dump_file) + { + struct leaf_counts cnt; + insn_count_leaves (def_insn, &cnt); + COMBINE_LOG ("insn"); + if (conditional_jump_p (def_insn)) + COMBINE_LOG ("insn-type-cond-cf"); + else if (control_flow_insn_p (def_insn)) + COMBINE_LOG ("insn-type-uncond-cf"); + else + COMBINE_LOG ("insn-type-noncf"); + fprintf (dump_file, "def insn %d: ", INSN_UID (def_insn)); + print_inline_rtx (dump_file, def_insn, 4); + fprintf (dump_file, "\n"); + log_leaves ("insn", &cnt); + } + + /* Check that def_insn defines only one used register + (condition 2) */ + def_expr = single_set (def_insn); + if (def_expr == NULL_RTX) + { + COMBINE_LOG ("insn defines more than one or no value"); + continue; + } + def_expr = SET_DEST (def_expr); + + /* TODO: SUBREG or REG. + DONE. */ + if (!is_reg_or_subreg_p (def_expr)) + { + COMBINE_LOG ("insn defines a non-register value"); + continue; + } + + /* TODO: defines real reg or subreg. + DONE. */ + if (real_reg_or_subreg_p (def_expr, true)) + { + COMBINE_LOG ("insn defines real register which is not CC"); + continue; + } + + /* TODO: no change req'd. Use of SUBREG implies use of REG. + DONE. */ + if (uses_real_reg_except_cc_p (def_insn)) + { + COMBINE_LOG ("insn uses real register"); + continue; + } + + if (modifies_memory_p (def_insn)) + { + COMBINE_LOG ("insn modifies memory and register"); + continue; + } + + /* Iterate from def to first use of defined register (or end + of BB). */ + for (use_insn = NEXT_INSN (def_insn); + use_insn && use_insn != NEXT_INSN (BB_END (bb)); + use_insn = NEXT_INSN (use_insn)) + { + int uses; + if (!INSN_P (use_insn)) + continue; + + if (conditional_jump_p (use_insn)) + continue; + + /* USES is number of non-def appearances of def in USE_INSN. */ + + /* TODO: + + If SUBREG, then count number of proper uses of + subreg. If overlapping reg found, then -1 should be + returned. + + If reg, then no change. + + DONE. */ + uses = count_references (use_insn, def_expr, false); + if (uses) + { + /* USED_USES is number of non-def appearances of def + in USE_INSN which are part of an expression which + actually used (not dead). */ + + /* TODO: same as above. DONE. */ + int used_uses = count_references (use_insn, def_expr, true); + + /* insn uses reg. Check to see if it is only used once and + if it is dead. */ + if (dump_file) + { + fprintf (dump_file, "use insn %d: ", INSN_UID (use_insn)); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + if (uses == -1) + { + COMBINE_LOG ("unpropagatable use (different mode, in use insn, etc)"); + break; + } + if (used_uses > 1) + { + COMBINE_LOG ("register used more than once at first use"); + break; + } + + /* TODO: make sure that dead_p properly handles SUBREG case. DONE.*/ + if (!reg_dead_p (use_insn, get_reg_rtx (def_expr))) + { + COMBINE_LOG ("register not dead at first use"); + break; + } + + /* Check for instances of SUBREG copies. DONE. */ + if (copy_mach_reg_p (use_insn)) + { + COMBINE_LOG ("copy instruction involving a machine register"); + break; + } + + /* Combine insns together. */ + merge_def (def_insn, use_insn, def_expr); + if (dump_file) + { + COMBINE_LOG ("insn merged"); + fprintf (dump_file, "new insn: "); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + merged = true; + break; + } + else + { + /* Check to see if use_insn sets/clobbers any of the + registers used by def_insn. If one of these + registers is set/clobbers then we can't combine + def_insn into anything later because it's + dependences are changed. (condition 4). + + Note: Can't use DF_INSN_USES because the insn + combining makes these invalid. However, + DF_INSN_DEF will always be valid. */ + for (use_vec = DF_INSN_DEFS (use_insn); *use_vec; use_vec++) + if (reg_referenced_p (DF_REF_REG (*use_vec), PATTERN (def_insn))) + { + if (dump_file) + { + COMBINE_LOG ("dependency of def clobbered before use"); + fprintf (dump_file, "clobbering insn: "); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + break; + } + /* Loop exited prematurely only if dependencies clobbered. */ + if (*use_vec) + break; + + if (store_aliases_p (use_insn, def_insn)) + { + if (dump_file) + { + COMBINE_LOG ("store aliases memory loads/stores of def"); + fprintf (dump_file, "aliasing insn: "); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + break; + } + + /* Don't propagate across definition of real register. */ + if (defines_used_real_reg_p (use_insn, true)) + { + if (dump_file) + { + COMBINE_LOG ("real register defined before use"); + fprintf (dump_file, "defined insn: "); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + break; + } + + /* If def references memory, then don't propagate across a call. */ + if (CALL_P (use_insn) + && references_memory_p (def_insn)) + { + if (dump_file) + { + COMBINE_LOG ("call encountered and def references memory"); + fprintf (dump_file, "call insn: "); + print_inline_rtx (dump_file, use_insn, 4); + fprintf (dump_file, "\n"); + } + break; + } + } + } + if (!use_insn || use_insn == NEXT_INSN (BB_END (bb))) + COMBINE_LOG ("no use in basic block"); + } + if (dump_file) + log_bb_data (bb, "bb-after"); + } +} + +static unsigned +rest_of_handle_icg_combine (void) +{ + combine_insns (); + + return 0; +} + +static bool +gate_icg_combine (void) +{ + return flag_icg; +} + + +struct rtl_opt_pass pass_icg_combine = +{ + { + RTL_PASS, + "icg_combine", /* name */ + gate_icg_combine, /* gate */ + rest_of_handle_icg_combine, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + } +}; + + +/* Logging stuff */ + +/* Returns number of insns in basic block BB. Better, existing way to + do this? */ + +static int +bb_num_insns (basic_block bb) +{ + rtx insn; + int n = 0; + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + n++; + return n; +} + +struct leaf_data +{ + rtx insn; + + /* Arrays indexed by regno recording the number of live/dead uses in + the insn. (Shamefully terrible, should use more space-efficient data + structure). */ + int *dead_uses; + int *live_uses; + struct leaf_counts *pcnt; +}; + +static int +accum_leaf_1 (rtx *x, void *p) +{ + struct leaf_data *data = (struct leaf_data *)p; + if ((*x != NULL_RTX) + && (REG_P (*x) || MEM_P (*x) || CONST_INT_P (*x))) + { + data->pcnt->leaves++; + if (CONST_INT_P (*x)) + data->pcnt->con++; + else if (MEM_P (*x)) + data->pcnt->mem++; + else if (REG_P (*x)) + { + data->pcnt->reg++; + if (reg_dead_p (data->insn, *x)) + data->dead_uses[REGNO (*x)]++; + else + data->live_uses[REGNO (*x)]++; + } + } + return 0; +} + +/* Accumulate the types and number of leaves in the insn defined in + DATA. DATA->dead_uses and DATA->live uses must be arrays allocated + with max_reg_num() elements. DATA->pcnt must be valid pointer to + leaf count data structure. */ + +static void +accum_leaf (struct leaf_data *data) +{ + int r; + + for_each_ref_exp (data->insn, accum_leaf_1, true, data); + + for (r = 0; r < max_reg_num (); r++) + { + if (data->dead_uses[r] == 1) + data->pcnt->reg_single_dead++; + else if (data->dead_uses[r] > 1) + data->pcnt->reg_mult_dead += data->dead_uses[r]; + + if (data->live_uses[r] == 1) + data->pcnt->reg_single_live++; + else if (data->live_uses[r] > 1) + data->pcnt->reg_mult_live += data->live_uses[r]; + } +} + +/* Count the types and number of leaves in INSN. Values are placed in + PCNT. */ + +static void +insn_count_leaves (rtx insn, struct leaf_counts *pcnt) +{ + struct leaf_data data; + data.insn = insn; + data.dead_uses = (int *)xcalloc (sizeof (int), max_reg_num ()); + data.live_uses = (int *)xcalloc (sizeof (int), max_reg_num ()); + data.pcnt = pcnt; + memset (data.pcnt, 0, sizeof (struct leaf_counts)); + accum_leaf (&data); + + free (data.dead_uses); + free (data.live_uses); +} + +/* Count the types and number of leaves in BB. Values are placed in + PCNT. */ + +static void +bb_count_leaves (basic_block bb, struct leaf_counts *pcnt) +{ + struct leaf_data data; + rtx insn; + + data.dead_uses = (int *)xmalloc (sizeof (int) * max_reg_num ()); + data.live_uses = (int *)xmalloc (sizeof (int) * max_reg_num ()); + data.pcnt = pcnt; + memset (data.pcnt, 0, sizeof (struct leaf_counts)); + + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + { + data.insn = insn; + memset (data.dead_uses, 0, max_reg_num () * sizeof (int)); + memset (data.live_uses, 0, max_reg_num () * sizeof (int)); + accum_leaf (&data); + } + + free (data.dead_uses); + free (data.live_uses); +} + +static void +log_leaves (const char *str, struct leaf_counts *pcnt) +{ + if (dump_file) + { + char s[256]; +#define LOG(p, f, d) { snprintf (s, 256, "%s-%s", p, f); COMBINE_LOG_DATA (s, d); } + LOG (str, "leaves", pcnt->leaves); + LOG (str, "memory", pcnt->mem); + LOG (str, "const", pcnt->con); + LOG (str, "register", pcnt->reg); + LOG (str, "register-single-live", pcnt->reg_single_live); + LOG (str, "register-multiple-live", pcnt->reg_mult_live); + LOG (str, "register-single-dead", pcnt->reg_single_dead); + LOG (str, "register-multiple-dead", pcnt->reg_mult_dead); +#undef LOG + } +} + +/* Dump dataflow information to a file. */ + +static void +dump_def_use (FILE *fp, basic_block bb) +{ + rtx insn; + fprintf (dump_file, "\n" "Dataflow for BB %d:\n", bb->index); + FOR_BB_INSNS (bb, insn) + { + df_ref *df_vec; + + if (!INSN_P (insn)) + continue; + + fprintf (fp, "\n" "insn %d: ", INSN_UID (insn)); + print_inline_rtx (fp, insn, 4); + fprintf (fp, "\n Defs: "); + for (df_vec = DF_INSN_DEFS (insn); *df_vec; df_vec++) + { + rtx reg = DF_REF_REG (*df_vec); + print_inline_rtx (fp, reg, 2); + if (reg_unused_p (insn, get_reg_rtx (reg))) + fprintf (fp, " UNUSED"); + fprintf (fp, "; "); + } + + /* use DF_REF_REG to get register reference. */ + + fprintf (fp, " \n Uses: "); + for (df_vec = DF_INSN_USES (insn); *df_vec; df_vec++) + { + rtx reg = DF_REF_REG (*df_vec); + print_inline_rtx (fp, reg, 2); + if (reg_dead_p (insn, get_reg_rtx (reg))) + fprintf (fp, " DEAD"); + fprintf (fp, "; "); + } + fprintf (fp, "\n"); + } +} + +/* Log leaf information about the basic block BB to dump_file. Prefix + any data fields with PREFIX. */ + +static void +log_bb_data (basic_block bb, const char *prefix) +{ + rtx insn; + struct leaf_counts cnt; + int ucf = 0, ccf = 0, ncf = 0; + int ucf_leaves = 0, ccf_leaves = 0, ncf_leaves = 0; + char s[256]; + + /* Log data for all insns. */ + bb_count_leaves (bb, &cnt); + snprintf (s, 256, "%s-insns", prefix); + COMBINE_LOG_DATA (s, bb_num_insns(bb)); + log_leaves (prefix, &cnt); + + /* Count number of leaves and insns for three different insn types: + - unconditional control_flow + - conditional control_flow + - non control flow */ + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + { + insn_count_leaves (insn, &cnt); + if (conditional_jump_p (insn)) + { + ccf++; + ccf_leaves += cnt.leaves; + } + else if (control_flow_insn_p (insn)) + { + ucf++; + ucf_leaves += cnt.leaves; + } + else + { + ncf++; + ncf_leaves += cnt.leaves; + } + } + snprintf (s, 256, "%s-uncond-cf-insns", prefix); + COMBINE_LOG_DATA (s, ucf); + snprintf (s, 256, "%s-cond-cf-insns", prefix); + COMBINE_LOG_DATA (s, ccf); + snprintf (s, 256, "%s-non-cf-insns", prefix); + COMBINE_LOG_DATA (s, ncf); + + snprintf (s, 256, "%s-uncond-cf-leaves", prefix); + COMBINE_LOG_DATA (s, ucf_leaves); + snprintf (s, 256, "%s-cond-cf-leaves", prefix); + COMBINE_LOG_DATA (s, ccf_leaves); + snprintf (s, 256, "%s-non-cf-leaves", prefix); + COMBINE_LOG_DATA (s, ncf_leaves); +} diff --git a/iburg/briggs/icg-costs.c b/iburg/briggs/icg-costs.c new file mode 100644 index 00000000000..c586217b42e --- /dev/null +++ b/iburg/briggs/icg-costs.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "sparseset.h" +#include "tree-pass.h" + +#include "icg.h" + +#define forall(i, s) EXECUTE_IF_SET_IN_SPARSESET(s, i) + + +/* + * See Preston's thesis, section 8.7 + * + * Note that here we're treating each expression tree + * as a single instruction, with interior registers + * given infinite spill cost. + * + * May want to reconsider this some day. + * + * This is a very simple implementation, so we can get going. + * Currently it assumes spilling will add loads and stores + * for each definition and use. Later, we can extend it + * to include all of Chaitin's clever ideas. + * + */ + + +static +float frequency; + +static +unsigned pass; + +#define find(r) (icg_reg_vector[r].root) + +static +void cost_copy(const unsigned original_x, const unsigned original_y) { + const unsigned x = find(original_x); + const unsigned y = find(original_y); + if (x != y && + (pass > 0 || + (x >= FIRST_PSEUDO_REGISTER && y >= FIRST_PSEUDO_REGISTER))) { + icg_reg_vector[x].copies += frequency; + icg_reg_vector[y].copies += frequency; + } +} + + +static +void cost_load(const unsigned original_x) { + const unsigned x = find(original_x); + icg_reg_vector[x].loads += frequency; + icg_reg_vector[x].leaf = true; +} + + +static +void cost_store(const unsigned original_x) { + const unsigned x = find(original_x); + icg_reg_vector[x].stores += frequency; +} + + +static +void memorable(const unsigned original_x) { + const unsigned x = find(original_x); + icg_reg_vector[x].leaf = false; +} + + +static +void forgettable(const unsigned original_x) { + const unsigned x = find(original_x); + if (icg_reg_vector[x].leaf) { + icg_reg_vector[x].points += frequency; + icg_reg_vector[x].leaf = false; + } +} + + +static +void reduce_costs(icg_node *p, NT goalNT) +{ + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + reduce_costs(kid[i], nts[i]); + switch (rule) { +#include "icg-costs.cases" + } +} + + + +void icg_costs(unsigned p) +{ + unsigned r; + basic_block bb; + + pass = p; + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + { + icg_reg_vector[r].cost = 1.0/0.0; + icg_reg_vector[r].loads = 0.0; + icg_reg_vector[r].stores = 0.0; + icg_reg_vector[r].points = 0.0; + icg_reg_vector[r].copies = 0.0; + icg_reg_vector[r].leaf = false; + } + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) + { + icg_reg_vector[r].cost = 0.0; + icg_reg_vector[r].loads = 0.0; + icg_reg_vector[r].stores = 0.0; + icg_reg_vector[r].points = 0.0; + icg_reg_vector[r].copies = 0.0; + icg_reg_vector[r].leaf = false; + } + for (r = icg_live_ranges; r < icg_interior_regs; r++) + { + icg_reg_vector[r].cost = 1.0/0.0; + icg_reg_vector[r].loads = 0.0; + icg_reg_vector[r].stores = 0.0; + icg_reg_vector[r].points = 0.0; + icg_reg_vector[r].copies = 0.0; + icg_reg_vector[r].leaf = false; + } + + FOR_EACH_BB(bb) + { + rtx insn; + frequency = bb->frequency; + if (frequency < 1.0) + frequency = 1.0; + FOR_BB_INSNS_REVERSE(bb, insn) + { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + reduce_costs(tree, burm_goal_NT); + } + } + } + + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) + icg_reg_vector[r].cost = 3*icg_reg_vector[r].loads + + 3*icg_reg_vector[r].stores + + icg_reg_vector[r].points + - icg_reg_vector[r].copies; + if (dump_file) + { + fprintf(dump_file, "\n" "spill costs\n"); + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) + if (icg_reg_vector[r].root == r) + fprintf(dump_file, " r%-2d = %6.0f (%6.0f, %6.0f, %6.0f, %6.0f)\n", r, + icg_reg_vector[r].cost, + icg_reg_vector[r].loads, + icg_reg_vector[r].points, + icg_reg_vector[r].stores, + icg_reg_vector[r].copies); + } +} diff --git a/iburg/briggs/icg-debug.c b/iburg/briggs/icg-debug.c new file mode 100644 index 00000000000..3c2d9656730 --- /dev/null +++ b/iburg/briggs/icg-debug.c @@ -0,0 +1,805 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "target.h" /* for targetm */ +#include "output.h" /* for asm_fprintf */ + +/* start taken from dwarf2out.c */ +#ifndef FUNC_BEGIN_LABEL + #define FUNC_BEGIN_LABEL "LFB" +#endif + +#ifndef FUNC_END_LABEL + #define FUNC_END_LABEL "LFE" +#endif +/* end taken from dwarf2out.c */ + +#include "icg.h" + +static +void bad_register_argument(unsigned r, char type) +{ + fflush(stdout); + fprintf(stderr, "bad argument to register format: r=%3d rtype='%c'\n", + r, type); + gcc_assert(false); + /*NOTREACHED*/ +} + +/* + * allowable types in argument t are: + * 'b' an 8-bit QI general-purpose register (e.g., %al and %r8b) + * 'h' an 8-bit QI general-purpose register (e.g., %ah and %bh) + * 'w' a 16-bit HI general-purpose register (e.g., %ax and %r8w) + * 'd' a 32-bit SI general-purpose register (e.g., %eax and %r8d) + * 'q' a 64-bit DI general-purpose register (e.g., %rax and %r8) + * 'x' an xmm register (e.g., %xmm8) + */ + +static +const char *register_format_str(char *buf, + size_t buflen, unsigned r, char type) +{ + r = icg_path_compress(r); + switch (r) { + case REG_RAX: + switch (type) { + case 'b': return("%al"); + case 'h': return("%ah"); + case 'w': return("%ax"); + case 'l': + case 'd': return("%eax"); + case 'q': return("%rax"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RBX: + switch (type) { + case 'b': return("%bl"); + case 'h': return("%bh"); + case 'w': return("%bx"); + case 'l': + case 'd': return("%ebx"); + case 'q': return("%rbx"); + default: + bad_register_argument(r, type); + break; + } + break; + + case REG_RCX: + switch (type) { + case 'b': return("%cl"); + case 'h': return("%ch"); + case 'w': return("%cx"); + case 'l': + case 'd': return("%ecx"); + case 'q': return("%rcx"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RDX: + switch (type) { + case 'b': return("%dl"); + case 'h': return("%dh"); + case 'w': return("%dx"); + case 'l': + case 'd': return("%edx"); + case 'q': return("%rdx"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RSI: + switch (type) { + case 'b': return("%sil"); + case 'w': return("%si"); + case 'l': + case 'd': return("%esi"); + case 'q': return("%rsi"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RDI: + switch (type) { + case 'b': return("%dil"); + case 'w': return("%di"); + case 'l': + case 'd': return("%edi"); + case 'q': return("%rdi"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RBP: + switch (type) { + case 'b': return("%bpl"); + case 'w': return("%bp"); + case 'l': + case 'd': return("%ebp"); + case 'q': return("%rbp"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + case REG_RSP: + switch (type) { + case 'b': return("%spl"); + case 'w': return("%sp"); + case 'l': + case 'd': return("%esp"); + case 'q': return("%rsp"); + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + /* + * r8..r15 + */ + case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: + switch (type) { + case 'b': snprintf(buf, buflen, "%%r%ub", r - 29); return buf; + case 'w': snprintf(buf, buflen, "%%r%uw", r - 29); return buf; + case 'l': + case 'd': snprintf(buf, buflen, "%%r%ud", r - 29); return buf; + case 'q': snprintf(buf, buflen, "%%r%u", r - 29); return buf; + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + /* + * xmm0 .. xmm7 + */ + case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: + switch (type) { + case 'x': + snprintf(buf, buflen, "%%xmm%u", r - 21); return buf; + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + /* + * xmm8..xmm15 + */ + case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: + switch (type) { + case 'x': + snprintf(buf, buflen, "%%xmm%u", r - 45 + 8); return buf; + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + + default: + switch (type) { + case 'b': snprintf(buf, buflen, "%%r%ub", r); return buf; + case 'w': snprintf(buf, buflen, "%%r%uw", r); return buf; + case 'l': + case 'd': snprintf(buf, buflen, "%%r%ud", r); return buf; + case 'q': snprintf(buf, buflen, "%%r%u", r); return buf; + case 'x': snprintf(buf, buflen, "%%xmm%u", r); return buf; + default: + bad_register_argument(r, type); + /*NOTREACHED*/ + break; + } + break; + } + return "?"; +} + +static +void register_format(unsigned r, char type) +{ + char buf[BUFSIZ]; + const char *str; + buf[0] = 0; + str = register_format_str(buf, sizeof(buf), r, type); + fputs(str, dump_file); +} + + +static +void bid_format_struct(const amode a) +{ + if (a.string) { + fprintf(dump_file, "%s", a.string); + if (a.disp > 0) { + fprintf(dump_file, "+"); + } + } + /* + * Apparently due to a buglet in gcc4.3.1, + * icg+rtl prints 0(%rbp) for some reason, + * so we want to emulate that so we can diff assembly code output. + */ + if (a.disp != 0 || a.base == REG_RBP) { + fprintf(dump_file, "%d", a.disp); + } + fprintf(dump_file, "("); + if (a.base_valid && !a.base_rip) { + register_format(a.base, 'q'); /* pointers are always 64-bits */ + } else if (a.base_rip) { + fprintf(dump_file, "%%rip"); + } + if (a.scale > 0) { + fprintf(dump_file, ","); + register_format(a.index, 'q'); + if (a.scale > 1) { + fprintf(dump_file, ",%d", a.scale); + } + } + fprintf(dump_file, ")"); +} + +static +void address_format(icg_node *r) +{ + bid_format_struct(r->a); +} + + + +static +void dump(const char *name) +{ + fprintf(dump_file, "\t%s\n", name); +} + + +/* + * single register dst + */ +static +void dumpR(const char *name, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + +/* + * single memory + */ +static +void dumpM(const char *name, icg_node *a) +{ + fprintf(dump_file, "\t%s\t", name); + address_format(a); + fprintf(dump_file, "\n"); +} + + +/* + * 2 register operand + */ +static +void dumpRR(const char *name, + unsigned src, char src_type, + unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + register_format(src, src_type); + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * 3 register operand + */ +static +void dumpRRR(const char *name, + unsigned src1, char src1_type, + unsigned src2, char src2_type, + unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + register_format(src1, src1_type); + fprintf(dump_file, ", "); + register_format(src2, src2_type); + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + +static +void dumpasm_worker(FILE *dump_file, + const char *template, + const char *index_to_str[], size_t nindex_to_str) +{ + if (template) { + const char *cp; + for (cp = template; *cp; cp++) { + switch (*cp) { + case '%': + cp += 1; + if (*cp == '%') { + fputc('%', dump_file); + continue; + } else if (ISDIGIT(*cp) && ((size_t)(*cp-'0')) < nindex_to_str) { + fputs(index_to_str[*cp - '0'], dump_file); + } else { + icg_nyi("unknown or invalid asm escape character '%c' in ``%s''", + *cp, template); + } + break; + default: + fputc(*cp, dump_file); + break; + } + } + } +} + +static +void dumpasmRRR(const char *template, + unsigned src1, char src1_type, + unsigned src2, char src2_type, + unsigned dst, char dst_type) +{ + char dst_fmt[BUFSIZ]; + char src1_fmt[BUFSIZ]; + char src2_fmt[BUFSIZ]; + const char *index_to_str[3]; + + index_to_str[0] = register_format_str(dst_fmt, sizeof(dst_fmt), dst, dst_type); + index_to_str[1] = register_format_str(src1_fmt, sizeof(src1_fmt), src1, src1_type); + index_to_str[2] = register_format_str(src2_fmt, sizeof(src2_fmt), src2, src2_type); + + fprintf(dump_file, "\t"); + dumpasm_worker(dump_file, template, index_to_str, 3); + fprintf(dump_file, "\n"); +} + +/* + * register src, memory dst + */ +static +void dumpRM(const char *name, unsigned src, char src_type, icg_node *a) +{ + (void) dumpRM; + fprintf(dump_file, "\t%s\t", name); + register_format(src, src_type); + fprintf(dump_file, ", "); + address_format(a); + fprintf(dump_file, "\n"); +} + + +static +void dumpRMbid(const char *name, unsigned src, char src_type, + unsigned base, bool base_valid, + unsigned index, int scale, int disp, const char *s) + { + fprintf(dump_file, "\t%s\t", name); + register_format(src, src_type); + fprintf(dump_file, ", "); + { + amode a; + a.base = base; + a.base_valid = base_valid; + a.base_rip = 0; + a.index = index; + a.scale = scale; + a.disp = disp; + a.string = s; + bid_format_struct(a); + } + fprintf(dump_file, "\n"); +} + +/* + * memory src, register dst + */ +static +void dumpMR(const char *name, icg_node *a, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + address_format(a); + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * memory src (bid format), register dst + */ +static +void dumpMbidR(const char *name, + unsigned base, bool base_valid, + unsigned index, int scale, + int disp, const char *s, + unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + { + amode a; + a.base = base; + a.base_valid = base_valid; + a.base_rip = 0; + a.index = index; + a.scale = scale; + a.disp = disp; + a.string = s; + bid_format_struct(a); + } + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + + +/* + * immediate operand + */ +static +void imm_format(icg_node *imm) +{ + fprintf(dump_file, "$"); + if (imm->a.string) { + fprintf(dump_file, "%s", imm->a.string); + if (imm->val > 0) { + fprintf(dump_file, "+%lld", imm->val); + } + else if (imm->val < 0) { + fprintf(dump_file, "%lld", imm->val); + } + } + else + fprintf(dump_file, "%lld", imm->val); +} + + +/* + * immediate src, register dst + */ +static +void dumpIR(const char *name, icg_node *imm, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + imm_format(imm); + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * operator with a count of 1 (used for salq, shrq and sarq) + */ +static +void dumpIR1(const char *name, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t$1,", name); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * operator with a count of -1 (used for sbbl, sometimes) + */ +static +void dumpIRm1(const char *name, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t$1,", name); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * immediate source n, register dst + */ +static +void dumpIRn(const char *name, int n, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t$%d,", name, n); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +/* + * immediate, src register, dst register + */ +static +void dumpIRR(const char *name, icg_node *imm, + unsigned src, unsigned dst, char rt) +{ + fprintf(dump_file, "\t%s\t", name); + imm_format(imm); + fprintf(dump_file, ", "); + register_format(src, rt); + fprintf(dump_file, ", "); + register_format(dst, rt); + fprintf(dump_file, "\n"); +} + +/* + * immediate memory +*/ +static +void dumpIM(const char *name, icg_node *imm, icg_node *a) +{ + fprintf(dump_file, "\t%s\t", name); + imm_format(imm); + fprintf(dump_file, ", "); + address_format(a); + fprintf(dump_file, "\n"); +} + + +/* + * immediate memory register + */ +static +void dumpIMR(const char *name, icg_node *imm, icg_node *a, unsigned dst, char dst_type) +{ + fprintf(dump_file, "\t%s\t", name); + imm_format(imm); + fprintf(dump_file, ", "); + address_format(a); + fprintf(dump_file, ", "); + register_format(dst, dst_type); + fprintf(dump_file, "\n"); +} + + +static +void dump_call(const char *s) +{ + fprintf(dump_file, "\t" "call\t%s\n", s); +} + +/* + * Call indirect through a register + */ +static +void dump_callR(unsigned r) +{ + const char dst_type = 'q'; + fprintf(dump_file, "\t" "call\t*"); + register_format(r, dst_type); + fprintf(dump_file, "\n"); +} + +/* + * Call indirect through a memory location + */ +static +void dump_callM(const amode a) +{ + fprintf(dump_file, "\t" "call\t*"); + bid_format_struct(a); + fprintf(dump_file, "\n"); +} + +/* + * dump register to register copy only if the copy is non trivial + */ +static +void dump_copy(const char *name, unsigned src, unsigned dst, char type) +{ + if (icg_path_compress(src) != icg_path_compress(dst)) { + dumpRR(name, src, type, dst, type); + } +} + +static +void dump_jump(const char *opcode_name, icg_node *p) +{ + const rtx ref = XEXP (p->rtl, 0); + const int ln = CODE_LABEL_NUMBER(ref); + char buf[BUFSIZ]; + fprintf(dump_file, "\t" "%s" "\t", opcode_name); + snprintf(buf, sizeof(buf), ".L%d", ln); + ASM_OUTPUT_LABELREF (dump_file, buf); + fprintf(dump_file, "\n"); +} + +static +void dump_jumpR(const char *opcode_name, unsigned src, char src_type) +{ + fprintf(dump_file, "\t" "%s" "\t", opcode_name); + register_format(src, src_type); + fprintf(dump_file, "\n"); +} + +static +void dump_jumpM(const char *opcode_name, icg_node *a) +{ + fprintf(dump_file, "\t" "%s" "\t", opcode_name); + address_format(a); + fprintf(dump_file, "\n"); +} + +/* + * get an array data structure that maps rule number to grammar source locus + */ +#include "icg-rulemaps.c" + +/* + * Visit each node in the parse tree. + * Print the burm rule if do_burm is non-zero. + * Also print the assembly code. + * Execute the debug portion of the rule as given in the plug spec. + */ +static +void reduce_debug(icg_node *p, NT goalNT, int do_burm, int depth) +{ + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + + if (do_burm) { + icg_trace_rule(dump_file, p, depth, goalNT); + } + icg_burm_kids(p, rule, kid); + /* + * The visit permutation is only valid for non-chain rules with >= 2 nonterminals + */ + if (nts[0] && nts[1] && p->perm_kids >= 2) { + int i; + for (i = 0; i < p->perm_kids; i++) { + const int k = p->perm[i]; + reduce_debug(kid[k], nts[k], do_burm, depth+1); + } + } + else { + int i; + for (i = 0; nts[i]; i++) { + reduce_debug(kid[i], nts[i], do_burm, depth+1); + } + } + switch (rule) { +#include "icg-debug.cases" + } +} + +void icg_trace_rule(FILE *dump_file, const icg_node *p, int depth, NT goalNT) +{ + if (dump_file == 0) dump_file = stdout; + if (p == 0) return; + if (p->state_label) { + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + int i; + for (i = 0; i < depth; i++) { + fputc(' ', dump_file); + } + fprintf(dump_file, "%s (at %s:%d) {rule %d} <tree:%p>\n", + icg_burm_string[rule], + icg_rule_to_locus[rule].filename, + icg_rule_to_locus[rule].line_number, + rule, + (const void *)p + ); + } +} + +static +void bbhook(void) +{ +} + +static +void dump_bb_label(basic_block bb) +{ + rtx label = BB_HEAD(bb); /* do not call block_label, as it will make a new block */ + const int ln = CODE_LABEL_NUMBER(label); + char buf[BUFSIZ]; + if (ln >= 0) { + snprintf(buf, sizeof(buf), ".L%d", ln); + ASM_OUTPUT_LABEL(dump_file, buf); + } else { + bbhook(); + } +} + +/* + * Dump out the entire function. + * First, dump out the burm rules + assembly code. + * Then, dump out just the assembly code. + */ +void +icg_debug(const char *whence) { + (void) dumpRRR; /* shut up gcc "defined but not used" message */ + (void) dumpRMbid; /* shut up gcc "defined but not used" message */ + (void) dump_jumpM; /* shut up gcc "defined but not used" message */ + if (dump_file) { + { + basic_block bb; + fprintf(dump_file, "; START icg_debug part 1 %s {\n", whence); + FOR_EACH_BB(bb) { + rtx insn; + dump_bb_label(bb); + FOR_BB_INSNS(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) + reduce_debug(tree, /*stmt*/1, /*do_burm*/1, 0); + } + } + fprintf(dump_file, "; END icg_debug part 1 %s }\n", whence); + fprintf(dump_file, "\n\n"); + } + + { + basic_block bb; + const char *aname = (IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); + fprintf(dump_file, "; START icg_debug part 2 %s {\n", whence); + + fprintf(dump_file, "\t" ".p2align 4,,15\n"); + fprintf(dump_file, ".globl %s\n", aname); + fprintf(dump_file, "\t" ".type" "\t" "%s, @function\n", aname); + fprintf(dump_file, "%s:\n", aname); + /* see dwarf2out.c */ + ASM_OUTPUT_DEBUG_LABEL (dump_file, FUNC_BEGIN_LABEL, + current_function_funcdef_no); + + FOR_EACH_BB(bb) { + rtx insn; + dump_bb_label(bb); + FOR_BB_INSNS(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) + reduce_debug(tree, /*stmt*/1, /*do_burm*/0, 0); + } + } + fprintf(dump_file, "\t" "ret" "\n"); + /* see dwarf2out.c */ + ASM_OUTPUT_DEBUG_LABEL (dump_file, FUNC_END_LABEL, + current_function_funcdef_no); + fprintf(dump_file, "\t" ".size" "\t" "%s, .-%s\n", aname, aname); + fprintf(dump_file, "; END icg_debug part 2 %s }\n", whence); + } + } +} diff --git a/iburg/briggs/icg-emit.c b/iburg/briggs/icg-emit.c new file mode 100644 index 00000000000..8f7b2252d7a --- /dev/null +++ b/iburg/briggs/icg-emit.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2008 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 + * <http://www.gnu.org/licenses/>. + * + * + * This file implements the out of ICG generation of RTL. + */ + +#include "obstack.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "expr.h" +#include "icg.h" +#include "icg-opcode.h" + + +/* =============================================================== + Helper Functions + =============================================================== */ + +/* Bit Scan right, in terms of the Count Leading Zero rtl opcode */ +static rtx +gen_rtx_BSR_DI(enum machine_mode mode, rtx l) +{ + return gen_rtx_MINUS(mode, GEN_INT(63), gen_rtx_CLZ(mode, l)); +} +static rtx +gen_rtx_BSR_SI(enum machine_mode mode, rtx l) +{ + return gen_rtx_MINUS(mode, GEN_INT(31), gen_rtx_CLZ(mode, l)); +} +static rtx +gen_rtx_BSR_HI(enum machine_mode mode, rtx l) +{ + return gen_rtx_MINUS(mode, GEN_INT(15), gen_rtx_CLZ(mode, l)); +} + +static rtx +gen_rtx_ANDNOT(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_AND(mode, gen_rtx_NOT(mode, l), r); +} + +static rtx +gen_rtx_LT_swap(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_LT(mode, r, l); +} + +static rtx +gen_rtx_LE_swap(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_LE(mode, r, l); +} + +static rtx +gen_rtx_COMPARE_assist(bool is_test_variant, + enum machine_mode cc_mode, enum machine_mode rtx_mode, + rtx l, rtx r) +{ + if (is_test_variant) { + return gen_rtx_COMPARE(cc_mode, gen_rtx_AND(rtx_mode, l, r), GEN_INT(0)); + } else { + return gen_rtx_COMPARE(cc_mode, l, r); + } +} + +static rtx +gen_rtx_DIV_helper(bool issigned, enum machine_mode mode, rtx l, rtx r) +{ + if (issigned) { + return gen_rtx_DIV(mode, l, r); + } else { + return gen_rtx_UDIV(mode, l, r); + } +} + +static rtx +gen_rtx_MOD_helper(bool issigned, enum machine_mode mode, rtx l, rtx r) +{ + if (issigned) { + return gen_rtx_MOD(mode, l, r); + } else { + return gen_rtx_UMOD(mode, l, r); + } +} + +static rtx +gen_rtx_IEEE_MAX_helper(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_UNSPEC(mode, gen_rtvec(2, l, r), UNSPEC_IEEE_MAX); +} + +static rtx +gen_rtx_IEEE_MIN_helper(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_UNSPEC(mode, gen_rtvec(2, l, r), UNSPEC_IEEE_MIN); +} + +static rtx +gen_rtx_ADD_CARRY(enum machine_mode mode, rtx l, rtx r) +{ + return gen_rtx_UNSPEC(mode, gen_rtvec(2, l, r), UNSPEC_ADD_CARRY); +} + +/* + * gen_rtx_addr - generate an rtx for + * base-reg + index-reg * scale + disp + * + * if disp == 0, there is no displacement + * if scale== 0, there is no index register. + * if (!valid), there is no base-reg + */ +static rtx +gen_rtx_addr(enum machine_mode mode, rtx base, rtx index, rtx disp) +{ + return gen_rtx_PLUS(mode, gen_rtx_PLUS(mode, index, disp), base); +} + +static rtx +gen_rtx_imm_constant(long long int val, const char *string, rtx original_rtx) +{ + if (string) { + rtx symbol = 0; + const enum rtx_code expr_code = GET_CODE(original_rtx); + if (expr_code == CONST) { + return original_rtx; + } + /* + * Make a copy of the original_rtx, so that the handles to the constant + * pool will be preserved. + * Symbol is almost surely going to be original_rtx. + */ + symbol = copy_rtx(original_rtx); + if (val) { + return gen_rtx_CONST(DImode, + gen_rtx_PLUS(DImode, symbol, GEN_INT(val))); + } else { + return symbol; + } + } else { + return GEN_INT(val); + } +} + +static rtx +gen_rtx_imm(long long int val, const char *string) +{ + return gen_rtx_imm_constant(val, string, 0); +} + + +static void +dump_insn(rtx node, const char *fname, int lineno) +{ + if (dump_file) { + fprintf(dump_file, " RTL: %s:%d: ", fname ? fname : "", lineno); + print_inline_rtx(dump_file, node, 0); + fprintf(dump_file, "\n"); + } +} + + +/* + * target instructions built from emit_plain do not kill the condition codes + */ +static void +icg_emit_plain(rtx guts) +{ + dump_insn(emit_insn(guts), 0, 0); +} +static void +icg_emit_plain_tagged(rtx guts, const char *fname, int lineno) +{ + rtx emit_rtx = emit_insn(guts); + dump_insn(emit_rtx, fname, lineno); +} + + +/* + * target instructions built from emit_plain do kill the condition codes + */ +static void +icg_emit_clobber(rtx guts) +{ + rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, gen_rtvec(2, guts, clobber)); + icg_emit_plain(parallel); +} + +/* + * This is the preferred entry point. Pass in file name and line number + * so that we can emit more accurate error messages if need be + */ +static void +icg_emit_clobber_tagged(rtx guts, const char *fname, int lineno) +{ + rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, gen_rtvec(2, guts, clobber)); + icg_emit_plain_tagged(parallel, fname, lineno); +} + + +/* =============================================================== */ +#include "icg-ruleinfo.h" +unsigned icg_rulecount[PLUG_NRULES]; +void icg_print_rulecount(FILE *dump_file, int dump_code) +{ + int rn; + if (dump_file == 0) { + dump_file = stdout; + } + { + const char *msg; + if (dump_code < 0) { + msg = "All rules."; + } else if (dump_code == 0) { + msg = "Rules that were NOT used"; + } else { + msg = "Rules that were used"; + } + fprintf(dump_file, "# %s\n", msg); + } + for (rn = 0; rn < PLUG_NRULES; rn++) { + if (0 + || (dump_code < 0) + || (dump_code == 0 && icg_rulecount[rn] == 0) + || (dump_code > 0 && icg_rulecount[rn] > 0) + ) { + if (icg_burm_string[rn]) { + fprintf(dump_file, "%5d %4d %s\n", + rn, + icg_rulecount[rn], + icg_burm_string[rn]); + } + } + } +} + +void icg_read_rulecount(FILE *read_file) +{ + char buf[BUFSIZ]; + int rn = 0; + int count = 0; + while (fgets(buf, sizeof(buf), read_file) == buf) { + if (buf[0] == '#') { + continue; + } + if (sscanf(buf, "%d %d", &rn, &count) == 2) { + icg_rulecount[rn] = count; + } + } +} +void icg_dump_rulecount(void) +{ + icg_print_rulecount(stdout, 1); +} + + +static const char *icg_rulecount_fname = "icg_rulecount.dump"; +static +void end_reduce_emit_rtl(void) +{ + FILE *icg_rulecount_file = fopen(icg_rulecount_fname, "w"); + if (icg_rulecount_file) { + if (1) { + icg_print_rulecount(icg_rulecount_file, -1); + } else { + /*const size_t nitems =*/ fwrite(icg_rulecount, + sizeof(icg_rulecount[0]), PLUG_NRULES, icg_rulecount_file); + fclose(icg_rulecount_file); icg_rulecount_file = 0; + } + } +} + +static +void start_reduce_emit_rtl(void) +{ + FILE *icg_rulecount_file = fopen(icg_rulecount_fname, "r"); + if (icg_rulecount_file) { + if (1) { + icg_read_rulecount(icg_rulecount_file); + } else { + struct stat sbuf; + if (stat(icg_rulecount_fname, &sbuf) < 0 + || (sbuf.st_size != sizeof(icg_rulecount))) { + /*VOID*/ + } else { + /*const size_t nitems =*/ fread(icg_rulecount, + sizeof(icg_rulecount[0]), PLUG_NRULES, icg_rulecount_file); + fclose(icg_rulecount_file); icg_rulecount_file = 0; + } + } + } + atexit(end_reduce_emit_rtl); +} + +static +void reduce_emit_rtl(icg_node *p, NT goalNT) +{ + icg_node *kid[MAX_KIDS]; + + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + p->goalNT = goalNT; + + { + /* + * profile rule number usage + */ + static int did_reduce_emit_rtl = 0; + if (!did_reduce_emit_rtl) { + start_reduce_emit_rtl(); + } + did_reduce_emit_rtl += 1; + icg_rulecount[rule] += 1; + } + + icg_burm_kids(p, rule, kid); + /* + * The visit permutation is only valid for non-chain rules with >= 2 nonterminals + */ + if (nts[0] && nts[1] && p->perm_kids >= 2) { + int i; + for (i = 0; i < p->perm_kids; i++) { + const int k = p->perm[i]; + reduce_emit_rtl(kid[k], nts[k]); + } + } + else { + int i; + for (i = 0; nts[i]; i++) { + reduce_emit_rtl(kid[i], nts[i]); + } + } + + switch (rule) { +#include "icg-emit.cases" + } +} + +void icg_emit(void) +{ + basic_block bb; + (void)gen_rtx_LT_swap; + (void)gen_rtx_LE_swap; + (void)gen_rtx_imm; + (void)gen_rtx_ADD_CARRY; + + if (dump_file) { + fprintf(dump_file, "===== start Emit ===== {\n"); + } + + FOR_EACH_BB(bb) { + rtx insn, curr; + FOR_BB_INSNS_SAFE(bb, insn, curr) { + const unsigned id = INSN_UID(insn); + + icg_node *p = icg_insn2tree[id]; + if (p) { + rtx current_insn; + icg_insn2goalNT[id] = p->goalNT; + if (dump_file) { + fprintf (dump_file, "Emit: <tree:%p>", (void *)p); + if (0) { + /* this is not too useful, as it is only for the root */ + icg_trace_rule (dump_file, p, 0, p->goalNT); + } + print_inline_rtx (dump_file, insn, 0); + fprintf (dump_file, "\n"); + } + + start_sequence(); + reduce_emit_rtl(p, burm_goal_NT); + current_insn = get_insns(); + end_sequence(); + + if (current_insn) { + emit_insn_before(current_insn, insn); + delete_insn(insn); + } + } + } + } + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + + if (dump_file) { + fprintf(dump_file, "===== end Emit ===== }\n"); + } + +} diff --git a/iburg/briggs/icg-filter.c b/iburg/briggs/icg-filter.c new file mode 100644 index 00000000000..b437e612852 --- /dev/null +++ b/iburg/briggs/icg-filter.c @@ -0,0 +1,415 @@ +/* Decide whether to use IRA or ICG at function granularity. + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "tm_p.h" +#include "errors.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "df.h" +#include "langhooks.h" +#include "icg.h" + +#define MAX_NAME_SIZE 256 + +static int original_flag_icg = -1; +static int original_flag_late_codegen = -1; + +/* Strip leading and trailing white space and comments from line. + Modifies STR. Stupid C, I hate you. */ + +static +char *strip_string(char *str) +{ + char *start, *end; + + for (start = str; + *start && (*start == ' ' || *start == '\t' || *start == '\n'); + start++) { } + if (*start) + { + for (end = start; *end; end++) { + if (*end == '#') + { + *end = '\0'; + break; + } + } + for (; end >= start && (*end == '\0' || *end == ' ' + || *end == '\t' || *end == '\n'); end--) + *end = '\0'; + } + return start; +} + + +/* Reads in a file specified by FLAG_VALUE into NAMES. Memory is + allocated for NAMES. Returns sense of filter based on + existence of leading '-' in FLAG_VALUE. */ + +static bool +read_allocate_names (const char *flag_value, char ***names) +{ + const char *filename; + bool sense; + int n, nlines; + char buf[MAX_NAME_SIZE] ; + FILE *fp; + + /* FLAG_VALUE always begins with '='. */ + gcc_assert (flag_value[0] == '='); + if (flag_value[1] == '-') { + sense = true; + filename = &(flag_value[2]); + } else { + sense = false; + filename = &(flag_value[1]); + } + fp = fopen (filename, "r"); + if (fp == NULL) + internal_error ("Can't open ICG filter file \"%s\".", filename); + + /* First run through, count number of lines. */ + nlines = 0; + while (fgets (buf, MAX_NAME_SIZE, fp) == buf) + if (*(strip_string (buf))) + nlines++; + *names = XNEWVEC (char *, nlines + 1); + (*names)[nlines] = NULL; + + /* Second run, save lines. */ + rewind(fp); + n = 0; + while (fgets (buf, MAX_NAME_SIZE, fp) == buf) + { + char *str = strip_string (buf); + if (*str) + { + gcc_assert (n < nlines); + (*names)[n] = XNEWVEC (char, MAX_NAME_SIZE); + strncpy((*names)[n], str, MAX_NAME_SIZE); + n++; + } + } + fclose(fp); + return sense; +} + +/* Returns TRUE if NAME is in NAMES, where NAMES is created with + read_allocate_names. */ + +static bool +name_in_array_p (const char *name, char **names) +{ + int i; + for (i = 0; names[i]; i++) + if (strcmp (name, names[i]) == 0) + return true; + return false; +} + +#define REJECT(msg) { \ + fflush(stdout); \ + fprintf(stderr, "ICG rejects \"%s\" (%s): %s\n", dname, aname, msg); \ + return true; \ +} + +/* + * Return TRUE if this node is to be rejected, + * eg it appears to contain things that the rest of ICG can not handle. + */ +static +bool icg_filter_walk_rtx_tree_test(rtx insn, const char *dname, const char *aname) +{ + enum rtx_code this_code; + enum machine_mode this_mode; + + this_code = GET_CODE(insn); + this_mode = GET_MODE(insn); + + switch (this_mode) { + + case XFmode: + REJECT("XFmode"); + /*NOTREACHED*/ + + case TFmode: + REJECT("TFmode"); + /*NOTREACHED*/ + + default: + break; + } + + switch (this_code) { + + case UNSPEC: + { + const int unspec_code = XINT(insn, 1); + if (unspec_code == UNSPEC_SSE_PROLOGUE_SAVE) { + REJECT("UNSPEC_SSE_PROLOGUE_SAVE in function"); + /*NOTREACHED*/ + } + if (unspec_code == UNSPEC_ADD_CARRY) { + REJECT("UNSPEC_ADD_CARRY in function"); + /*NOTREACHED*/ + } + } + break; + + case UNSPEC_VOLATILE: + { + const int unspec_code = XINT(insn, 1); + char buf[BUFSIZ]; + /* + * some candidates: + * UNSPEC_SET_GOT (done as a pattern sync_old_addsi), code: lock xaddl %eax + * (tarpit to support UNSPEC_SET_GOT in gcc/config/i386) + */ + snprintf(buf, sizeof(buf), + "unspec_volatile code in function: %d", unspec_code); + REJECT(buf); + /*NOTREACHED*/ + } + break; + + case ASM_OPERANDS: + { + const char *template = ASM_OPERANDS_TEMPLATE(insn); + char buf[BUFSIZ]; + snprintf(buf, sizeof(buf), "asm in function: \"%s\"", + template ? template : "?"); + if (icg_analyze_asm(insn, ICG_ASM_PHASE_FILTER)) { + fflush(stdout); + fprintf(stderr, "ICG consumes asm \"%s\" (%s): %s\n", dname, aname, buf); \ + /* We will attempt to accept this */ + } else { + REJECT(buf); + } + } + break; + + default: + break; + } + return false; /* this node is not rejected, eg it is accepted */ +} + +typedef struct icg_filter_closure_ { + const char *dname; + const char *aname; +} icg_filter_closure; + +/* + * This is a worker function for for_each_rtx. + * Return -1 to stop traversing sub expressions. + * Return 0 to continue traversing. + * Otherwise stop traversal immediately; we'll do this when we reject the tree. + */ +static +int icg_filter_walk_worker(rtx *x, void *data) +{ + const icg_filter_closure *cl = (const icg_filter_closure *)data; + if (x && *x) { + rtx insn = *x; + const bool node_rejected = icg_filter_walk_rtx_tree_test(insn, cl->dname, cl->aname); + if (node_rejected) { + return 1; /* return 1 immediately */ + } + } + return 0; /* continue traversing */ +} + +/* + * Return TRUE iff ICG rejects this tree as a candidate, + * eg return FALSE if ICG should accept this tree + * (Note logical inversion with skip_icg_p.) + */ +static +bool icg_filter_walk_rtx_tree(rtx insn, const char *dname, const char *aname) +{ + icg_filter_closure cld; + icg_filter_closure *cl = &cld; + bool is_rejected = false; + cl->dname = dname; + cl->aname = aname; + is_rejected = for_each_rtx(&insn, icg_filter_walk_worker, cl); + return is_rejected; +} + +/* Programmatically determine whether the function should be compiled + with ICG. (Note logical inversion with + icg_filter_walk_rtx_tree). */ + +static bool +skip_icg_programmatic_p (const char *dname, const char *aname) +{ + basic_block bb; + rtx insn; + + FOR_EACH_BB (bb) { + FOR_BB_INSNS (bb, insn) { + if (INSN_P (insn)) { + if (icg_filter_walk_rtx_tree(insn, dname, aname) == true) { + /* + * There's a rejected node somewhere in the tree. We return + * true indicating that we do not accept the tree. + */ + return true; + } + } + } + } + return false; +} + +/* Return TRUE iff ICG should not be applied to the current function based + on flag_icg_filter_file option. */ + +static bool +skip_icg_file_p (const char *dname, const char *aname) +{ + static char **names = NULL; + static bool skip_sense; + bool match; + + gcc_assert (flag_icg_filter_file); + if (!names) + skip_sense = read_allocate_names (flag_icg_filter_file, &names); + + match = name_in_array_p (main_input_filename, names); + if (skip_sense && match) + REJECT ("filename name matches in icg-filter reject file"); + if (!skip_sense && !match) + REJECT ("filename name not in icg-filter accept file"); + return false; +} + + +/* Return TRUE iff ICG should not be applied to the current function + based on flag_icg_filter_function option. */ + +static bool +skip_icg_function_p (const char *dname, const char *aname) +{ + static char **names = NULL; + static bool skip_sense; + bool match; + + gcc_assert (flag_icg_filter_function); + if (!names) + skip_sense = read_allocate_names (flag_icg_filter_function, &names); + + match = name_in_array_p (dname, names) || name_in_array_p (aname, names); + if (skip_sense && match) + REJECT ("function name matches in icg-filter reject file"); + if (!skip_sense && !match) + REJECT ("function name not in icg-filter accept file"); + return false; +} + +#undef REJECT + +/* Return TRUE iff ICG should not be applied to the current function + based on -ficg-filter-* flags. */ + +static bool +skip_icg_p (void) +{ + const char *dname = current_function_name(); + const char *aname = current_function_assembler_name(); + + if (flag_icg_filter_program && + skip_icg_programmatic_p (dname, aname)) { + return true; + } + + if (flag_icg_filter_file && skip_icg_file_p (dname, aname)) { + return true; + } + + if (flag_icg_filter_function && skip_icg_function_p (dname, aname)) { + return true; + } + + fflush(stdout); + fprintf(stderr, "ICG accepts \"%s\" (%s)\n", dname, aname); + return false; +} + +/* Decide whether to use ICG or IRA for this function and set the + flags accordingly. */ + +static unsigned +rest_of_handle_icg_filter (void) +{ + if (skip_icg_p ()) + { + flag_icg = 0; + flag_late_codegen = 1; + flag_ira = 1; + } + else + { + flag_icg = 1; + flag_late_codegen = original_flag_late_codegen; + flag_ira = 0; + } + return 0; +} + +static bool +gate_icg_filter (void) +{ + if (original_flag_icg == -1) + { + original_flag_icg = flag_icg; + original_flag_late_codegen = flag_late_codegen; + } + + return (original_flag_icg && (flag_icg_filter_program + || flag_icg_filter_file + || flag_icg_filter_function)); +} + + +struct rtl_opt_pass pass_icg_filter = +{ + { + RTL_PASS, + "icg", /* name */ + gate_icg_filter, /* gate */ + rest_of_handle_icg_filter, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + } +}; diff --git a/iburg/briggs/icg-final.c b/iburg/briggs/icg-final.c new file mode 100644 index 00000000000..085dd3ba58f --- /dev/null +++ b/iburg/briggs/icg-final.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "flags.h" + +#include "icg.h" + +#define find(r) (icg_reg_vector[r].root) + +static +void reduce_final(icg_node *p, NT goalNT) { + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + reduce_final(kid[i], nts[i]); + switch (rule) { +#include "icg-final.cases" + } +} + + +void icg_final(void) +{ + basic_block bb; + if (frame_pointer_needed) { + icg_reg_vector[REG_FP].root = REG_RBP; + icg_reg_vector[REG_ARGP].root = REG_RBP; + } + else { + icg_reg_vector[REG_FP].root = REG_RSP; + icg_reg_vector[REG_ARGP].root = REG_RSP; + } + + if (dump_file) { + unsigned r; + for (r = 0; r < icg_interior_regs; r++) + fprintf(dump_file, "r = %3d, root = %3d, color = %3d\n", + r, icg_reg_vector[r].root, icg_reg_vector[r].color); + } + + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS(bb, insn) { + int id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + reduce_final(tree, burm_goal_NT); + } + } + } +} diff --git a/iburg/briggs/icg-forward-prop.c b/iburg/briggs/icg-forward-prop.c new file mode 100644 index 00000000000..741dda6be3e --- /dev/null +++ b/iburg/briggs/icg-forward-prop.c @@ -0,0 +1,361 @@ +/* + * Performs a pass of forward propagation of the side-tree data structure. + * Intended to run after the update finder and aims to catch opportunities + * exposed by the update finder (i.e., when what used to be 2 references + * becomes a single reference). + * + * The idea is to examine all the expressions defined in each basic block. + * If the expression is used once inside the block (and nowhere else), + * then we'd like to propagate it forward to its use. This'll allow + * better matching during instruction selection. + */ + +#include "obstack.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "icg.h" +#include "icg-opcode.h" +#include "insn-constants.h" +#include "sparseset.h" + + + +sparseset live_set, interesting, dup_set; + +static +void check_refs(icg_node *tree) { + if (tree) { + check_refs(tree->left); + check_refs(tree->right); + if (REG_DI <= tree->op && tree->op <= REG_SF) { + if (!sparseset_bit_p(live_set, tree->r)) { + if (sparseset_bit_p(interesting, tree->r)) + sparseset_set_bit(dup_set, tree->r); + else + sparseset_set_bit(interesting, tree->r); + } + } + } +} + + + +static +void check_lhs(icg_node *tree) { + if (REG_DI <= tree->op && tree->op <= REG_SF) + ; + else if (REGX_DI <= tree->op && tree->op <= REGX_SF) + ; + else if (SUBREG_DI <= tree->op && tree->op <= SUBREG_SF) + check_lhs(tree->left); + else + check_refs(tree); +} + + + +static +void rewrite_refs(icg_node *tree) { + if (tree) { + rewrite_refs(tree->left); + rewrite_refs(tree->right); + if (REG_DI <= tree->op && tree->op <= REG_SF && sparseset_bit_p(interesting, tree->r)) { + tree->rx = tree->r; + tree->op = tree->op - REG_DI + REGX_DI; + } + } +} + + + +static +void rewrite_lhs(icg_node *tree) { + if (REG_DI <= tree->op && tree->op <= REG_SF) + ; + else if (REGX_DI <= tree->op && tree->op <= REGX_SF) + ; + else if (SUBREG_DI <= tree->op && tree->op <= SUBREG_SF) + rewrite_lhs(tree->left); + else + rewrite_refs(tree); +} + + + +static +void update_refs(icg_node *tree) { + if (tree) { + update_refs(tree->left); + update_refs(tree->right); + if (REG_DI <= tree->op && tree->op <= REG_SF) + sparseset_set_bit(live_set, tree->rx); + else if (REGX_DI <= tree->op && tree->op <= REGX_SF) + sparseset_set_bit(live_set, tree->rx); + } +} + + + +static +void update_lhs(icg_node *tree) { + if (REG_DI <= tree->op && tree->op <= REG_SF) + sparseset_clear_bit(live_set, tree->r); + else if (REGX_DI <= tree->op && tree->op <= REGX_SF) + sparseset_clear_bit(live_set, tree->rx); + else if (SUBREG_DI <= tree->op && tree->op <= SUBREG_SF) + update_lhs(tree->left); + else + update_refs(tree); +} + + + +/* + * We need to walk backwards over the basic block, + * looking for oppoertunities to rewrite REG references to REGX references. + * These opportunities occure naturally when finding updates. + * They're important to get because they indicate when a register goes dead, + * which in turn helps control the forward propagation. + */ + +static +void redo_dfa(basic_block bb) { + rtx insn; + unsigned i; + unsigned *live_out = icg_lr_liveout[bb->index]->name; + unsigned n = icg_lr_liveout[bb->index]->size; + + sparseset_clear(live_set); + for (i = 0; i < n; i++) + sparseset_set_bit(live_set, live_out[i]); + + if (dump_file) { + fprintf(dump_file, "\n\tlive-out = { "); + for (i = 0; i < icg_live_ranges; i++) + if (sparseset_bit_p(live_set, i)) + fprintf(dump_file, "%d ", i); + fprintf(dump_file, "}\n"); + } + + FOR_BB_INSNS_REVERSE(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + /* look for REG refs that should be REGX */ + sparseset_clear(interesting); + sparseset_clear(dup_set); + if (tree->op == SET_ALL) { + check_lhs(tree->left); + check_refs(tree->right); + } + else + check_refs(tree); + sparseset_and_compl(interesting, interesting, dup_set); + + /* rewrite interesting REG refs to REGX */ + if (sparseset_cardinality(interesting) > 0) { + if (tree->op == SET_ALL) { + rewrite_lhs(tree->left); + rewrite_refs(tree->right); + } + else + rewrite_refs(tree); + } + + /* update live_set */ + if (tree->op == SET_ALL) { + update_lhs(tree->left); + update_refs(tree->right); + } + else + update_refs(tree); + } + } + + if (dump_file) { + fprintf(dump_file, "\tlive-in = { "); + for (i = 0; i < icg_live_ranges; i++) + if (sparseset_bit_p(live_set, i)) + fprintf(dump_file, "%d ", i); + fprintf(dump_file, "}\n"); + } +} + + + + + + +struct obstack prop_obstack; + +typedef struct dep { + unsigned lr; + struct dep *next; +} Dep; + + +Dep *mem_deps; +Dep **reg_dep; + +struct _icg_node **reg_def; + +static +void cleanup(Dep *dep) { + while (dep) { + reg_def[dep->lr] = 0; + dep = dep->next; + } +} + + +/* + * if we see a REG reference, then we delete any associated definition, + * since we don't want to propagate things that have multiple uses. + */ + +static +void look_for_reg_refs(icg_node *tree) { + if (tree) { + look_for_reg_refs(tree->left); + look_for_reg_refs(tree->right); + if (REG_DI <= tree->op && tree->op <= REG_QI) + reg_def[tree->r] = 0; + } +} + + +static +Dep *add_dep_to_list(unsigned r, Dep *list) { + Dep *dep = (Dep *) obstack_alloc(&prop_obstack, sizeof(Dep)); + dep->lr = r; + dep->next = list; + return dep; +} + + +static +void collect_dependences(unsigned r, icg_node *tree) { + if (tree) { + collect_dependences(r, tree->left); + collect_dependences(r, tree->right); + if (REGX_DI <= tree->op && tree->op <= REGX_QI) + reg_dep[tree->rx] = add_dep_to_list(r, reg_dep[tree->rx]); + else if (REG_DI <= tree->op && tree->op <= REG_QI) + reg_dep[tree->r] = add_dep_to_list(r, reg_dep[tree->r]); + else if (MEM_DI <= tree->op && tree->op <= MEM_QI) + mem_deps = add_dep_to_list(r, mem_deps); + } +} + + +static +void handle_def(unsigned r, icg_node *expr) { + reg_def[r] = expr; + collect_dependences(r, expr); +} + + +static +void forward_prop(basic_block bb) { + rtx insn; + unsigned i; + mem_deps = 0; + for (i = 0; i < icg_live_ranges; i++) { + reg_dep[i] = 0; + reg_def[i] = 0; + } + FOR_BB_INSNS(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + look_for_reg_refs(tree); + switch (tree->op) { + case SET_ALL: { + icg_node *left = tree->left; + if (REGX_DI <= left->op && left->op <= REGX_QI) + handle_def(left->rx, tree->right); + else if (REG_DI <= left->op && left->op <= REG_QI) + handle_def(left->r, tree->right); + else if (SUBREG_DI <= left->op && left->op <= SUBREG_QI) { + if (REGX_DI <= left->left->op && left->left->op <= REGX_QI) + handle_def(left->rx, tree->right); + else if (REG_DI <= left->left->op && left->left->op <= REG_QI) + handle_def(left->r, tree->right); + else + cleanup(mem_deps); + } + else + cleanup(mem_deps); + break; + } + case MEM_PLUS_DI: case MEM_PLUS_SI: case MEM_PLUS_HI: case MEM_PLUS_QI: + case MEM_MINUS_DI: case MEM_MINUS_SI: case MEM_MINUS_HI: case MEM_MINUS_QI: + case MEM_NEG_DI: case MEM_NEG_SI: case MEM_NEG_HI: case MEM_NEG_QI: + case MEM_NOT_DI: case MEM_NOT_SI: case MEM_NOT_HI: case MEM_NOT_QI: + case MEM_AND_DI: case MEM_AND_SI: case MEM_AND_HI: case MEM_AND_QI: + case MEM_IOR_DI: case MEM_IOR_SI: case MEM_IOR_HI: case MEM_IOR_QI: + case MEM_XOR_DI: case MEM_XOR_SI: case MEM_XOR_HI: case MEM_XOR_QI: + case MEM_ASHIFT_DI: case MEM_ASHIFT_SI: case MEM_ASHIFT_HI: case MEM_ASHIFT_QI: + case MEM_LSHIFTRT_DI: case MEM_LSHIFTRT_SI: case MEM_LSHIFTRT_HI: case MEM_LSHIFTRT_QI: + case MEM_ASHIFTRT_DI: case MEM_ASHIFTRT_SI: case MEM_ASHIFTRT_HI: case MEM_ASHIFTRT_QI: + case MEM_ROTATE_DI: case MEM_ROTATE_SI: case MEM_ROTATE_HI: case MEM_ROTATE_QI: + case MEM_ROTATERT_DI: case MEM_ROTATERT_SI: case MEM_ROTATERT_HI: case MEM_ROTATERT_QI: { + icg_node *mem = tree->left; + icg_node *addr = mem->left; + if (REGX_DI <= addr->op && addr->op <= REGX_QI) { + unsigned r = addr->rx; + if (reg_def[r]) { + + } + } + cleanup(mem_deps); + break; + } + default: + cleanup(mem_deps); + break; + } + } + } +} + + + + + +void icg_forward_prop(void) { + basic_block bb; + void *big_mark; + + if (dump_file) + fprintf(dump_file, "\nstarting forward prop\n"); + + live_set = sparseset_alloc(icg_live_ranges); + dup_set = sparseset_alloc(icg_live_ranges); + interesting = sparseset_alloc(icg_live_ranges); + + gcc_obstack_init(&prop_obstack); + big_mark = obstack_alloc(&prop_obstack, 0); + reg_dep = (Dep **) obstack_alloc(&prop_obstack, icg_live_ranges*sizeof(Dep *)); + reg_def = (struct _icg_node **) obstack_alloc(&prop_obstack, icg_live_ranges*sizeof(struct _icg_node *)); + FOR_EACH_BB(bb) { + void *prop_mark = obstack_alloc(&prop_obstack, 0); + redo_dfa(bb); + forward_prop(bb); + obstack_free(&prop_obstack, prop_mark); + } + obstack_free(&prop_obstack, big_mark); + sparseset_free(live_set); + sparseset_free(dup_set); + sparseset_free(interesting); + + if (dump_file) + fprintf(dump_file, "finished forward prop\n\n"); +} diff --git a/iburg/briggs/icg-grammars/Makefile b/iburg/briggs/icg-grammars/Makefile new file mode 100644 index 00000000000..1812d503e43 --- /dev/null +++ b/iburg/briggs/icg-grammars/Makefile @@ -0,0 +1,32 @@ +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# +.PHONY: x +PYFILES = \ + x86-64.gr.py \ + x86-64.float.py \ + x86-64.int.py \ + x86-64.misc.py \ + x86-64.string.py \ + x86-64.asm.py \ +# + +VICTIM = x86-64.int.py + +.PHONY: all shard +all: $(PYFILES:%.py=%.pyout) Makefile + +%.pyout: %.py plug.py x86-64.gr.py Makefile + python $< > $@ + +.PHONY: shard +shard: $(VICTIM) shardgrammar + ./shardgrammar $< + +shardgrammar: shardgrammar.cc Makefile + g++ -g -Wall -o $@ $< + +.PHONY: clean +clean: + rm -rf shardgrammar tmp/ *.pyout shards/ diff --git a/iburg/briggs/icg-grammars/TODO b/iburg/briggs/icg-grammars/TODO new file mode 100644 index 00000000000..1b64da21f01 --- /dev/null +++ b/iburg/briggs/icg-grammars/TODO @@ -0,0 +1,86 @@ +Fri Oct 10 10:58:19 PDT 2008 + testvector.cc loop bottom comparision uses cmpl(icg), not cmpq (ira). + The index is an int, subregs occur. + +Fri Oct 17 14:28:41 PDT 2008 + gcc prefers movapd over movsd for moving xmm registers around + +Thu Oct 30 12:48:14 PDT 2008 + Unary {negate,complement,update} of memory (update of memory, + requires semantic analysis before syntactic matching) + +Get plug to accept \n inside of string constants used directly in printf statements + +Fortran integer(1) operations produce operators such as IDIV_QI and related. + +Rename find to icg_find, and implement as a function that can be called. + +06Nov2008 + need to add "leave" instruction and tidy up the entry/exit sequence + +Fri Nov 7 14:31:36 PST 2008 + need to handle generation of "js" instead of "jl", which requires tracking + CCGOCmode (garbage overflow/carry) somehow, which might require a new NT + to parallel rcc and its friends. This turned up in code that converts + a uint64 to a double. + +Thu Dec 4 10:27:50 PST 2008 + zippy compiled -O3 stumbles across UNSPEC_ADD_CARRY, + but I don't see an addc in the ira output + +Sun Dec 7 09:35:47 PST 2008 + both IRA and IG fail to find the code "cmpb ...; adcl $0, *(addr)", + eg a mem update form of an existing idiom for doing conditional increments. + +Thu Dec 4 10:27:50 PST 2008 + In examining diffs between ira and icg, here are some new ones to + add to the gallery; I'm omitting existing well-known differences + such as wiffing associative operators. + + IRA: + testq %rax, %rax + jns .L30 + + ICG: + movabsq $9223372036854775807, %rcx + cmpq %rcx, %rax + jbe .L30 + (That's 0x7fffffffffffffff, eg MAX_INT64) + ------------------------- + IRA: + cmpq %rdx, %rax + je .L84 + cmpq %rdx, %rax + ja .L85 + + ICG: + cmpq %rdx, %rax + je .L84 + ja .L85 + ----------------------------- + + IRA: + testb $4, %dil + ICG: + testl $4, %edi + + + ----------------------------- + IRA: + testb $1, %al + ICG: + andl $1, $eax ; # %eax is dead + + ------------------ + ICG seems to have an extra move to set up actual argument 0 + to a function call, but at the same call site saves a move of the return value. + + ------------------- + Our code surrounding __builtin_strlen is different/wrong, but that instruction + sequence involving "repnz scasb" isn't fully debugged. + + ------------------------ + I'm seeing additional register to register moves in ICG. + + ------------------- + diff --git a/iburg/briggs/icg-grammars/plug.py b/iburg/briggs/icg-grammars/plug.py new file mode 100644 index 00000000000..14230ce4d6a --- /dev/null +++ b/iburg/briggs/icg-grammars/plug.py @@ -0,0 +1,489 @@ +#{([ + +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +# -*- mode: python -*- + +import inspect +import os +import parser +import pprint +import re +import string +import symbol +import sys +import token +import types + +# +# Plug nonterminals are lexically all in lower case, _ or digits; +# Python fortunately matches this with islower. +# +def is_plug_nonterm(symbol): + return symbol.islower() + +# +# Plug terminals are lexically all in upper case, _ or digits; +# Python fortunately matches this with isupper. +# +def is_plug_term(symbol): + return symbol.isupper() + +do_shards = False +if do_shards: + dir = "shards" + if os.path.isdir(dir) == False: + os.mkdir(dir) + +def plugrule3(handle, table, actions, trace=0): + plug_basicrule(handle, table, actions, trace) + +def plugrule2(table, actions, trace=0): + plug_basicrule(None, table, actions, trace) + +def plug_basicrule(handle, table, actions, trace): + global global_rule_to_locus + global global_file_has_been_read + + trace = 0 + frames = inspect.getouterframes(inspect.currentframe()) + frame = frames[2] # frames for: plug_basic_rule, plugrule3 + + last_file_name = frame[1] # full path + last_line_number = frame[2] # last line at call site + actions_start_line_number = last_line_number - actions.count("\n") + + # + # Assuming standard formatting of plug rules, there's exactly one line + # in the table for each plug rule and its attributes. + # However, comments in python are discarded and do NOT appear + # in the table (a tuple). + # + # We'll compensate for this by reading the entire .py file + # as a text file, and extract the rules from that, + # and keep track of a map from rule name to file locus. + # + line_number = actions_start_line_number - len(table); + file_name = os.path.basename(last_file_name); + + # + # Read the file name as a text file to get an exact source file locus. + # (The file is read only once.) + # + read_file_as_text(last_file_name) + + # + # The variable handle names the block of rules and semantic actions. + # + if handle == None: + handle = file_name + "-" + str(line_number); + + # + # The variable errorlocus names the conventional file:linenumber. + # + errorlocus = file_name + ":" + str(actions_start_line_number) + + # + # Print out the actions to a file named by the handle. + # We can then use tkdiff to compare different actions + # so that we can manually figure out how to merge together + # blocks of rules that share similar semantics. + # + if do_shards: + shard_fd = open(dir + "/" + handle, "w"); + print >>shard_fd, "// %s line %d" % (file_name, line_number); + print >>shard_fd, "%s\n" % actions + shard_fd.close() + shard_fd = None + + transtab = string.maketrans('', ''); + var_val_map = {} + rownumber = -1 + vars = table[0] + for vals in table[1:]: + rownumber += 1 + if trace: + print "rn=%d vals=%s" % (rownumber, vals) + + # + # new_actions will be rewritten according to the bindings + # established by reference to nonterminals + # or by reference to table header variables. + # + new_actions = actions + var_val_map.clear() + for i in xrange(len(vars)): + var = vars[i] # name of variable + val = vals[i] # value to substitute + if trace: + print "var=%s val=%s" % (var, val) + + if var == "rule": + current_textual_rule = val.translate(transtab, string.whitespace) + # + # Analyze the rule, returning the map ntref_to_pos + # from NT names or NT aliases to burg rhs NT positions. + # Here, val is the entire rule body. + # + ntref_to_pos, ntref_to_nt = plug_analyze_rule(val, + file_name, line_number) + + # + # Given NT specs of the form xyz.suffix remove .suffix + # .suffix is an alias for the NT that is used to turn + # .suffix named nonterminals into positional references on the rhs. + # + re_object = re.compile(r'\.\b[a-z_0-9]+\b') + val = re_object.sub('', val, 0) + + # + # Set up to use safe_substitute + # to substitute occurances of $var for val. + # + var_val_map[var] = val + + check_attr_use(file_name, actions_start_line_number, + ntref_to_nt, actions, trace) + + # + # The function safe_substitute will change $$ to just $, + # but we have to preserve the $$ for plug usage. + # (There may be a way to change this behaviour with subclassing Template) + # So we rewrite $$ to $lhs, + # and then use Template.safe_substitute to map $lhs to $$. + # + re_object = re.compile(r'\$\$') + new_actions = re_object.sub('$lhs', new_actions, 0) + + t0 = string.Template(new_actions) + new_actions = t0.safe_substitute(var_val_map) + + t1 = string.Template(new_actions) + new_actions = t1.safe_substitute(ntref_to_pos) + + # + # Print out the rewritten actions, with preprocessor style + # line coordinates suitable for plug/C++. + # There's one coordinate for the rule, + # and another coordinate for the semantic actions. + # + global global_rule_to_locus + if global_rule_to_locus.has_key(current_textual_rule): + text_file_name = global_rule_to_locus[current_textual_rule][0] + text_line_number = global_rule_to_locus[current_textual_rule][1] + print "#line %d \"%s\"" % (text_line_number, text_file_name) + else: + print "#line %d \"%s\"" % (line_number, file_name) + + new_actions = new_actions.strip() + outnumber = 0 + for line in new_actions.split("\n"): + outnumber += 1 + if outnumber == 2: + # + # Bias up the starting line number for the actions so + # we can compensate for the $rule $cost line. + # + print "#line %d \"%s\"" % (actions_start_line_number+2, file_name) + print "%s" % (line) + + return + + +# +# Read the entire file as text, and construct a map from rules to line numbers +# this map will be more accurate than counting sublists in the first argument. +# Store the information in the dictionary global_rule_to_locus +# +global_rule_to_locus = {} +global_file_has_been_read = {} +def read_file_as_text(file_name): + global global_rule_to_locus + global global_file_has_been_read + + if global_file_has_been_read.has_key(file_name): + return + global_file_has_been_read[file_name] = 1 + + line_number = 0 + rexpr_rule = r"\[\"([A-Za-z0-9._ ]+:[^\"]*)\"" + re_object_rule = re.compile(rexpr_rule); + transtab = string.maketrans('', ''); + + for line in open(file_name, "r").readlines(): + line_number += 1 + line = line.strip() + m = re_object_rule.match(line) + if m != None: + textual_rule = m.group(1) + textual_rule = textual_rule.translate(transtab, string.whitespace); + if global_rule_to_locus.has_key(textual_rule): + print >> sys.stderr, "rule occurs at %s:%-5d and %s:%-5d %s" % ( + global_rule_to_locus[textual_rule][0], + global_rule_to_locus[textual_rule][1], + os.path.basename(file_name), + line_number, + textual_rule + ) + global_rule_to_locus[textual_rule] = \ + [os.path.basename(file_name), line_number] + + return + +global_fault_to_issued = {} +def check_attr_use(filename, actions_line_number, + ntref_to_nt, actions, trace = 0): + global global_fault_to_issued + + # + # Look in the unmodified semantic actions for + # $ntref->field + # and map ntref to the corresponding true nt. + # Construct a map from true nt to the fields that are used. + # + if trace > 1: + print "ntref_to_nt=%s" % (ntref_to_nt) + + nt_to_attrref = {} + for ntref in ntref_to_nt: + nt = ntref_to_nt[ntref] + rexpr = r"\$(" + ntref + r")[ ]*" + r"->" + r"[ ]*" + r"([a-zA-Z0-9_]+)"; + re_object = re.compile(rexpr); + deltaline = 0 + for line in actions.split("\n"): + for attr_ref in re_object.findall(line): + # + # attr_ref is a list of pairs (ntref, field_name) + # + field_name = attr_ref[1] + nt_to_attrref.setdefault(nt, {}) + nt_to_attrref[nt].setdefault(field_name, actions_line_number+deltaline) + deltaline += 1 + + if trace > 0: + print "nt_to_attrref = %s" % (nt_to_attrref) + + # + # For each NT, do an asymmetric difference between the set of fields used + # and the set of legal fields; if we use a field that isn't legal to use + # issue an error message + # + for nt in nt_to_attrref: + for attrref in nt_to_attrref[nt]: + first_line_number = nt_to_attrref[nt][attrref] + if global_nt_to_attrs.has_key(nt) and len(global_nt_to_attrs[nt]) > 0: + try: + global_nt_to_attrs[nt].index(attrref) + except: + msg = "%s:%d: illegal reference to NT %s attribute %s" % \ + (filename, first_line_number, nt, attrref) + if not global_fault_to_issued.has_key(msg): + print >>sys.stderr, "%s" % (msg) + global_fault_to_issued[msg] = 1 + + return + +# +# Given a plug rule as a string of the form "lhs : rhs" +# return two dictionaries. +# The 1st dictionary maps plug nonterminal references to 1-based +# nonterminal positions, with 1 being the leftmost nonterminal on the rhs. +# Thus, for rule x.y we'll map $y to 2(say). +# +# Ths 2nd dictionary maps plug nonterminal references +# to grammatical non terminal names. +# Thus, for rule x.y we'll map $y to $x. +# +def plug_analyze_rule(rule, file_name, line_number, trace=0): + nt_pos = 0 + ntref_to_pos = {} + ntref_to_nt = {} + + # + # Remove occurances of plug terminal names, + # using simple lexical naming conventions. + # The machine spec must adhere to these lexical conventions. + # + subject = rule + re_object = re.compile(r'\b' + r'[A-Z_0-9]+' + r'\b') + subject = re_object.sub(' ', subject, 0) + + # + # Remove occurances of plug rule building operators. + # + re_object = re.compile(r'[(),|:@]') + subject = re_object.sub(' ', subject, 0) + + nt_pos = 0 + for plug_nt_handle in subject.split(): + # + # The nonterminal is lexically of the form x.y. + # Construct a map $y to $N if y exists, or $x to $N otherwise; + # we preferentially use the ".y" disambiguator. + # + crack_list = plug_nt_handle.split('.') + if len(crack_list) > 1: + ntref_to_nt[crack_list[-1]] = crack_list[0] + else: + ntref_to_nt[crack_list[0]] = crack_list[0] + + alias = crack_list[-1] # the last item on the list + if nt_pos == 0: + ntref_to_pos[alias] = "$" + "$" + else: + ntref_to_pos[alias] = "$" + str(nt_pos) + nt_pos += 1 + # + # Because Template::safe_substitute rewrites $$ to $ + # and $$ is needed for plug, we arrange to use rexprs to + # rewrite $$ to $lhs, and then use this map to rewrite $lhs back to $$. + # + ntref_to_pos['lhs'] = '$$' # $$ ==> $lhs ==> $$ + + if trace: + print "%s" % (str(ntref_to_nt)) + + return ntref_to_pos, ntref_to_nt + + +# +# This is demo code. +# Walk the python parse tree and print it out. +# +def print_parse_tree(tup, depth): + if len(tup) == 0: + return + x = tup[0] + if token.ISTERMINAL(x): + print "%s TERM ==> %3d %3d %s" % \ + (' '*2*depth, depth, x, token.tok_name[x]) + else: + print "%s NONTERM ==> %3d %3d %s" % \ + (' '*2*depth, depth, x, symbol.sym_name[x]) + for kid in tup[1:]: + print_parse_tree(kid, depth+1) + return + +# +# This is demo code. +# Walk the parse tree tup and construct the list back +# from all python terminal symbols. Python terminals are not the +# same as plug terminals. +# +def parse_tree_to_terms(tup, back, trace=0): + if len(tup) > 0: + x = tup[0] + if token.ISTERMINAL(x): + sym = token.tok_name[x] + if trace: + print "sym=%s" % (sym) + if sym == 'NAME': + ret = [sym, tup[1]] + elif sym == 'NUMBER': + ret = [sym, tup[1]] + else: + ret = sym + if trace: + print "return %s " % (ret) + back.append(ret) + else: + for kid in tup[1:]: + parse_tree_to_terms(kid, back, trace) + return back + + +global_plug_errors = 0 +def plug_fault(msg): + global global_plug_errors + + print >>sys.stderr, "%s" % (msg) + sys.exit(1) + return + +# +# terminal declarations map terminal names to the legal attribute fields. +# +global_term_number = 0 +global_nt_to_attrs = {} +global_is_term = {} +global_is_nonterm = {} +global_print_plug_decls = 1 + +def nonterm(symbol, fields = []): + global global_nt_to_attrs + global global_is_nonterm + global global_is_term + global global_print_plug_decls + + if global_is_nonterm.has_key(symbol): + plug_fault("symbol ``%s'' already declared as a non-terminal" % (symbol)) + if global_is_term.has_key(symbol): + plug_fault("symbol ``%s'' already declared as a terminal" % (symbol)) + if not is_plug_nonterm(symbol): + plug_fault("non-terminal symbol ``%s'' does not follow lexical conventions" % (symbol)) + + global_is_nonterm[symbol] = 1 + global_nt_to_attrs[symbol] = fields + + if global_print_plug_decls: + print "nonterm %s;" % (symbol) + + return + +def term_incr(incr): + global global_term_number + global_term_number += incr + return + +def term_align(align): + global global_term_number + global_term_number = ((global_term_number + align-1)/align) * align + return + +def term(symbol): + global global_is_term + global global_is_nonterm + global global_term_number + global global_print_plug_decls + + if global_is_term.has_key(symbol): + plug_fault("symbol ``%s'' already declared as a terminal" % (symbol)) + if global_is_nonterm.has_key(symbol): + plug_fault("symbol ``%s'' already declared as a non-terminal" % (symbol)) + if not is_plug_term(symbol): + plug_fault("terminal symbol ``%s'' does not follow lexical conventions" % (symbol)) + + global_is_term[symbol] = global_term_number + + if global_print_plug_decls: + print "term %s = %d;" % (symbol, global_term_number) + + global_term_number += 1 + return + +def term_cross(name, suffixes): + for suffix in suffixes: + term(name + "_" + suffix) + return + +def reduce(block_name, file_name): + global global_print_plug_decls + + if global_print_plug_decls: + print "reduce %s = \"%s\";" % (block_name, file_name) + return + +def start(nt): + global global_is_term + global global_print_plug_decls + + if not global_is_nonterm.has_key(nt): + plug_fault("start symbol ``%s'' is not declared as a nonterminal" % (nt)) + if global_print_plug_decls: + print "start %s;" % (nt) + return + +#})] diff --git a/iburg/briggs/icg-grammars/shardgrammar.cc b/iburg/briggs/icg-grammars/shardgrammar.cc new file mode 100644 index 00000000000..d69d840e076 --- /dev/null +++ b/iburg/briggs/icg-grammars/shardgrammar.cc @@ -0,0 +1,495 @@ +// {([ +// +// Copyright (c) 2008 Google Inc. All rights reserved. +// +// rrh@google.com 08/08/2008 +// +// $Header: $ +// + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +int string_distance(const char *a, const char *b) +{ + const size_t n = strlen(a); + const size_t m = strlen(b); + int *c = new int[(n+1)*(m+1)]; +#define access(i, j) ((i)*(m+1)+(j)) + for (size_t i = 0; i <= n; i++) { + c[access(i,0)] = i; + } + for (size_t j = 0; j <= m; j++) { + c[access(0,j)] = j; + } + for (size_t i = 1; i <= n; i++) { + for (size_t j = 1; j <= m; j++) { + const int x = c[access(i-1,j-0)] + 1; + const int y = c[access(i-0,j-1)] + 1; + int z = c[access(i-1,j-1)] + 0; + if (a[i-1] != b[j-1]) { + z += 1; + } + if (x <= y && x <= z) { + c[access(i,j)] = x; + } else if (y <= x && y <= z) { + c[access(i,j)] = y; + } else { + c[access(i,j)] = z; + } + } + } + const int back = c[access(n, m)]; + delete [] c; + return back; +} + +double string_similarity (const char *a, const char *b, int &edit_distance) +{ + const size_t totalLength = strlen(a) + strlen(b); + edit_distance = string_distance(a, b); + double m1 = (1.0*totalLength - 2.0*edit_distance)/totalLength; + if (m1 < 0) { + m1 = 0.0; + } + return m1; +} + +// +// Test jig +// +void string_distance_test(const char *a, const char *b) +{ + fprintf(stdout, "string_distance %10s %10s ==> %2d\n", + a, b, string_distance(a, b) + ); +} + +void string_distance_unittest(void) +{ + string_distance_test("abc", "abc"); + string_distance_test("ab", "abc"); + string_distance_test("bc", "abc"); + string_distance_test("Abc", "abc"); + string_distance_test("abC", "abc"); + string_distance_test("AbC", "abc"); +} + +void append(const char *&dst, const char *s1, const char *s2) +{ + const size_t nlg = 0 + + (dst ? ::strlen(dst) : 0) + + (s1 ? ::strlen(s1) : 0) + + (s2 ? ::strlen(s2) : 0) + ; + char *back = new char[nlg+1]; + ::snprintf(back, nlg+1, "%s%s%s", + dst ? dst : "", + s1 ? s1 : "", + s2 ? s2 : "" + ); + delete [] dst; dst = 0; + dst = back; +} + +const char *stringtrim(const char *src) +{ + if (src == 0) { + return 0; + } + const char *first = src; + while (*first && isspace(*first)) { + first += 1; + } + const char *last = src + strlen(src) - 1; + while (last >= first && isspace(*last)) { + last -= 1; + } + const size_t lg = last - first + 1; + char *back = new char[lg+1]; + ::strncpy(back, first, lg); + back[lg] = 0; + return back; +} + +// +// Read the grammar files enumerated on the argument line. +// Output one file for each block of rules. +// The output files end up in the directory "./tmp" +// + +int global_block_number = 0; + +class Key { +public: + const char *ifname; + int lineno_s; + int lineno_e; +}; + +class KeyRecord { +public: + Key key; + const char *ofname; // output file name + + const char *rules; // rules (grammar) + const char *trimrules; // string trimmed rules (grammar) + size_t lgrules; // length of rules, bytes + + const char *sems; // semantic actions (block-labeled C code) + const char *trimsems; // string trimmed semantic actions + size_t lgsems; // length of semantic actions, bytes + + KeyRecord *best_other; // best other KeyRecord + double best_similarity; // similarty of best other KeyRecord + int best_edit_distance; // edit dist of best other KeyRecord + +public: + KeyRecord(void); +}; + +KeyRecord::KeyRecord(void) { + ofname = 0; + rules = 0; + trimrules = 0; + sems = 0; + trimsems = 0; + lgrules = 0; + lgsems = 0; + best_other = 0; + best_similarity = 0.0; + best_edit_distance = -1; +} + +void print_singleton(FILE *fp, const KeyRecord *rp) +{ + const Key &k = rp->key; + fprintf(fp, " {%s %4d %4d}", k.ifname, k.lineno_s, k.lineno_e); +} + +void print_pairs(FILE *fp, const KeyRecord *ri, const KeyRecord *rj) +{ + if (ri && rj) { + fprintf(fp, " tkdiff %4s %4s ", ri->ofname, rj->ofname); + } + if (ri) { + print_singleton(fp, ri); + } + fprintf(fp, " vs"); + if (rj) { + print_singleton(fp, rj); + } +} + +// +// Obsolete: this was pre-pythonization of the plug spec files +// +int read_grammar_file(const char *ifname) +{ + int lineno = 0; + extern int global_block_number; + global_block_number += 1; + FILE *ifd = ::fopen(ifname, "r"); + if (ifd == NULL) { + return -1; + } + + enum State { + State_none, + State_rules + }; + State state = State_none; + + int lineno_s = -1; + int lineno_e = -1; + + const char *rules = 0; // all syntactic rules in this block + const char *trimrules = 0; // all syntactic rules in this block, trimmed + int lgrules = 0; // number of lines in rules + + const char *sems = 0; // all semantic actions in this block + const char *trimsems = 0; // all semantic actions in this block, trimmed + int lgsems = 0; + + enum { + NRULES=600 + }; + KeyRecord *ruleinfo[NRULES]; + + for (int i = 0; i < NRULES; i++) { + ruleinfo[i] = 0; + } + + int nruleinfo = 0; + int in_shard_region = 0; + + char line[8*BUFSIZ]; + while (::fgets(line, sizeof(line), ifd) == line) { + lineno += 1; + if (!in_shard_region) { + if (::strncmp(line, "<SHARD>", 7) == 0) { + in_shard_region = 1; + } + continue; + } + // + // look for some kind of syntactic rule + // + if (isalpha(line[0]) && ::index(line, ':') > line+0) { + if (state != State_rules) { + lineno_s = lineno; + state = State_rules; + rules = 0; + trimrules = 0; + sems = 0; + trimsems = 0; + } + append(trimrules, stringtrim(line), "\n"); + append(rules, line, 0); + lgrules += 1; + continue; + } + + // + // some intermediate line, between rule definitions + // and the closing syntax of the rule block + // + if (state == State_rules) { + append(trimsems, stringtrim(line), "\n"); + append(sems, line, 0); + lgsems +=1; + } + + // + // end of block + // + if (::strstr(line, "\175;")) { + lineno_e = lineno; + char ofname[BUFSIZ]; + ::snprintf(ofname, sizeof(ofname), "tmp/%03d", global_block_number); + FILE *ofd = ::fopen(ofname, "w"); + if (ofd == NULL) { + continue; + } + fprintf(ofd, \ + "// file %4s contains %3d+%3d lines from %5d .. %5d of file %s\n", + ofname, + lgrules, + lgsems, + lineno_s, lineno_e, + ifname + ); + fprintf(ofd, "%s", rules); + fprintf(ofd, "%s", sems); + ::fclose(ofd); + + KeyRecord *p = new KeyRecord(); + ruleinfo[nruleinfo] = p; + nruleinfo += 1; + + if (nruleinfo >= NRULES) { + fprintf(stderr, "too many rules, max of %d\n", NRULES); + exit(1); + } + p->ofname = strdup(ofname); + + p->key.ifname = ifname; + p->key.lineno_s = lineno_s; + p->key.lineno_e = lineno_e; + + p->trimsems = trimsems; + p->sems = sems; + p->lgsems = lgsems; + + p->trimrules = trimrules; + p->rules = rules; + p->lgrules = lgrules; + + rules = 0; + trimrules = 0; + lgrules = 0; + + sems = 0; + trimsems = 0; + lgsems = 0; + + global_block_number += 1; + state = State_none; + } + } + ::fclose(ifd); ifd = 0; + + const int nkey = nruleinfo; + + // + // Compare 2 blocks of semantic actions that + // are within $offset line numbers of each other. + // use the Levenshtein distance (minimal number of edits) + // + for (int i = 0; i < nkey; i++) { + KeyRecord *ri = ruleinfo[i]; + if (ri->best_other) continue; + fprintf(stdout, "\n"); // block spacing + for (int j = 0; j < nkey; j++) { + KeyRecord *rj = ruleinfo[j]; + if (rj->best_other) continue; + + int edit_distance = 0; + const double similarity = + string_similarity(ri->trimsems, rj->trimsems, edit_distance); + if (edit_distance < 30) { + rj->best_other = ri; + rj->best_edit_distance = edit_distance; + rj->best_similarity = similarity; + if (ri != rj) { + fprintf(stdout, "edit= %4d sim= %8.4f", + edit_distance, similarity + ); + print_pairs(stdout, ri, rj); + fprintf(stdout, "\n"); + } + } + + } + } + + return 0; +} + +struct simcarrier { + double similarity; + int i; + int j; +}; + +int simcarriersorter(const void *vp1, const void *vp2) +{ + const simcarrier *p1 = (const simcarrier *)vp1; + const simcarrier *p2 = (const simcarrier *)vp2; + const int reverse = -1; + if (p1->similarity < p2->similarity) { + return reverse * -1; + } + if (p1->similarity > p2->similarity) { + return reverse * 1; + } + return 0; +} + +int abs(const int x) +{ + return x < 0 ? -x : x; +} +void print_info(FILE *fp, const simcarrier *info, int index, + size_t *lengths, const char **names) +{ + const int i = info[index].i; + const int j = info[index].j; + fprintf(stdout, "%5.3f %5d %5d tkdiff -w %30s %30s\n", + info[index].similarity, + lengths[i], lengths[j], + names[i], names[j] + ); +} + +int main(int argc, const char *argv[]) +{ + if (0) { + string_distance_unittest(); + } + if (0) { + ::mkdir("./tmp", 0777); + for (int i = 1; i < argc; i++) { + read_grammar_file(argv[i]); + } + } + if (1) { + const char **contents = new const char *[argc]; + size_t *lengths = new size_t[argc]; + for (int i = 1; i < argc; i++) { + contents[i] = 0; + lengths[i] = 0; + } + for (int i = 1; i < argc; i++) { + FILE *ifd = ::fopen(argv[i], "r"); + if (ifd) { + struct stat sbuf; + ::stat(argv[i], &sbuf); + lengths[i] = sbuf.st_size; + contents[i] = new char[lengths[i]]; + char *last = (char *)contents[i]; + char line[8*BUFSIZ]; + while (::fgets(line, sizeof(line), ifd) == line) { + const char *trimmed = stringtrim(line); + strcat(last, trimmed); + last += strlen(last); + } + } + ::fclose(ifd); + } + + simcarrier *info = new simcarrier[argc*argc]; + for (int i = 1; i < argc; i++) { + for (int j = 1; j < argc; j++) { + const int index = i*argc+j; + info[index].i = i; + info[index].j = j; + info[index].similarity = 0.0; + } + } + for (int i = 1; i < argc; i++) { + // fprintf(stdout, "progress: %4d/%-4d\n", i, argc); + if (contents[i] == 0) continue; + const bool isdivi = strstr(contents[i], "MOD") || strstr(contents[i], "DIV"); + int nhit = 0; + for (int j = i+1; j < argc; j++) { + if (contents[j] == 0) continue; + const bool isdivj = strstr(contents[j], "MOD") || strstr(contents[j], "DIV"); + if (abs(lengths[i] - lengths[j]) > 0.20*lengths[j]) { + continue; + } + const int index = i*argc+j; + int edit_distance; + info[index].similarity = + string_similarity(contents[i], contents[j], edit_distance); + if (0 + || (isdivi && isdivj) + || info[index].similarity > 0.80) { + print_info(stdout, info, index, lengths, argv); + nhit += 1; + } + } + if (nhit) { + fprintf(stdout, "\n"); + fflush(stdout); + } + } + + if (0) { + fprintf(stdout, "# --- Sorted Similarity Summary ---\n"); + ::qsort(info, argc*argc, sizeof(info[0]), simcarriersorter); + int nhit = 0; + for (int index = 0; index < argc*argc; index++) { + if (info[index].similarity > 0) { + if (info[index].similarity < 1.00) { + print_info(stdout, info, index, lengths, argv); + nhit += 1; + if (nhit > 20) { + break; + } + } + } + } + } + + } + + exit(0); +} + +// })] diff --git a/iburg/briggs/icg-grammars/x86-64.asm.py b/iburg/briggs/icg-grammars/x86-64.asm.py new file mode 100644 index 00000000000..6123a1f9bad --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.asm.py @@ -0,0 +1,121 @@ +# {([ + +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +# -*- mode: python -*- + +import plug + +# global_print_plug_decls = 0; execfile("x86-64.gr.py") + +# +# example: __asm__ __volatile__("mfence" : : : "memory"); +# +plug.plugrule3("asm_nulary", [ + ["rule", "cost"], + ["stmt: ASM_NULLARY", [0, 0]], +], """ + $rule $cost + debug { + icg_analyze_asm(p->rtl, ICG_ASM_PHASE_DEBUG); + }, + emit { + } + ; +""") + +# +# Example: +# __asm__("bsr %1, %0\n\t" "cmovz %2, %0" : "=&r" (bits) : "ro" (v), "r" (neg1) : "cc") +# +# For this rule, the destination register should be DIFFERENT from any of the source registers +# +plug.plugrule3("asm_binary_rrr", [ + ["rule", "cost", "schar", "rtx_mode"], + ["r64x.dst: ASM_BINARY_RRR_DI(r64.src1, r64.src2)", [0, 0], 'q', "DImode"], + ["r32x.dst: ASM_BINARY_RRR_SI(r32.src1, r32.src2)", [0, 0], 'l', "SImode"], +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + icg_reg_vector[$src1->rx].kind = INT_REGISTER; + icg_reg_vector[$src2->rx].kind = INT_REGISTER; + }, + supairs { + /* TODO */ + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($src1->r)); + sparseset_set_bit(live, find($src2->r)); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1->r); + forgettable($src2->r); + }, + debug { + const rtx rtx = p->rtl; + dumpasmRRR(ASM_OPERANDS_TEMPLATE(rtx), + $src1->r, '$schar', + $src2->r, '$schar', + $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + static int doit = 1; + if (doit) { + const rtx expr = p->rtl; + rtx src1 = gen_rtx_REG($rtx_mode, $src1->r); + rtx src2 = gen_rtx_REG($rtx_mode, $src2->r); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + /* + 0 ASM_OPERANDS_TEMPLATE + 1 ASM_OPERANDS_OUTPUT_CONSTRAINT + 2 ASM_OPERANDS_OUTPUT_IDX + 3 ASM_OPERANDS_INPUT_VEC + 4 ASM_OPERANDS_INPUT_CONSTRAINT_VEC + 3,N ASM_OPERANDS_INPUT + 3 ASM_OPERANDS_INPUT_LENGTH + 4,N ASM_OPERANDS_INPUT_CONSTRAINT_EXP + 4,N ASM_OPERANDS_INPUT_CONSTRAINT + 4,N ASM_OPERANDS_INPUT_MODE + 5, ASM_OPERANDS_SOURCE_LOCATION + 1, ASM_INPUT_SOURCE_LOCATION + */ + /* + * TODO: how is the output register $dst tied up into the asm rtx? + */ + rtx asm_rtx = gen_rtx_ASM_OPERANDS($rtx_mode, + /*0*/ASM_OPERANDS_TEMPLATE(expr), + /*1*/ASM_OPERANDS_OUTPUT_CONSTRAINT(expr), + /*2*/ASM_OPERANDS_OUTPUT_IDX(expr), + /*3*/gen_rtvec(2, src1, src2), + /*4*/ASM_OPERANDS_INPUT_CONSTRAINT_VEC(expr), + /*5*/ASM_OPERANDS_SOURCE_LOCATION(expr) + ); + rtx set_rtx = gen_rtx_SET(VOIDmode, dst, asm_rtx); + rtvec vect = gen_rtvec(3, + set_rtx, + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FPSR_REG)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, vect); + icg_emit_plain(parallel); + } + } + ; +""") + diff --git a/iburg/briggs/icg-grammars/x86-64.asm.pyout b/iburg/briggs/icg-grammars/x86-64.asm.pyout new file mode 100644 index 00000000000..1e0de4ce1dc --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.asm.pyout @@ -0,0 +1,171 @@ +#line 19 "x86-64.asm.py" +stmt: ASM_NULLARY [0, 0] +#line 22 "x86-64.asm.py" + debug { + icg_analyze_asm(p->rtl, ICG_ASM_PHASE_DEBUG); + }, + emit { + } + ; +#line 38 "x86-64.asm.py" +r64x: ASM_BINARY_RRR_DI(r64, r64) [0, 0] +#line 42 "x86-64.asm.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + icg_reg_vector[$1->rx].kind = INT_REGISTER; + icg_reg_vector[$2->rx].kind = INT_REGISTER; + }, + supairs { + /* TODO */ + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + forgettable($2->r); + }, + debug { + const rtx rtx = p->rtl; + dumpasmRRR(ASM_OPERANDS_TEMPLATE(rtx), + $1->r, 'q', + $2->r, 'q', + $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + static int doit = 1; + if (doit) { + const rtx expr = p->rtl; + rtx src1 = gen_rtx_REG(DImode, $1->r); + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx dst = gen_rtx_REG(DImode, $$->rx); + /* + 0 ASM_OPERANDS_TEMPLATE + 1 ASM_OPERANDS_OUTPUT_CONSTRAINT + 2 ASM_OPERANDS_OUTPUT_IDX + 3 ASM_OPERANDS_INPUT_VEC + 4 ASM_OPERANDS_INPUT_CONSTRAINT_VEC + 3,N ASM_OPERANDS_INPUT + 3 ASM_OPERANDS_INPUT_LENGTH + 4,N ASM_OPERANDS_INPUT_CONSTRAINT_EXP + 4,N ASM_OPERANDS_INPUT_CONSTRAINT + 4,N ASM_OPERANDS_INPUT_MODE + 5, ASM_OPERANDS_SOURCE_LOCATION + 1, ASM_INPUT_SOURCE_LOCATION + */ + /* + * TODO: how is the output register $$ tied up into the asm rtx? + */ + rtx asm_rtx = gen_rtx_ASM_OPERANDS(DImode, + /*0*/ASM_OPERANDS_TEMPLATE(expr), + /*1*/ASM_OPERANDS_OUTPUT_CONSTRAINT(expr), + /*2*/ASM_OPERANDS_OUTPUT_IDX(expr), + /*3*/gen_rtvec(2, src1, src2), + /*4*/ASM_OPERANDS_INPUT_CONSTRAINT_VEC(expr), + /*5*/ASM_OPERANDS_SOURCE_LOCATION(expr) + ); + rtx set_rtx = gen_rtx_SET(VOIDmode, dst, asm_rtx); + rtvec vect = gen_rtvec(3, + set_rtx, + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FPSR_REG)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, vect); + icg_emit_plain(parallel); + } + } + ; +#line 39 "x86-64.asm.py" +r32x: ASM_BINARY_RRR_SI(r32, r32) [0, 0] +#line 42 "x86-64.asm.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + icg_reg_vector[$1->rx].kind = INT_REGISTER; + icg_reg_vector[$2->rx].kind = INT_REGISTER; + }, + supairs { + /* TODO */ + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + forgettable($2->r); + }, + debug { + const rtx rtx = p->rtl; + dumpasmRRR(ASM_OPERANDS_TEMPLATE(rtx), + $1->r, 'l', + $2->r, 'l', + $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + static int doit = 1; + if (doit) { + const rtx expr = p->rtl; + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + /* + 0 ASM_OPERANDS_TEMPLATE + 1 ASM_OPERANDS_OUTPUT_CONSTRAINT + 2 ASM_OPERANDS_OUTPUT_IDX + 3 ASM_OPERANDS_INPUT_VEC + 4 ASM_OPERANDS_INPUT_CONSTRAINT_VEC + 3,N ASM_OPERANDS_INPUT + 3 ASM_OPERANDS_INPUT_LENGTH + 4,N ASM_OPERANDS_INPUT_CONSTRAINT_EXP + 4,N ASM_OPERANDS_INPUT_CONSTRAINT + 4,N ASM_OPERANDS_INPUT_MODE + 5, ASM_OPERANDS_SOURCE_LOCATION + 1, ASM_INPUT_SOURCE_LOCATION + */ + /* + * TODO: how is the output register $$ tied up into the asm rtx? + */ + rtx asm_rtx = gen_rtx_ASM_OPERANDS(SImode, + /*0*/ASM_OPERANDS_TEMPLATE(expr), + /*1*/ASM_OPERANDS_OUTPUT_CONSTRAINT(expr), + /*2*/ASM_OPERANDS_OUTPUT_IDX(expr), + /*3*/gen_rtvec(2, src1, src2), + /*4*/ASM_OPERANDS_INPUT_CONSTRAINT_VEC(expr), + /*5*/ASM_OPERANDS_SOURCE_LOCATION(expr) + ); + rtx set_rtx = gen_rtx_SET(VOIDmode, dst, asm_rtx); + rtvec vect = gen_rtvec(3, + set_rtx, + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FPSR_REG)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, vect); + icg_emit_plain(parallel); + } + } + ; diff --git a/iburg/briggs/icg-grammars/x86-64.float.py b/iburg/briggs/icg-grammars/x86-64.float.py new file mode 100644 index 00000000000..7cde34c55f6 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.float.py @@ -0,0 +1,768 @@ +#{([ + +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +# -*- mode: python -*- + +import plug + +# global_print_plug_decls = 0; execfile("x86-64.gr.py") + +# rd - a double-precision register that must be preserved +# rdx - a double-precision register that need not be preserved +# +# rf - a single-precision register that must be preserved +# rfx - a single-precision register that need not be preserved +# +# lhsd - a double-precision left-hand side (either register or memory) +# lfsf - a single-precision left-hand side (either register or memory) + +#------------------------------------------------------------- +# lhs rules + +plug.plugrule3 ("floatlhsreg", [ + ["rule", "cost"], + + ["lhsd.dst : REGX_DF", [0, 0]], + ["lhsf.dst : REGX_SF", [0, 0]], + ["lhsd.dst : REG_DF", [0, 0]], + ["lhsf.dst : REG_SF", [0, 0]], + +], """ + $rule $cost + names { + $dst->spilled = false; + }, + kinds { + icg_reg_vector[$dst->r].kind = FLOAT_REGISTER; + }, + costs { + cost_store($dst->r); + }, + spill { + dirty |= make_spill_code(find($dst->r), $dst); + }, + final { + $dst->r = icg_reg_vector[find($dst->r)].color; + }; +""") + + + + +plug.plugrule3 ("floatlhsstore", [ + ["rule", "cost", "rtx_mode"], + + ["lhsd.lhs : MEM_DF(addr.dst)", [0, 0], "DFmode"], + ["lhsf.lhs : MEM_SF(addr.dst)", [0, 0], "SFmode"], + +], """ + $rule $cost + names { + $lhs->spilled = true; + $lhs->a.base = $dst->a.base; + $lhs->a.base_valid = $dst->a.base_valid; + $lhs->a.index = $dst->a.index; + $lhs->a.scale = $dst->a.scale; + $lhs->a.disp = $dst->a.disp; + $lhs->a.string = $dst->a.string; + }, + emit { + $lhs->rtl = $dst->rtl; + }; +""") + + + +# +# Floating point assignment +# +plug.plugrule3 ("floatassignment", [ + ["rule", "cost", "opcode", "rtxmode"], + + ["stmt : SET_ALL(lhsd.dst, rd.src)", [0, 0], "movsd", "DFmode"], + ["stmt : SET_ALL(lhsf.dst, rf.src)", [0, 0], "movss", "SFmode"], + +], """ + $rule $cost + supairs { + suOrder2($stmt, $dst, $src, kid, kids); + }, + coalesce { + if (!$dst->spilled) + coalesces += attempt_coalesce(pass, $dst->r, $src->r); + }, + build { + if ($dst->spilled) { + sparseset_set_bit(live, find($src->r)); + add_addr(live, $dst); + } + else + add_copy_edges($dst->r, $src->r, live); + }, + remat { + flags = 0; + }, + costs { + if (!$dst->spilled) + cost_copy($src->r, $dst->r); + }, + debug { + if ($dst->spilled) + dumpRM("$opcode", $src->r, 'x', $dst); + else + dump_copy("$opcode", $src->r, $dst->r, 'x'); + }, + emit { + rtx src = gen_rtx_REG($rtxmode, $src->r); + rtx dst = $dst->spilled ? gen_rtx_MEM($rtxmode, $dst->rtl) : gen_rtx_REG($rtxmode, $dst->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +#------------------------------------------------------------- +# register-register chain rules + +plug.plugrule3 ("floatdst", [ + ["rule", "cost", "rfield"], + + ["rd.dst : REG_DF", [0, 0], "r"], + ["rf.dst : REG_SF", [0, 0], "r"], + ["rdx.dst : REGX_DF", [0, 0], "rx"], + ["rfx.dst : REGX_SF", [0, 0], "rx"], + +], """ + $rule $cost + kinds { + icg_reg_vector[$dst->$rfield].kind = FLOAT_REGISTER; + }, + costs { + cost_load($dst->$rfield); + }, + supairs { + $dst->extra = 0; /* TODO? only for rdx: rules */ + $dst->freed = 0; /* TODO? only for rdx: rules */ + }, + spill { + dirty |= make_spill_code(find($dst->$rfield), $dst); + }, + final { + $dst->$rfield = icg_reg_vector[find($dst->$rfield)].color; + }; +""") + + +plug.plugrule3 ("floatchainxsrc", [ + ["rule", "cost"], + + ["rd.dst : rdx.src", [0, 0]], + ["rf.dst : rfx.src", [0, 0]], + +], """ + $rule $cost + supairs { + $dst->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $dst->r = $src->rx; + }, + final { + $dst->r = $src->rx; + }; +""") + +# assume coalesce will fail (but try anyway) + +plug.plugrule3 ("floatchainxdst", [ + ["rule", "cost", "opcode", "rtx_mode"], + + #["rdx.dst : rd.src", [2, 4], "movsd", "DFmode"], + #["rfx.dst : rf.src", [2, 4], "movss", "SFmode"], + ["rdx.dst : rd.src", [2, 4], "movapd", "DFmode"], # movapd used by icg+rtl backend for intra-xmm moves + ["rfx.dst : rf.src", [2, 4], "movaps", "SFmode"], # movaps used by icg+rtl backend for intra-xmm moves + +], """ + $rule $cost + supairs { + if ($dst->freed > 0) + $dst->freed--; + else + $dst->extra++; + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = FLOAT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $dst->rx, $src->r); + }, + build { + add_copy_edges($dst->rx, $src->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($dst->rx, $src->r); + }, + debug { + dump_copy("$opcode", $src->r, $dst->rx, 'x'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + const rtx src = gen_rtx_REG($rtx_mode, $src->r); + const rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +#---------------------------------------------------------------- + + +# +# floating point loads +# +plug.plugrule3 ("floatloadbasic", [ + ["rule", "cost", "opcode", "rtx_mode"], + + ["rdx.dst : MEM_DF(addr)", [3, 2], "movsd", "DFmode"], + ["rfx.dst : MEM_SF(addr)", [3, 2], "movss", "SFmode"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = FLOAT_REGISTER; + }, + supairs { + if ($addr->freed > 0) { + $dst->extra = $addr->extra; + $dst->freed = $addr->freed - 1; + } + else { + $dst->extra = $addr->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpMR("$opcode", $addr, $dst->rx, 'x'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = gen_rtx_MEM($rtx_mode, $addr->rtl); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# +# floating point converts (tar pit) +# ieee rounding modes and various conversions are ignored. +# + +# +# convert from ieee64 to int64, int32, int16(?), or int8(?) +# convert from ieee32 to int64, int32, int16(?), or int8(?) +# +plug.plugrule3 ("floatmovcvt", [ + ["rule", "cost", "isRR", "dst_rtx_mode", "src_rtx_mode", "opcode"], + + ["r64x.dst : FIX_DI(rd.src)", [1, 1], 1, "DImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r32x.dst : FIX_SI(rd.src)", [1, 1], 1, "SImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r16x.dst : FIX_HI(rd.src)", [1, 1], 1, "HImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r8x.dst : FIX_QI(rd.src)", [1, 1], 1, "QImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + + ["r64x.dst : FIX_DI(rf.src)", [1, 1], 1, "DImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r32x.dst : FIX_SI(rf.src)", [1, 1], 1, "SImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r16x.dst : FIX_HI(rf.src)", [1, 1], 1, "HImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r8x.dst : FIX_QI(rf.src)", [1, 1], 1, "QImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + + ["r64x.dst : FIX_DI(MEM_DF(addr.src))", [1, 1], 0, "DImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r32x.dst : FIX_SI(MEM_DF(addr.src))", [1, 1], 0, "SImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r16x.dst : FIX_HI(MEM_DF(addr.src))", [1, 1], 0, "HImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + ["r8x.dst : FIX_QI(MEM_DF(addr.src))", [1, 1], 0, "QImode", "DFmode", "cvttsd2siq"], # LIE (TODO) + + ["r64x.dst : FIX_DI(MEM_SF(addr.src))", [1, 1], 0, "DImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r32x.dst : FIX_SI(MEM_SF(addr.src))", [1, 1], 0, "SImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r16x.dst : FIX_HI(MEM_SF(addr.src))", [1, 1], 0, "HImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + ["r8x.dst : FIX_QI(MEM_SF(addr.src))", [1, 1], 0, "QImode", "SFmode", "cvttsd2siq"], # LIE (TODO) + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + if ($isRR) { + sparseset_set_bit(live, find($src->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $src); + }, + remat { + flags = 0; + }, + costs { + if ($isRR) { + memorable($src->r); + } + }, + debug { + if ($isRR) { + dumpRR("$opcode", $src->r, 'x', $dst->rx, 'q'); + } else { + dumpMR("$opcode", $src, $dst->rx, 'q'); + } + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = $isRR + ? gen_rtx_REG($src_rtx_mode, $src->r) + : gen_rtx_MEM($src_rtx_mode, $src->rtl); + rtx dst = gen_rtx_REG($dst_rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX($dst_rtx_mode, src))); + }; +""") + +# +# convert with truncation from ieee64 to ieee32 +# this can be done by cvtsd2ss (scalar double to scalar single) +# or by the sequence unpcklpd (unpack low double precision fp); cvtpd2ps +# the 2 insn sequence is what gcc produces, and may be one cycle faster; +# it ends up with an ieee32 duplicated in both 32-bit halves +# of the result register. +# convert with extension from ieee32 to ieee64 +# +plug.plugrule3("floatmovtruncate", [ + ["rule", "cost", "isRR", "src_mode", "dst_mode", "opcode", "rtx_builder"], + + ["rfx.dst : FLOAT_TRUNCATE_SF(rd.src)", [1, 1], 1, "DFmode", "SFmode", + "cvtsd2ss", "gen_rtx_FLOAT_TRUNCATE"], + ["rfx.dst : FLOAT_TRUNCATE_SF(MEM_DF(addr.src))", [1, 1], 0, "DFmode", "SFmode", + "cvtsd2ss", "gen_rtx_FLOAT_TRUNCATE"], + ["rdx.dst : FLOAT_EXTEND_DF(rf.src)", [1, 1], 1, "SFmode", "DFmode", + "cvtss2sd", "gen_rtx_FLOAT_EXTEND"], + ["rdx.dst : FLOAT_EXTEND_DF(MEM_SF(addr.src))", [1, 1], 0, "SFmode", "DFmode", + "cvtss2sd", "gen_rtx_FLOAT_EXTEND"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + if ($isRR) { + sparseset_set_bit(live, find($src->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $src); + }, + remat { + flags = 0; + }, + costs { + if ($isRR) { + memorable($src->r); + } + }, + debug { + if ($isRR) { + dumpRR("$opcode", $src->r, 'x', $dst->rx, 'x'); + } else { + dumpMR("$opcode", $src, $dst->rx, 'x'); + } + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = $isRR + ? gen_rtx_REG($src_mode, $src->r) + : gen_rtx_MEM($src_mode, $src->rtl); + rtx dst = gen_rtx_REG($dst_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, $rtx_builder($dst_mode, src))); + }; +""") + +# +# convert from int64 to ieee64 +# convert from int64 to ieee32 +# +plug.plugrule3("floatcvtfromint", [ + ["rule", "cost", "isRR", "src_mode", "dst_mode", "opcode", "rtx_builder"], + + ["rdx.dst : FLOAT_DF(r64.src)", [1, 1], 1, "DImode", "DFmode", "cvtsi2sdq", "gen_rtx_FLOAT"], + ["rdx.dst : FLOAT_DF(MEM_DI(addr.src))", [1, 1], 0, "DImode", "DFmode", "cvtsi2sdq", "gen_rtx_FLOAT"], + ["rfx.dst : FLOAT_SF(r64.src)", [1, 1], 1, "DImode", "SFmode", "cvtsi2ssq", "gen_rtx_FLOAT"], + ["rfx.dst : FLOAT_SF(MEM_DI(addr.src))", [1, 1], 0, "DImode", "SFmode", "cvtsi2ssq", "gen_rtx_FLOAT"], + + ["rdx.dst : FLOAT_DF(r32.src)", [1, 1], 1, "SImode", "DFmode", "cvtsi2sdl", "gen_rtx_FLOAT"], + ["rdx.dst : FLOAT_DF(MEM_SI(addr.src))", [1, 1], 0, "SImode", "DFmode", "cvtsi2sdl", "gen_rtx_FLOAT"], + ["rfx.dst : FLOAT_SF(r32.src)", [1, 1], 1, "SImode", "SFmode", "cvtsi2ssl", "gen_rtx_FLOAT"], + ["rfx.dst : FLOAT_SF(MEM_SI(addr.src))", [1, 1], 0, "SImode", "SFmode", "cvtsi2ssl", "gen_rtx_FLOAT"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + if ($isRR) { + sparseset_set_bit(live, find($src->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $src); + }, + remat { + flags = 0; + }, + costs { + if ($isRR) { + memorable($src->r); + } + }, + debug { + if ($isRR) { + dumpRR("$opcode", $src->r, 'q', $dst->rx, 'x'); + } else { + dumpMR("$opcode", $src, $dst->rx, 'x'); + } + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = $isRR + ? gen_rtx_REG($src_mode, $src->r) + : gen_rtx_MEM($src_mode, $src->rtl); + rtx dst = gen_rtx_REG($dst_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, $rtx_builder($dst_mode, src))); + }; +""") + +plug.plugrule3("floatbasicrr", [ + ["rule", "cost", "isRR", "isCommute", "opcode", "rtx_mode", "rtx_builder"], + + ["rdx.dst: PLUS_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "addsd", "DFmode", "gen_rtx_PLUS"], + ["rfx.dst: PLUS_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "addss", "SFmode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VDI(rdx.src1 | rd.src2)", [1, 1], 1, 1, "paddq", "V2DImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VSI(rdx.src1 | rd.src2)", [1, 1], 1, 1, "paddd", "V4SImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VHI(rdx.src1 | rd.src2)", [1, 1], 1, 1, "paddw", "V8HImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VQI(rdx.src1 | rd.src2)", [1, 1], 1, 1, "paddb", "V16QImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VDF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "addpd", "V2DFmode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VSF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "addps", "V4SFmode", "gen_rtx_PLUS"], + + ["rdx.dst: PLUS_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "addsd", "DFmode", "gen_rtx_PLUS"], + ["rfx.dst: PLUS_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "addss", "SFmode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VDI(rdx.src1 | MEM_VDI(addr.src2))", [1, 1], 0, 0, "paddq", "V2DImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VSI(rdx.src1 | MEM_VSI(addr.src2))", [1, 1], 0, 0, "paddd", "V4SImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VHI(rdx.src1 | MEM_VHI(addr.src2))", [1, 1], 0, 0, "paddw", "V8HImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VQI(rdx.src1 | MEM_VQI(addr.src2))", [1, 1], 0, 0, "paddb", "V16QImode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VDF(rdx.src1 | MEM_VDF(addr.src2))", [1, 1], 0, 0, "addpd", "V2DFmode", "gen_rtx_PLUS"], + ["rdx.dst: PLUS_VSF(rdx.src1 | MEM_VSF(addr.src2))", [1, 1], 0, 0, "addps", "V4SFmode", "gen_rtx_PLUS"], + + ["rdx.dst: PLUS_DF(rdx.src1 , NEG_DF(rd.src2))", [1, 1], 1, 0, "subsd", "DFmode", "gen_rtx_MINUS"], + ["rfx.dst: PLUS_SF(rfx.src1 , NEG_SF(rf.src2))", [1, 1], 1, 0, "subss", "SFmode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VDI(rdx.src1 , NEG_VDI(rd.src2))", [1, 1], 1, 0, "psubq", "V2DImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VSI(rdx.src1 , NEG_VSI(rd.src2))", [1, 1], 1, 0, "psubd", "V4SImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VHI(rdx.src1 , NEG_VHI(rd.src2))", [1, 1], 1, 0, "psubw", "V8HImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VQI(rdx.src1 , NEG_VQI(rd.src2))", [1, 1], 1, 0, "psubb", "V16QImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VDF(rdx.src1 , NEG_VDF(rd.src2))", [1, 1], 1, 0, "subpd", "V2DFmode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VSF(rdx.src1 , NEG_VSF(rd.src2))", [1, 1], 1, 0, "subps", "V4SFmode", "gen_rtx_MINUS"], + + ["rdx.dst: PLUS_DF(rdx.src1 , NEG_DF(MEM_DF(addr.src2)))", [1, 1], 0, 0, "subsd", "DFmode", "gen_rtx_MINUS"], + ["rfx.dst: PLUS_SF(rfx.src1 , NEG_SF(MEM_SF(addr.src2)))", [1, 1], 0, 0, "subss", "SFmode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VDI(rdx.src1 , NEG_VDI(MEM_VDI(addr.src2)))", [1, 1], 0, 0, "psubq", "V2DImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VSI(rdx.src1 , NEG_VSI(MEM_VSI(addr.src2)))", [1, 1], 0, 0, "psubd", "V4SImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VHI(rdx.src1 , NEG_VHI(MEM_VHI(addr.src2)))", [1, 1], 0, 0, "psubw", "V8HImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VQI(rdx.src1 , NEG_VQI(MEM_VQI(addr.src2)))", [1, 1], 0, 0, "psubb", "V16QImode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VDF(rdx.src1 , NEG_VDF(MEM_VDF(addr.src2)))", [1, 1], 0, 0, "subpd", "V2DFmode", "gen_rtx_MINUS"], + ["rdx.dst: PLUS_VSF(rdx.src1 , NEG_VSF(MEM_VSF(addr.src2)))", [1, 1], 0, 0, "subps", "V4SFmode", "gen_rtx_MINUS"], + + ["rdx.dst: MINUS_DF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "subsd", "DFmode", "gen_rtx_MINUS"], + ["rfx.dst: MINUS_SF(rfx.src1 , rf.src2)", [1, 1], 1, 0, "subss", "SFmode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VDI(rdx.src1 , rd.src2)", [1, 1], 1, 0, "psubq", "V2DImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VSI(rdx.src1 , rd.src2)", [1, 1], 1, 0, "psubd", "V4SImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VHI(rdx.src1 , rd.src2)", [1, 1], 1, 0, "psubw", "V8HImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VQI(rdx.src1 , rd.src2)", [1, 1], 1, 0, "psubb", "V16QImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VDF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "subpd", "V2DFmode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VSF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "subps", "V4SFmode", "gen_rtx_MINUS"], + + ["rdx.dst: MINUS_DF(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "subsd", "DFmode", "gen_rtx_MINUS"], + ["rfx.dst: MINUS_SF(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "subss", "SFmode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VDI(rdx.src1 , MEM_VDI(addr.src2))", [1, 1], 0, 0, "psubq", "V2DImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VSI(rdx.src1 , MEM_VSI(addr.src2))", [1, 1], 0, 0, "psubd", "V4SImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VHI(rdx.src1 , MEM_VHI(addr.src2))", [1, 1], 0, 0, "psubw", "V8HImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VQI(rdx.src1 , MEM_VQI(addr.src2))", [1, 1], 0, 0, "psubb", "V16QImode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VDF(rdx.src1 , MEM_VDF(addr.src2))", [1, 1], 0, 0, "subpd", "V2DFmode", "gen_rtx_MINUS"], + ["rdx.dst: MINUS_VSF(rdx.src1 , MEM_VSF(addr.src2))", [1, 1], 0, 0, "subps", "V4SFmode", "gen_rtx_MINUS"], + + ["rdx.dst: MULT_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "mulsd", "DFmode", "gen_rtx_MULT"], + ["rfx.dst: MULT_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "mulss", "SFmode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VHI(rdx.src1 | rd.src2)", [1, 1], 1, 1, "pmullw", "V8HImode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VDF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "mulpd", "V2DFmode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VSF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "mulps", "V4SFmode", "gen_rtx_MULT"], + + ["rdx.dst: MULT_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "mulsd", "DFmode", "gen_rtx_MULT"], + ["rfx.dst: MULT_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "mulss", "SFmode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VHI(rdx.src1 | MEM_VHI(addr.src2))", [1, 1], 0, 0, "pmullw", "V8HImode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VDF(rdx.src1 | MEM_VDF(addr.src2))", [1, 1], 0, 0, "mulpd", "V2DFmode", "gen_rtx_MULT"], + ["rdx.dst: MULT_VSF(rdx.src1 | MEM_VSF(addr.src2))", [1, 1], 0, 0, "mulps", "V4SFmode", "gen_rtx_MULT"], + + ["rdx.dst: DIV_DF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "divsd", "DFmode", "gen_rtx_DIV"], + ["rfx.dst: DIV_SF(rfx.src1 , rf.src2)", [1, 1], 1, 0, "divss", "SFmode", "gen_rtx_DIV"], + ["rdx.dst: DIV_VDF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "divpd", "V2DFmode", "gen_rtx_DIV"], + ["rdx.dst: DIV_VSF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "divps", "V4SFmode", "gen_rtx_DIV"], + + ["rdx.dst: DIV_DF(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "divsd", "DFmode", "gen_rtx_DIV"], + ["rfx.dst: DIV_SF(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "divss", "SFmode", "gen_rtx_DIV"], + ["rdx.dst: DIV_VDF(rdx.src1 , MEM_VHI(addr.src2))", [1, 1], 0, 0, "divpd", "V8HImode", "gen_rtx_DIV"], + ["rdx.dst: DIV_VSF(rdx.src1 , MEM_VSF(addr.src2))", [1, 1], 0, 0, "divps", "V4SFmode", "gen_rtx_DIV"], + + ["rdx.dst: IOR_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "orpd", "DFmode", "gen_rtx_IOR"], + ["rfx.dst: IOR_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "orps", "SFmode", "gen_rtx_IOR"], + ["rdx.dst: XOR_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "xorpd", "DFmode", "gen_rtx_XOR"], + ["rfx.dst: XOR_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "xorps", "SFmode", "gen_rtx_XOR"], + ["rdx.dst: AND_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "andpd", "DFmode", "gen_rtx_AND"], + ["rfx.dst: AND_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "andps", "SFmode", "gen_rtx_AND"], + ["rdx.dst: AND_DF(NOT_DF(rdx.src1) | rd.src2)", [1, 1], 1, 1, "andnpd", "DFmode", "gen_rtx_ANDNOT"], + ["rfx.dst: AND_SF(NOT_SF(rfx.src1) | rf.src2)", [1, 1], 1, 1, "andnps", "SFmode", "gen_rtx_ANDNOT"], + + # + # TODO: naked NOT_DF and NOT_SF done by xor with a mask of all 1's (similar to NEG_DF and NEG_SF) + # + + # + # TODO: vector (packed.src2) variants of vector Booleans + + # + # TODO: For gcc 4.3.1, icg+rtl phase can't seem to consume RTL for AND/IOR/XOR to xmm registers from memory + # gcc 4.4 appears to be able to do these memory operations from memory + # + #["rdx.dst: IOR_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, "orpd", "DFmode", "gen_rtx_IOR"], + #["rfx.dst: IOR_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, "orps", "SFmode", "gen_rtx_IOR"], + + #["rdx.dst: XOR_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, "xorpd", "DFmode", "gen_rtx_XOR"], + #["rfx.dst: XOR_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, "xorps", "SFmode", "gen_rtx_XOR"], + + #["rdx.dst: AND_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, "andpd", "DFmode", "gen_rtx_AND"], + #["rfx.dst: AND_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, "andps", "SFmode", "gen_rtx_AND"], + #["rdx.dst: AND_DF(NOT_DF(rdx.src1) | MEM_DF(addr.src2))", [1, 1], 0, "andnpd", "DFmode", "gen_rtx_ANDNOT"], + #["rfx.dst: AND_SF(NOT_SF(rfx.src1) | MEM_SF(addr.src2))", [1, 1], 0, "andnps", "SFmode", "gen_rtx_ANDNOT"], + + # + # TODO: it isn't clear when the FLT family (including FTE and FLE) come into the IL. + # + # FGE needs swapped operands from normal (eg, needs (rd, rdx.src2)); + # FGE uses wrapper function gen_rtx_LT_swap and gen_rtx_LE_swap + # We also need to interchange uses of $src1 and $src2 in rules from normal. + # Use a plug operator @ which is ``reverse ,'' (2nd | alternative.src2). + # + # This is a complete tarpit. + # + + # + # TODO vector (packed.src2) variants of the comparisons + # + + ["rdx.dst: UNLT_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmpltsd", "DFmode", "gen_rtx_UNLT"], + ["rdx.dst: UNLE_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmplesd", "DFmode", "gen_rtx_UNLE"], + ["rdx.dst: UNEQ_ALL(rdx.src1 | rd.src2)", [1, 1], 1, 1, "cmpeqsd", "DFmode", "gen_rtx_UNEQ"], + ["rdx.dst: LTGT_ALL(rdx.src1 | rd.src2)", [1, 1], 1, 1, "cmpneqsd", "DFmode", "gen_rtx_LTGT"], + ["rdx.dst: UNGE_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmpnltsd", "DFmode", "gen_rtx_UNGE"], + ["rdx.dst: UNGT_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmpnlesd", "DFmode", "gen_rtx_UNGT"], + + ["rfx.dst: UNLT_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpltss", "SFmode", "gen_rtx_UNLT"], + ["rfx.dst: UNLE_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpless", "SFmode", "gen_rtx_UNLE"], + ["rfx.dst: UNEQ_ALL(rfx.src1 | rf.src2)", [1, 1], 1, 1, "cmpeqss", "SFmode", "gen_rtx_UNEQ"], + ["rfx.dst: LTGT_ALL(rfx.src1 | rf.src2)", [1, 1], 1, 1, "cmpneqss", "SFmode", "gen_rtx_LTGT"], + ["rfx.dst: UNGE_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpnltss", "SFmode", "gen_rtx_UNGE"], + ["rfx.dst: UNGT_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpnless", "SFmode", "gen_rtx_UNGT"], + + ["rdx.dst: UNLT_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpltsd", "DFmode", "gen_rtx_UNLT"], + ["rdx.dst: UNLE_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmplesd", "DFmode", "gen_rtx_UNLE"], + ["rdx.dst: UNEQ_ALL(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpeqsd", "DFmode", "gen_rtx_UNEQ"], + ["rdx.dst: LTGT_ALL(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpneqsd", "DFmode", "gen_rtx_LTGT"], + ["rdx.dst: UNGE_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpnltsd", "DFmode", "gen_rtx_UNGE"], + ["rdx.dst: UNGT_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpnlesd", "DFmode", "gen_rtx_UNGT"], + + ["rfx.dst: UNLT_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpltss", "SFmode", "gen_rtx_UNLT"], + ["rfx.dst: UNLE_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpless", "SFmode", "gen_rtx_UNLE"], + ["rfx.dst: UNEQ_ALL(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpeqss", "SFmode", "gen_rtx_UNEQ"], + ["rfx.dst: LTGT_ALL(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpneqss", "SFmode", "gen_rtx_LTGT"], + ["rfx.dst: UNGE_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpnltss", "SFmode", "gen_rtx_UNGE"], + ["rfx.dst: UNGT_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpnless", "SFmode", "gen_rtx_UNGT"], + + # + # it isn't clear when/if the F..._DF and F..._SF operators will appear + # + ["rdx.dst: FLT_DF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmpltsd", "DFmode", "gen_rtx_LT"], + ["rdx.dst: FLE_DF(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmplesd", "DFmode", "gen_rtx_LE"], + ["rdx.dst: FEQ_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "cmpeqsd", "DFmode", "gen_rtx_EQ"], + ["rdx.dst: FNEQ_DF(rdx.src1| rd.src2)", [1, 1], 1, 1, "cmpnesd", "DFmode", "gen_rtx_NE"], + ["rdx.dst: FGE_DF(rdx.src1 @ rd.src2)", [1, 1], 1, 0, "cmpltsd", "DFmode", "gen_rtx_LT_swap"], + ["rdx.dst: FGT_DF(rdx.src1 @ rd.src2)", [1, 1], 1, 0, "cmplesd", "DFmode", "gen_rtx_LE_swap"], + + ["rfx.dst: FLT_SF(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpltss", "SFmode", "gen_rtx_LT"], + ["rfx.dst: FLE_SF(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpless", "SFmode", "gen_rtx_LE"], + ["rfx.dst: FEQ_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "cmpeqss", "SFmode", "gen_rtx_EQ"], + ["rfx.dst: FNEQ_SF(rfx.src1| rf.src2)", [1, 1], 1, 1, "cmpneqss", "SFmode", "gen_rtx_NE"], + ["rfx.dst: FGE_SF(rfx.src1 @ rf.src2)", [1, 1], 1, 0, "cmpltss", "SFmode", "gen_rtx_LT_swap"], + ["rfx.dst: FGT_SF(rfx.src1 @ rf.src2)", [1, 1], 1, 0, "cmpless", "SFmode", "gen_rtx_LE_swap"], + + ["rdx.dst: FLT_DF(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpltsd", "DFmode", "gen_rtx_LT"], + ["rdx.dst: FLE_DF(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmplesd", "DFmode", "gen_rtx_LE"], + ["rdx.dst: FEQ_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpeqsd", "DFmode", "gen_rtx_EQ"], + ["rdx.dst: FNEQ_DF(rdx.src1| MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpneqsd", "DFmode", "gen_rtx_NE"], + ["rdx.dst: FGE_DF(rdx.src1 @ MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpltsd", "DFmode", "gen_rtx_LT_swap"], + ["rdx.dst: FGT_DF(rdx.src1 @ MEM_DF(addr.src2))", [1, 1], 0, 0, "cmplesd", "DFmode", "gen_rtx_LE_swap"], + + ["rfx.dst: FLT_SF(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpltss", "SFmode", "gen_rtx_LT"], + ["rfx.dst: FLE_SF(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpless", "SFmode", "gen_rtx_LE"], + ["rfx.dst: FEQ_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpeqss", "SFmode", "gen_rtx_EQ"], + ["rfx.dst: FNEQ_SF(rfx.src1| MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpneqss", "SFmode", "gen_rtx_NE"], + ["rfx.dst: FGE_SF(rfx.src1 @ MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpltss", "SFmode", "gen_rtx_LT_swap"], + ["rfx.dst: FGT_SF(rfx.src1 @ MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpless", "SFmode", "gen_rtx_LE_swap"], + + ["rdx.dst: LT_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmpltsd", "DFmode", "gen_rtx_LT"], + ["rdx.dst: LE_ALL(rdx.src1 , rd.src2)", [1, 1], 1, 0, "cmplesd", "DFmode", "gen_rtx_LE"], + ["rdx.dst: EQ_ALL(rdx.src1 | rd.src2)", [1, 1], 1, 1, "cmpeqsd", "DFmode", "gen_rtx_EQ"], + ["rdx.dst: NE_ALL(rdx.src1 | rd.src2)", [1, 1], 1, 1, "cmpnesd", "DFmode", "gen_rtx_NE"], + ["rdx.dst: GE_ALL(rdx.src1 @ rd.src2)", [1, 1], 1, 0, "cmpltsd", "DFmode", "gen_rtx_LT_swap"], + ["rdx.dst: GT_ALL(rdx.src1 @ rd.src2)", [1, 1], 1, 0, "cmplesd", "DFmode", "gen_rtx_LE_swap"], + + ["rfx.dst: LT_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpltss", "SFmode", "gen_rtx_LT"], + ["rfx.dst: LE_ALL(rfx.src1 , rf.src2)", [1, 1], 1, 0, "cmpless", "SFmode", "gen_rtx_LE"], + ["rfx.dst: EQ_ALL(rfx.src1 | rf.src2)", [1, 1], 1, 1, "cmpeqss", "SFmode", "gen_rtx_EQ"], + ["rfx.dst: NE_ALL(rfx.src1 | rf.src2)", [1, 1], 1, 1, "cmpneqss","SFmode", "gen_rtx_NE"], + ["rfx.dst: GE_ALL(rfx.src1 @ rf.src2)", [1, 1], 1, 0, "cmpltss", "SFmode", "gen_rtx_LT_swap"], + ["rfx.dst: GT_ALL(rfx.src1 @ rf.src2)", [1, 1], 1, 0, "cmpless", "SFmode", "gen_rtx_LE_swap"], + + ["rdx.dst: LT_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpltsd", "DFmode", "gen_rtx_LT"], + ["rdx.dst: LE_ALL(rdx.src1 , MEM_DF(addr.src2))", [1, 1], 0, 0, "cmplesd", "DFmode", "gen_rtx_LE"], + ["rdx.dst: EQ_ALL(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpeqsd", "DFmode", "gen_rtx_EQ"], + ["rdx.dst: NE_ALL(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpneqsd", "DFmode", "gen_rtx_NE"], + ["rdx.dst: GE_ALL(rdx.src1 @ MEM_DF(addr.src2))", [1, 1], 0, 0, "cmpltsd", "DFmode", "gen_rtx_LT_swap"], + ["rdx.dst: GT_ALL(rdx.src1 @ MEM_DF(addr.src2))", [1, 1], 0, 0, "cmplesd", "DFmode", "gen_rtx_LE_swap"], + + ["rfx.dst: LT_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpltss", "SFmode", "gen_rtx_LT"], + ["rfx.dst: LE_ALL(rfx.src1 , MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpless", "SFmode", "gen_rtx_LE"], + ["rfx.dst: EQ_ALL(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpeqss", "SFmode", "gen_rtx_EQ"], + ["rfx.dst: NE_ALL(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpneqss", "SFmode", "gen_rtx_NE"], + ["rfx.dst: GE_ALL(rfx.src1 @ MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpltss", "SFmode", "gen_rtx_LT_swap"], + ["rfx.dst: GT_ALL(rfx.src1 @ MEM_SF(addr.src2))", [1, 1], 0, 0, "cmpless", "SFmode", "gen_rtx_LE_swap"], + + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "maxsd", "DFmode", "gen_rtx_IEEE_MAX_helper"], + ["rfx.dst: ICG_UNSPEC_IEEE_MAX_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "maxss", "SFmode", "gen_rtx_IEEE_MAX_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_VDF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "maxpd", "V2DFmode", "gen_rtx_IEEE_MAX_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_VSF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "maxps", "V4SFmode", "gen_rtx_IEEE_MAX_helper"], + + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "maxsd", "DFmode", "gen_rtx_IEEE_MAX_helper"], + ["rfx.dst: ICG_UNSPEC_IEEE_MAX_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "maxss", "SFmode", "gen_rtx_IEEE_MAX_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_VDF(rdx.src1 | MEM_VDF(addr.src2))", [1, 1], 0, 0, "maxpd", "V2DFmode", "gen_rtx_IEEE_MAX_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MAX_VSF(rdx.src1 | MEM_VSF(addr.src2))", [1, 1], 0, 0, "maxps", "V4SFmode", "gen_rtx_IEEE_MAX_helper"], + + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_DF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "minsd", "DFmode", "gen_rtx_IEEE_MIN_helper"], + ["rfx.dst: ICG_UNSPEC_IEEE_MIN_SF(rfx.src1 | rf.src2)", [1, 1], 1, 1, "minss", "SFmode", "gen_rtx_IEEE_MIN_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_VDF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "minpd", "V2DFmode", "gen_rtx_IEEE_MIN_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_VSF(rdx.src1 | rd.src2)", [1, 1], 1, 1, "minps", "V4SFmode", "gen_rtx_IEEE_MIN_helper"], + + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_DF(rdx.src1 | MEM_DF(addr.src2))", [1, 1], 0, 0, "minsd", "DFmode", "gen_rtx_IEEE_MIN_helper"], + ["rfx.dst: ICG_UNSPEC_IEEE_MIN_SF(rfx.src1 | MEM_SF(addr.src2))", [1, 1], 0, 0, "minss", "SFmode", "gen_rtx_IEEE_MIN_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_VDF(rdx.src1 | MEM_VDF(addr.src2))", [1, 1], 0, 0, "minpd", "V2DFmode", "gen_rtx_IEEE_MIN_helper"], + ["rdx.dst: ICG_UNSPEC_IEEE_MIN_VSF(rdx.src1 | MEM_VSF(addr.src2))", [1, 1], 0, 0, "minps", "V4SFmode", "gen_rtx_IEEE_MIN_helper"], + + +], """ + $rule $cost + supairs { + suOrder2($dst, $src1, $src2, kid, kids); + }, + names { + $dst->rx = $src1->rx; + }, + final { + $dst->rx = $src1->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if ($isRR) { + sparseset_set_bit(live, find($src2->r)); + } + else add_addr(live, $src2); + }, + remat { + flags = 0; + }, + costs { + if ($isRR) + memorable($src2->r); + if ($isCommute) + memorable($src1->rx); + else + forgettable($src1->rx); + }, + debug { + if ($isRR) { + dumpRR("$opcode", $src2->r, 'x', $dst->rx, 'x'); + } else { + dumpMR("$opcode", $src2, $dst->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src1->rx); + rtx src = $isRR + ? $rtx_builder($rtx_mode, dst, gen_rtx_REG($rtx_mode, $src2->r)) + : $rtx_builder($rtx_mode, dst, gen_rtx_MEM($rtx_mode, $src2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +#})] diff --git a/iburg/briggs/icg-grammars/x86-64.float.pyout b/iburg/briggs/icg-grammars/x86-64.float.pyout new file mode 100644 index 00000000000..9f22f53812f --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.float.pyout @@ -0,0 +1,9140 @@ +#line 29 "x86-64.float.py" +lhsd : REGX_DF [0, 0] +#line 36 "x86-64.float.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 30 "x86-64.float.py" +lhsf : REGX_SF [0, 0] +#line 36 "x86-64.float.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 31 "x86-64.float.py" +lhsd : REG_DF [0, 0] +#line 36 "x86-64.float.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 32 "x86-64.float.py" +lhsf : REG_SF [0, 0] +#line 36 "x86-64.float.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 59 "x86-64.float.py" +lhsd : MEM_DF(addr) [0, 0] +#line 64 "x86-64.float.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 60 "x86-64.float.py" +lhsf : MEM_SF(addr) [0, 0] +#line 64 "x86-64.float.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 86 "x86-64.float.py" +stmt : SET_ALL(lhsd, rd) [0, 0] +#line 91 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movsd", $2->r, 'x', $1); + else + dump_copy("movsd", $2->r, $1->r, 'x'); + }, + emit { + rtx src = gen_rtx_REG(DFmode, $2->r); + rtx dst = $1->spilled ? gen_rtx_MEM(DFmode, $1->rtl) : gen_rtx_REG(DFmode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 87 "x86-64.float.py" +stmt : SET_ALL(lhsf, rf) [0, 0] +#line 91 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movss", $2->r, 'x', $1); + else + dump_copy("movss", $2->r, $1->r, 'x'); + }, + emit { + rtx src = gen_rtx_REG(SFmode, $2->r); + rtx dst = $1->spilled ? gen_rtx_MEM(SFmode, $1->rtl) : gen_rtx_REG(SFmode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 133 "x86-64.float.py" +rd : REG_DF [0, 0] +#line 140 "x86-64.float.py" + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_load($$->r); + }, + supairs { + $$->extra = 0; /* TODO? only for rdx: rules */ + $$->freed = 0; /* TODO? only for rdx: rules */ + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 134 "x86-64.float.py" +rf : REG_SF [0, 0] +#line 140 "x86-64.float.py" + kinds { + icg_reg_vector[$$->r].kind = FLOAT_REGISTER; + }, + costs { + cost_load($$->r); + }, + supairs { + $$->extra = 0; /* TODO? only for rdx: rules */ + $$->freed = 0; /* TODO? only for rdx: rules */ + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 135 "x86-64.float.py" +rdx : REGX_DF [0, 0] +#line 140 "x86-64.float.py" + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; /* TODO? only for rdx: rules */ + $$->freed = 0; /* TODO? only for rdx: rules */ + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 136 "x86-64.float.py" +rfx : REGX_SF [0, 0] +#line 140 "x86-64.float.py" + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; /* TODO? only for rdx: rules */ + $$->freed = 0; /* TODO? only for rdx: rules */ + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 162 "x86-64.float.py" +rd : rdx [0, 0] +#line 167 "x86-64.float.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 163 "x86-64.float.py" +rf : rfx [0, 0] +#line 167 "x86-64.float.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 185 "x86-64.float.py" +rdx : rd [2, 4] +#line 190 "x86-64.float.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movapd", $1->r, $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + const rtx src = gen_rtx_REG(DFmode, $1->r); + const rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 186 "x86-64.float.py" +rfx : rf [2, 4] +#line 190 "x86-64.float.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movaps", $1->r, $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + const rtx src = gen_rtx_REG(SFmode, $1->r); + const rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 236 "x86-64.float.py" +rdx : MEM_DF(addr) [3, 2] +#line 241 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsd", $1, $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 237 "x86-64.float.py" +rfx : MEM_SF(addr) [3, 2] +#line 241 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movss", $1, $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 292 "x86-64.float.py" +r64x : FIX_DI(rd) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(DImode, src))); + }; +#line 293 "x86-64.float.py" +r32x : FIX_SI(rd) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(SImode, src))); + }; +#line 294 "x86-64.float.py" +r16x : FIX_HI(rd) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(HImode, src))); + }; +#line 295 "x86-64.float.py" +r8x : FIX_QI(rd) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(QImode, src))); + }; +#line 297 "x86-64.float.py" +r64x : FIX_DI(rf) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(DImode, src))); + }; +#line 298 "x86-64.float.py" +r32x : FIX_SI(rf) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(SImode, src))); + }; +#line 299 "x86-64.float.py" +r16x : FIX_HI(rf) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(HImode, src))); + }; +#line 300 "x86-64.float.py" +r8x : FIX_QI(rf) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(QImode, src))); + }; +#line 302 "x86-64.float.py" +r64x : FIX_DI(MEM_DF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(DImode, src))); + }; +#line 303 "x86-64.float.py" +r32x : FIX_SI(MEM_DF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(SImode, src))); + }; +#line 304 "x86-64.float.py" +r16x : FIX_HI(MEM_DF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(HImode, src))); + }; +#line 305 "x86-64.float.py" +r8x : FIX_QI(MEM_DF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(QImode, src))); + }; +#line 307 "x86-64.float.py" +r64x : FIX_DI(MEM_SF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(DImode, src))); + }; +#line 308 "x86-64.float.py" +r32x : FIX_SI(MEM_SF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(SImode, src))); + }; +#line 309 "x86-64.float.py" +r16x : FIX_HI(MEM_SF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(HImode, src))); + }; +#line 310 "x86-64.float.py" +r8x : FIX_QI(MEM_SF(addr)) [1, 1] +#line 314 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvttsd2siq", $1->r, 'x', $$->rx, 'q'); + } else { + dumpMR("cvttsd2siq", $1, $$->rx, 'q'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FIX(QImode, src))); + }; +#line 370 "x86-64.float.py" +rfx : FLOAT_TRUNCATE_SF(rd) [1, 1] +#line 381 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtsd2ss", $1->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cvtsd2ss", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT_TRUNCATE(SFmode, src))); + }; +#line 372 "x86-64.float.py" +rfx : FLOAT_TRUNCATE_SF(MEM_DF(addr)) [1, 1] +#line 381 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtsd2ss", $1->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cvtsd2ss", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DFmode, $1->r) + : gen_rtx_MEM(DFmode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT_TRUNCATE(SFmode, src))); + }; +#line 374 "x86-64.float.py" +rdx : FLOAT_EXTEND_DF(rf) [1, 1] +#line 381 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtss2sd", $1->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cvtss2sd", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT_EXTEND(DFmode, src))); + }; +#line 376 "x86-64.float.py" +rdx : FLOAT_EXTEND_DF(MEM_SF(addr)) [1, 1] +#line 381 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is rd */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtss2sd", $1->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cvtss2sd", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SFmode, $1->r) + : gen_rtx_MEM(SFmode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT_EXTEND(DFmode, src))); + }; +#line 432 "x86-64.float.py" +rdx : FLOAT_DF(r64) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtsi2sdq", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2sdq", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DImode, $1->r) + : gen_rtx_MEM(DImode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(DFmode, src))); + }; +#line 433 "x86-64.float.py" +rdx : FLOAT_DF(MEM_DI(addr)) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtsi2sdq", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2sdq", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DImode, $1->r) + : gen_rtx_MEM(DImode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(DFmode, src))); + }; +#line 434 "x86-64.float.py" +rfx : FLOAT_SF(r64) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtsi2ssq", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2ssq", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(DImode, $1->r) + : gen_rtx_MEM(DImode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(SFmode, src))); + }; +#line 435 "x86-64.float.py" +rfx : FLOAT_SF(MEM_DI(addr)) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtsi2ssq", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2ssq", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(DImode, $1->r) + : gen_rtx_MEM(DImode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(SFmode, src))); + }; +#line 437 "x86-64.float.py" +rdx : FLOAT_DF(r32) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtsi2sdl", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2sdl", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SImode, $1->r) + : gen_rtx_MEM(SImode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(DFmode, src))); + }; +#line 438 "x86-64.float.py" +rdx : FLOAT_DF(MEM_SI(addr)) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtsi2sdl", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2sdl", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SImode, $1->r) + : gen_rtx_MEM(SImode, $1->rtl); + rtx dst = gen_rtx_REG(DFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(DFmode, src))); + }; +#line 439 "x86-64.float.py" +rfx : FLOAT_SF(r32) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (1) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (1) { + memorable($1->r); + } + }, + debug { + if (1) { + dumpRR("cvtsi2ssl", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2ssl", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 1 + ? gen_rtx_REG(SImode, $1->r) + : gen_rtx_MEM(SImode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(SFmode, src))); + }; +#line 440 "x86-64.float.py" +rfx : FLOAT_SF(MEM_SI(addr)) [1, 1] +#line 444 "x86-64.float.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + /* NYI */ + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + if (0) { + sparseset_set_bit(live, find($1->r)); /* r, not rx, as rhs is r64 */ + } + else add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + if (0) { + memorable($1->r); + } + }, + debug { + if (0) { + dumpRR("cvtsi2ssl", $1->r, 'q', $$->rx, 'x'); + } else { + dumpMR("cvtsi2ssl", $1, $$->rx, 'x'); + } + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = 0 + ? gen_rtx_REG(SImode, $1->r) + : gen_rtx_MEM(SImode, $1->rtl); + rtx dst = gen_rtx_REG(SFmode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, gen_rtx_FLOAT(SFmode, src))); + }; +#line 491 "x86-64.float.py" +rdx: PLUS_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("addsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_PLUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 492 "x86-64.float.py" +rfx: PLUS_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("addss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_PLUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 493 "x86-64.float.py" +rdx: PLUS_VDI(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("paddq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_PLUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 494 "x86-64.float.py" +rdx: PLUS_VSI(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("paddd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_PLUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 495 "x86-64.float.py" +rdx: PLUS_VHI(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("paddw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_PLUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 496 "x86-64.float.py" +rdx: PLUS_VQI(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("paddb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_PLUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 497 "x86-64.float.py" +rdx: PLUS_VDF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("addpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_PLUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 498 "x86-64.float.py" +rdx: PLUS_VSF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("addps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_PLUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_PLUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 500 "x86-64.float.py" +rdx: PLUS_DF(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("addsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_PLUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 501 "x86-64.float.py" +rfx: PLUS_SF(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("addss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_PLUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 502 "x86-64.float.py" +rdx: PLUS_VDI(rdx | MEM_VDI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("paddq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_PLUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 503 "x86-64.float.py" +rdx: PLUS_VSI(rdx | MEM_VSI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("paddd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_PLUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 504 "x86-64.float.py" +rdx: PLUS_VHI(rdx | MEM_VHI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("paddw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_PLUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 505 "x86-64.float.py" +rdx: PLUS_VQI(rdx | MEM_VQI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("paddb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("paddb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_PLUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 506 "x86-64.float.py" +rdx: PLUS_VDF(rdx | MEM_VDF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("addpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_PLUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 507 "x86-64.float.py" +rdx: PLUS_VSF(rdx | MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("addps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("addps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_PLUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_PLUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 509 "x86-64.float.py" +rdx: PLUS_DF(rdx , NEG_DF(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MINUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 510 "x86-64.float.py" +rfx: PLUS_SF(rfx , NEG_SF(rf)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MINUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 511 "x86-64.float.py" +rdx: PLUS_VDI(rdx , NEG_VDI(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_MINUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 512 "x86-64.float.py" +rdx: PLUS_VSI(rdx , NEG_VSI(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_MINUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 513 "x86-64.float.py" +rdx: PLUS_VHI(rdx , NEG_VHI(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MINUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 514 "x86-64.float.py" +rdx: PLUS_VQI(rdx , NEG_VQI(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_MINUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 515 "x86-64.float.py" +rdx: PLUS_VDF(rdx , NEG_VDF(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MINUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 516 "x86-64.float.py" +rdx: PLUS_VSF(rdx , NEG_VSF(rd)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MINUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 518 "x86-64.float.py" +rdx: PLUS_DF(rdx , NEG_DF(MEM_DF(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MINUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 519 "x86-64.float.py" +rfx: PLUS_SF(rfx , NEG_SF(MEM_SF(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MINUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 520 "x86-64.float.py" +rdx: PLUS_VDI(rdx , NEG_VDI(MEM_VDI(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_MINUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 521 "x86-64.float.py" +rdx: PLUS_VSI(rdx , NEG_VSI(MEM_VSI(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_MINUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 522 "x86-64.float.py" +rdx: PLUS_VHI(rdx , NEG_VHI(MEM_VHI(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MINUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 523 "x86-64.float.py" +rdx: PLUS_VQI(rdx , NEG_VQI(MEM_VQI(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_MINUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 524 "x86-64.float.py" +rdx: PLUS_VDF(rdx , NEG_VDF(MEM_VDF(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MINUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 525 "x86-64.float.py" +rdx: PLUS_VSF(rdx , NEG_VSF(MEM_VSF(addr))) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MINUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 527 "x86-64.float.py" +rdx: MINUS_DF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MINUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 528 "x86-64.float.py" +rfx: MINUS_SF(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MINUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 529 "x86-64.float.py" +rdx: MINUS_VDI(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_MINUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 530 "x86-64.float.py" +rdx: MINUS_VSI(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_MINUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 531 "x86-64.float.py" +rdx: MINUS_VHI(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MINUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 532 "x86-64.float.py" +rdx: MINUS_VQI(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("psubb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_MINUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 533 "x86-64.float.py" +rdx: MINUS_VDF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MINUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 534 "x86-64.float.py" +rdx: MINUS_VSF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("subps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MINUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MINUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 536 "x86-64.float.py" +rdx: MINUS_DF(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MINUS(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 537 "x86-64.float.py" +rfx: MINUS_SF(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MINUS(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 538 "x86-64.float.py" +rdx: MINUS_VDI(rdx , MEM_VDI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubq", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubq", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V2DImode, dst, gen_rtx_REG(V2DImode, $2->r)) + : gen_rtx_MINUS(V2DImode, dst, gen_rtx_MEM(V2DImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 539 "x86-64.float.py" +rdx: MINUS_VSI(rdx , MEM_VSI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V4SImode, dst, gen_rtx_REG(V4SImode, $2->r)) + : gen_rtx_MINUS(V4SImode, dst, gen_rtx_MEM(V4SImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 540 "x86-64.float.py" +rdx: MINUS_VHI(rdx , MEM_VHI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MINUS(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 541 "x86-64.float.py" +rdx: MINUS_VQI(rdx , MEM_VQI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("psubb", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("psubb", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V16QImode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V16QImode, dst, gen_rtx_REG(V16QImode, $2->r)) + : gen_rtx_MINUS(V16QImode, dst, gen_rtx_MEM(V16QImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 542 "x86-64.float.py" +rdx: MINUS_VDF(rdx , MEM_VDF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MINUS(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 543 "x86-64.float.py" +rdx: MINUS_VSF(rdx , MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("subps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("subps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MINUS(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MINUS(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 545 "x86-64.float.py" +rdx: MULT_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("mulsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MULT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MULT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 546 "x86-64.float.py" +rfx: MULT_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("mulss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MULT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MULT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 547 "x86-64.float.py" +rdx: MULT_VHI(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("pmullw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("pmullw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 1 + ? gen_rtx_MULT(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MULT(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 548 "x86-64.float.py" +rdx: MULT_VDF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("mulpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MULT(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MULT(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 549 "x86-64.float.py" +rdx: MULT_VSF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("mulps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_MULT(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MULT(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 551 "x86-64.float.py" +rdx: MULT_DF(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("mulsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MULT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_MULT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 552 "x86-64.float.py" +rfx: MULT_SF(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("mulss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MULT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_MULT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 553 "x86-64.float.py" +rdx: MULT_VHI(rdx | MEM_VHI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("pmullw", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("pmullw", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 0 + ? gen_rtx_MULT(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_MULT(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 554 "x86-64.float.py" +rdx: MULT_VDF(rdx | MEM_VDF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("mulpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MULT(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_MULT(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 555 "x86-64.float.py" +rdx: MULT_VSF(rdx | MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("mulps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("mulps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_MULT(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_MULT(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 557 "x86-64.float.py" +rdx: DIV_DF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("divsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_DIV(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_DIV(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 558 "x86-64.float.py" +rfx: DIV_SF(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("divss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_DIV(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_DIV(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 559 "x86-64.float.py" +rdx: DIV_VDF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("divpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_DIV(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_DIV(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 560 "x86-64.float.py" +rdx: DIV_VSF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("divps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_DIV(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_DIV(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 562 "x86-64.float.py" +rdx: DIV_DF(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("divsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_DIV(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_DIV(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 563 "x86-64.float.py" +rfx: DIV_SF(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("divss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_DIV(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_DIV(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 564 "x86-64.float.py" +rdx: DIV_VDF(rdx , MEM_VHI(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("divpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V8HImode, $1->rx); + rtx src = 0 + ? gen_rtx_DIV(V8HImode, dst, gen_rtx_REG(V8HImode, $2->r)) + : gen_rtx_DIV(V8HImode, dst, gen_rtx_MEM(V8HImode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 565 "x86-64.float.py" +rdx: DIV_VSF(rdx , MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("divps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("divps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_DIV(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_DIV(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 567 "x86-64.float.py" +rdx: IOR_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("orpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("orpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IOR(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_IOR(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 568 "x86-64.float.py" +rfx: IOR_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("orps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("orps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IOR(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_IOR(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 569 "x86-64.float.py" +rdx: XOR_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("xorpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("xorpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_XOR(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_XOR(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 570 "x86-64.float.py" +rfx: XOR_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("xorps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("xorps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_XOR(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_XOR(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 571 "x86-64.float.py" +rdx: AND_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("andpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("andpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_AND(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_AND(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 572 "x86-64.float.py" +rfx: AND_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("andps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("andps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_AND(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_AND(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 573 "x86-64.float.py" +rdx: AND_DF(NOT_DF(rdx) | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("andnpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("andnpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_ANDNOT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_ANDNOT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 574 "x86-64.float.py" +rfx: AND_SF(NOT_SF(rfx) | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("andnps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("andnps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_ANDNOT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_ANDNOT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 613 "x86-64.float.py" +rdx: UNLT_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNLT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNLT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 614 "x86-64.float.py" +rdx: UNLE_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNLE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNLE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 615 "x86-64.float.py" +rdx: UNEQ_ALL(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNEQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNEQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 616 "x86-64.float.py" +rdx: LTGT_ALL(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpneqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LTGT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LTGT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 617 "x86-64.float.py" +rdx: UNGE_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNGE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNGE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 618 "x86-64.float.py" +rdx: UNGT_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnlesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnlesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNGT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNGT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 620 "x86-64.float.py" +rfx: UNLT_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNLT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNLT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 621 "x86-64.float.py" +rfx: UNLE_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNLE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNLE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 622 "x86-64.float.py" +rfx: UNEQ_ALL(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNEQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNEQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 623 "x86-64.float.py" +rfx: LTGT_ALL(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LTGT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LTGT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 624 "x86-64.float.py" +rfx: UNGE_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNGE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNGE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 625 "x86-64.float.py" +rfx: UNGT_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_UNGT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNGT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 627 "x86-64.float.py" +rdx: UNLT_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNLT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNLT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 628 "x86-64.float.py" +rdx: UNLE_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNLE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNLE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 629 "x86-64.float.py" +rdx: UNEQ_ALL(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNEQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNEQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 630 "x86-64.float.py" +rdx: LTGT_ALL(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LTGT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LTGT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 631 "x86-64.float.py" +rdx: UNGE_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpnltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNGE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNGE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 632 "x86-64.float.py" +rdx: UNGT_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpnlesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnlesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNGT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_UNGT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 634 "x86-64.float.py" +rfx: UNLT_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNLT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNLT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 635 "x86-64.float.py" +rfx: UNLE_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNLE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNLE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 636 "x86-64.float.py" +rfx: UNEQ_ALL(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNEQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNEQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 637 "x86-64.float.py" +rfx: LTGT_ALL(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LTGT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LTGT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 638 "x86-64.float.py" +rfx: UNGE_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpnltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNGE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNGE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 639 "x86-64.float.py" +rfx: UNGT_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpnless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_UNGT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_UNGT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 644 "x86-64.float.py" +rdx: FLT_DF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 645 "x86-64.float.py" +rdx: FLE_DF(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 646 "x86-64.float.py" +rdx: FEQ_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_EQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_EQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 647 "x86-64.float.py" +rdx: FNEQ_DF(rdx| rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_NE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_NE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 648 "x86-64.float.py" +rdx: FGE_DF(rdx @ rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 649 "x86-64.float.py" +rdx: FGT_DF(rdx @ rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 651 "x86-64.float.py" +rfx: FLT_SF(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 652 "x86-64.float.py" +rfx: FLE_SF(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 653 "x86-64.float.py" +rfx: FEQ_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_EQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_EQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 654 "x86-64.float.py" +rfx: FNEQ_SF(rfx| rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_NE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_NE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 655 "x86-64.float.py" +rfx: FGE_SF(rfx @ rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 656 "x86-64.float.py" +rfx: FGT_SF(rfx @ rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 658 "x86-64.float.py" +rdx: FLT_DF(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 659 "x86-64.float.py" +rdx: FLE_DF(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 660 "x86-64.float.py" +rdx: FEQ_DF(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_EQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_EQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 661 "x86-64.float.py" +rdx: FNEQ_DF(rdx| MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_NE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_NE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 662 "x86-64.float.py" +rdx: FGE_DF(rdx @ MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 663 "x86-64.float.py" +rdx: FGT_DF(rdx @ MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 665 "x86-64.float.py" +rfx: FLT_SF(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 666 "x86-64.float.py" +rfx: FLE_SF(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 667 "x86-64.float.py" +rfx: FEQ_SF(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_EQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_EQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 668 "x86-64.float.py" +rfx: FNEQ_SF(rfx| MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_NE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_NE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 669 "x86-64.float.py" +rfx: FGE_SF(rfx @ MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 670 "x86-64.float.py" +rfx: FGT_SF(rfx @ MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 672 "x86-64.float.py" +rdx: LT_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 673 "x86-64.float.py" +rdx: LE_ALL(rdx , rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 674 "x86-64.float.py" +rdx: EQ_ALL(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_EQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_EQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 675 "x86-64.float.py" +rdx: NE_ALL(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpnesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpnesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_NE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_NE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 676 "x86-64.float.py" +rdx: GE_ALL(rdx @ rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 677 "x86-64.float.py" +rdx: GT_ALL(rdx @ rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 679 "x86-64.float.py" +rfx: LT_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 680 "x86-64.float.py" +rfx: LE_ALL(rfx , rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 681 "x86-64.float.py" +rfx: EQ_ALL(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_EQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_EQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 682 "x86-64.float.py" +rfx: NE_ALL(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_NE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_NE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 683 "x86-64.float.py" +rfx: GE_ALL(rfx @ rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LT_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 684 "x86-64.float.py" +rfx: GT_ALL(rfx @ rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_LE_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 686 "x86-64.float.py" +rdx: LT_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 687 "x86-64.float.py" +rdx: LE_ALL(rdx , MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 688 "x86-64.float.py" +rdx: EQ_ALL(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_EQ(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_EQ(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 689 "x86-64.float.py" +rdx: NE_ALL(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_NE(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_NE(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 690 "x86-64.float.py" +rdx: GE_ALL(rdx @ MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LT_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 691 "x86-64.float.py" +rdx: GT_ALL(rdx @ MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmplesd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmplesd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE_swap(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_LE_swap(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 693 "x86-64.float.py" +rfx: LT_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 694 "x86-64.float.py" +rfx: LE_ALL(rfx , MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 695 "x86-64.float.py" +rfx: EQ_ALL(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpeqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpeqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_EQ(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_EQ(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 696 "x86-64.float.py" +rfx: NE_ALL(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpneqss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpneqss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_NE(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_NE(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 697 "x86-64.float.py" +rfx: GE_ALL(rfx @ MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpltss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpltss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LT_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LT_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 698 "x86-64.float.py" +rfx: GT_ALL(rfx @ MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("cmpless", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("cmpless", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_LE_swap(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_LE_swap(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 700 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("maxsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MAX_helper(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 701 "x86-64.float.py" +rfx: ICG_UNSPEC_IEEE_MAX_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("maxss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MAX_helper(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 702 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_VDF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("maxpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MAX_helper(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 703 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_VSF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("maxps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MAX_helper(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 705 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_DF(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("maxsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MAX_helper(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 706 "x86-64.float.py" +rfx: ICG_UNSPEC_IEEE_MAX_SF(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("maxss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MAX_helper(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 707 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_VDF(rdx | MEM_VDF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("maxpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MAX_helper(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 708 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MAX_VSF(rdx | MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("maxps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("maxps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MAX_helper(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_IEEE_MAX_helper(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 710 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_DF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("minsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MIN_helper(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 711 "x86-64.float.py" +rfx: ICG_UNSPEC_IEEE_MIN_SF(rfx | rf) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("minss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MIN_helper(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 712 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_VDF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("minpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MIN_helper(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 713 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_VSF(rdx | rd) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (1) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($2->r); + if (1) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (1) { + dumpRR("minps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 1 + ? gen_rtx_IEEE_MIN_helper(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 715 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_DF(rdx | MEM_DF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("minsd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minsd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MIN_helper(DFmode, dst, gen_rtx_REG(DFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(DFmode, dst, gen_rtx_MEM(DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 716 "x86-64.float.py" +rfx: ICG_UNSPEC_IEEE_MIN_SF(rfx | MEM_SF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("minss", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minss", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MIN_helper(SFmode, dst, gen_rtx_REG(SFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(SFmode, dst, gen_rtx_MEM(SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 717 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_VDF(rdx | MEM_VDF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("minpd", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minpd", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V2DFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MIN_helper(V2DFmode, dst, gen_rtx_REG(V2DFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(V2DFmode, dst, gen_rtx_MEM(V2DFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 718 "x86-64.float.py" +rdx: ICG_UNSPEC_IEEE_MIN_VSF(rdx | MEM_VSF(addr)) [1, 1] +#line 723 "x86-64.float.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + if (0) { + sparseset_set_bit(live, find($2->r)); + } + else add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($2->r); + if (0) + memorable($1->rx); + else + forgettable($1->rx); + }, + debug { + if (0) { + dumpRR("minps", $2->r, 'x', $$->rx, 'x'); + } else { + dumpMR("minps", $2, $$->rx, 'x'); + } + }, + emit { + rtx dst = gen_rtx_REG(V4SFmode, $1->rx); + rtx src = 0 + ? gen_rtx_IEEE_MIN_helper(V4SFmode, dst, gen_rtx_REG(V4SFmode, $2->r)) + : gen_rtx_IEEE_MIN_helper(V4SFmode, dst, gen_rtx_MEM(V4SFmode, $2->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; diff --git a/iburg/briggs/icg-grammars/x86-64.gr b/iburg/briggs/icg-grammars/x86-64.gr new file mode 100644 index 00000000000..400db859e76 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.gr @@ -0,0 +1,72 @@ +/* -*- mode: c -*- */ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include <stdio.h> +#include <assert.h> + +#include "obstack.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "basic-block.h" +#include "hard-reg-set.h" +#include "insn-config.h" +#include "recog.h" +#include "icg.h" + +#define NODEPTR_TYPE icg_nodes +#define STATE_TYPE icg_state_type + +#define OP_LABEL(p) ((p)->op) +#define STATE_LABEL(p) ((p)->state_label) +#define LEFT_CHILD(p) ((p)->left) +#define RIGHT_CHILD(p) ((p)->right) +#define PANIC printf + +#define ALLOC xmalloc + +/* + * Undefine the fancy abort so the burg output will compile. + * Later, maybe modify burg. + */ +#undef abort + +STATE_TYPE icg_burm_state(int, STATE_TYPE, STATE_TYPE); +int icg_burm_op_label(NODEPTR_TYPE); +STATE_TYPE icg_burm_state_label(NODEPTR_TYPE); +NODEPTR_TYPE icg_burm_child(NODEPTR_TYPE, int); + + +static int trace = -1; + +/* burm_trace - print trace message for matching p; decrement trace */ +static void icg_burm_trace(NODEPTR_TYPE p, int eruleno, + float cost, float bestcost) { + if (trace < 0) { + fprintf(stderr, "%p matched %s = %d with cost %g vs. %g\n", + (void *)p, icg_burm_string[eruleno], eruleno, cost, bestcost); + } else if (trace > 0 && cost < bestcost) { + --trace; + fprintf(stderr, "%p matched %s = %d with cost %g\n", + (void *)p, icg_burm_string[eruleno], eruleno, cost); + } + (void) icg_burm_trace; /* dummy reference to hush compiler warning */ +} + + +%% + +//The following includes are done by the Makefile; +// native plug can't handle includes at this place in the input. +// +//include "x86-64.gr.pyout"; +//include "x86-64.int.pyout"; +//include "x86-64.float.pyout"; +//include "x86-64.misc.pyout"; +//include "x86-64.string.pyout"; + diff --git a/iburg/briggs/icg-grammars/x86-64.gr.py b/iburg/briggs/icg-grammars/x86-64.gr.py new file mode 100644 index 00000000000..023258cf9d1 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.gr.py @@ -0,0 +1,662 @@ +# {([ +# -*- mode: python -*- +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +import plug + + +# To begin, minimally cover the RTL operations. +# Eventually, cover all the x86-64 instructions. +# There can be overlap, and burg will make the best choices for us. + + +# When I'm going to need to make a copy of a register +# (as in idiv), require that it be in an regx. That way, +# if it's already there, we have a good chance of coalescing. +# If it's just in a reg form, the chain rule reg:regx will +# copy it for us, and we'll surely coalesce one of the copies. +# May be even more important for mult and plus, where we'd +# like to be able to reuse either of the inputs if it's available, +# only making a copy if necessary. + +# Costs are from AMD's Barcelona Software Optimization Guide, Appendix C +# Since most everything is DirectPathSingle, I'm using latency as +# the primary cost and instruction size as the secondary cost. + +# +# The opcodes' enumeration values have been carefully chosen +# For many of the "traditional" operators, +# the sizemode is encoded in the last base-(tb_align) digit +# (eg, extractable using % tb_align). +# The operator itself is encoded in the remaining more sig digits. +# New operators always start off at values N*tb_align. +# +# See the encoding done in get_operator_mode. +# calling plug.term_align(tb_align) steps from operator to operator; +# calling plug.term_incr(5) gets us from the base operator (DI type) to the 1st float type.. +# +# int64 DI: delta == 0 +# int32 SI: delta == 1 +# int16 HI: delta == 2 +# int8 QI: delta == 3 +# int128 TI: delta == 4 +# int256 OI: delta == 5 +# ieee64 DF: delta == 6 +# ieee32 SF: delta == 7 +# vint64 VDI: delta == 8 +# vint32 VSI: delta == 9 +# vint16 VHI: delta == 10 +# vint8 VQI: delta == 11 +# vieee64 VDF: delta == 12 +# vieee32 VSF: delta == 13 + +tb_align = 14 + +# +# Some operators use suffix _ALL, which means "all types". +# + +# +# start of operators that encode the operator and the result type. +# DO NOT USE opcode value 0. We skip the first block of terminals. +# +plug.term_incr(1) # skip opcode value 0 + +std_type_suffixes = ["DI", "SI", "HI", "QI", "TI", "OI", "DF", "SF"] +int_type_suffixes = ["DI", "SI", "HI", "QI", "TI", "OI"] +uns_type_suffixes = ["DI", "SI", "HI", "QI", "TI", "OI"] +mem_type_suffixes = ["DI", "SI", "HI", "QI"] +vec_type_suffixes = ["DI", "SI", "HI", "QI", "TI", "OI", "DF", "SF", + "VDI", "VSI", "VHI", "VQI", "VDF", "VSF"] + +plug.term_align(tb_align); plug.term_cross("REG", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("REGX", std_type_suffixes) + +# +# We probably don't need the full cross product involving std_type_suffixes +# as the only type suffix used in practice is _DI. +# +plug.term_align(tb_align); plug.term_cross("REGCC", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("REGCCX", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("REGCCFPU", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("REGCCFPUX", std_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("ZERO_EXTEND", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("SIGN_EXTEND", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("SUBREG", std_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("PREFETCH", vec_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("PLUS", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_PLUS", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MINUS", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_MINUS", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("NEG", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_NEG", mem_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("MULT", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("DIV", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("UDIV", uns_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MOD", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("UMOD", int_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("SMIN", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("SMAX", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("UMIN", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("UMAX", int_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("CLZ", int_type_suffixes) # x86_64 advanced bit manipulations +plug.term_align(tb_align); plug.term_cross("POPCOUNT", int_type_suffixes) # x86_64 advanced bit manipulations +plug.term_align(tb_align); plug.term_cross("BSF", ["HI", "SI", "DI"]) # no 8 bit variant +plug.term_align(tb_align); plug.term_cross("BSR", ["HI", "SI", "DI"]) # no 8 bit variant + +# +# MEMB is a binary operator. +# The left child is the address, +# and the right child is a constant carrying +# the size of the memory block, in units of size_t. +# We only(?) deal with DImode types. +# +plug.term_align(tb_align); plug.term_cross("MEMB", std_type_suffixes) + +# +# We see bitwise boolean operators on DF and SF registers for some kinds of +# comparison operators that want to yield 1.0 or 0.0 +# by doing bit manipulations. +# +plug.term_align(tb_align); plug.term_cross("NOT", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_NOT", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("AND", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_AND", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("IOR", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_IOR", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("XOR", vec_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_XOR", mem_type_suffixes) + +# +# this structure of names is inherited from the gcc RTL namespace. Too bad the directionality +# of ASHIFT isn't encoded as ASHIFTL or something similar. +# ASHIFT: arithmetic shift left +# LSHIFTRT: logical right shift +# ASHIFTRT: arithmetic right shift +# ROTATE: rotate left +# ROTATERT: rotate right +# +plug.term_align(tb_align); plug.term_cross("ASHIFT", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_ASHIFT", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("LSHIFTRT", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_LSHIFTRT", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("ASHIFTRT", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_ASHIFTRT", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("ROTATE", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_ROTATE", mem_type_suffixes) +plug.term_align(tb_align); plug.term_cross("ROTATERT", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("MEM_ROTATERT", mem_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("FIX", int_type_suffixes) +plug.term_align(tb_align); plug.term_cross("TRUNCATE", int_type_suffixes) + +plug.term_align(tb_align); plug.term_cross("ASM_BINARY_RRR", int_type_suffixes); + +plug.term("ASM_NULLARY"); + +float_only = ["DF", "SF"]; +def term_base_float(name): + plug.term(name + "_BASE"); plug.term_incr(5); plug.term_cross(name, float_only) + +plug.term_align(tb_align); term_base_float("FLOAT") + +# +# FLOAT_TRUNCATE uses an ieee64 and yields an ieee32 +# +plug.term_align(tb_align); term_base_float("FLOAT_TRUNCATE") + +# +# FLOAT_EXTEND uses an ieee32 and yields an ieee64 +# +plug.term_align(tb_align); term_base_float("FLOAT_EXTEND") + +plug.term_align(tb_align); plug.term_cross("UPDATE", mem_type_suffixes) + +# +# This was an attempt by rrh on Oct 9, 2008 to use cmpsd instruction +# for compares that must yield a double value (in C++), compares normally +# yield a Boolean but some upstream phase recognizes +# (double compare double) ==> double +# as a special case, and transforms it into some other tree. +# The transformation is correct, but inefficient; +# see gcc.gnu.org/bugzilla bug/issue 37784 +# +# See CMPSD page in AMD manual +# +# TODO: it isn't clear when FLT_DF is produced vs UNLT_ALL vs LT_ALL +# when comparing doubles/floats. +# +plug.term_align(tb_align); term_base_float( "FEQ") +plug.term_align(tb_align); term_base_float( "FLT") +plug.term_align(tb_align); term_base_float( "FLE") +plug.term_align(tb_align); term_base_float("FUNORD") +plug.term_align(tb_align); term_base_float( "FNEQ") +plug.term_align(tb_align); term_base_float( "FNLT") +plug.term_align(tb_align); term_base_float( "FNLE") +plug.term_align(tb_align); term_base_float( "FORD") +plug.term_align(tb_align); term_base_float( "FGE") # synthetic +plug.term_align(tb_align); term_base_float( "FGT") # synthetic + + + +# +# end of operators that encode the operator and result type. +# + +plug.term_align(tb_align); plug.term("SYMBOL_REF_DI") +plug.term("SYMBOL_REF_32") +plug.term("SYMBOL_REF_64") +plug.term("LABEL_REF_DI") + +# +# For ordered scalar compares yielding a condition code. +# However sometimes we see these operators in the context double + (double < double). +# +plug.term("LT_ALL") # signed +plug.term("LE_ALL") # signed +plug.term("EQ_ALL") # unsigned and signed +plug.term("NE_ALL") # unsigned and signed +plug.term("GE_ALL") # signed +plug.term("GT_ALL") # signed + +plug.term("LTS_ALL") # signed (when mode is CCGOC: CC garbage overflow carry, generate "js") + +plug.term("LTU_ALL") # unsigned +plug.term("LEU_ALL") # unsigned +plug.term("GEU_ALL") # unsigned +plug.term("GTU_ALL") # unsigned + +# +# For unordered floating point compares yielding a condition code. +# +plug.term("UNEQ_ALL") # unordered floating point +plug.term("UNGE_ALL") # unordered floating point +plug.term("UNGT_ALL") # unordered floating point +plug.term("UNLE_ALL") # unordered floating point +plug.term("UNLT_ALL") # unordered floating point +plug.term("LTGT_ALL") # unordered floating point +plug.term("UNORDERED_ALL") # unordered floating point +plug.term("ORDERED_ALL") # unordered floating point + + +plug.term_align(tb_align); plug.term("PC_ALL"); # program counter + +plug.term("COMPARE_CC") + +plug.term("COND_MOVE"); plug.term("COND_MOVE_XX") +plug.term("PAIR_ALL") + +# +# do I need all the types for CONST, +# or is CONST only used for relocatable addresses? +# +plug.term("CONST_DI") + +plug.term("PARALLEL_ALL") +plug.term("SET_ALL") +plug.term("USE_ALL") +plug.term("END_OF_LIST") +plug.term("CALL_ALL") +plug.term("LIST_ALL") +plug.term("DEF_ALL") + +plug.term("CONST_0") # the constant +0 +plug.term("CONST_P1") # the constant +1 +plug.term("CONST_P2") # the constant +2 +plug.term("CONST_P3") # the constant +3 +plug.term("CONST_P4") # the constant +4 +plug.term("CONST_P8") # the constant +8 +plug.term("CONST_P15") # the constant +15 (for BSR idiom) +plug.term("CONST_P16") # the constant +16 +plug.term("CONST_P24") # the constant +24 +plug.term("CONST_P31") # the constant +31 (for BSR idiom) +plug.term("CONST_P32") # the constant +32 +plug.term("CONST_P48") # the constant +48 +plug.term("CONST_P56") # the constant +56 +plug.term("CONST_P63") # the constant +63 (for BSR idiom) +plug.term("CONST_P255") # the constant +255 +plug.term("CONST_N1") # the constant -1 + +plug.term("CONST4P") # a 4 bit positive constant, including the sign bit, [0..7] +plug.term("CONST5P") +plug.term("CONST6P") +plug.term("CONST7P") +plug.term("CONST8P") +plug.term("CONST12P") +plug.term("CONST13P") +plug.term("CONST14P") +plug.term("CONST15P") +plug.term("CONST16P") +plug.term("CONST28P") +plug.term("CONST29P") +plug.term("CONST30P") +plug.term("CONST31P") +plug.term("CONST32P") +plug.term("CONST64P") + +plug.term("CONST4N") # a 4-bit negative constant, [-8..-1] +plug.term("CONST5N") +plug.term("CONST6N") +plug.term("CONST7N") +plug.term("CONST8N") +plug.term("CONST12N") +plug.term("CONST13N") +plug.term("CONST14N") +plug.term("CONST15N") +plug.term("CONST16N") +plug.term("CONST28N") +plug.term("CONST29N") +plug.term("CONST30N") +plug.term("CONST31N") +plug.term("CONST32N") +plug.term("CONST64N") + +plug.term("CONSTIEEE32") # an IEEE-32 constant +plug.term("CONSTIEEE64") # an IEEE-32 constant + +# +# Add terminal symbols for all of the UNSPECs. +# We'll only add rules for the UNSPECs as we encounter a need. +# +plug.term("ICG_UNSPEC_GOT") # 0 +plug.term("ICG_UNSPEC_GOTOFF") # 1 +plug.term("ICG_UNSPEC_GOTPCREL") # 2 +plug.term("ICG_UNSPEC_GOTTPOFF") # 3 +plug.term("ICG_UNSPEC_TPOFF") # 4 +plug.term("ICG_UNSPEC_NTPOFF") # 5 +plug.term("ICG_UNSPEC_DTPOFF") # 6 +plug.term("ICG_UNSPEC_GOTNTPOFF") # 7 +plug.term("ICG_UNSPEC_INDNTPOFF") # 8 +plug.term("ICG_UNSPEC_PLTOFF") # 9 +plug.term("ICG_UNSPEC_MACHOPIC_OFFSET") # 10 +plug.term("ICG_UNSPEC_STACK_ALLOC") # 11 +plug.term("ICG_UNSPEC_SET_GOT") # 12 +plug.term("ICG_UNSPEC_SSE_PROLOGUE_SAVE") # 13 +plug.term("ICG_UNSPEC_REG_SAVE") # 14 +plug.term("ICG_UNSPEC_DEF_CFA") # 15 +plug.term("ICG_UNSPEC_SET_RIP") # 16 +plug.term("ICG_UNSPEC_SET_GOT_OFFSET") # 17 +plug.term("ICG_UNSPEC_TP") # 18 +plug.term("ICG_UNSPEC_TLS_GD") # 19 +plug.term("ICG_UNSPEC_TLS_LD_BASE") # 20 +plug.term("ICG_UNSPEC_TLSDESC") # 21 +plug.term("ICG_UNSPEC_SCAS") # 30 +plug.term("ICG_UNSPEC_FNSTSW") # 31 +plug.term("ICG_UNSPEC_SAHF") # 32 +plug.term("ICG_UNSPEC_FSTCW") # 33 +plug.term_align(tb_align); plug.term_cross("ICG_UNSPEC_ADD_CARRY", vec_type_suffixes) # 34 +plug.term("ICG_UNSPEC_FLDCW") # 35 +plug.term("ICG_UNSPEC_REP") # 36 +plug.term("ICG_UNSPEC_EH_RETURN") # 37 +plug.term("ICG_UNSPEC_LD_MPIC") # 38 +plug.term("ICG_UNSPEC_TRUNC_NOOP") # 39 +plug.term("ICG_UNSPEC_FIX_NOTRUNC") # 40 +plug.term("ICG_UNSPEC_PFRCPIT1") # 40 +plug.term("ICG_UNSPEC_MASKMOV") # 41 +plug.term("ICG_UNSPEC_PFRCPIT2") # 41 +plug.term("ICG_UNSPEC_MOVMSK") # 42 +plug.term("ICG_UNSPEC_PFRSQRT") # 42 +plug.term("ICG_UNSPEC_MOVNT") # 43 +plug.term("ICG_UNSPEC_PFRSQIT1") # 43 +plug.term("ICG_UNSPEC_MFENCE") # 44 +plug.term("ICG_UNSPEC_MOVU") # 44 +plug.term("ICG_UNSPEC_LFENCE") # 45 +plug.term("ICG_UNSPEC_RCP") # 45 +plug.term("ICG_UNSPEC_PSADBW") # 46 +plug.term("ICG_UNSPEC_RSQRT") # 46 +plug.term("ICG_UNSPEC_LDDQU") # 47 +plug.term("ICG_UNSPEC_SFENCE") # 47 +plug.term("ICG_UNSPEC_PFRCP") # 49 +plug.term("ICG_UNSPEC_COPYSIGN") # 50 +plug.term_align(tb_align); plug.term_cross("ICG_UNSPEC_IEEE_MIN", vec_type_suffixes) # 51 +plug.term_align(tb_align); plug.term_cross("ICG_UNSPEC_IEEE_MAX", vec_type_suffixes) # 52 +plug.term("ICG_UNSPEC_SIN") # 60 +plug.term("ICG_UNSPEC_COS") # 61 +plug.term("ICG_UNSPEC_FPATAN") # 62 +plug.term("ICG_UNSPEC_FYL2X") # 63 +plug.term("ICG_UNSPEC_FYL2XP1") # 64 +plug.term("ICG_UNSPEC_FRNDINT") # 65 +plug.term("ICG_UNSPEC_FIST") # 66 +plug.term("ICG_UNSPEC_F2XM1") # 67 +plug.term("ICG_UNSPEC_TAN") # 68 +plug.term("ICG_UNSPEC_FXAM") # 69 +plug.term("ICG_UNSPEC_FRNDINT_FLOOR") # 70 +plug.term("ICG_UNSPEC_FRNDINT_CEIL") # 71 +plug.term("ICG_UNSPEC_FRNDINT_TRUNC") # 72 +plug.term("ICG_UNSPEC_FRNDINT_MASK_PM") # 73 +plug.term("ICG_UNSPEC_FIST_FLOOR") # 74 +plug.term("ICG_UNSPEC_FIST_CEIL") # 75 +plug.term("ICG_UNSPEC_SINCOS_COS") # 80 +plug.term("ICG_UNSPEC_SINCOS_SIN") # 81 +plug.term("ICG_UNSPEC_XTRACT_FRACT") # 84 +plug.term("ICG_UNSPEC_XTRACT_EXP") # 85 +plug.term("ICG_UNSPEC_FSCALE_FRACT") # 86 +plug.term("ICG_UNSPEC_FSCALE_EXP") # 87 +plug.term("ICG_UNSPEC_FPREM_F") # 88 +plug.term("ICG_UNSPEC_FPREM_U") # 89 +plug.term("ICG_UNSPEC_FPREM1_F") # 90 +plug.term("ICG_UNSPEC_FPREM1_U") # 91 +plug.term("ICG_UNSPEC_C2_FLAG") # 95 +plug.term("ICG_UNSPEC_SP_SET") # 100 +plug.term("ICG_UNSPEC_SP_TEST") # 101 +plug.term("ICG_UNSPEC_SP_TLS_SET") # 102 +plug.term("ICG_UNSPEC_SP_TLS_TEST") # 103 +plug.term("ICG_UNSPEC_PSHUFB") # 120 +plug.term("ICG_UNSPEC_PSIGN") # 121 +plug.term("ICG_UNSPEC_PALIGNR") # 122 +plug.term("ICG_UNSPEC_EXTRQI") # 130 +plug.term("ICG_UNSPEC_EXTRQ") # 131 +plug.term("ICG_UNSPEC_INSERTQI") # 132 +plug.term("ICG_UNSPEC_INSERTQ") # 133 +plug.term("ICG_UNSPEC_BLENDV") # 134 +plug.term("ICG_UNSPEC_INSERTPS") # 135 +plug.term("ICG_UNSPEC_DP") # 136 +plug.term("ICG_UNSPEC_MOVNTDQA") # 137 +plug.term("ICG_UNSPEC_MPSADBW") # 138 +plug.term("ICG_UNSPEC_PHMINPOSUW") # 139 +plug.term("ICG_UNSPEC_PTEST") # 140 +plug.term("ICG_UNSPEC_ROUND") # 141 +plug.term("ICG_UNSPEC_CRC32") # 143 +plug.term("ICG_UNSPEC_PCMPESTR") # 144 +plug.term("ICG_UNSPEC_PCMPISTR") # 145 +plug.term("ICG_UNSPEC_SSE5_INTRINSIC") # 150 +plug.term("ICG_UNSPEC_SSE5_UNSIGNED_CMP") # 151 +plug.term("ICG_UNSPEC_SSE5_TRUEFALSE") # 152 +plug.term("ICG_UNSPEC_SSE5_PERMUTE") # 153 +plug.term("ICG_UNSPEC_FRCZ") # 154 +plug.term("ICG_UNSPEC_CVTPH2PS") # 155 +plug.term("ICG_UNSPEC_CVTPS2PH") # 156 +plug.term("ICG_UNSPEC_AESENC") # 159 +plug.term("ICG_UNSPEC_AESENCLAST") # 160 +plug.term("ICG_UNSPEC_AESDEC") # 161 +plug.term("ICG_UNSPEC_AESDECLAST") # 162 +plug.term("ICG_UNSPEC_AESIMC") # 163 +plug.term("ICG_UNSPEC_AESKEYGENASSIST") # 164 +plug.term("ICG_UNSPEC_PCLMUL") # 165 +plug.term("ICG_UNSPEC_PCMP") # 166 +plug.term("ICG_UNSPEC_VPERMIL") # 167 +plug.term("ICG_UNSPEC_VPERMIL2") # 168 +plug.term("ICG_UNSPEC_VPERMIL2F128") # 169 +plug.term("ICG_UNSPEC_MASKLOAD") # 170 +plug.term("ICG_UNSPEC_MASKSTORE") # 171 +plug.term("ICG_UNSPEC_CAST") # 172 +plug.term("ICG_UNSPEC_VTESTP") # 173 + +plug.nonterm("stmt") +plug.nonterm("nocc") # computation to memory, without any side effects on condition codes + +# +# Preston writes (02Jul2008): +# All the integer registers are 64 bits, +# but lots of times they hold smaller values. I differentiate between these cases: +# +# r64 +# r32 - don't know the value of the upper 32 bits +# rz32 - the upper 32 bits are 0 +# r16 - don't know the value of the upper 48 bits +# rz16 - the upper 48 bits are all zero +# rs16 - the upper 32 are zero, the next 16 are a sign extension of the lower 16 +# r8 - don't know the value of the upper 56 bits +# rz8 - the upper 56 bits are all zero +# rs8 - the upper 32 bits are 0, the next 24 are a sign extension of the lower 8 +# +# +# There are also the "x" variants of each of these, r64x, r32x, rz32x, etc. +# The 'x' variant means that the register will NOT be reused. +# The non-'x' variant continues to be live, so is read only. +# +# non terminals prefixed with "cc" means that the condition code is also set +# and is live and is to be used immediately. For example "if (a+b > 0)" +# would be done as an add of rn:=a+b, and then a branch; no intermediate test is needed. +# +# TODO (05Nov2008): the register allocator may spill and reload and the condition codes will not +# be spilled/reloaded. This perhaps needs to be marked as a special case in the allocator? +# +# All of these oddball cases come up because of the oddball way the x86-64 +# works. It all started when I had to load an 8-bit value from memory to +# a register. I had a choice: either sign extend it to 32 bit (zeroing the +# upper 32 bits), or zero extend it to 32 bits (still zeroing the upper +# 32 bits). How to choose between them? So I made all these names and +# added many, many grammar rules to force iburg to choose between them. +# Worked a treat. +# +# Last night, I had the idea of condensing the set of non-terminal +# names, combining r8, r16, r32, and r64 into a single class called r64. +# After all, it's basically a register right? And we'd differentiate +# between things using the mode of the operation. Plus, I'd be able to +# take advantage of a few more tricky situations. +# +# It almost worked. Where it fails is with SIGN_EXTEND and ZERO_EXTEND. +# The problem is that the mode of these specifies what the result should be +# (e.g., DI) but not what the source was. I need to know both so I can +# know to extend from 8 to 64 bits, or 16 to 64, etc. +# + +legal_lhs_attrs = ["r", "rtl", "spilled"] + +plug.nonterm("lhs64", legal_lhs_attrs) +plug.nonterm("lhs32", legal_lhs_attrs) +plug.nonterm("lhs16", legal_lhs_attrs) +plug.nonterm("lhs8", legal_lhs_attrs) +plug.nonterm("lhsd", legal_lhs_attrs) +plug.nonterm("lhsf", legal_lhs_attrs) + +legal_rx_attrs = ["rx", "extra", "freed"] +legal_r_attrs = ["r", "extra", "freed"] + +plug.nonterm("rd", legal_r_attrs) +plug.nonterm("rdx", legal_rx_attrs) + +plug.nonterm("rf", legal_r_attrs) +plug.nonterm("rfx", legal_rx_attrs) + +plug.nonterm("r64", legal_r_attrs) +plug.nonterm("r64x", legal_rx_attrs) + +plug.nonterm("r32", legal_r_attrs) +plug.nonterm("r32x", legal_rx_attrs) + +plug.nonterm("rz32") # rzN is zero-extended to 64 bits +plug.nonterm("rz32x", legal_rx_attrs) # rzN is zero-extended to 64 bits + +plug.nonterm("r16", legal_r_attrs) +plug.nonterm("r16x", legal_rx_attrs) +plug.nonterm("rz16", legal_r_attrs) +plug.nonterm("rz16x", legal_rx_attrs) +# rsN is sign-extended to 32 bits +plug.nonterm("rs16", legal_r_attrs ) +plug.nonterm("rs16x", legal_rx_attrs) # rsN is sign-extended to 32 bits + +plug.nonterm("r8", legal_r_attrs) +plug.nonterm("r8x", legal_rx_attrs) +plug.nonterm("rz8", legal_r_attrs) +plug.nonterm("rz8x", legal_rx_attrs) +plug.nonterm("rs8", legal_r_attrs) +plug.nonterm("rs8x", legal_rx_attrs) + +plug.nonterm("ccr64x", legal_rx_attrs) +plug.nonterm("ccr32x", legal_rx_attrs) +plug.nonterm("ccrz32x", legal_rx_attrs) +plug.nonterm("ccr16x", legal_rx_attrs) +plug.nonterm("ccrz16x", legal_rx_attrs) +plug.nonterm("ccrs16x", legal_rx_attrs) + +plug.nonterm("ccr8x", legal_rx_attrs) +plug.nonterm("ccrz8x", legal_rx_attrs) +plug.nonterm("ccrs8x", legal_rx_attrs) + +bogus_attrs = ["foo"] +plug.nonterm("rcc", bogus_attrs) # condition code +plug.nonterm("urcc", bogus_attrs) # unordered condition code (floating point) +plug.nonterm("condition", ["code", "cc_code"]) + +plug.nonterm("disp", ["a", "rtl"]) +plug.nonterm("addr", ["a", "extra", "freed", "rtl"]) + +plug.nonterm("base64", ["extra", "freed", "a", "rtl"]) +plug.nonterm("base32", ["extra", "freed", "a", "rtl"]) +plug.nonterm("base16", ["extra", "freed", "a", "rtl"]) +plug.nonterm("base8", ["extra", "freed", "a", "rtl"]) + +plug.nonterm("index64", ["extra", "freed", "a", "rtl"]) +plug.nonterm("index32", ["extra", "freed", "a", "rtl"]) +plug.nonterm("index16", ["extra", "freed", "a", "rtl"]) +plug.nonterm("index8", ["extra", "freed", "a", "rtl"]) + +plug.nonterm("scon", ["val"]) +plug.nonterm("mcon", ["val"]) +plug.nonterm("imm4", ["val"]) +plug.nonterm("imm5", ["val"]) +plug.nonterm("imm6", ["val"]) +plug.nonterm("imm7", ["val"]) +plug.nonterm("imm8", ["val"]) +plug.nonterm("imm12", ["val"]) +plug.nonterm("imm13", ["val"]) +plug.nonterm("imm14", ["val"]) +plug.nonterm("imm15", ["val"]) +plug.nonterm("imm16", ["val"]) +plug.nonterm("imm28", ["val"]) +plug.nonterm("imm29", ["val"]) +plug.nonterm("imm30", ["val"]) +plug.nonterm("imm31", ["val"]) +plug.nonterm("imm32", ["val", "a", "rtl"]) +plug.nonterm("imm64", ["val"]) + +plug.nonterm("pos8", ["val"]) +plug.nonterm("pos16", ["val"]) +plug.nonterm("pos32", ["val"]) +plug.nonterm("pureimm32", ["val"]) # only constants; no symbols involved + +plug.nonterm("label") +plug.nonterm("compare") +plug.nonterm("use") +plug.nonterm("def") +plug.nonterm("use_list") +plug.nonterm("def_list") + +plug.nonterm("symbol") +plug.nonterm("symbol32") +plug.nonterm("symbol64") + +plug.reduce("names" , "icg-names.cases") # a pass for numbering all the temporary registers +plug.reduce("kinds" , "icg-kinds.cases") # a pass for setting the kind of each register +plug.reduce("supairs" , "icg-supairs.cases") # a pass for computing SU pairs +plug.reduce("build" , "icg-build.cases") # a pass for building the inteference graph +plug.reduce("coalesce" , "icg-coalesce.cases") # a pass for coalescing +plug.reduce("remat" , "icg-remat.cases") # a pass for finding rematerialization opportunities +plug.reduce("costs" , "icg-costs.cases") # a pass for computing spill costs +plug.reduce("spill" , "icg-spill.cases") # a pass for adding spill code +plug.reduce("debug" , "icg-debug.cases") # a pass for dumping debuggable stuff +plug.reduce("final" , "icg-final.cases") # final rewrite of code with colored registers +plug.reduce("targeting" , "icg-targeting.cases") # a pass for coalescing for copy above commutative expressions +plug.reduce("emit" , "icg-emit.cases") # a pass for generating RTL + +plug.start("stmt") + + +# costs +# +# I'm using two parts, [latency, bytes], where latency is more significant. +# Most everything on the Opteron has a 1-cycle latency, so it's not too interesting. +# The encoding size, in bytes, will often be the differentiator. +# I can't be perfectly accurate, because the final size will sometimes +# depend on the registers assigned. +# +# Here's a summary of what I've seen in experiments for addressing modes +# (this is only the part the addressing mode contributes to the total cost), +# so something like +# +# movq 5(%rax,%rbx,4),%rcx +# +# has requires 2 bytes for the basic movq + whatever the addressing mode +# contributes (in this case, 3 more bytes for a total of 5). +# +# I test the size of things by typing instructions into a .s file +# and running them through the assembler, like this +# +# gcc -c -Wa,-alh test.s +# +# which spits out a listing. Be sure to use a 64-bit version of gcc! +# +# addressing +# mode cost comments +#-------------------------------------------------------------------- +# (base) 1 a base register contributes 1 +# (base,index) 2 an index register add 1 +# (base,index,4) 2 even if it is shifted +# 1(base,index,4) 3 a displacement adds 1 byte, if it fits +# 130(base,index,4) 6 or 4 bytes +# (,index) 6 an index by itself is expensive +# 1(,index,4) 6 same cost +# 130(,index,4) 6 same cost +# 130 6 direct (use RIP instead) +# 130(%RIP) 5 position independent + +# })] diff --git a/iburg/briggs/icg-grammars/x86-64.gr.pyout b/iburg/briggs/icg-grammars/x86-64.gr.pyout new file mode 100644 index 00000000000..4d5acb6ae85 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.gr.pyout @@ -0,0 +1,778 @@ +term REG_DI = 14; +term REG_SI = 15; +term REG_HI = 16; +term REG_QI = 17; +term REG_TI = 18; +term REG_OI = 19; +term REG_DF = 20; +term REG_SF = 21; +term REGX_DI = 28; +term REGX_SI = 29; +term REGX_HI = 30; +term REGX_QI = 31; +term REGX_TI = 32; +term REGX_OI = 33; +term REGX_DF = 34; +term REGX_SF = 35; +term REGCC_DI = 42; +term REGCC_SI = 43; +term REGCC_HI = 44; +term REGCC_QI = 45; +term REGCC_TI = 46; +term REGCC_OI = 47; +term REGCC_DF = 48; +term REGCC_SF = 49; +term REGCCX_DI = 56; +term REGCCX_SI = 57; +term REGCCX_HI = 58; +term REGCCX_QI = 59; +term REGCCX_TI = 60; +term REGCCX_OI = 61; +term REGCCX_DF = 62; +term REGCCX_SF = 63; +term REGCCFPU_DI = 70; +term REGCCFPU_SI = 71; +term REGCCFPU_HI = 72; +term REGCCFPU_QI = 73; +term REGCCFPU_TI = 74; +term REGCCFPU_OI = 75; +term REGCCFPU_DF = 76; +term REGCCFPU_SF = 77; +term REGCCFPUX_DI = 84; +term REGCCFPUX_SI = 85; +term REGCCFPUX_HI = 86; +term REGCCFPUX_QI = 87; +term REGCCFPUX_TI = 88; +term REGCCFPUX_OI = 89; +term REGCCFPUX_DF = 90; +term REGCCFPUX_SF = 91; +term ZERO_EXTEND_DI = 98; +term ZERO_EXTEND_SI = 99; +term ZERO_EXTEND_HI = 100; +term ZERO_EXTEND_QI = 101; +term ZERO_EXTEND_TI = 102; +term ZERO_EXTEND_OI = 103; +term ZERO_EXTEND_DF = 104; +term ZERO_EXTEND_SF = 105; +term SIGN_EXTEND_DI = 112; +term SIGN_EXTEND_SI = 113; +term SIGN_EXTEND_HI = 114; +term SIGN_EXTEND_QI = 115; +term SIGN_EXTEND_TI = 116; +term SIGN_EXTEND_OI = 117; +term SIGN_EXTEND_DF = 118; +term SIGN_EXTEND_SF = 119; +term SUBREG_DI = 126; +term SUBREG_SI = 127; +term SUBREG_HI = 128; +term SUBREG_QI = 129; +term SUBREG_TI = 130; +term SUBREG_OI = 131; +term SUBREG_DF = 132; +term SUBREG_SF = 133; +term MEM_DI = 140; +term MEM_SI = 141; +term MEM_HI = 142; +term MEM_QI = 143; +term MEM_TI = 144; +term MEM_OI = 145; +term MEM_DF = 146; +term MEM_SF = 147; +term MEM_VDI = 148; +term MEM_VSI = 149; +term MEM_VHI = 150; +term MEM_VQI = 151; +term MEM_VDF = 152; +term MEM_VSF = 153; +term PREFETCH_DI = 154; +term PREFETCH_SI = 155; +term PREFETCH_HI = 156; +term PREFETCH_QI = 157; +term PREFETCH_TI = 158; +term PREFETCH_OI = 159; +term PREFETCH_DF = 160; +term PREFETCH_SF = 161; +term PREFETCH_VDI = 162; +term PREFETCH_VSI = 163; +term PREFETCH_VHI = 164; +term PREFETCH_VQI = 165; +term PREFETCH_VDF = 166; +term PREFETCH_VSF = 167; +term PLUS_DI = 168; +term PLUS_SI = 169; +term PLUS_HI = 170; +term PLUS_QI = 171; +term PLUS_TI = 172; +term PLUS_OI = 173; +term PLUS_DF = 174; +term PLUS_SF = 175; +term PLUS_VDI = 176; +term PLUS_VSI = 177; +term PLUS_VHI = 178; +term PLUS_VQI = 179; +term PLUS_VDF = 180; +term PLUS_VSF = 181; +term MEM_PLUS_DI = 182; +term MEM_PLUS_SI = 183; +term MEM_PLUS_HI = 184; +term MEM_PLUS_QI = 185; +term MINUS_DI = 196; +term MINUS_SI = 197; +term MINUS_HI = 198; +term MINUS_QI = 199; +term MINUS_TI = 200; +term MINUS_OI = 201; +term MINUS_DF = 202; +term MINUS_SF = 203; +term MINUS_VDI = 204; +term MINUS_VSI = 205; +term MINUS_VHI = 206; +term MINUS_VQI = 207; +term MINUS_VDF = 208; +term MINUS_VSF = 209; +term MEM_MINUS_DI = 210; +term MEM_MINUS_SI = 211; +term MEM_MINUS_HI = 212; +term MEM_MINUS_QI = 213; +term NEG_DI = 224; +term NEG_SI = 225; +term NEG_HI = 226; +term NEG_QI = 227; +term NEG_TI = 228; +term NEG_OI = 229; +term NEG_DF = 230; +term NEG_SF = 231; +term NEG_VDI = 232; +term NEG_VSI = 233; +term NEG_VHI = 234; +term NEG_VQI = 235; +term NEG_VDF = 236; +term NEG_VSF = 237; +term MEM_NEG_DI = 238; +term MEM_NEG_SI = 239; +term MEM_NEG_HI = 240; +term MEM_NEG_QI = 241; +term MULT_DI = 252; +term MULT_SI = 253; +term MULT_HI = 254; +term MULT_QI = 255; +term MULT_TI = 256; +term MULT_OI = 257; +term MULT_DF = 258; +term MULT_SF = 259; +term MULT_VDI = 260; +term MULT_VSI = 261; +term MULT_VHI = 262; +term MULT_VQI = 263; +term MULT_VDF = 264; +term MULT_VSF = 265; +term DIV_DI = 266; +term DIV_SI = 267; +term DIV_HI = 268; +term DIV_QI = 269; +term DIV_TI = 270; +term DIV_OI = 271; +term DIV_DF = 272; +term DIV_SF = 273; +term DIV_VDI = 274; +term DIV_VSI = 275; +term DIV_VHI = 276; +term DIV_VQI = 277; +term DIV_VDF = 278; +term DIV_VSF = 279; +term UDIV_DI = 280; +term UDIV_SI = 281; +term UDIV_HI = 282; +term UDIV_QI = 283; +term UDIV_TI = 284; +term UDIV_OI = 285; +term MOD_DI = 294; +term MOD_SI = 295; +term MOD_HI = 296; +term MOD_QI = 297; +term MOD_TI = 298; +term MOD_OI = 299; +term UMOD_DI = 308; +term UMOD_SI = 309; +term UMOD_HI = 310; +term UMOD_QI = 311; +term UMOD_TI = 312; +term UMOD_OI = 313; +term SMIN_DI = 322; +term SMIN_SI = 323; +term SMIN_HI = 324; +term SMIN_QI = 325; +term SMIN_TI = 326; +term SMIN_OI = 327; +term SMAX_DI = 336; +term SMAX_SI = 337; +term SMAX_HI = 338; +term SMAX_QI = 339; +term SMAX_TI = 340; +term SMAX_OI = 341; +term UMIN_DI = 350; +term UMIN_SI = 351; +term UMIN_HI = 352; +term UMIN_QI = 353; +term UMIN_TI = 354; +term UMIN_OI = 355; +term UMAX_DI = 364; +term UMAX_SI = 365; +term UMAX_HI = 366; +term UMAX_QI = 367; +term UMAX_TI = 368; +term UMAX_OI = 369; +term CLZ_DI = 378; +term CLZ_SI = 379; +term CLZ_HI = 380; +term CLZ_QI = 381; +term CLZ_TI = 382; +term CLZ_OI = 383; +term POPCOUNT_DI = 392; +term POPCOUNT_SI = 393; +term POPCOUNT_HI = 394; +term POPCOUNT_QI = 395; +term POPCOUNT_TI = 396; +term POPCOUNT_OI = 397; +term BSF_HI = 406; +term BSF_SI = 407; +term BSF_DI = 408; +term BSR_HI = 420; +term BSR_SI = 421; +term BSR_DI = 422; +term MEMB_DI = 434; +term MEMB_SI = 435; +term MEMB_HI = 436; +term MEMB_QI = 437; +term MEMB_TI = 438; +term MEMB_OI = 439; +term MEMB_DF = 440; +term MEMB_SF = 441; +term NOT_DI = 448; +term NOT_SI = 449; +term NOT_HI = 450; +term NOT_QI = 451; +term NOT_TI = 452; +term NOT_OI = 453; +term NOT_DF = 454; +term NOT_SF = 455; +term NOT_VDI = 456; +term NOT_VSI = 457; +term NOT_VHI = 458; +term NOT_VQI = 459; +term NOT_VDF = 460; +term NOT_VSF = 461; +term MEM_NOT_DI = 462; +term MEM_NOT_SI = 463; +term MEM_NOT_HI = 464; +term MEM_NOT_QI = 465; +term AND_DI = 476; +term AND_SI = 477; +term AND_HI = 478; +term AND_QI = 479; +term AND_TI = 480; +term AND_OI = 481; +term AND_DF = 482; +term AND_SF = 483; +term AND_VDI = 484; +term AND_VSI = 485; +term AND_VHI = 486; +term AND_VQI = 487; +term AND_VDF = 488; +term AND_VSF = 489; +term MEM_AND_DI = 490; +term MEM_AND_SI = 491; +term MEM_AND_HI = 492; +term MEM_AND_QI = 493; +term IOR_DI = 504; +term IOR_SI = 505; +term IOR_HI = 506; +term IOR_QI = 507; +term IOR_TI = 508; +term IOR_OI = 509; +term IOR_DF = 510; +term IOR_SF = 511; +term IOR_VDI = 512; +term IOR_VSI = 513; +term IOR_VHI = 514; +term IOR_VQI = 515; +term IOR_VDF = 516; +term IOR_VSF = 517; +term MEM_IOR_DI = 518; +term MEM_IOR_SI = 519; +term MEM_IOR_HI = 520; +term MEM_IOR_QI = 521; +term XOR_DI = 532; +term XOR_SI = 533; +term XOR_HI = 534; +term XOR_QI = 535; +term XOR_TI = 536; +term XOR_OI = 537; +term XOR_DF = 538; +term XOR_SF = 539; +term XOR_VDI = 540; +term XOR_VSI = 541; +term XOR_VHI = 542; +term XOR_VQI = 543; +term XOR_VDF = 544; +term XOR_VSF = 545; +term MEM_XOR_DI = 546; +term MEM_XOR_SI = 547; +term MEM_XOR_HI = 548; +term MEM_XOR_QI = 549; +term ASHIFT_DI = 560; +term ASHIFT_SI = 561; +term ASHIFT_HI = 562; +term ASHIFT_QI = 563; +term ASHIFT_TI = 564; +term ASHIFT_OI = 565; +term MEM_ASHIFT_DI = 574; +term MEM_ASHIFT_SI = 575; +term MEM_ASHIFT_HI = 576; +term MEM_ASHIFT_QI = 577; +term LSHIFTRT_DI = 588; +term LSHIFTRT_SI = 589; +term LSHIFTRT_HI = 590; +term LSHIFTRT_QI = 591; +term LSHIFTRT_TI = 592; +term LSHIFTRT_OI = 593; +term MEM_LSHIFTRT_DI = 602; +term MEM_LSHIFTRT_SI = 603; +term MEM_LSHIFTRT_HI = 604; +term MEM_LSHIFTRT_QI = 605; +term ASHIFTRT_DI = 616; +term ASHIFTRT_SI = 617; +term ASHIFTRT_HI = 618; +term ASHIFTRT_QI = 619; +term ASHIFTRT_TI = 620; +term ASHIFTRT_OI = 621; +term MEM_ASHIFTRT_DI = 630; +term MEM_ASHIFTRT_SI = 631; +term MEM_ASHIFTRT_HI = 632; +term MEM_ASHIFTRT_QI = 633; +term ROTATE_DI = 644; +term ROTATE_SI = 645; +term ROTATE_HI = 646; +term ROTATE_QI = 647; +term ROTATE_TI = 648; +term ROTATE_OI = 649; +term MEM_ROTATE_DI = 658; +term MEM_ROTATE_SI = 659; +term MEM_ROTATE_HI = 660; +term MEM_ROTATE_QI = 661; +term ROTATERT_DI = 672; +term ROTATERT_SI = 673; +term ROTATERT_HI = 674; +term ROTATERT_QI = 675; +term ROTATERT_TI = 676; +term ROTATERT_OI = 677; +term MEM_ROTATERT_DI = 686; +term MEM_ROTATERT_SI = 687; +term MEM_ROTATERT_HI = 688; +term MEM_ROTATERT_QI = 689; +term FIX_DI = 700; +term FIX_SI = 701; +term FIX_HI = 702; +term FIX_QI = 703; +term FIX_TI = 704; +term FIX_OI = 705; +term TRUNCATE_DI = 714; +term TRUNCATE_SI = 715; +term TRUNCATE_HI = 716; +term TRUNCATE_QI = 717; +term TRUNCATE_TI = 718; +term TRUNCATE_OI = 719; +term ASM_BINARY_RRR_DI = 728; +term ASM_BINARY_RRR_SI = 729; +term ASM_BINARY_RRR_HI = 730; +term ASM_BINARY_RRR_QI = 731; +term ASM_BINARY_RRR_TI = 732; +term ASM_BINARY_RRR_OI = 733; +term ASM_NULLARY = 734; +term FLOAT_BASE = 742; +term FLOAT_DF = 748; +term FLOAT_SF = 749; +term FLOAT_TRUNCATE_BASE = 756; +term FLOAT_TRUNCATE_DF = 762; +term FLOAT_TRUNCATE_SF = 763; +term FLOAT_EXTEND_BASE = 770; +term FLOAT_EXTEND_DF = 776; +term FLOAT_EXTEND_SF = 777; +term UPDATE_DI = 784; +term UPDATE_SI = 785; +term UPDATE_HI = 786; +term UPDATE_QI = 787; +term FEQ_BASE = 798; +term FEQ_DF = 804; +term FEQ_SF = 805; +term FLT_BASE = 812; +term FLT_DF = 818; +term FLT_SF = 819; +term FLE_BASE = 826; +term FLE_DF = 832; +term FLE_SF = 833; +term FUNORD_BASE = 840; +term FUNORD_DF = 846; +term FUNORD_SF = 847; +term FNEQ_BASE = 854; +term FNEQ_DF = 860; +term FNEQ_SF = 861; +term FNLT_BASE = 868; +term FNLT_DF = 874; +term FNLT_SF = 875; +term FNLE_BASE = 882; +term FNLE_DF = 888; +term FNLE_SF = 889; +term FORD_BASE = 896; +term FORD_DF = 902; +term FORD_SF = 903; +term FGE_BASE = 910; +term FGE_DF = 916; +term FGE_SF = 917; +term FGT_BASE = 924; +term FGT_DF = 930; +term FGT_SF = 931; +term SYMBOL_REF_DI = 938; +term SYMBOL_REF_32 = 939; +term SYMBOL_REF_64 = 940; +term LABEL_REF_DI = 941; +term LT_ALL = 942; +term LE_ALL = 943; +term EQ_ALL = 944; +term NE_ALL = 945; +term GE_ALL = 946; +term GT_ALL = 947; +term LTS_ALL = 948; +term LTU_ALL = 949; +term LEU_ALL = 950; +term GEU_ALL = 951; +term GTU_ALL = 952; +term UNEQ_ALL = 953; +term UNGE_ALL = 954; +term UNGT_ALL = 955; +term UNLE_ALL = 956; +term UNLT_ALL = 957; +term LTGT_ALL = 958; +term UNORDERED_ALL = 959; +term ORDERED_ALL = 960; +term PC_ALL = 966; +term COMPARE_CC = 967; +term COND_MOVE = 968; +term COND_MOVE_XX = 969; +term PAIR_ALL = 970; +term CONST_DI = 971; +term PARALLEL_ALL = 972; +term SET_ALL = 973; +term USE_ALL = 974; +term END_OF_LIST = 975; +term CALL_ALL = 976; +term LIST_ALL = 977; +term DEF_ALL = 978; +term CONST_0 = 979; +term CONST_P1 = 980; +term CONST_P2 = 981; +term CONST_P3 = 982; +term CONST_P4 = 983; +term CONST_P8 = 984; +term CONST_P15 = 985; +term CONST_P16 = 986; +term CONST_P24 = 987; +term CONST_P31 = 988; +term CONST_P32 = 989; +term CONST_P48 = 990; +term CONST_P56 = 991; +term CONST_P63 = 992; +term CONST_P255 = 993; +term CONST_N1 = 994; +term CONST4P = 995; +term CONST5P = 996; +term CONST6P = 997; +term CONST7P = 998; +term CONST8P = 999; +term CONST12P = 1000; +term CONST13P = 1001; +term CONST14P = 1002; +term CONST15P = 1003; +term CONST16P = 1004; +term CONST28P = 1005; +term CONST29P = 1006; +term CONST30P = 1007; +term CONST31P = 1008; +term CONST32P = 1009; +term CONST64P = 1010; +term CONST4N = 1011; +term CONST5N = 1012; +term CONST6N = 1013; +term CONST7N = 1014; +term CONST8N = 1015; +term CONST12N = 1016; +term CONST13N = 1017; +term CONST14N = 1018; +term CONST15N = 1019; +term CONST16N = 1020; +term CONST28N = 1021; +term CONST29N = 1022; +term CONST30N = 1023; +term CONST31N = 1024; +term CONST32N = 1025; +term CONST64N = 1026; +term CONSTIEEE32 = 1027; +term CONSTIEEE64 = 1028; +term ICG_UNSPEC_GOT = 1029; +term ICG_UNSPEC_GOTOFF = 1030; +term ICG_UNSPEC_GOTPCREL = 1031; +term ICG_UNSPEC_GOTTPOFF = 1032; +term ICG_UNSPEC_TPOFF = 1033; +term ICG_UNSPEC_NTPOFF = 1034; +term ICG_UNSPEC_DTPOFF = 1035; +term ICG_UNSPEC_GOTNTPOFF = 1036; +term ICG_UNSPEC_INDNTPOFF = 1037; +term ICG_UNSPEC_PLTOFF = 1038; +term ICG_UNSPEC_MACHOPIC_OFFSET = 1039; +term ICG_UNSPEC_STACK_ALLOC = 1040; +term ICG_UNSPEC_SET_GOT = 1041; +term ICG_UNSPEC_SSE_PROLOGUE_SAVE = 1042; +term ICG_UNSPEC_REG_SAVE = 1043; +term ICG_UNSPEC_DEF_CFA = 1044; +term ICG_UNSPEC_SET_RIP = 1045; +term ICG_UNSPEC_SET_GOT_OFFSET = 1046; +term ICG_UNSPEC_TP = 1047; +term ICG_UNSPEC_TLS_GD = 1048; +term ICG_UNSPEC_TLS_LD_BASE = 1049; +term ICG_UNSPEC_TLSDESC = 1050; +term ICG_UNSPEC_SCAS = 1051; +term ICG_UNSPEC_FNSTSW = 1052; +term ICG_UNSPEC_SAHF = 1053; +term ICG_UNSPEC_FSTCW = 1054; +term ICG_UNSPEC_ADD_CARRY_DI = 1064; +term ICG_UNSPEC_ADD_CARRY_SI = 1065; +term ICG_UNSPEC_ADD_CARRY_HI = 1066; +term ICG_UNSPEC_ADD_CARRY_QI = 1067; +term ICG_UNSPEC_ADD_CARRY_TI = 1068; +term ICG_UNSPEC_ADD_CARRY_OI = 1069; +term ICG_UNSPEC_ADD_CARRY_DF = 1070; +term ICG_UNSPEC_ADD_CARRY_SF = 1071; +term ICG_UNSPEC_ADD_CARRY_VDI = 1072; +term ICG_UNSPEC_ADD_CARRY_VSI = 1073; +term ICG_UNSPEC_ADD_CARRY_VHI = 1074; +term ICG_UNSPEC_ADD_CARRY_VQI = 1075; +term ICG_UNSPEC_ADD_CARRY_VDF = 1076; +term ICG_UNSPEC_ADD_CARRY_VSF = 1077; +term ICG_UNSPEC_FLDCW = 1078; +term ICG_UNSPEC_REP = 1079; +term ICG_UNSPEC_EH_RETURN = 1080; +term ICG_UNSPEC_LD_MPIC = 1081; +term ICG_UNSPEC_TRUNC_NOOP = 1082; +term ICG_UNSPEC_FIX_NOTRUNC = 1083; +term ICG_UNSPEC_PFRCPIT1 = 1084; +term ICG_UNSPEC_MASKMOV = 1085; +term ICG_UNSPEC_PFRCPIT2 = 1086; +term ICG_UNSPEC_MOVMSK = 1087; +term ICG_UNSPEC_PFRSQRT = 1088; +term ICG_UNSPEC_MOVNT = 1089; +term ICG_UNSPEC_PFRSQIT1 = 1090; +term ICG_UNSPEC_MFENCE = 1091; +term ICG_UNSPEC_MOVU = 1092; +term ICG_UNSPEC_LFENCE = 1093; +term ICG_UNSPEC_RCP = 1094; +term ICG_UNSPEC_PSADBW = 1095; +term ICG_UNSPEC_RSQRT = 1096; +term ICG_UNSPEC_LDDQU = 1097; +term ICG_UNSPEC_SFENCE = 1098; +term ICG_UNSPEC_PFRCP = 1099; +term ICG_UNSPEC_COPYSIGN = 1100; +term ICG_UNSPEC_IEEE_MIN_DI = 1106; +term ICG_UNSPEC_IEEE_MIN_SI = 1107; +term ICG_UNSPEC_IEEE_MIN_HI = 1108; +term ICG_UNSPEC_IEEE_MIN_QI = 1109; +term ICG_UNSPEC_IEEE_MIN_TI = 1110; +term ICG_UNSPEC_IEEE_MIN_OI = 1111; +term ICG_UNSPEC_IEEE_MIN_DF = 1112; +term ICG_UNSPEC_IEEE_MIN_SF = 1113; +term ICG_UNSPEC_IEEE_MIN_VDI = 1114; +term ICG_UNSPEC_IEEE_MIN_VSI = 1115; +term ICG_UNSPEC_IEEE_MIN_VHI = 1116; +term ICG_UNSPEC_IEEE_MIN_VQI = 1117; +term ICG_UNSPEC_IEEE_MIN_VDF = 1118; +term ICG_UNSPEC_IEEE_MIN_VSF = 1119; +term ICG_UNSPEC_IEEE_MAX_DI = 1120; +term ICG_UNSPEC_IEEE_MAX_SI = 1121; +term ICG_UNSPEC_IEEE_MAX_HI = 1122; +term ICG_UNSPEC_IEEE_MAX_QI = 1123; +term ICG_UNSPEC_IEEE_MAX_TI = 1124; +term ICG_UNSPEC_IEEE_MAX_OI = 1125; +term ICG_UNSPEC_IEEE_MAX_DF = 1126; +term ICG_UNSPEC_IEEE_MAX_SF = 1127; +term ICG_UNSPEC_IEEE_MAX_VDI = 1128; +term ICG_UNSPEC_IEEE_MAX_VSI = 1129; +term ICG_UNSPEC_IEEE_MAX_VHI = 1130; +term ICG_UNSPEC_IEEE_MAX_VQI = 1131; +term ICG_UNSPEC_IEEE_MAX_VDF = 1132; +term ICG_UNSPEC_IEEE_MAX_VSF = 1133; +term ICG_UNSPEC_SIN = 1134; +term ICG_UNSPEC_COS = 1135; +term ICG_UNSPEC_FPATAN = 1136; +term ICG_UNSPEC_FYL2X = 1137; +term ICG_UNSPEC_FYL2XP1 = 1138; +term ICG_UNSPEC_FRNDINT = 1139; +term ICG_UNSPEC_FIST = 1140; +term ICG_UNSPEC_F2XM1 = 1141; +term ICG_UNSPEC_TAN = 1142; +term ICG_UNSPEC_FXAM = 1143; +term ICG_UNSPEC_FRNDINT_FLOOR = 1144; +term ICG_UNSPEC_FRNDINT_CEIL = 1145; +term ICG_UNSPEC_FRNDINT_TRUNC = 1146; +term ICG_UNSPEC_FRNDINT_MASK_PM = 1147; +term ICG_UNSPEC_FIST_FLOOR = 1148; +term ICG_UNSPEC_FIST_CEIL = 1149; +term ICG_UNSPEC_SINCOS_COS = 1150; +term ICG_UNSPEC_SINCOS_SIN = 1151; +term ICG_UNSPEC_XTRACT_FRACT = 1152; +term ICG_UNSPEC_XTRACT_EXP = 1153; +term ICG_UNSPEC_FSCALE_FRACT = 1154; +term ICG_UNSPEC_FSCALE_EXP = 1155; +term ICG_UNSPEC_FPREM_F = 1156; +term ICG_UNSPEC_FPREM_U = 1157; +term ICG_UNSPEC_FPREM1_F = 1158; +term ICG_UNSPEC_FPREM1_U = 1159; +term ICG_UNSPEC_C2_FLAG = 1160; +term ICG_UNSPEC_SP_SET = 1161; +term ICG_UNSPEC_SP_TEST = 1162; +term ICG_UNSPEC_SP_TLS_SET = 1163; +term ICG_UNSPEC_SP_TLS_TEST = 1164; +term ICG_UNSPEC_PSHUFB = 1165; +term ICG_UNSPEC_PSIGN = 1166; +term ICG_UNSPEC_PALIGNR = 1167; +term ICG_UNSPEC_EXTRQI = 1168; +term ICG_UNSPEC_EXTRQ = 1169; +term ICG_UNSPEC_INSERTQI = 1170; +term ICG_UNSPEC_INSERTQ = 1171; +term ICG_UNSPEC_BLENDV = 1172; +term ICG_UNSPEC_INSERTPS = 1173; +term ICG_UNSPEC_DP = 1174; +term ICG_UNSPEC_MOVNTDQA = 1175; +term ICG_UNSPEC_MPSADBW = 1176; +term ICG_UNSPEC_PHMINPOSUW = 1177; +term ICG_UNSPEC_PTEST = 1178; +term ICG_UNSPEC_ROUND = 1179; +term ICG_UNSPEC_CRC32 = 1180; +term ICG_UNSPEC_PCMPESTR = 1181; +term ICG_UNSPEC_PCMPISTR = 1182; +term ICG_UNSPEC_SSE5_INTRINSIC = 1183; +term ICG_UNSPEC_SSE5_UNSIGNED_CMP = 1184; +term ICG_UNSPEC_SSE5_TRUEFALSE = 1185; +term ICG_UNSPEC_SSE5_PERMUTE = 1186; +term ICG_UNSPEC_FRCZ = 1187; +term ICG_UNSPEC_CVTPH2PS = 1188; +term ICG_UNSPEC_CVTPS2PH = 1189; +term ICG_UNSPEC_AESENC = 1190; +term ICG_UNSPEC_AESENCLAST = 1191; +term ICG_UNSPEC_AESDEC = 1192; +term ICG_UNSPEC_AESDECLAST = 1193; +term ICG_UNSPEC_AESIMC = 1194; +term ICG_UNSPEC_AESKEYGENASSIST = 1195; +term ICG_UNSPEC_PCLMUL = 1196; +term ICG_UNSPEC_PCMP = 1197; +term ICG_UNSPEC_VPERMIL = 1198; +term ICG_UNSPEC_VPERMIL2 = 1199; +term ICG_UNSPEC_VPERMIL2F128 = 1200; +term ICG_UNSPEC_MASKLOAD = 1201; +term ICG_UNSPEC_MASKSTORE = 1202; +term ICG_UNSPEC_CAST = 1203; +term ICG_UNSPEC_VTESTP = 1204; +nonterm stmt; +nonterm nocc; +nonterm lhs64; +nonterm lhs32; +nonterm lhs16; +nonterm lhs8; +nonterm lhsd; +nonterm lhsf; +nonterm rd; +nonterm rdx; +nonterm rf; +nonterm rfx; +nonterm r64; +nonterm r64x; +nonterm r32; +nonterm r32x; +nonterm rz32; +nonterm rz32x; +nonterm r16; +nonterm r16x; +nonterm rz16; +nonterm rz16x; +nonterm rs16; +nonterm rs16x; +nonterm r8; +nonterm r8x; +nonterm rz8; +nonterm rz8x; +nonterm rs8; +nonterm rs8x; +nonterm ccr64x; +nonterm ccr32x; +nonterm ccrz32x; +nonterm ccr16x; +nonterm ccrz16x; +nonterm ccrs16x; +nonterm ccr8x; +nonterm ccrz8x; +nonterm ccrs8x; +nonterm rcc; +nonterm urcc; +nonterm condition; +nonterm disp; +nonterm addr; +nonterm base64; +nonterm base32; +nonterm base16; +nonterm base8; +nonterm index64; +nonterm index32; +nonterm index16; +nonterm index8; +nonterm scon; +nonterm mcon; +nonterm imm4; +nonterm imm5; +nonterm imm6; +nonterm imm7; +nonterm imm8; +nonterm imm12; +nonterm imm13; +nonterm imm14; +nonterm imm15; +nonterm imm16; +nonterm imm28; +nonterm imm29; +nonterm imm30; +nonterm imm31; +nonterm imm32; +nonterm imm64; +nonterm pos8; +nonterm pos16; +nonterm pos32; +nonterm pureimm32; +nonterm label; +nonterm compare; +nonterm use; +nonterm def; +nonterm use_list; +nonterm def_list; +nonterm symbol; +nonterm symbol32; +nonterm symbol64; +reduce names = "icg-names.cases"; +reduce kinds = "icg-kinds.cases"; +reduce supairs = "icg-supairs.cases"; +reduce build = "icg-build.cases"; +reduce coalesce = "icg-coalesce.cases"; +reduce remat = "icg-remat.cases"; +reduce costs = "icg-costs.cases"; +reduce spill = "icg-spill.cases"; +reduce debug = "icg-debug.cases"; +reduce final = "icg-final.cases"; +reduce targeting = "icg-targeting.cases"; +reduce emit = "icg-emit.cases"; +start stmt; diff --git a/iburg/briggs/icg-grammars/x86-64.int.py b/iburg/briggs/icg-grammars/x86-64.int.py new file mode 100644 index 00000000000..9710178704d --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.int.py @@ -0,0 +1,4093 @@ +# {([ +# -*- mode: python -*- +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +import plug + +# global_print_plug_decls = 0; execfile("x86-64.gr.py") + + +#------------------------------------------------------------- +# lhs rules + +plug.plugrule3("intlhsreg", [ + ["rule", "cost"], + + ["lhs64.dst : REGX_DI", [0, 0]], + ["lhs32.dst : REGX_SI", [0, 0]], + ["lhs16.dst : REGX_HI", [0, 0]], + ["lhs8.dst : REGX_QI", [0, 0]], + ["lhs64.dst : REG_DI", [0, 0]], + ["lhs32.dst : REG_SI", [0, 0]], + ["lhs16.dst : REG_HI", [0, 0]], + ["lhs8.dst : REG_QI", [0, 0]], + +], """ + $rule $cost + names { + $dst->spilled = false; + }, + kinds { + icg_reg_vector[$dst->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($dst->r); + }, + spill { + dirty |= make_spill_code(find($dst->r), $dst); + }, + final { + $dst->r = icg_reg_vector[find($dst->r)].color; + }; +""") + + + +plug.plugrule3("intlhsstore", [ + ["rule", "cost", "rtx_mode"], + + ["lhs64.lhs : MEM_DI(addr.dst)", [3, 0], "DImode"], + ["lhs32.lhs : MEM_SI(addr.dst)", [3, 0], "SImode"], + ["lhs16.lhs : MEM_HI(addr.dst)", [3, 0], "HImode"], + ["lhs8.lhs : MEM_QI(addr.dst)", [3, 0], "QImode"], + + # + # Added 10Nov2008 + # in some cases we'll see IL where floating point values + # are held in 64-bit GPRs. + # This happens with the translation of CONST_DOUBLE, + # where the 64-bit constant is materialized into a GPR + # with a movabsq (say) and then treated as a double. + # It isn't clear why/when the front end will give + # us trees holding CONST_DOUBLE, which we turn into CONST_64P. + # + ["lhs64.lhs : MEM_DF(addr.dst)", [0, 0], "DImode"], + ["lhs32.lhs : MEM_SF(addr.dst)", [0, 0], "SImode"], + +], """ + $rule $cost + names { + $lhs->spilled = true; + $lhs->a.base = $dst->a.base; + $lhs->a.base_valid = $dst->a.base_valid; + $lhs->a.index = $dst->a.index; + $lhs->a.scale = $dst->a.scale; + $lhs->a.disp = $dst->a.disp; + $lhs->a.string = $dst->a.string; + }, + remat { + flags = 0; + }, + emit { + $lhs->rtl = $dst->rtl; + }; +""") + + +# +# integer assignment +# +plug.plugrule3 ("intassignment", [ + ["rule", "cost", "mopcode", "mmode", "mchar", "ropcode", "rmode", "rchar"], + + ["stmt : SET_ALL(lhs64.dst, r64.src)", [0, 0], "movq", "DImode", 'q', "movq", "DImode", 'q'], + ["stmt : SET_ALL(lhs32.dst, r32.src)", [0, 0], "movl", "SImode", 'l', "movl", "SImode", 'l'], + ["stmt : SET_ALL(lhs16.dst, r16.src)", [0, 0], "movw", "HImode", 'w', "movl", "SImode", 'l'], + ["stmt : SET_ALL(lhs8.dst, r8.src)", [0, 0], "movb", "QImode", 'b', "movl", "SImode", 'l'], + + # paradoxical subregs in the lval context, easy + ["stmt : SET_ALL(SUBREG_DI(lhs32.dst, CONST_0), r64.src)", [0, 0], "movl", "SImode", 'l', "movl", "SImode", 'l'], + ["stmt : SET_ALL(SUBREG_DI(lhs16.dst, CONST_0), r64.src)", [0, 0], "movw", "HImode", 'w', "movl", "SImode", 'l'], + ["stmt : SET_ALL(SUBREG_DI(lhs8.dst, CONST_0), r64.src)", [0, 0], "movb", "QImode", 'b', "movl", "SImode", 'l'], + ["stmt : SET_ALL(SUBREG_SI(lhs16.dst, CONST_0), r32.src)", [0, 0], "movw", "HImode", 'w', "movl", "SImode", 'l'], + ["stmt : SET_ALL(SUBREG_SI(lhs8.dst, CONST_0), r32.src)", [0, 0], "movb", "QImode", 'b', "movl", "SImode", 'l'], + ["stmt : SET_ALL(SUBREG_HI(lhs8.dst, CONST_0), r16.src)", [0, 0], "movb", "QImode", 'b', "movl", "SImode", 'l'], + +], """ + $rule $cost + supairs { + suOrder2($stmt, $dst, $src, kid, kids); + }, + coalesce { + if (!$dst->spilled) + coalesces += attempt_coalesce(pass, $dst->r, $src->r); + }, + build { + if ($dst->spilled) { + sparseset_set_bit(live, find($src->r)); + add_addr(live, $dst); + } + else + add_copy_edges($dst->r, $src->r, live); + }, + costs { + if (!$dst->spilled) + cost_copy($src->r, $dst->r); + }, + debug { + if ($dst->spilled) + dumpRM("$mopcode", $src->r, '$mchar', $dst); + else + dump_copy("$ropcode", $src->r, $dst->r, '$rchar'); + }, + emit { + if ($dst->spilled) { + rtx src = gen_rtx_REG($mmode, $src->r); + rtx dst = gen_rtx_MEM($mmode, $dst->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG($rmode, $src->r); + rtx dst = gen_rtx_REG($rmode, $dst->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +""") + + +plug.plugrule3("immstore", [ + ["rule", "cost", "opcode", "rtx_mode"], + + ["stmt : SET_ALL(MEM_DI(addr), imm32.const)", [3, 2], "movq", "DImode"], + ["stmt : SET_ALL(MEM_SI(addr), imm32.const)", [3, 1], "movl", "SImode"], + ["stmt : SET_ALL(MEM_HI(addr), imm16.const)", [3, 2], "movw", "HImode"], + ["stmt : SET_ALL(MEM_QI(addr), imm8.const)", [3, 1], "movb", "QImode"], + +], """ + $rule $cost + build { + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpIM("$opcode", $const, $addr); + }, + emit { + rtx src = gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl); + rtx dst = gen_rtx_MEM($rtx_mode, $addr->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + + +#------------------------------------------------------------- +# reg-reg chain rules + +plug.plugrule3("regdst", [ + ["rule", "cost"], + + ["r64.dst : REG_DI", [0, 0]], + ["r32.dst : REG_SI", [0, 0]], + ["r16.dst : REG_HI", [0, 0]], + ["r8.dst : REG_QI", [0, 0]], + +], """ + $rule $cost + kinds { + icg_reg_vector[$dst->r].kind = INT_REGISTER; + }, + costs { + cost_load($dst->r); + }, + spill { + dirty |= make_spill_code(find($dst->r), $dst); + }, + final { + $dst->r = icg_reg_vector[find($dst->r)].color; + }; +""") + +# +# This block differs from the rule above in that it has an supairs field. +# +plug.plugrule3("regsrc", [ + ["rule", "cost"], + + ["r64x.dst : REGX_DI", [0, 0]], + ["r32x.dst : REGX_SI", [0, 0]], + ["r16x.dst : REGX_HI", [0, 0]], + ["r8x.dst : REGX_QI", [0, 0]], + +], """ + $rule $cost + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + costs { + cost_load($dst->rx); + }, + supairs { + $dst->extra = 0; + $dst->freed = 0; + }, + spill { + dirty |= make_spill_code(find($dst->rx), $dst); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }; +""") + +#------------------------------------------------------------- +# register-register chain rules + +# this set of rules acts to rename, throwing away a bit of +# the information carried in the name of the non-terminal + +plug.plugrule3 ("regchaindiscard", [ + ["rule", "cost"], + +# here we throw away the fact that the RHS is zero or sign extended + + ["r32.dst : rz32.src", [0, 0]], + ["r16.dst : rz16.src", [0, 0]], + ["r16.dst : rs16.src", [0, 0]], + ["r8.dst : rz8.src", [0, 0]], + ["r8.dst : rs8.src", [0, 0]], + + ["r32x.dst : rz32x.src", [0, 0]], + ["r16x.dst : rz16x.src", [0, 0]], + ["r16x.dst : rs16x.src", [0, 0]], + ["r8x.dst : rz8x.src", [0, 0]], + ["r8x.dst : rs8x.src", [0, 0]], + + ["ccr32x.dst : ccrz32x.src", [0, 0]], + ["ccr16x.dst : ccrz16x.src", [0, 0]], + ["ccr16x.dst : ccrs16x.src", [0, 0]], + ["ccr8x.dst : ccrz8x.src", [0, 0]], + ["ccr8x.dst : ccrs8x.src", [0, 0]], + +# here we throw away the fact that the condition code is set + + ["r64x.dst : ccr64x.src", [0, 0]], + ["r32x.dst : ccr32x.src", [0, 0]], + ["rz32x.dst : ccrz32x.src", [0, 0]], + ["r16x.dst : ccr16x.src", [0, 0]], + ["rz16x.dst : ccrz16x.src", [0, 0]], + ["rs16x.dst : ccrs16x.src", [0, 0]], + ["r8x.dst : ccr8x.src", [0, 0]], + ["rz8x.dst : ccrz8x.src", [0, 0]], + ["rs8x.dst : ccrs8x.src", [0, 0]], + +], """ + $rule $cost + ; +""") + +# +# Throw away the upper part of a register. +# Contrast TRUNCATE with SUBREG. It isn't clear why TRUNCATE is used +# in one context and SUBREG in another. +# + +plug.plugrule3 ("regtruncate0", [ + ["rule", "cost"], + + ["r32.dst: TRUNCATE_SI(r64.src)", [0, 0]], + ["r16.dst: TRUNCATE_HI(r64.src)", [0, 0]], + ["r8.dst: TRUNCATE_QI(r64.src)", [0, 0]], + ["r16.dst: TRUNCATE_HI(r32.src)", [0, 0]], + ["r8.dst: TRUNCATE_QI(r32.src)", [0, 0]], + ["r8.dst: TRUNCATE_QI(r16.src)", [0, 0]], + + # normal subregs in rval context + ["r32.dst : SUBREG_SI(r64.src, CONST_0)", [0, 0]], + ["r16.dst : SUBREG_HI(r64.src, CONST_0)", [0, 0]], + ["r8.dst : SUBREG_QI(r64.src, CONST_0)", [0, 0]], + ["r16.dst : SUBREG_HI(r32.src, CONST_0)", [0, 0]], + ["r8.dst : SUBREG_QI(r32.src, CONST_0)", [0, 0]], + ["r8.dst : SUBREG_QI(r16.src, CONST_0)", [0, 0]], + + # paradoxical subregs in rval context + ["r64.dst : SUBREG_DI(r32.src, CONST_0)", [0, 0]], + ["r64.dst : SUBREG_DI(r16.src, CONST_0)", [0, 0]], + ["r64.dst : SUBREG_DI(r8.src, CONST_0)", [0, 0]], + ["r32.dst : SUBREG_SI(r16.src, CONST_0)", [0, 0]], + ["r32.dst : SUBREG_SI(r8.src, CONST_0)", [0, 0]], + ["r16.dst : SUBREG_HI(r8.src, CONST_0)", [0, 0]], + +], """ + $rule $cost + names { + $dst->r = $src->r; + }, + final { + $dst->r = $src->r; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }; +""") + +plug.plugrule3 ("regtruncate1", [ + ["rule", "cost"], + ["r32x.dst: TRUNCATE_SI(r64x.src)", [0, 0]], + ["r16x.dst: TRUNCATE_HI(r64x.src)", [0, 0]], + ["r8x.dst: TRUNCATE_QI(r64x.src)", [0, 0]], + ["r16x.dst: TRUNCATE_HI(r32x.src)", [0, 0]], + ["r8x.dst: TRUNCATE_QI(r32x.src)", [0, 0]], + ["r8x.dst: TRUNCATE_QI(r16x.src)", [0, 0]], + + ["r32x.dst : SUBREG_SI(r64x.src, CONST_0)", [0, 0]], + ["r16x.dst : SUBREG_HI(r64x.src, CONST_0)", [0, 0]], + ["r8x.dst : SUBREG_QI(r64x.src, CONST_0)", [0, 0]], + ["r16x.dst : SUBREG_HI(r32x.src, CONST_0)", [0, 0]], + ["r8x.dst : SUBREG_QI(r32x.src, CONST_0)", [0, 0]], + ["r8x.dst : SUBREG_QI(r16x.src, CONST_0)", [0, 0]], + + ["r64x.dst : SUBREG_DI(r32x.src, CONST_0)", [0, 0]], + ["r64x.dst : SUBREG_DI(r16x.src, CONST_0)", [0, 0]], + ["r64x.dst : SUBREG_DI(r8x.src, CONST_0)", [0, 0]], + ["r32x.dst : SUBREG_SI(r16x.src, CONST_0)", [0, 0]], + ["r32x.dst : SUBREG_SI(r8x.src, CONST_0)", [0, 0]], + ["r16x.dst : SUBREG_HI(r8x.src, CONST_0)", [0, 0]], + +], """ + $rule $cost + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }; +""") + + +# this set of rules lets us use an RX as if it were an R. + +plug.plugrule3 ("regchainxsrc", [ + ["rule", "cost"], + + ["r64.dst : r64x.src", [0, 0]], + ["r32.dst : r32x.src", [0, 0]], + ["rz32.dst : rz32x.src", [0, 0]], + ["r16.dst : r16x.src", [0, 0]], + ["rz16.dst : rz16x.src", [0, 0]], + ["rs16.dst : rs16x.src", [0, 0]], + ["r8.dst : r8x.src", [0, 0]], + ["rz8.dst : rz8x.src", [0, 0]], + ["rs8.dst : rs8x.src", [0, 0]], + +], """ + $rule $cost + supairs { + $dst->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $dst->r = $src->rx; + }, + final { + $dst->r = $src->rx; + }; +""") + + +# assume coalesce will fail (but try anyway) +plug.plugrule3("regchainxdst", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["r64x.dst : r64.src", [1, 3], "movq", 'q', "DImode"], + ["rz32x.dst : r32.src", [1, 2], "movl", 'l', "SImode"], + ["r16x.dst : r16.src", [1, 2], "movl", 'l', "SImode"], + ["rz16x.dst : rz16.src", [1, 2], "movl", 'l', "SImode"], + ["rs16x.dst : rs16.src", [1, 2], "movl", 'l', "SImode"], + ["r8x.dst : r8.src", [1, 2], "movl", 'l', "SImode"], + ["rz8x.dst : rz8.src", [1, 2], "movl", 'l', "SImode"], + ["rs8x.dst : rs8.src", [1, 2], "movl", 'l', "SImode"], + +], """ + $rule $cost + supairs { + if ($dst->freed > 0) + $dst->freed--; + else + $dst->extra++; + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $dst->rx, $src->r); + }, + build { + add_copy_edges($dst->rx, $src->r, live); + }, + costs { + cost_copy($dst->rx, $src->r); + }, + debug { + dump_copy("$opcode", $src->r, $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = gen_rtx_REG($rtx_mode, $src->r); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + + +# these are various NOPs that might be introduced when messing with spill code +plug.plugrule3("regchainnoprr", [ + ["rule", "cost"], + + ["r64.dst : PLUS_DI(r64.src | CONST_0)", [0, 0]], + ["r32.dst : PLUS_SI(r32.src | CONST_0)", [0, 0]], + ["r16.dst : PLUS_HI(r16.src | CONST_0)", [0, 0]], + ["r8.dst : PLUS_QI(r8.src | CONST_0)", [0, 0]], + ["rz32.dst : PLUS_SI(rz32.src | CONST_0)", [0, 0]], + ["rz16.dst : PLUS_HI(rz16.src | CONST_0)", [0, 0]], + ["rz8.dst : PLUS_QI(rz8.src | CONST_0)", [0, 0]], + ["rs16.dst : PLUS_HI(rs16.src | CONST_0)", [0, 0]], + ["rs8.dst : PLUS_QI(rs8.src | CONST_0)", [0, 0]], + + ["r64.dst : MINUS_DI(r64.src | CONST_0)", [0, 0]], + ["r32.dst : MINUS_SI(r32.src | CONST_0)", [0, 0]], + ["r16.dst : MINUS_HI(r16.src | CONST_0)", [0, 0]], + ["r8.dst : MINUS_QI(r8.src | CONST_0)", [0, 0]], + ["rz32.dst : MINUS_SI(rz32.src | CONST_0)", [0, 0]], + ["rz16.dst : MINUS_HI(rz16.src | CONST_0)", [0, 0]], + ["rz8.dst : MINUS_QI(rz8.src | CONST_0)", [0, 0]], + ["rs16.dst : MINUS_HI(rs16.src | CONST_0)", [0, 0]], + ["rs8.dst : MINUS_QI(rs8.src | CONST_0)", [0, 0]], + +], """ + $rule $cost + names { + $dst->r = $src->r; + }, + final { + $dst->r = $src->r; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }; +""") + + + + +plug.plugrule3("regchainnoprxrx", [ + ["rule", "cost"], + + ["r64x.dst : PLUS_DI(r64x.src | CONST_0)", [0, 0]], + ["r32x.dst : PLUS_SI(r32x.src | CONST_0)", [0, 0]], + ["r16x.dst : PLUS_HI(r16x.src | CONST_0)", [0, 0]], + ["r8x.dst : PLUS_QI(r8x.src | CONST_0)", [0, 0]], + ["rz32x.dst : PLUS_SI(rz32x.src | CONST_0)", [0, 0]], + ["rz16x.dst : PLUS_HI(rz16x.src | CONST_0)", [0, 0]], + ["rz8x.dst : PLUS_QI(rz8x.src | CONST_0)", [0, 0]], + ["rs16x.dst : PLUS_HI(rs16x.src | CONST_0)", [0, 0]], + ["rs8x.dst : PLUS_QI(rs8x.src | CONST_0)", [0, 0]], + + ["ccr64x.dst : PLUS_DI(ccr64x.src | CONST_0)", [0, 0]], + ["ccr32x.dst : PLUS_SI(ccr32x.src | CONST_0)", [0, 0]], + ["ccr16x.dst : PLUS_HI(ccr16x.src | CONST_0)", [0, 0]], + ["ccr8x.dst : PLUS_QI(ccr8x.src | CONST_0)", [0, 0]], + ["ccrz32x.dst : PLUS_SI(ccrz32x.src | CONST_0)", [0, 0]], + ["ccrz16x.dst : PLUS_HI(ccrz16x.src | CONST_0)", [0, 0]], + ["ccrz8x.dst : PLUS_QI(ccrz8x.src | CONST_0)", [0, 0]], + ["ccrs16x.dst : PLUS_HI(ccrs16x.src | CONST_0)", [0, 0]], + ["ccrs8x.dst : PLUS_QI(ccrs8x.src | CONST_0)", [0, 0]], + + ["r64x.dst : MINUS_DI(r64x.src | CONST_0)", [0, 0]], + ["r32x.dst : MINUS_SI(r32x.src | CONST_0)", [0, 0]], + ["r16x.dst : MINUS_HI(r16x.src | CONST_0)", [0, 0]], + ["r8x.dst : MINUS_QI(r8x.src | CONST_0)", [0, 0]], + ["rz32x.dst : MINUS_SI(rz32x.src | CONST_0)", [0, 0]], + ["rz16x.dst : MINUS_HI(rz16x.src | CONST_0)", [0, 0]], + ["rz8x.dst : MINUS_QI(rz8x.src | CONST_0)", [0, 0]], + ["rs16x.dst : MINUS_HI(rs16x.src | CONST_0)", [0, 0]], + ["rs8x.dst : MINUS_QI(rs8x.src | CONST_0)", [0, 0]], + + ["ccr64x.dst : MINUS_DI(ccr64x.src | CONST_0)", [0, 0]], + ["ccr32x.dst : MINUS_SI(ccr32x.src | CONST_0)", [0, 0]], + ["ccr16x.dst : MINUS_HI(ccr16x.src | CONST_0)", [0, 0]], + ["ccr8x.dst : MINUS_QI(ccr8x.src | CONST_0)", [0, 0]], + ["ccrz32x.dst : MINUS_SI(ccrz32x.src | CONST_0)", [0, 0]], + ["ccrz16x.dst : MINUS_HI(ccrz16x.src | CONST_0)", [0, 0]], + ["ccrz8x.dst : MINUS_QI(ccrz8x.src | CONST_0)", [0, 0]], + ["ccrs16x.dst : MINUS_HI(ccrs16x.src | CONST_0)", [0, 0]], + ["ccrs8x.dst : MINUS_QI(ccrs8x.src | CONST_0)", [0, 0]], + +], """ + $rule $cost + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }; +""") + + + +#----------------------------------------------------------- +# loading constants + +# use XOR to zero register. +# Note that upper-half of word is automatically +# cleared with a 32-bit operation, saving a byte. +plug.plugrule3("zeroload", [ + ["rule", "cost", "opcode", "rtx_mode", "reg_kind", 'schar'], + + ["ccr64x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + ["ccrz32x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + ["ccrz16x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + ["ccrs16x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + ["ccrz8x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + ["ccrs8x.dst : CONST_0", [1, 2], "xorl", "SImode", "INT_REGISTER", 'l'], + [ "rdx.dst : CONST_0", [2, 4], "xorpd", "DFmode", "FLOAT_REGISTER", 'x'], + [ "rfx.dst : CONST_0", [2, 4], "xorps", "SFmode", "FLOAT_REGISTER", 'x'], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = $reg_kind; + }, + supairs { + $dst->extra = 1; + $dst->freed = 0; + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("$opcode", $dst->rx, '$schar', $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = gen_rtx_XOR($rtx_mode, dst, dst); + icg_emit_clobber(gen_rtx_SET($rtx_mode, dst, src)); + }; +""") + + +plug.plugrule3("immload", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["r64x.dst : imm64.const", [1, 2], "movabsq", 'q', "DImode"], + ["r64x.dst : pos32.const", [1, 1], "movl", 'd', "SImode"], + ["rz32x.dst : imm32.const", [1, 1], "movl", 'd', "SImode"], + # + # the latency on the next two rules is indeed 2 cycles + # (because they imply a register merge) + # + ["r16x.dst : imm16.const", [2, 2], "movw", 'w', "HImode"], + ["r8x.dst : imm8.const", [2, 1], "movb", 'b', "QImode"], + # + # using imm32 here to ensure instruction size computes correctly + # + ["r16x.dst : imm32.const", [1, 5-4], "movl", 'd', "SImode"], + ["rz16x.dst : pos16.const", [1, 5-2], "movl", 'd', "SImode"], + ["r8x.dst : imm32.const", [1, 5-4], "movl", 'd', "SImode"], + ["rz8x.dst : pos8.const", [1, 5-1], "movl", 'd', "SImode"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + $dst->extra = 1; + $dst->freed = 0; + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("$opcode", $const, $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +#-------------------------------------------------------------- +# plus + + +# +# The inc and dec instructions do not set the C (carry) flag. +# Consequently, they are not necessarily equivalent to an add instruction with literal 1. +# However, it seems that for the 6 signed comparisons that the C flag is not consulted. +# For the 6 unsigned compares, the C flag is consulted. +# TODO: there's no way to distinguish if the inc/dec instruction is used in an unsigned context. +# +plug.plugrule3("reginc", [ + ["rule", "cost", "opcode", "schar", "mode_slot", "rtx_builder"], + + ["r64x.dst : PLUS_DI(r64x.src | CONST_P1)", [1, 3], "incq", 'q', "DImode", "gen_rtx_PLUS"], + ["rz32x.dst : PLUS_SI(r32x.src | CONST_P1)", [1, 2], "incl", 'd', "SImode", "gen_rtx_PLUS"], + ["r16x.dst : PLUS_HI(r16x.src | CONST_P1)", [1, 3], "incw", 'w', "HImode", "gen_rtx_PLUS"], + ["r8x.dst : PLUS_QI(r8x.src | CONST_P1)", [1, 2], "incb", 'b', "QImode", "gen_rtx_PLUS"], + + ["r64x.dst : PLUS_DI(r64x.src | CONST_N1)", [1, 3], "decq", 'q', "DImode", "gen_rtx_MINUS"], + ["rz32x.dst : PLUS_SI(r32x.src | CONST_N1)", [1, 2], "decl", 'd', "SImode", "gen_rtx_MINUS"], + ["r16x.dst : PLUS_HI(r16x.src | CONST_N1)", [1, 3], "decw", 'w', "HImode", "gen_rtx_MINUS"], + ["r8x.dst : PLUS_QI(r8x.src | CONST_N1)", [1, 2], "decb", 'b', "QImode", "gen_rtx_MINUS"], + + # we can propagate the zero extension info + ["rz16x.dst : PLUS_HI(rz16x.src | CONST_P1)", [1, 3], "incw", 'w', "HImode", "gen_rtx_PLUS"], + ["rz8x.dst : PLUS_QI(rz8x.src | CONST_P1)", [1, 2], "incb", 'b', "QImode", "gen_rtx_PLUS"], + ["rz16x.dst : PLUS_HI(rz16x.src | CONST_N1)", [1, 3], "decw", 'w', "HImode", "gen_rtx_MINUS"], + ["rz8x.dst : PLUS_QI(rz8x.src | CONST_N1)", [1, 2], "decb", 'b', "QImode", "gen_rtx_MINUS"], + + # we can save a byte for 16-bit values (but we lose the zero extension) + ["r16x.dst : PLUS_HI(r16x.src | CONST_P1)", [1, 2], "incl", 'd', "SImode", "gen_rtx_PLUS"], + ["r16x.dst : PLUS_HI(r16x.src | CONST_N1)", [1, 2], "decl", 'd', "SImode", "gen_rtx_MINUS"], + + # repeat for MINUS + ["r64x.dst : MINUS_DI(r64x.src | CONST_N1)", [1, 3], "incq", 'q', "DImode", "gen_rtx_PLUS"], + ["rz32x.dst : MINUS_SI(r32x.src | CONST_N1)", [1, 2], "incl", 'd', "SImode", "gen_rtx_PLUS"], + ["r16x.dst : MINUS_HI(r16x.src | CONST_N1)", [1, 3], "incw", 'w', "HImode", "gen_rtx_PLUS"], + ["r8x.dst : MINUS_QI(r8x.src | CONST_N1)", [1, 2], "incb", 'b', "QImode", "gen_rtx_PLUS"], + + ["r64x.dst : MINUS_DI(r64x.src | CONST_P1)", [1, 3], "decq", 'q', "DImode", "gen_rtx_MINUS"], + ["rz32x.dst : MINUS_SI(r32x.src | CONST_P1)", [1, 2], "decl", 'd', "SImode", "gen_rtx_MINUS"], + ["r16x.dst : MINUS_HI(r16x.src | CONST_P1)", [1, 3], "decw", 'w', "HImode", "gen_rtx_MINUS"], + ["r8x.dst : MINUS_QI(r8x.src | CONST_P1)", [1, 2], "decb", 'b', "QImode", "gen_rtx_MINUS"], + + ["rz16x.dst : MINUS_HI(rz16x.src | CONST_N1)", [1, 3], "incw", 'w', "HImode", "gen_rtx_PLUS"], + ["rz8x.dst : MINUS_QI(rz8x.src | CONST_N1)", [1, 2], "incb", 'b', "QImode", "gen_rtx_PLUS"], + ["rz16x.dst : MINUS_HI(rz16x.src | CONST_P1)", [1, 3], "decw", 'w', "HImode", "gen_rtx_MINUS"], + ["rz8x.dst : MINUS_QI(rz8x.src | CONST_P1)", [1, 2], "decb", 'b', "QImode", "gen_rtx_MINUS"], + + ["r16x.dst : MINUS_HI(r16x.src | CONST_N1)", [1, 2], "incl", 'd', "SImode", "gen_rtx_PLUS"], + ["r16x.dst : MINUS_HI(r16x.src | CONST_P1)", [1, 2], "decl", 'd', "SImode", "gen_rtx_MINUS"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpR("$opcode", $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($mode_slot, $src->rx); + rtx src = $rtx_builder($mode_slot, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +plug.plugrule3("basicir", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + ["ccr64x.dst : PLUS_DI(r64x.src | imm8.const)", [1, 3], "addq", 'q', "DImode", "gen_rtx_PLUS"], + ["ccr64x.dst : PLUS_DI(r64x.src | imm32.const)", [1, 3], "addq", 'q', "DImode", "gen_rtx_PLUS"], + ["ccrz32x.dst : PLUS_SI(r32x.src | imm8.const)", [1, 2], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccrz32x.dst : PLUS_SI(r32x.src | imm32.const)", [1, 2], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | imm8.const)", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | imm16.const)", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | imm8.const)", [1, 2], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + # we can propagate the zero extension info + ["ccrz16x.dst : PLUS_HI(rz16x.src | imm8.const)", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz16x.dst : PLUS_HI(rz16x.src | imm16.const)",[1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | imm8.const)", [1, 2], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + # we can save a byte for 16-bit values (but we lose the condition code and zero extension) + ["r16x.dst : PLUS_HI(r16x.src | imm8.const)", [1, 2], "addl", 'l', "SImode", "gen_rtx_PLUS"], + + # repeat for MINUS + ["ccr64x.dst : MINUS_DI(r64x.src, imm8.const)", [1, 3], "subq", 'q', "DImode", "gen_rtx_MINUS"], + ["ccr64x.dst : MINUS_DI(r64x.src, imm32.const)", [1, 3], "subq", 'q', "DImode", "gen_rtx_MINUS"], + ["ccrz32x.dst : MINUS_SI(r32x.src, imm8.const)", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccrz32x.dst : MINUS_SI(r32x.src, imm32.const)", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, imm8.const)", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, imm16.const)", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, imm8.const)", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + ["ccrz16x.dst : MINUS_HI(rz16x.src, imm8.const)", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz16x.dst : MINUS_HI(rz16x.src, imm16.const)",[1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, imm8.const)", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + [" r16x.dst : MINUS_HI(r16x.src, imm8.const)", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS"], + + # simple versions, optimizations will come later, to be automatically generated + ["ccr64x.dst : AND_DI(r64x.src | imm8.const)", [1, 3], "andq", 'q', "DImode", "gen_rtx_AND"], + ["ccr64x.dst : AND_DI(r64x.src | imm32.const)", [1, 3], "andq", 'q', "DImode", "gen_rtx_AND"], + ["ccrz32x.dst : AND_SI(r32x.src | imm8.const)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND"], + ["ccrz32x.dst : AND_SI(r32x.src | imm32.const)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND"], + ["ccr16x.dst : AND_HI(r16x.src | imm8.const)", [1, 3], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccr16x.dst : AND_HI(r16x.src | imm16.const)", [1, 3], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccr8x.dst : AND_QI(r8x.src | imm8.const)", [1, 2], "andb", 'b', "QImode", "gen_rtx_AND"], + + # we can save a byte for 16-bit values (but we lose the condition code) + ["r16x.dst : AND_HI(r16x.src | imm8.const)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND"], + + # repeat for XOR + ["ccr64x.dst : XOR_DI(r64x.src | imm8.const)", [1, 3], "xorq", 'q', "DImode", "gen_rtx_XOR"], + ["ccr64x.dst : XOR_DI(r64x.src | imm32.const)", [1, 3], "xorq", 'q', "DImode", "gen_rtx_XOR"], + ["ccrz32x.dst : XOR_SI(r32x.src | imm8.const)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR"], + ["ccrz32x.dst : XOR_SI(r32x.src | imm32.const)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR"], + ["ccr16x.dst : XOR_HI(r16x.src | imm8.const)", [1, 3], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccr16x.dst : XOR_HI(r16x.src | imm16.const)", [1, 3], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccr8x.dst : XOR_QI(r8x.src | imm8.const)", [1, 2], "xorb", 'b', "QImode", "gen_rtx_XOR"], + + ["r16x.dst : XOR_HI(r16x.src | imm8.const)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR"], + + # repeat for IOR + ["ccr64x.dst : IOR_DI(r64x.src | imm8.const)", [1, 3], "orq", 'q', "DImode", "gen_rtx_IOR"], + ["ccr64x.dst : IOR_DI(r64x.src | imm32.const)", [1, 3], "orq", 'q', "DImode", "gen_rtx_IOR"], + ["ccrz32x.dst : IOR_SI(r32x.src | imm8.const)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR"], + ["ccrz32x.dst : IOR_SI(r32x.src | imm32.const)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR"], + ["ccr16x.dst : IOR_HI(r16x.src | imm8.const)", [1, 3], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccr16x.dst : IOR_HI(r16x.src | imm16.const)", [1, 3], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccr8x.dst : IOR_QI(r8x.src | imm8.const)", [1, 2], "orb", 'b', "QImode", "gen_rtx_IOR"], + + ["r16x.dst : IOR_HI(r16x.src | imm8.const)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIR("$opcode", $const, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src->rx); + rtx src = $rtx_builder($rtx_mode, dst, gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +plug.plugrule3("basicmr", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + ["ccr64x.dst : PLUS_DI(r64x.src | MEM_DI(addr))", [4, 2], "addq", 'q', "DImode", "gen_rtx_PLUS"], + ["ccrz32x.dst : PLUS_SI(r32x.src | MEM_SI(addr))", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | MEM_HI(addr))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | MEM_QI(addr))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + ["ccrz16x.dst : PLUS_HI(rz16x.src | MEM_HI(addr))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | MEM_QI(addr))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + + ["ccrz32x.dst : PLUS_SI(r32x.src | SUBREG_SI(MEM_DI(addr), CONST_0))", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + ["ccrz16x.dst : PLUS_HI(rz16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz16x.dst : PLUS_HI(rz16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + + + ["ccr64x.dst : MINUS_DI(r64x.src, NEG_DI(MEM_DI(addr)))", [4, 2], "addq", 'q', "DImode", "gen_rtx_PLUS"], + ["ccrz32x.dst : MINUS_SI(r32x.src, NEG_SI(MEM_SI(addr)))", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, NEG_HI(MEM_HI(addr)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, NEG_QI(MEM_QI(addr)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + ["ccrz16x.dst : MINUS_HI(rz16x.src, NEG_HI(MEM_HI(addr)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, NEG_QI(MEM_QI(addr)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + + ["ccrz32x.dst : MINUS_SI(r32x.src, NEG_SI(SUBREG_SI(MEM_DI(addr), CONST_0)))", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + ["ccrz16x.dst : MINUS_HI(rz16x.src, NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz16x.dst : MINUS_HI(rz16x.src, NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0)))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0)))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS"], + + + + ["ccr64x.dst : MINUS_DI(r64x.src, MEM_DI(addr))", [4, 2], "subq", 'q', "DImode", "gen_rtx_MINUS"], + ["ccrz32x.dst : MINUS_SI(r32x.src, MEM_SI(addr))", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, MEM_HI(addr))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, MEM_QI(addr))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + ["ccrz16x.dst : MINUS_HI(rz16x.src, MEM_HI(addr))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, MEM_QI(addr))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + + ["ccrz32x.dst : MINUS_SI(r32x.src, SUBREG_SI(MEM_DI(addr), CONST_0))", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr16x.dst : MINUS_HI(r16x.src, SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccr8x.dst : MINUS_QI(r8x.src, SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + ["ccrz16x.dst : MINUS_HI(rz16x.src, SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz16x.dst : MINUS_HI(rz16x.src, SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : MINUS_QI(rz8x.src, SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + + + ["ccr64x.dst : PLUS_DI(r64x.src | NEG_DI(MEM_DI(addr)))", [4, 2], "subq", 'q', "DImode", "gen_rtx_MINUS"], + ["ccrz32x.dst : PLUS_SI(r32x.src | NEG_SI(MEM_SI(addr)))", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | NEG_HI(MEM_HI(addr)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | NEG_QI(MEM_QI(addr)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + ["ccrz16x.dst : PLUS_HI(rz16x.src | NEG_HI(MEM_HI(addr)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | NEG_QI(MEM_QI(addr)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + + ["ccrz32x.dst : PLUS_SI(r32x.src | NEG_SI(SUBREG_SI(MEM_DI(addr), CONST_0)))", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr16x.dst : PLUS_HI(r16x.src | NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccr8x.dst : PLUS_QI(r8x.src | NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + ["ccrz16x.dst : PLUS_HI(rz16x.src | NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz16x.dst : PLUS_HI(rz16x.src | NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0)))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + ["ccrz8x.dst : PLUS_QI(rz8x.src | NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0)))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS"], + + + + # imul does not set the condition codes in a useful way + ["r64x.dst : MULT_DI(r64x.src | MEM_DI(addr))", [7, 2], "imulq", 'q', "DImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(r32x.src | MEM_SI(addr))", [6, 1], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16x.src | MEM_HI(addr))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + ["rz16x.dst : MULT_HI(rz16x.src | MEM_HI(addr))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + + ["rz32x.dst : MULT_SI(r32x.src | SUBREG_SI(MEM_DI(addr), CONST_0))", [6, 1], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + ["rz16x.dst : MULT_HI(rz16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["rz16x.dst : MULT_HI(rz16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [6, 2], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + + + ["ccr64x.dst : AND_DI(r64x.src | MEM_DI(addr))", [4, 2], "andq", 'q', "DImode", "gen_rtx_AND"], + ["ccrz32x.dst : AND_SI(r32x.src | MEM_SI(addr))", [4, 1], "andl", 'l', "SImode", "gen_rtx_AND"], + ["ccr16x.dst : AND_HI(r16x.src | MEM_HI(addr))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccr8x.dst : AND_QI(r8x.src | MEM_QI(addr))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + + ["ccrz16x.dst : AND_HI(rz16x.src | MEM_HI(addr))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccrz8x.dst : AND_QI(rz8x.src | MEM_QI(addr))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + + + ["ccrz32x.dst : AND_SI(r32x.src | SUBREG_SI(MEM_DI(addr), CONST_0))", [4, 1], "andl", 'l', "SImode", "gen_rtx_AND"], + ["ccr16x.dst : AND_HI(r16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccr16x.dst : AND_HI(r16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccr8x.dst : AND_QI(r8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + ["ccr8x.dst : AND_QI(r8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + ["ccr8x.dst : AND_QI(r8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + + ["ccrz16x.dst : AND_HI(rz16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccrz16x.dst : AND_HI(rz16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND"], + ["ccrz8x.dst : AND_QI(rz8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + ["ccrz8x.dst : AND_QI(rz8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + ["ccrz8x.dst : AND_QI(rz8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND"], + + + + ["ccr64x.dst : IOR_DI(r64x.src | MEM_DI(addr))", [4, 2], "orq", 'q', "DImode", "gen_rtx_IOR"], + ["ccrz32x.dst : IOR_SI(r32x.src | MEM_SI(addr))", [4, 1], "orl", 'l', "SImode", "gen_rtx_IOR"], + ["ccr16x.dst : IOR_HI(r16x.src | MEM_HI(addr))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccr8x.dst : IOR_QI(r8x.src | MEM_QI(addr))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + + ["ccrz16x.dst : IOR_HI(rz16x.src | MEM_HI(addr))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccrz8x.dst : IOR_QI(rz8x.src | MEM_QI(addr))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + + + ["ccrz32x.dst : IOR_SI(r32x.src | SUBREG_SI(MEM_DI(addr), CONST_0))", [4, 1], "orl", 'l', "SImode", "gen_rtx_IOR"], + ["ccr16x.dst : IOR_HI(r16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccr16x.dst : IOR_HI(r16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccr8x.dst : IOR_QI(r8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + ["ccr8x.dst : IOR_QI(r8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + ["ccr8x.dst : IOR_QI(r8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + + ["ccrz16x.dst : IOR_HI(rz16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccrz16x.dst : IOR_HI(rz16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR"], + ["ccrz8x.dst : IOR_QI(rz8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + ["ccrz8x.dst : IOR_QI(rz8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + ["ccrz8x.dst : IOR_QI(rz8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR"], + + + + ["ccr64x.dst : XOR_DI(r64x.src | MEM_DI(addr))", [4, 2], "xorq", 'q', "DImode", "gen_rtx_XOR"], + ["ccrz32x.dst : XOR_SI(r32x.src | MEM_SI(addr))", [4, 1], "xorl", 'l', "SImode", "gen_rtx_XOR"], + ["ccr16x.dst : XOR_HI(r16x.src | MEM_HI(addr))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccr8x.dst : XOR_QI(r8x.src | MEM_QI(addr))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + + ["ccrz16x.dst : XOR_HI(rz16x.src | MEM_HI(addr))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccrz8x.dst : XOR_QI(rz8x.src | MEM_QI(addr))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + + + ["ccrz32x.dst : XOR_SI(r32x.src | SUBREG_SI(MEM_DI(addr), CONST_0))", [4, 1], "xorl", 'l', "SImode", "gen_rtx_XOR"], + ["ccr16x.dst : XOR_HI(r16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccr16x.dst : XOR_HI(r16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccr8x.dst : XOR_QI(r8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + ["ccr8x.dst : XOR_QI(r8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + ["ccr8x.dst : XOR_QI(r8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + + ["ccrz16x.dst : XOR_HI(rz16x.src | SUBREG_HI(MEM_DI(addr), CONST_0))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccrz16x.dst : XOR_HI(rz16x.src | SUBREG_HI(MEM_SI(addr), CONST_0))", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR"], + ["ccrz8x.dst : XOR_QI(rz8x.src | SUBREG_QI(MEM_DI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + ["ccrz8x.dst : XOR_QI(rz8x.src | SUBREG_QI(MEM_SI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + ["ccrz8x.dst : XOR_QI(rz8x.src | SUBREG_QI(MEM_HI(addr), CONST_0))", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR"], + +], """ + $rule $cost + supairs { + suOrder2($dst, $src, $addr, kid, kids); + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + costs { + forgettable($src->rx); + }, + debug { + dumpMR("$opcode", $addr, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src->rx); + rtx src = $rtx_builder($rtx_mode, dst, gen_rtx_MEM($rtx_mode, $addr->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# We're penalizing most of the r-r add instructions because we'd prefer to use the 3-address LEA alternative. +# We'd remove the add variants entirely, but sometimes it's worth having them for the condition code, etc. +# TODO (maybe): have a separate penalty field/flag that adds a tiny penalty (say 1/10). + +plug.plugrule3("basicrr", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "commute"], + + ["ccr64x.dst : PLUS_DI(r64x.src1 | r64.src2)", [1, 3+1], "addq", 'q', "DImode", "gen_rtx_PLUS", 1], + ["ccrz32x.dst : PLUS_SI(r32x.src1 | r32.src2)", [1, 2+1], "addl", 'l', "SImode", "gen_rtx_PLUS", 1], + ["ccr16x.dst : PLUS_HI(r16x.src1 | r16.src2)", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 1], + ["ccr8x.dst : PLUS_QI(r8x.src1 | r8.src2)", [1, 2+1], "addb", 'b', "QImode", "gen_rtx_PLUS", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : PLUS_HI(rz16x.src1 | r16.src2)", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 1], + ["ccrz8x.dst : PLUS_QI(rz8x.src1 | r8.src2)", [1, 2+1], "addb", 'b', "QImode", "gen_rtx_PLUS", 1], + + # we can save a byte for 16-bit values (but we lose the condition code and zero extension) + ["r16x.dst : PLUS_HI(r16x.src1 | r16.src2)", [1, 2+1], "addl", 'l', "SImode", "gen_rtx_PLUS", 1], + + + ["ccr64x.dst : MINUS_DI(r64x.src1, NEG_DI(r64.src2))", [1, 3+1], "addq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["ccrz32x.dst : MINUS_SI(r32x.src1, NEG_SI(r32.src2))", [1, 2+1], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["ccr16x.dst : MINUS_HI(r16x.src1, NEG_HI(r16.src2))", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["ccr8x.dst : MINUS_QI(r8x.src1, NEG_QI(r8.src2))", [1, 2+1], "addb", 'b', "QImode", "gen_rtx_PLUS", 0], + + # we can propagate the zero extension info + ["ccrz16x.dst : MINUS_HI(rz16x.src1, NEG_HI(r16.src2))", [1, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["ccrz8x.dst : MINUS_QI(rz8x.src1, NEG_HI(r8.src2))", [1, 2+1], "addb", 'b', "QImode", "gen_rtx_PLUS", 0], + + # we can save a byte for 16-bit values (but we lose the condition code and zero extension) + ["r16x.dst : MINUS_HI(r16x.src1, NEG_HI(r16.src2))", [1, 2+1], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + + + ["ccr64x.dst : PLUS_DI(r64x.src1 | NEG_DI(r64.src2))", [1, 3], "subq", 'q', "DImode", "gen_rtx_MINUS", 1], + ["ccrz32x.dst : PLUS_SI(r32x.src1 | NEG_SI(r32.src2))", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 1], + ["ccr16x.dst : PLUS_HI(r16x.src1 | NEG_HI(r16.src2))", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 1], + ["ccr8x.dst : PLUS_QI(r8x.src1 | NEG_QI(r8.src2))", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : PLUS_HI(rz16x.src1 | NEG_HI(r16.src2))", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 1], + ["ccrz8x.dst : PLUS_QI(rz8x.src1 | NEG_QI(r8.src2))", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS", 1], + + # we can save a byte for 16-bit values (but we lose the condition code and zero extension) + ["r16x.dst : PLUS_HI(r16x.src1 | NEG_HI(r16.src2))", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 1], + + + ["ccr64x.dst : MINUS_DI(r64x.src1, r64.src2)", [1, 3], "subq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["ccrz32x.dst : MINUS_SI(r32x.src1, r32.src2)", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["ccr16x.dst : MINUS_HI(r16x.src1, r16.src2)", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["ccr8x.dst : MINUS_QI(r8x.src1, r8.src2)", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS", 0], + + # we can propagate the zero extension info + ["ccrz16x.dst : MINUS_HI(rz16x.src1, r16.src2)", [1, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["ccrz8x.dst : MINUS_QI(rz8x.src1, r8.src2)", [1, 2], "subb", 'b', "QImode", "gen_rtx_MINUS", 0], + + # we can save a byte for 16-bit values (but we lose the condition code and zero extension) + ["r16x.dst : MINUS_HI(r16x.src1, r16.src2)", [1, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + + + # imul doesn't set the CC usefully. We use 32-bit multiply to accomplish 8 and 16-bit multiplication + ["r64x.dst : MULT_DI(r64x.src1 | r64.src2)", [4, 4], "imulq", 'q', "DImode", "gen_rtx_MULT", 1], + ["rz32x.dst : MULT_SI(r32x.src1 | r32.src2)", [3, 3], "imull", 'l', "SImode", "gen_rtx_MULT", 1], + ["r16x.dst : MULT_HI(r16x.src1 | r16.src2)", [3, 3], "imull", 'l', "SImode", "gen_rtx_MULT", 1], + ["r8x.dst : MULT_QI(r8x.src1 | r8.src2)", [3, 3], "imull", 'l', "SImode", "gen_rtx_MULT", 1], + + # we can propagate the zero extension info if we use the 16-bit multiplication + ["rz16x.dst : MULT_HI(rz16x.src1 | r16.src2)", [3, 4], "imulw", 'w', "HImode", "gen_rtx_MULT", 1], + + + ["ccr64x.dst : AND_DI(r64x.src1 | r64.src2)", [1, 3], "andq", 'q', "DImode", "gen_rtx_AND", 1], + ["ccrz32x.dst : AND_SI(r32x.src1 | r32.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["ccr16x.dst : AND_HI(r16x.src1 | r16.src2)", [1, 3], "andw", 'w', "HImode", "gen_rtx_AND", 1], + ["ccr8x.dst : AND_QI(r8x.src1 | r8.src2)", [1, 2], "andb", 'b', "QImode", "gen_rtx_AND", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : AND_HI(rz16x.src1 | r16.src2)", [1, 3], "andw", 'w', "HImode", "gen_rtx_AND", 1], + ["ccrz8x.dst : AND_QI(rz8x.src1 | r8.src2)", [1, 2], "andb", 'b', "QImode", "gen_rtx_AND", 1], + + # sometimes it's worth doing these with a 32-bit AND (but we lose the accurate CC) + ["r16x.dst : AND_HI(r16x.src1 | r16.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rz16x.dst : AND_HI(rz16x.src1 | r16.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rz16x.dst : AND_HI(r16x.src1 | rz16.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rs16x.dst : AND_HI(rs16x.src1 | rs16.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["r8x.dst : AND_QI(r8x.src1 | r8.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rz8x.dst : AND_QI(rz8x.src1 | r8.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rz8x.dst : AND_QI(r8x.src1 | rz8.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + ["rs8x.dst : AND_QI(rs8x.src1 | rs8.src2)", [1, 2], "andl", 'l', "SImode", "gen_rtx_AND", 1], + + + ["ccr64x.dst : IOR_DI(r64x.src1 | r64.src2)", [1, 3], "orq", 'q', "DImode", "gen_rtx_IOR", 1], + ["ccrz32x.dst : IOR_SI(r32x.src1 | r32.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + ["ccr16x.dst : IOR_HI(r16x.src1 | r16.src2)", [1, 3], "orw", 'w', "HImode", "gen_rtx_IOR", 1], + ["ccr8x.dst : IOR_QI(r8x.src1 | r8.src2)", [1, 2], "orb", 'b', "QImode", "gen_rtx_IOR", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : IOR_HI(rz16x.src1 | r16.src2)", [1, 3], "orw", 'w', "HImode", "gen_rtx_IOR", 1], + ["ccrz8x.dst : IOR_QI(rz8x.src1 | r8.src2)", [1, 2], "orb", 'b', "QImode", "gen_rtx_IOR", 1], + + + # sometimes it's worth doing these with a 32-bit OR (but we lose the accurate CC) + ["r16x.dst : IOR_HI(r16x.src1 | r16.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + ["rz16x.dst : IOR_HI(rz16x.src1 | rz16.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + ["rs16x.dst : IOR_HI(rs16x.src1 | rs16.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + ["rz8x.dst : IOR_QI(rz8x.src1 | rz8.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + ["rs8x.dst : IOR_QI(rs8x.src1 | rs8.src2)", [1, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 1], + + + + ["ccr64x.dst : XOR_DI(r64x.src1 | r64.src2)", [1, 3], "xorq", 'q', "DImode", "gen_rtx_XOR", 1], + ["ccrz32x.dst : XOR_SI(r32x.src1 | r32.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + ["ccr16x.dst : XOR_HI(r16x.src1 | r16.src2)", [1, 3], "xorw", 'w', "HImode", "gen_rtx_XOR", 1], + ["ccr8x.dst : XOR_QI(r8x.src1 | r8.src2)", [1, 2], "xorb", 'b', "QImode", "gen_rtx_XOR", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : XOR_HI(rz16x.src1 | r16.src2)", [1, 3], "xorw", 'w', "HImode", "gen_rtx_XOR", 1], + ["ccrz8x.dst : XOR_QI(rz8x.src1 | r8.src2)", [1, 2], "xorb", 'b', "QImode", "gen_rtx_XOR", 1], + + # sometimes it's worth doing these with a 32-bit XOR (but we lose the accurate CC) + ["r16x.dst : XOR_HI(r16x.src1 | r16.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + ["rz16x.dst : XOR_HI(rz16x.src1 | rz16.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + ["rs16x.dst : XOR_HI(rs16x.src1 | rs16.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + ["rz8x.dst : XOR_QI(rz8x.src1 | rz8.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + ["rs8x.dst : XOR_QI(rs8x.src1 | rs8.src2)", [1, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 1], + + +], """ + $rule $cost + supairs { + suOrder2($dst, $src1, $src2, kid, kids); + }, + names { + $dst->rx = $src1->rx; + }, + final { + $dst->rx = $src1->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($src2->r)); + }, + remat { + flags = 0; + }, + costs { + if ($commute) + memorable($src1->r); + else + forgettable($src1->rx); + memorable($src2->r); + }, + debug { + dumpRR("$opcode", $src2->r, '$schar', $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src1->rx); + rtx src = $rtx_builder($rtx_mode, dst, gen_rtx_REG($rtx_mode, $src2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +plug.plugrule3("basicneg", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "rcc_clobber"], + + ["ccr64x.dst : NEG_DI(r64x.src)", [1, 3], "negq", 'q', "DImode", "gen_rtx_NEG", 1], + ["ccrz32x.dst : NEG_SI(r32x.src)", [1, 2], "negl", 'l', "SImode", "gen_rtx_NEG", 1], + ["ccr16x.dst : NEG_HI(r16x.src)", [1, 3], "negw", 'w', "HImode", "gen_rtx_NEG", 1], + ["ccr8x.dst : NEG_QI(r8x.src)", [1, 2], "negb", 'b', "QImode", "gen_rtx_NEG", 1], + + # we can propagate the zero extension info + ["ccrz16x.dst : NEG_HI(rz16x.src)", [1, 3], "negw", 'w', "HImode", "gen_rtx_NEG", 1], + ["ccrz8x.dst : NEG_QI(rz8x.src)", [1, 2], "negb", 'b', "QImode", "gen_rtx_NEG", 1], + + # sometimes it's worth doing this with a 32-bit NEGATE (but we lose the accurate CC) + ["r16x.dst : NEG_HI(r16x.src)", [1, 2], "negl", 'l', "SImode", "gen_rtx_NEG", 1], + + # sometimes it's worth doing this with a 32-bit NEGATE (and we get an accurate CC) + ["ccrs16x.dst : NEG_HI(rs16x.src)", [1, 2], "negl", 'l', "SImode", "gen_rtx_NEG", 1], + ["ccrs8x.dst : NEG_HI(rs8x.src)", [1, 2], "negl", 'l', "SImode", "gen_rtx_NEG", 1], + + + # Note that "not" does not affect any flags, but "neg" does. + ["r64x.dst : NOT_DI(r64x.src)", [1, 3], "notq", 'q', "DImode", "gen_rtx_NOT", 0], + ["rz32x.dst : NOT_SI(r32x.src)", [1, 2], "notl", 'l', "SImode", "gen_rtx_NOT", 0], + ["r16x.dst : NOT_HI(r16x.src)", [1, 3], "notw", 'w', "HImode", "gen_rtx_NOT", 0], + ["r8x.dst : NOT_QI(r8x.src)", [1, 2], "notb", 'b', "QImode", "gen_rtx_NOT", 0], + + # we can propagate the zero extension info + ["rz16x.dst : NOT_HI(rz16x.src)", [1, 3], "notw", 'w', "HImode", "gen_rtx_NOT", 0], + ["rz8x.dst : NOT_QI(rz8x.src)", [1, 2], "notb", 'b', "QImode", "gen_rtx_NOT", 0], + + # sometimes it's worth doing this with a 32-bit NOT + ["r16x.dst : NOT_HI(r16x.src)", [1, 2], "notl", 'l', "SImode", "gen_rtx_NOT", 0], + ["rs16x.dst : NOT_HI(rs16x.src)", [1, 2], "notl", 'l', "SImode", "gen_rtx_NOT", 0], + ["rs8x.dst : NOT_QI(rs8x.src)", [1, 2], "notl", 'l', "SImode", "gen_rtx_NOT", 0], + +], """ + $rule $cost + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpR("$opcode", $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src->rx); + rtx src = $rtx_builder($rtx_mode, gen_rtx_REG($rtx_mode, $src->rx)); + ($rcc_clobber ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; + +""") + +plug.plugrule3("extenders", [ + ["rule", "cost", "field"], + + ["r64x.dst : NEG_DI(NEG_DI(r64x.src))", [0, 0], "rx"], + ["r32x.dst : NEG_SI(NEG_SI(r32x.src))", [0, 0], "rx"], + ["rz32x.dst : NEG_SI(NEG_SI(rz32x.src))", [0, 0], "rx"], + ["r16x.dst : NEG_HI(NEG_HI(r16x.src))", [0, 0], "rx"], + ["rz16x.dst : NEG_HI(NEG_HI(rz16x.src))", [0, 0], "rx"], + ["rs16x.dst : NEG_HI(NEG_HI(rs16x.src))", [0, 0], "rx"], + ["r8x.dst : NEG_QI(NEG_QI(r8x.src))", [0, 0], "rx"], + ["rz8x.dst : NEG_QI(NEG_QI(rz8x.src))", [0, 0], "rx"], + ["rs8x.dst : NEG_QI(NEG_QI(rs8x.src))", [0, 0], "rx"], + ["rdx.dst : NEG_DF(NEG_DF(rdx.src))", [0, 0], "rx"], + ["rfx.dst : NEG_SF(NEG_SF(rfx.src))", [0, 0], "rx"], + + ["rz32.dst : SIGN_EXTEND_SI(rs16.src)", [0, 0], "r"], + ["rz32.dst : SIGN_EXTEND_SI(rs8.src)", [0, 0], "r"], + ["rs16.dst : SIGN_EXTEND_HI(rs8.src)", [0, 0], "r"], + ["rz32x.dst : SIGN_EXTEND_SI(rs16x.src)", [0, 0], "rx"], + ["rz32x.dst : SIGN_EXTEND_SI(rs8x.src)", [0, 0], "rx"], + ["rs16x.dst : SIGN_EXTEND_HI(rs8x.src)", [0, 0], "rx"], + + ["rz32.dst : ZERO_EXTEND_SI(rz16.src)", [0, 0], "r"], + ["rz32.dst : ZERO_EXTEND_SI(rz8.src)", [0, 0], "r"], + ["rz16.dst : ZERO_EXTEND_HI(rz8.src)", [0, 0], "r"], + ["rz32x.dst : ZERO_EXTEND_SI(rz16x.src)", [0, 0], "rx"], + ["rz32x.dst : ZERO_EXTEND_SI(rz8x.src)", [0, 0], "rx"], + ["rz16x.dst : ZERO_EXTEND_HI(rz8x.src)", [0, 0], "rx"], + + # + # This is a little subtle. + # By requiring a regx, I force a chain rule to make + # a copy (if required) and it'll use a 32-bit copy + # (versus the more expensive 64-bit copy). + # + ["r64x.dst : ZERO_EXTEND_DI(rz32x.src)", [0, 0], "rx"], + ["r64x.dst : ZERO_EXTEND_DI(rz16x.src)", [0, 0], "rx"], + ["r64x.dst : ZERO_EXTEND_DI(rz8x.src)", [0, 0], "rx"], + ["r64.dst : ZERO_EXTEND_DI(rz32.src)", [0, 0], "r"], + ["r64.dst : ZERO_EXTEND_DI(rz16.src)", [0, 0], "r"], + ["r64.dst : ZERO_EXTEND_DI(rz8.src)", [0, 0], "r"], + +], """ + $rule $cost + names { + $dst->$field = $src->$field; + }, + final { + $dst->$field = $src->$field; + }, + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }; +""") + + +#---------------------------------------------------------------- +# mult +# +# Note that imul doesn't set the CC usefully. +# + +plug.plugrule3("multrri", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + ["r64x.dst : MULT_DI(r64.src | imm8.const)", [4, 3], "imulq", 'q', "DImode", "gen_rtx_MULT"], + ["r64x.dst : MULT_DI(r64.src | imm32.const)", [4, 3], "imulq", 'q', "DImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(r32.src | imm8.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(r32.src | imm32.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16.src | imm8.const)", [4, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16.src | imm16.const)", [4, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + # we can propagate the zero extension info + ["rz16x.dst : MULT_HI(rz16.src | imm8.const)", [4, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["rz16x.dst : MULT_HI(rz16.src | imm16.const)", [4, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + # often it will be worth doing these with a 32-bit multiply + ["r16x.dst : MULT_HI(r16.src | imm8.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(r16.src | imm32.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r8x.dst : MULT_QI(r8.src | imm8.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r8x.dst : MULT_QI(r8.src | imm32.const)", [3, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; /* think about these */ + $dst->freed = $src->freed; + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + sparseset_set_bit(live, find($src->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($src->r); + }, + debug { + dumpIRR("$opcode", $const, $src->r, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_REG($rtx_mode, $src->r), + gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + +plug.plugrule3("multimr", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + ["r64x.dst : MULT_DI(MEM_DI(addr) | imm8.const)", [8, 3], "imulq", 'q', "DImode", "gen_rtx_MULT"], + ["r64x.dst : MULT_DI(MEM_DI(addr) | imm32.const)", [8, 3], "imulq", 'q', "DImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(MEM_SI(addr) | imm8.const)", [7, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(MEM_SI(addr) | imm32.const)", [7, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(MEM_HI(addr) | imm8.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(MEM_HI(addr) | imm16.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + + ["rz32x.dst : MULT_SI(SUBREG_SI(MEM_DI(addr), CONST_0) | imm8.const)", [7, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["rz32x.dst : MULT_SI(SUBREG_SI(MEM_DI(addr), CONST_0) | imm32.const)", [7, 2], "imull", 'l', "SImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(SUBREG_HI(MEM_DI(addr), CONST_0) | imm8.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(SUBREG_HI(MEM_SI(addr), CONST_0) | imm8.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(SUBREG_HI(MEM_DI(addr), CONST_0) | imm16.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + ["r16x.dst : MULT_HI(SUBREG_HI(MEM_SI(addr), CONST_0) | imm16.const)", [7, 3], "imulw", 'w', "HImode", "gen_rtx_MULT"], + +], """ + $rule $cost + supairs { + suOrder2($dst, $addr, $const, kid, kids); + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + add_addr(live, $addr); + }, + debug { + dumpIMR("$opcode", $const, $addr, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_MEM($rtx_mode, $addr->rtl), + gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# div and mod +# assume first coalesce will succeed. +# What about second? I guess we'll count it. +# +# Note that gcc doesn't use "cqo" for pentium, just the opteron. +# +# time is 2 + div, where div is, say, 50 +# + +plug.plugrule3("div", [ + ["rule", "cost", "opcode", "schar", "dst_reg_name", "rtx_mode", "mov_opcode", "extend_opcode", "isRR", "issigned"], + + ["r64x.dst : DIV_DI(r64x.src1, r64.src2)", [52, 8], "idivq", 'q', "REG_RAX", "DImode", "movq", "cqo", 1, 1], + ["rz32x.dst : DIV_SI(r32x.src1, r32.src2)", [52, 6], "idivl", 'd', "REG_RAX", "SImode", "movl", "cdq", 1, 1], + + ["r64x.dst : MOD_DI(r64x.src1, r64.src2)", [52, 8], "idivq", 'q', "REG_RDX", "DImode", "movq", "cqo", 1, 1], + ["rz32x.dst : MOD_SI(r32x.src1, r32.src2)", [52, 5], "idivl", 'd', "REG_RDX", "SImode", "movl", "cdq", 1, 1], + + ["r64x.dst : DIV_DI(r64x.src1, MEM_DI(addr.src2))", [52, 8], "idivq", 'q', "REG_RAX", "DImode", "movq", "cqo", 0, 1], + ["rz32x.dst : DIV_SI(r32x.src1, MEM_SI(addr.src2))", [52, 4], "idivl", 'd', "REG_RAX", "SImode", "movl", "cdq", 0, 1], + ["rz32x.dst : DIV_SI(r32x.src1, SUBREG_SI(MEM_DI(addr.src2), CONST_0))", [52, 4], "idivl", 'd', "REG_RAX", "SImode", "movl", "cdq", 0, 1], + + ["r64x.dst : MOD_DI(r64x.src1, MEM_DI(addr.src2))", [52, 8], "idivq", 'q', "REG_RDX", "DImode", "movq", "cqo", 0, 1], + ["rz32x.dst : MOD_SI(r32x.src1, MEM_SI(addr.src2))", [52, 4], "idivl", 'd', "REG_RDX", "SImode", "movl", "cdq", 0, 1], + ["rz32x.dst : MOD_SI(r32x.src1, SUBREG_SI(MEM_DI(addr.src2), CONST_0))", [52, 4], "idivl", 'd', "REG_RDX", "SImode", "movl", "cdq", 0, 1], + # + # TODO: DIV_HI + # TODO: MOD_HI + # TODO: MOD_QI (hard, as mod comes back in register %ah, eg (rax>>8)&0xff) (dst_reg_name must be REG_RAX) + # TODO: UMOD_QI (hard, as mod comes back in register %ah, eg (rax>>8)&0xff) (dst_reg_name must be REG_RAX) + # + + ["r64x.dst : UDIV_DI(r64x.src1, r64.src2)", [52, 8], "divq", 'q', "REG_RAX", "DImode", "movq", "xorl", 1, 0], + ["rz32x.dst : UDIV_SI(r32x.src1, r32.src2)", [52, 6], "divl", 'd', "REG_RAX", "SImode", "movl", "xorl", 1, 0], + ["r16x.dst : UDIV_HI(r16x.src1, r16.src2)", [52, 6], "divw", 'w', "REG_RAX", "HImode", "movl", "xorl", 1, 0], + ["r8x.dst : UDIV_QI(r16x.src1, r8.src2)", [52, 6], "divb", 'b', "REG_RAX", "QImode", "movl", "xor?", 1, 0], + + ["r64x.dst : UMOD_DI(r64x.src1, r64.src2)", [52, 8], "divq", 'q', "REG_RDX", "DImode", "movq", "xorl", 1, 0], + ["rz32x.dst : UMOD_SI(r32x.src1, r32.src2)", [52, 6], "divl", 'd', "REG_RDX", "SImode", "movl", "xorl", 1, 0], + ["r16x.dst : UMOD_HI(r16x.src1, r16.src2)", [52, 6], "divw", 'w', "REG_RDX", "HImode", "movl", "xorl", 1, 0], + + ["r64x.dst : UDIV_DI(r64x.src1, MEM_DI(addr.src2))", [52, 8], "divq", 'q', "REG_RAX", "DImode", "movq", "xorl", 0, 0], + ["rz32x.dst : UDIV_SI(r32x.src1, MEM_SI(addr.src2))", [52, 5], "divl", 'd', "REG_RAX", "SImode", "movl", "xorl", 0, 0], + ["rz32x.dst : UDIV_SI(r32x.src1, SUBREG_SI(MEM_DI(addr.src2), CONST_0))", [52, 5], "divl", 'd', "REG_RAX", "SImode", "movl", "xorl", 0, 0], + ["r16x.dst : UDIV_HI(r16x.src1, MEM_HI(addr.src2))", [52, 6], "divw", 'w', "REG_RAX", "HImode", "movl", "xorl", 0, 0], + ["r16x.dst : UDIV_HI(r16x.src1, SUBREG_HI(MEM_DI(addr.src2), CONST_0))", [52, 6], "divw", 'w', "REG_RAX", "HImode", "movl", "xorl", 0, 0], + ["r16x.dst : UDIV_HI(r16x.src1, SUBREG_HI(MEM_SI(addr.src2), CONST_0))", [52, 6], "divw", 'w', "REG_RAX", "HImode", "movl", "xorl", 0, 0], + ["r8x.dst : UDIV_QI(r16x.src1, SUBREG_QI(MEM_DI(addr.src2), CONST_0))", [52, 6], "divb", 'b', "REG_RAX", "QImode", "movl", "xor?", 0, 0], + ["r8x.dst : UDIV_QI(r16x.src1, SUBREG_QI(MEM_SI(addr.src2), CONST_0))", [52, 6], "divb", 'b', "REG_RAX", "QImode", "movl", "xor?", 0, 0], + ["r8x.dst : UDIV_QI(r16x.src1, SUBREG_QI(MEM_HI(addr.src2), CONST_0))", [52, 6], "divb", 'b', "REG_RAX", "QImode", "movl", "xor?", 0, 0], + + ["r64x.dst : UMOD_DI(r64x.src1, MEM_DI(addr.src2))", [52, 8], "divq", 'q', "REG_RDX", "DImode", "movq", "xorl", 0, 0], + ["rz32x.dst : UMOD_SI(r32x.src1, MEM_SI(addr.src2))", [52, 5], "divl", 'd', "REG_RDX", "SImode", "movl", "xorl", 0, 0], + ["rz32x.dst : UMOD_SI(r32x.src1, SUBREG_SI(MEM_DI(addr.src2), CONST_0))", [52, 5], "divl", 'd', "REG_RDX", "SImode", "movl", "xorl", 0, 0], + ["r16x.dst : UMOD_HI(r16x.src1, MEM_HI(addr.src2))", [52, 6], "divw", 'w', "REG_RDX", "HImode", "movl", "xorl", 0, 0], + ["r16x.dst : UMOD_HI(r16x.src1, SUBREG_HI(MEM_DI(addr.src2), CONST_0))", [52, 6], "divw", 'w', "REG_RDX", "HImode", "movl", "xorl", 0, 0], + ["r16x.dst : UMOD_HI(r16x.src1, SUBREG_HI(MEM_SI(addr.src2), CONST_0))", [52, 6], "divw", 'w', "REG_RDX", "HImode", "movl", "xorl", 0, 0], + +], """ + $rule $cost + supairs { + if ($isRR) { + suOrder2($dst, $src1, $src2, kid, kids); + } else { + suOrder2($dst, $src1, $src2, kid, kids); + } + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $dst->rx, $dst_reg_name); + }, + build { + if ($dst_reg_name == REG_RAX) + add_copy_edges($dst->rx, REG_RAX, live); + + else + add_copy_edges($dst->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if ($isRR) + sparseset_set_bit(live, find($src2->r)); + else + add_addr(live, $src2); + + if ('$schar' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $src1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1->rx, REG_RAX); + memorable($src1->rx); + if ($isRR) + memorable($src2->r); + cost_copy($dst_reg_name, $dst->rx); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dump_copy("$mov_opcode", $src1->rx, REG_RAX, '$schar'); + if ('$schar' != 'b') { + if ($issigned) { + dump("$extend_opcode"); /* such as cqo or cdq */ + } else { + dumpRR("$extend_opcode", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if ($isRR) { + dumpR("$opcode", $src2->r, '$schar'); + } else { + dumpM("$opcode", $src2); + } + dump_copy("$mov_opcode", $dst_reg_name, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src1 = gen_rtx_REG($rtx_mode, $src1->rx); + rtx src2 = $isRR + ? gen_rtx_REG($rtx_mode, $src2->r) + : gen_rtx_MEM($rtx_mode, $src2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG($rtx_mode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('$schar' != 'b') ? gen_rtx_REG($rtx_mode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('$schar' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper($issigned, $rtx_mode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper($issigned, $rtx_mode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper($issigned, $rtx_mode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, ($dst_reg_name == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +""") + + +#--------------------------------------------------------------- +# signed div/mod in parallel +# TODO: merge with previous rule +# be careful with rax vs raxm +plug.plugrule3("pardivmod", [ + ["rule", "cost", "rtx_mode", "mov_opcode", "schar", "extend_opcode", "div_opcode", "isRR", "issigned"], + + ["""stmt : PARALLEL_ALL(SET_ALL(lhs64.dst1, DIV_DI(r64.src1a, r64.src1b)), + SET_ALL(lhs64.dst2, MOD_DI(r64.src2a, r64.src2b)))""", + [52, 8], "DImode", "movq", 'q', "cqo", "idivq", 1, 1], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, DIV_SI(r32.src1a, r32.src1b)), + SET_ALL(lhs32.dst2, MOD_SI(r32.src2a, r32.src2b)))""", + [52, 8], "SImode", "movl", 'd', "cdq", "idivl", 1, 1], + + ["""stmt : PARALLEL_ALL(SET_ALL(lhs64.dst1, UDIV_DI(r64.src1a, r64.src1b)), + SET_ALL(lhs64.dst2, UMOD_DI(r64.src2a, r64.src2b)))""", + [52, 8], "DImode", "movq", 'q', "xorl", "divq", 1, 0], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, UDIV_SI(r32.src1a, r32.src1b)), + SET_ALL(lhs32.dst2, UMOD_SI(r32.src2a, r32.src2b)))""", + [52, 8], "SImode", "movl", 'd', "xorl", "divl", 1, 0], + + ["""stmt : PARALLEL_ALL(SET_ALL(lhs64.dst1, DIV_DI(r64.src1a, MEM_DI(addr.src1b))), + SET_ALL(lhs64.dst2, MOD_DI(r64.src2a, MEM_DI(addr.src2b))))""", + [52, 8], "DImode", "movq", 'q', "cqo", "idivq", 0, 1], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, DIV_SI(r32.src1a, MEM_SI(addr.src1b))), + SET_ALL(lhs32.dst2, MOD_SI(r32.src2a, MEM_SI(addr.src2b))))""", + [52, 8], "SImode", "movl", 'd', "cltd", "idivl", 0, 1], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, DIV_SI(r32.src1a, SUBREG_SI(MEM_DI(addr.src1b), CONST_0))), + SET_ALL(lhs32.dst2, MOD_SI(r32.src2a, SUBREG_SI(MEM_DI(addr.src2b), CONST_0))))""", + [52, 8], "SImode", "movl", 'd', "cltd", "idivl", 0, 1], + + ["""stmt : PARALLEL_ALL(SET_ALL(lhs64.dst1, UDIV_DI(r64.src1a, MEM_DI(addr.src1b))), + SET_ALL(lhs64.dst2, UMOD_DI(r64.src2a, MEM_DI(addr.src2b))))""", + [52, 8], "DImode", "movq", 'q', "xorl", "divq", 0, 0], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, UDIV_SI(r32.src1a, MEM_SI(addr.src1b))), + SET_ALL(lhs32.dst2, UMOD_SI(r32.src2a, MEM_SI(addr.src2b))))""", + [52, 8], "SImode", "movl", 'd', "xorl", "divl", 0, 0], + ["""stmt : PARALLEL_ALL(SET_ALL(lhs32.dst1, UDIV_SI(r32.src1a, SUBREG_SI(MEM_DI(addr.src1b), CONST_0))), + SET_ALL(lhs32.dst2, UMOD_SI(r32.src2a, SUBREG_SI(MEM_DI(addr.src2b), CONST_0))))""", + [52, 8], "SImode", "movl", 'd', "xorl", "divl", 0, 0], + +], """ + $rule $cost + supairs { + /* suOrder2($stmt, $dst1, $src1a, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1a->r, REG_RAX); + if (!$dst1->spilled) + coalesces += attempt_coalesce(pass, $dst1->r, REG_RAX); + if (!$dst2->spilled) + coalesces += attempt_coalesce(pass, $dst2->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($dst2->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $dst2); + } + else + add_copy_edges($dst2->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($dst1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $dst1); + } + else + add_copy_edges($dst1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if ($isRR) + sparseset_set_bit(live, find($src1b->r)); + else + add_addr(live, $src1b); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $src1a->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1a->r); + cost_copy($src1a->r, REG_RAX); + if ($isRR) + memorable($src1b->r); + if (!$dst1->spilled) + cost_copy($dst1->r, REG_RAX); + if (!$dst2->spilled) + cost_copy(REG_RDX, $dst2->r); + }, + debug { + dump_copy("$mov_opcode", $src1a->r, REG_RAX, '$schar'); + + if ($issigned) + dump("$extend_opcode"); + else + dumpRR("$extend_opcode", REG_RDX, '$schar', REG_RDX, '$schar'); + + if ($isRR) + dumpR("$div_opcode", $src1b->r, '$schar'); + else + dumpM("$div_opcode", $src1b); + + if ($dst1->spilled) + dumpRM("$mov_opcode", REG_RAX, '$schar', $dst1); + else + dump_copy("$mov_opcode", REG_RAX, $dst1->r, '$schar'); + + if ($dst1->spilled) + dumpRM("$mov_opcode", REG_RDX, '$schar', $dst2); + else + dump_copy("$mov_opcode", REG_RDX, $dst2->r, '$schar'); + }, + emit { + rtx src1 = gen_rtx_REG($rtx_mode, $src1a->r); + rtx src2 = $isRR + ? gen_rtx_REG($rtx_mode, $src1b->r) + : gen_rtx_MEM($rtx_mode, $src1b->rtl); + rtx dst1 = $dst1->spilled + ? gen_rtx_MEM($rtx_mode, $dst1->rtl) + : gen_rtx_REG($rtx_mode, $dst1->r); + rtx dst2 = $dst2->spilled + ? gen_rtx_MEM($rtx_mode, $dst2->rtl) + : gen_rtx_REG($rtx_mode, $dst2->r); + rtx rax = gen_rtx_REG($rtx_mode, REG_RAX); + rtx rdx = gen_rtx_REG($rtx_mode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper($issigned, $rtx_mode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper($issigned, $rtx_mode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +""") + + +plug.plugrule3("pardivmod_hi", [ + ["rule", "cost"], + + ["""stmt : PARALLEL_ALL(SET_ALL(lhs16.dst1, UDIV_HI(r16.src1a, r16.src1b)), + PARALLEL_ALL(SET_ALL(lhs16.dst2, UMOD_HI(r16.src2a, r16.src2b)), + USE_ALL(CONST_0)))""", [52, 8]], +], """ + $rule $cost + supairs { + /* suOrder2($stmt, $dst1, $src1a, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1a->r, REG_RAX); + if (!$dst1->spilled) + coalesces += attempt_coalesce(pass, $dst1->r, REG_RAX); + if (!$dst2->spilled) + coalesces += attempt_coalesce(pass, $dst2->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($dst2->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $dst2); + } + else + add_copy_edges($dst2->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($dst1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $dst1); + } + else + add_copy_edges($dst1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + sparseset_set_bit(live, find($src1b->r)); + + /* xor instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $src1a->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1a->r); + cost_copy($src1a->r, REG_RAX); + memorable($src1b->r); + if (!$dst1->spilled) + cost_copy($dst1->r, REG_RAX); + if (!$dst2->spilled) + cost_copy(REG_RDX, $dst2->r); + }, + debug { + dump_copy("movl", $src1a->r, REG_RAX, 'd'); /* use movw? no, movl is preferred */ + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* use xorw? no, xorl is preferred */ + dumpR("divw", $src1b->r, 'w'); + dump_copy("movl", REG_RAX, $dst1->r, 'd'); /* use movw? no, movl is preferred */ + dump_copy("movl", REG_RDX, $dst2->r, 'd'); /* use movw? no, movl is preferred */ + }, + emit { + rtx dst1 = $dst1->spilled + ? gen_rtx_MEM(HImode, $dst1->rtl) + : gen_rtx_REG(HImode, $dst1->r); + rtx dst2 = $dst2->spilled + ? gen_rtx_MEM(HImode, $dst2->rtl) + : gen_rtx_REG(HImode, $dst2->r); + + rtx src1 = gen_rtx_REG(HImode, $src1a->r); + rtx src2 = gen_rtx_REG(HImode, $src1b->r); + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = gen_rtx_REG(HImode, REG_RDX); + rtx rdxm = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, rdxm, + gen_rtx_XOR(SImode, rdxm, rdxm))); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(4, + gen_rtx_SET(VOIDmode, rax, gen_rtx_UDIV(HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_UMOD(HImode, rax, src2)), + gen_rtx_USE(VOIDmode, rdx), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +""") + + +#-------------------------------------------------------------- +# +# Shifts by a variable count (versus a constant) require that the shift +# count be in register %cl. When we generate code, we'll have a copy +# from some symbolic register containing the count into %cl. +# With luck, the copy will be coalesced away during register allocation. +# For purposes of burg costs, we'll assume the coalesce is going to succeed. +# +# To help make sure the coalesce succeeds, we require that the register +# holding the count be an RX. Will this really help? Someday an experiment +# should be conducted. +# +# There are 3 varieties of shift in RTL +# ASHIFT - shift left, implemented via sal +# ASHIFTRT - arithmetic shift right, implemented via sar +# LSHIFTRT - logical shift right, implemented via shr +# ROTATE - rotate left, implemented via rol +# ROTATERT - rotate right, implemented via ror +# +# The shift instructions do not set the condition code flags if the shift count is 0. +# Consequently, we do not use the "ccr...x" non-terminal as the destination. +# Indeed, it seems that we may never rely on the condition codes set by a shift of any sort. +# Note that shift by 1 sets the OF flag; other shifts don't. Is implementation dependent. +# +plug.plugrule3("shiftrr", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + # we start with ASHIFT + ["r64x.dst : ASHIFT_DI(r64x.src1, r8x.src2)", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + ["rz32x.dst : ASHIFT_SI(r32x.src1, r8x.src2)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src1, r8x.src2)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["r8x.dst : ASHIFT_QI(r8x.src1, r8x.src2)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # we can preserve the zero-extension + ["rz16x.dst : ASHIFT_HI(rz16x.src1, r8x.src2)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["rz8x.dst : ASHIFT_QI(rz8x.src1, r8x.src2)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # it's worth doing this with a 32-bit op + ["r16x.dst : ASHIFT_HI(r16x.src1, r8x.src2)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + + # usually, the shift count is subreg'd to 8-bits + ["r64x.dst : ASHIFT_DI(r64x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + ["r64x.dst : ASHIFT_DI(r64x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + ["r64x.dst : ASHIFT_DI(r64x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + + ["rz32x.dst : ASHIFT_SI(r32x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["rz32x.dst : ASHIFT_SI(r32x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["rz32x.dst : ASHIFT_SI(r32x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + + ["r8x.dst : ASHIFT_QI(r8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + ["r8x.dst : ASHIFT_QI(r8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + ["r8x.dst : ASHIFT_QI(r8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # we can preserve the zero-extension + ["rz16x.dst : ASHIFT_HI(rz16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["rz16x.dst : ASHIFT_HI(rz16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["rz16x.dst : ASHIFT_HI(rz16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + + ["rz8x.dst : ASHIFT_QI(rz8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + ["rz8x.dst : ASHIFT_QI(rz8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + ["rz8x.dst : ASHIFT_QI(rz8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # it's worth doing these with a 32-bit op + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + + + + # ASHIFTRT is organized the same way + ["r64x.dst : ASHIFTRT_DI(r64x.src1, r8x.src2)", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + ["rz32x.dst : ASHIFTRT_SI(r32x.src1, r8x.src2)", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["r16x.dst : ASHIFTRT_HI(r16x.src1, r8x.src2)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["r8x.dst : ASHIFTRT_QI(r8x.src1, r8x.src2)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the zero-extension + ["rz16x.dst : ASHIFTRT_HI(rz16x.src1, r8x.src2)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["rz8x.dst : ASHIFTRT_QI(rz8x.src1, r8x.src2)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the sign-extension, using 32-bit op to save a byte on the 16-bit ops + ["rs16x.dst : ASHIFTRT_HI(rs16x.src1, r8x.src2)", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rs8x.dst : ASHIFTRT_QI(rs8x.src1, r8x.src2)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # usually, the shift count is subreg'd to 8-bits + ["r64x.dst : ASHIFTRT_DI(r64x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + ["r64x.dst : ASHIFTRT_DI(r64x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + ["r64x.dst : ASHIFTRT_DI(r64x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + + ["rz32x.dst : ASHIFTRT_SI(r32x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rz32x.dst : ASHIFTRT_SI(r32x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rz32x.dst : ASHIFTRT_SI(r32x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + + ["r16x.dst : ASHIFTRT_HI(r16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["r16x.dst : ASHIFTRT_HI(r16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["r16x.dst : ASHIFTRT_HI(r16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + + ["r8x.dst : ASHIFTRT_QI(r8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["r8x.dst : ASHIFTRT_QI(r8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["r8x.dst : ASHIFTRT_QI(r8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the zero-extension + ["rz16x.dst : ASHIFTRT_HI(rz16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["rz16x.dst : ASHIFTRT_HI(rz16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["rz16x.dst : ASHIFTRT_HI(rz16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + + ["rz8x.dst : ASHIFTRT_QI(rz8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["rz8x.dst : ASHIFTRT_QI(rz8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["rz8x.dst : ASHIFTRT_QI(rz8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the sign-extension, using 32-bit op to save a byte on the 16-bit ops + ["rs16x.dst : ASHIFTRT_HI(rs16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rs16x.dst : ASHIFTRT_HI(rs16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rs16x.dst : ASHIFTRT_HI(rs16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + + ["rs8x.dst : ASHIFTRT_QI(rs8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["rs8x.dst : ASHIFTRT_QI(rs8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + ["rs8x.dst : ASHIFTRT_QI(rs8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + + # LSHIFTRT is organized the same way + ["r64x.dst : LSHIFTRT_DI(r64x.src1, r8x.src2)", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + ["rz32x.dst : LSHIFTRT_SI(r32x.src1, r8x.src2)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["r16x.dst : LSHIFTRT_HI(r16x.src1, r8x.src2)", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + ["r8x.dst : LSHIFTRT_QI(r8x.src1, r8x.src2)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # we can preserve the zero-extension, using 32-bit op to save a byte on the 16-bit ops + ["rz16x.dst : LSHIFTRT_HI(rz16x.src1, r8x.src2)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz8x.dst : LSHIFTRT_QI(rz8x.src1, r8x.src2)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # usually, the shift count is subreg'd to 8-bits + ["r64x.dst : LSHIFTRT_DI(r64x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + ["r64x.dst : LSHIFTRT_DI(r64x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + ["r64x.dst : LSHIFTRT_DI(r64x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + + ["rz32x.dst : LSHIFTRT_SI(r32x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz32x.dst : LSHIFTRT_SI(r32x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz32x.dst : LSHIFTRT_SI(r32x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + + ["r16x.dst : LSHIFTRT_HI(r16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + ["r16x.dst : LSHIFTRT_HI(r16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + ["r16x.dst : LSHIFTRT_HI(r16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + + ["r8x.dst : LSHIFTRT_QI(r8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + ["r8x.dst : LSHIFTRT_QI(r8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + ["r8x.dst : LSHIFTRT_QI(r8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # we can preserve the zero-extension, using 32-bit op to save a byte on the 16-bit ops + ["rz16x.dst : LSHIFTRT_HI(rz16x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz16x.dst : LSHIFTRT_HI(rz16x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz16x.dst : LSHIFTRT_HI(rz16x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + + ["rz8x.dst : LSHIFTRT_QI(rz8x.src1, SUBREG_QI(r64x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + ["rz8x.dst : LSHIFTRT_QI(rz8x.src1, SUBREG_QI(r32x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + ["rz8x.dst : LSHIFTRT_QI(rz8x.src1, SUBREG_QI(r16x.src2, CONST_0))", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # ROTATE is organized the same way, but without any sign/zero extension tricks + ["r64x.dst : ROTATE_DI(r64x.src1, r8x.src2)", [1, 3], "rolq", 'q', "DImode", "gen_rtx_ROTATE"], + ["r32x.dst : ROTATE_SI(r32x.src1, r8x.src2)", [1, 2], "roll", 'l', "SImode", "gen_rtx_ROTATE"], + ["r16x.dst : ROTATE_HI(r16x.src1, r8x.src2)", [1, 3], "rolw", 'w', "HImode", "gen_rtx_ROTATE"], + ["r8x.dst : ROTATE_QI(r8x.src1, r8x.src2)", [1, 2], "rolb", 'b', "QImode", "gen_rtx_ROTATE"], + + # ROTATE_RT is organized the same way, but without any sign/zero extension tricks + ["r64x.dst : ROTATERT_DI(r64x.src1, r8x.src2)", [1, 3], "rorq", 'q', "DImode", "gen_rtx_ROTATERT"], + ["r32x.dst : ROTATERT_SI(r32x.src1, r8x.src2)", [1, 2], "rorl", 'l', "SImode", "gen_rtx_ROTATERT"], + ["r16x.dst : ROTATERT_HI(r16x.src1, r8x.src2)", [1, 3], "rorw", 'w', "HImode", "gen_rtx_ROTATERT"], + ["r8x.dst : ROTATERT_QI(r8x.src1, r8x.src2)", [1, 2], "rorb", 'b', "QImode", "gen_rtx_ROTATERT"], + +], """ + $rule $cost + supairs { + suOrder2($dst, $src1, $src2, kid, kids); + }, + names { + $dst->rx = $src1->rx; + }, + final { + $dst->rx = $src1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $src2->rx, REG_RCX); + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $src2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1->rx); + forgettable($src2->rx); + cost_copy(REG_RCX, $src2->rx); + }, + debug { + dump_copy("movl", $src2->rx, REG_RCX, 'd'); + dumpRR("$opcode", REG_RCX, 'b', $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $src1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $src2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = $rtx_builder($rtx_mode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# +# The shift instructions do not set the condition code flags if the shift count is 0. +# Consequently, we do not use the "ccr...x" non-terminal as the destination. +# +plug.plugrule3("shiftir", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + # we start with ASHIFT + ["r64x.dst : ASHIFT_DI(r64x.src, imm8.const)", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + ["rz32x.dst : ASHIFT_SI(r32x.src, imm8.const)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src, imm8.const)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["r8x.dst : ASHIFT_QI(r8x.src, imm8.const)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # we can preserve the zero extension + ["rz16x.dst : ASHIFT_HI(rz16x.src, imm8.const)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["rz8x.dst : ASHIFT_QI(rz8x.src, imm8.const)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # it's worth doing this with a 32-bit op + ["r16x.dst : ASHIFT_HI(r16x.src, imm8.const)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + + + # repeat for ASHIFTRT + ["r64x.dst : ASHIFTRT_DI(r64x.src, imm8.const)", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + ["rz32x.dst : ASHIFTRT_SI(r32x.src, imm8.const)", [1, 2], "sarw", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["r16x.dst : ASHIFTRT_HI(r16x.src, imm8.const)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["r8x.dst : ASHIFTRT_QI(r8x.src, imm8.const)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the zero extension + ["rz16x.dst : ASHIFTRT_HI(rz16x.src, imm8.const)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["rz8x.dst : ASHIFTRT_QI(rz8x.src, imm8.const)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the sign extension, using a 32-bit op to save a byte over the 16-bit op + ["rs16x.dst : ASHIFTRT_HI(rs16x.src, imm8.const)", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rs8x.dst : ASHIFTRT_QI(rs8x.src, imm8.const)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + + # repeat for LSHIFTRT + ["r64x.dst : LSHIFTRT_DI(r64x.src, imm8.const)", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + ["rz32x.dst : LSHIFTRT_SI(r32x.src, imm8.const)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["r16x.dst : LSHIFTRT_HI(r16x.src, imm8.const)", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + ["r8x.dst : LSHIFTRT_QI(r8x.src, imm8.const)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # we can preserve the zero extension, using a 32-bit op to save a byte over the 16-bit op + ["rz16x.dst : LSHIFTRT_HI(rz16x.src, imm8.const)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz8x.dst : LSHIFTRT_QI(rz8x.src, imm8.const)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # + # repeat for ROTATE, but without any tracking of sign/zero extension + # + ["r64x.dst : ROTATE_DI(r64x.src, imm8.const)", [1, 3], "rolq", 'q', "DImode", "gen_rtx_ROTATE"], + ["r32x.dst : ROTATE_SI(r32x.src, imm8.const)", [1, 2], "roll", 'l', "SImode", "gen_rtx_ROTATE"], + ["r16x.dst : ROTATE_HI(r16x.src, imm8.const)", [1, 3], "rolw", 'w', "HImode", "gen_rtx_ROTATE"], + ["r8x.dst : ROTATE_QI(r8x.src, imm8.const)", [1, 2], "rolb", 'b', "QImode", "gen_rtx_ROTATE"], + + ["r64x.dst : ROTATERT_DI(r64x.src, imm8.const)", [1, 3], "rorq", 'q', "DImode", "gen_rtx_ROTATERT"], + ["r32x.dst : ROTATERT_SI(r32x.src, imm8.const)", [1, 2], "rorl", 'l', "SImode", "gen_rtx_ROTATERT"], + ["r16x.dst : ROTATERT_HI(r16x.src, imm8.const)", [1, 3], "rorw", 'w', "HImode", "gen_rtx_ROTATERT"], + ["r8x.dst : ROTATERT_QI(r8x.src, imm8.const)", [1, 2], "rorb", 'b', "QImode", "gen_rtx_ROTATERT"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIR("$opcode", $const, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_REG($rtx_mode, $src->rx), + gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# +# Since we're shifting by 1 here, we can be confident that the CC is set correctly. +# Or can we? I don't understand this yet, so I'm going to leave out the ccr cases. +# + +plug.plugrule3("shift1r", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + # we start with ASHIFT + ["r64x.dst : ASHIFT_DI(r64x.src, CONST_P1)", [1, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT"], + ["rz32x.dst : ASHIFT_SI(r32x.src, CONST_P1)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + ["r16x.dst : ASHIFT_HI(r16x.src, CONST_P1)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["r8x.dst : ASHIFT_QI(r8x.src, CONST_P1)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # we can preserve the zero extension + ["rz16x.dst : ASHIFT_HI(rz16x.src, CONST_P1)", [1, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT"], + ["rz8x.dst : ASHIFT_QI(rz8x.src, CONST_P1)", [1, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT"], + + # it's sometimes worth doing this with a 32-bit op, though we lose the CC + ["r16x.dst : ASHIFT_HI(r16x.src, CONST_P1)", [1, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT"], + + + # ASHIFTRT is organized the same way + ["r64x.dst : ASHIFTRT_DI(r64x.src, CONST_P1)", [1, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT"], + ["rz32x.dst : ASHIFTRT_SI(r32x.src, CONST_P1)", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["r16x.dst : ASHIFTRT_HI(r16x.src, CONST_P1)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["r8x.dst : ASHIFTRT_QI(r8x.src, CONST_P1)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the zero extension + ["rz16x.dst : ASHIFTRT_HI(rz16x.src, CONST_P1)", [1, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT"], + ["rz8x.dst : ASHIFTRT_QI(rz8x.src, CONST_P1)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + # we can preserve the sign extension, using 32-bit op to save a byte on the 16-bit ops + ["rs16x.dst : ASHIFTRT_HI(rs16x.src, CONST_P1)", [1, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT"], + ["rs8x.dst : ASHIFTRT_QI(rs8x.src, CONST_P1)", [1, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT"], + + + # LSHIFTRT is organized the same way + ["r64x.dst : LSHIFTRT_DI(r64x.src, CONST_P1)", [1, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT"], + ["rz32x.dst : LSHIFTRT_SI(r32x.src, CONST_P1)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["r16x.dst : LSHIFTRT_HI(r16x.src, CONST_P1)", [1, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT"], + ["r8x.dst : LSHIFTRT_QI(r8x.src, CONST_P1)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + # we can preserve the zero-extension, using 32-bit op to save a byte on the 16-bit ops + ["rz16x.dst : LSHIFTRT_HI(rz16x.src, CONST_P1)", [1, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT"], + ["rz8x.dst : LSHIFTRT_QI(rz8x.src, CONST_P1)", [1, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT"], + + ["r64x.dst : ROTATE_DI(r64x.src, CONST_P1)", [1, 3], "rolq", 'q', "DImode", "gen_rtx_ROTATE"], + ["r32x.dst : ROTATE_SI(r32x.src, CONST_P1)", [1, 2], "roll", 'l', "SImode", "gen_rtx_ROTATE"], + ["r16x.dst : ROTATE_HI(r16x.src, CONST_P1)", [1, 3], "rolw", 'w', "HImode", "gen_rtx_ROTATE"], + ["r8x.dst : ROTATE_QI(r8x.src, CONST_P1)", [1, 2], "rolb", 'b', "QImode", "gen_rtx_ROTATE"], + ["r64x.dst : ROTATERT_DI(r64x.src, CONST_P1)", [1, 3], "rorq", 'q', "DImode", "gen_rtx_ROTATERT"], + ["r32x.dst : ROTATERT_SI(r32x.src, CONST_P1)", [1, 2], "rorl", 'l', "SImode", "gen_rtx_ROTATERT"], + ["r16x.dst : ROTATERT_HI(r16x.src, CONST_P1)", [1, 3], "rorw", 'w', "HImode", "gen_rtx_ROTATERT"], + ["r8x.dst : ROTATERT_QI(r8x.src, CONST_P1)", [1, 2], "rorb", 'b', "QImode", "gen_rtx_ROTATERT"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIR1("$opcode", $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_REG($rtx_mode, $src->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + +# +#------------------------------------------------------------ +# load effective address +# +# We can't use the obvious chain rule +# +# r64x : addr +# +# because we seem to get into some inconvenient cycle +# and some of the Node's fields get overwritten. +# +# Note that LEA doesn't set the condition code, so we +# always define an rx rather than a ccrx +# +# Since LEA is a 3-address instruction, there's no question +# of preserving zero or sign extensions. +# +# We use the 32-bit LEA for the 16-bit form, to save a byte, +# and for the 8-bit form, because there is no 8-bit LEA. +# +plug.plugrule3("leabd", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["r64x.dst : PLUS_DI(base64.base | disp.disp)", [1, 2], "leaq", 'q', "DImode"], + ["rz32x.dst : PLUS_SI(base32.base | disp.disp)", [1, 1], "leal", 'l', "SImode"], + ["r16x.dst : PLUS_HI(base16.base | disp.disp)", [1, 1], "leal", 'l', "SImode"], + ["r8x.dst : PLUS_QI(base8.base | disp.disp)", [1, 1], "leal", 'l', "SImode"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($base->freed > 0) { + $dst->extra = $base->extra; + $dst->freed = $base->freed - 1; + } + else { + $dst->extra = $base->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + }, + remat { + unsigned r = find($base->a.base); + if (r == REG_FP || r == REG_ARGP) + flags |= RHS_REMAT; + else + flags = 0; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, 0, 0, $disp->a.disp, $disp->a.string, + $dst->rx, '$schar'); + }, + emit { + rtx src = gen_rtx_PLUS($rtx_mode, $base->rtl, $disp->rtl); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +""") + +plug.plugrule3("leabi", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["r64x.dst : PLUS_DI(r64.base | r64.index)", [1, 3], "leaq", 'q', "DImode"], + ["rz32x.dst : PLUS_SI(r32.base | r32.index)", [1, 2], "leal", 'l', "SImode"], + ["r16x.dst : PLUS_HI(r16.base | r16.index)", [1, 2], "leal", 'l', "SImode"], + ["r8x.dst : PLUS_QI(r8.base | r8.index)", [1, 2], "leal", 'l', "SImode"], + + ["r64x.dst : MINUS_DI(r64.base, NEG_DI(r64.index))", [1, 3], "leaq", 'q', "DImode"], + ["rz32x.dst : MINUS_SI(r32.base, NEG_SI(r32.index))", [1, 2], "leal", 'l', "SImode"], + ["r16x.dst : MINUS_HI(r16.base, NEG_HI(r16.index))", [1, 2], "leal", 'l', "SImode"], + ["r8x.dst : MINUS_QI(r8.base, NEG_QI(r8.index))", [1, 2], "leal", 'l', "SImode"], + +], """ + $rule $cost + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->r)); + sparseset_set_bit(live, find($index->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($base->r); + memorable($index->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->r, true, $index->r, 1, 0, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src1 = gen_rtx_REG($rtx_mode, $base->r); + rtx src2 = gen_rtx_REG($rtx_mode, $index->r); + if ($base->a.base == $dst->rx) + src = gen_rtx_PLUS($rtx_mode, src1, src2); + else + src = gen_rtx_PLUS($rtx_mode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +""") + +plug.plugrule3("leabid", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["r64x.dst : PLUS_DI(base64.base | index64.index | disp.disp)", [2, 2], "leaq", 'q', "DImode"], + ["rz32x.dst : PLUS_SI(base32.base | index32.index | disp.disp)", [2, 1], "leal", 'l', "SImode"], + ["r16x.dst : PLUS_HI(base16.base | index16.index | disp.disp)", [2, 1], "leal", 'l', "SImode"], + ["r8x.dst : PLUS_QI(base8.base | index8.index | disp.disp)", [2, 1], "leal", 'l', "SImode"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->a.index)); + }, + remat { + flags = 0; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->a.index, $index->a.scale, $disp->a.disp, $disp->a.string, + $dst->rx, '$schar'); + }, + emit { + /* + * for some reason, 64 bit leaq must have the gcc tree + * built slightly differently, or the back end of gcc will + * not be able to match it. gen_rtx_addr will build a tree + * from two gen_rtx_PLUS, but with a different permutation + * than we use for the other kinds of lea instruction. + */ + const rtx src = ('$schar' == 'q') + ? gen_rtx_addr($rtx_mode, $base->rtl, $index->rtl, $disp->rtl) + : gen_rtx_PLUS(SImode, gen_rtx_PLUS($rtx_mode, $index->rtl, $base->rtl), $disp->rtl) + ; + const rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + + +# +# We need to exercise some care here to be sure that +# mcon*disp doesn't overflow it's allotted size. +# + +plug.plugrule3("leabis", [ + ["rule", "cost", "opcode", "schar", "scale"], + + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm5.const) | CONST_P8))", [2, 2], "leaq", 'q', 8], + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm29.const) | CONST_P8))", [2, 2], "leaq", 'q', 8], + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm6.const) | CONST_P4))", [2, 2], "leaq", 'q', 4], + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm30.const) | CONST_P4))", [2, 2], "leaq", 'q', 4], + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm7.const) | CONST_P2))", [2, 2], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm31.const) | CONST_P2))", [2, 2], "leaq", 'q', 2], + + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm5.const), CONST_P3))", [2, 2], "leaq", 'q', 8], + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm29.const), CONST_P3))", [2, 2], "leaq", 'q', 8], + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm6.const), CONST_P2))", [2, 2], "leaq", 'q', 4], + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm30.const), CONST_P2))", [2, 2], "leaq", 'q', 4], + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm7.const), CONST_P1))", [2, 2], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm31.const), CONST_P1))", [2, 2], "leaq", 'q', 2], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($index->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->r, $scale, $const->val*$scale, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $index->r); + rtx src = gen_rtx_addr(DImode, $base->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT($scale)), + GEN_INT($const->val*$scale)); + rtx dst = gen_rtx_REG(DImode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + +plug.plugrule3("leabis1", [ + ["rule", "cost", "opcode", "schar", "scale"], + + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm5.const) | CONST_P8))", [2, 1], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm29.const) | CONST_P8))", [2, 1], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm5.const) | CONST_P8))", [2, 1], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm13.const) | CONST_P8))", [2, 1], "leal", 'l', 8], + ["r8x.dst : PLUS_QI(base8.base | MULT_QI(PLUS_QI(r8.index | imm5.const) | CONST_P8))", [2, 1], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm6.const) | CONST_P4))", [2, 1], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm30.const) | CONST_P4))", [2, 1], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm6.const) | CONST_P4))", [2, 1], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm14.const) | CONST_P4))", [2, 1], "leal", 'l', 4], + ["r8x.dst : PLUS_QI(base8.base | MULT_QI(PLUS_QI(r8.index | imm6.const) | CONST_P4))", [2, 1], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm7.const) | CONST_P2))", [2, 1], "leal", 'l', 2], + ["rz32x.dst : PLUS_SI(base32.base | MULT_SI(PLUS_SI(r32.index | imm31.const) | CONST_P2))", [2, 1], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm7.const) | CONST_P2))", [2, 1], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | MULT_HI(PLUS_HI(r16.index | imm15.const) | CONST_P2))", [2, 1], "leal", 'l', 2], + ["r8x.dst : PLUS_QI(base8.base | MULT_QI(PLUS_QI(r8.index | imm7.const) | CONST_P2))", [2, 1], "leal", 'l', 2], + + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm5.const), CONST_P3))", [2, 1], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm29.const), CONST_P3))", [2, 1], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm5.const), CONST_P3))", [2, 1], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm13.const), CONST_P3))", [2, 1], "leal", 'l', 8], + ["r8x.dst : PLUS_QI(base8.base | ASHIFT_QI(PLUS_QI(r8.index | imm5.const), CONST_P3))", [2, 1], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm6.const), CONST_P2))", [2, 1], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm30.const), CONST_P2))", [2, 1], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm6.const), CONST_P2))", [2, 1], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm14.const), CONST_P2))", [2, 1], "leal", 'l', 4], + ["r8x.dst : PLUS_QI(base8.base | ASHIFT_QI(PLUS_QI(r8.index | imm6.const), CONST_P2))", [2, 1], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm7.const), CONST_P1))", [2, 1], "leal", 'l', 2], + ["rz32x.dst : PLUS_SI(base32.base | ASHIFT_SI(PLUS_SI(r32.index | imm31.const), CONST_P1))", [2, 1], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm7.const), CONST_P1))", [2, 1], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | ASHIFT_HI(PLUS_HI(r16.index | imm15.const), CONST_P1))", [2, 1], "leal", 'l', 2], + ["r8x.dst : PLUS_QI(base8.base | ASHIFT_QI(PLUS_QI(r8.index | imm7.const), CONST_P1))", [2, 1], "leal", 'l', 2], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($index->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->r, $scale, $const->val*$scale, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $index->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT($scale)), + $base->rtl), + GEN_INT($const->val*$scale)); + rtx dst = gen_rtx_REG(SImode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + + +# The costs here are strange because there are 2 immediates feeding into each rule +plug.plugrule3("leabis2", [ + ["rule", "cost", "opcode", "schar", "scale"], + + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm4.const2) | CONST_P8))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm28.const2) | CONST_P8))", [2, 0], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm5.const2) | CONST_P4))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm29.const2) | CONST_P4))", [2, 0], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm6.const2) | CONST_P2))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm30.const2) | CONST_P2))", [2, 0], "leaq", 'q', 2], + + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm4.const2), CONST_P3))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm28.const2), CONST_P3))", [2, 0], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm5.const2), CONST_P2))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm29.const2), CONST_P2))", [2, 0], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm6.const2), CONST_P1))", [2, 1], "leaq", 'q', 2], + ["r64x.dst : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm30.const2), CONST_P1))", [2, 0], "leaq", 'q', 2], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($index->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->r, $scale, $const1->val + $const2->val*$scale, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $index->r); + rtx src = gen_rtx_addr(DImode, $base->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT($scale)), + GEN_INT($const1->val + $const2->val*$scale)); + rtx dst = gen_rtx_REG(DImode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + + +# The costs here are strange because there are 2 immediates feeding into each rule +plug.plugrule3("leabis1", [ + ["rule", "cost", "opcode", "schar", "scale"], + + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | MULT_SI(PLUS_SI(r32.index | imm4.const2) | CONST_P8))", [2, 0], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | MULT_SI(PLUS_SI(r32.index | imm28.const2) | CONST_P8))", [2, 0], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | MULT_HI(PLUS_HI(r16.index | imm5.const2) | CONST_P8))", [2, 0], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | MULT_HI(PLUS_HI(r16.index | imm13.const2) | CONST_P8))", [2, 0], "leal", 'l', 8], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | MULT_QI(PLUS_QI(r8.index | imm5.const2) | CONST_P8))", [2, 0], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | MULT_SI(PLUS_SI(r32.index | imm6.const2) | CONST_P4))", [2, 0], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | MULT_SI(PLUS_SI(r32.index | imm30.const2) | CONST_P4))", [2, 0], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | MULT_HI(PLUS_HI(r16.index | imm6.const2) | CONST_P4))", [2, 0], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | MULT_HI(PLUS_HI(r16.index | imm14.const2) | CONST_P4))", [2, 0], "leal", 'l', 4], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | MULT_QI(PLUS_QI(r8.index | imm6.const2) | CONST_P4))", [2, 0], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | MULT_SI(PLUS_SI(r32.index | imm7.const2) | CONST_P2))", [2, 0], "leal", 'l', 2], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | MULT_SI(PLUS_SI(r32.index | imm31.const2) | CONST_P2))", [2, 0], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | MULT_HI(PLUS_HI(r16.index | imm7.const2) | CONST_P2))", [2, 0], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | MULT_HI(PLUS_HI(r16.index | imm15.const2) | CONST_P2))", [2, 0], "leal", 'l', 2], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | MULT_QI(PLUS_QI(r8.index | imm7.const2) | CONST_P2))", [2, 0], "leal", 'l', 2], + + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm5.const2), CONST_P3))", [2, 0], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm29.const2), CONST_P3))", [2, 0], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm5.const2), CONST_P3))", [2, 0], "leal", 'l', 8], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm13.const2), CONST_P3))", [2, 0], "leal", 'l', 8], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | ASHIFT_QI(PLUS_QI(r8.index | imm5.const2), CONST_P3))", [2, 0], "leal", 'l', 8], + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm6.const2), CONST_P2))", [2, 0], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm30.const2), CONST_P2))", [2, 0], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm6.const2), CONST_P2))", [2, 0], "leal", 'l', 4], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm14.const2), CONST_P2))", [2, 0], "leal", 'l', 4], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | ASHIFT_QI(PLUS_QI(r8.index | imm6.const2), CONST_P2))", [2, 0], "leal", 'l', 4], + ["rz32x.dst : PLUS_SI(base32.base | imm7.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm7.const2), CONST_P1))", [2, 0], "leal", 'l', 2], + ["rz32x.dst : PLUS_SI(base32.base | imm31.const1 | ASHIFT_SI(PLUS_SI(r32.index | imm31.const2), CONST_P1))", [2, 0], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | imm7.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm7.const2), CONST_P1))", [2, 0], "leal", 'l', 2], + ["r16x.dst : PLUS_HI(base16.base | imm15.const1 | ASHIFT_HI(PLUS_HI(r16.index | imm15.const2), CONST_P1))", [2, 0], "leal", 'l', 2], + ["r8x.dst : PLUS_QI(base8.base | imm7.const1 | ASHIFT_QI(PLUS_QI(r8.index | imm7.const2), CONST_P1))", [2, 0], "leal", 'l', 2], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($index->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->r, $scale, $const1->val + $const2->val*$scale, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $index->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT($scale)), + $base->rtl), + GEN_INT($const1->val + $const2->val*$scale)); + rtx dst = gen_rtx_REG(SImode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + + + + +plug.plugrule3("leabii", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "scale_factor", "order_key"], + + ["r64x.dst : PLUS_DI(base64.base | index64.index)", [2, 2], "leaq", 'q', "DImode", 0, 1], + ["rz32x.dst : PLUS_SI(base32.base | index32.index)", [2, 1], "leal", 'l', "SImode", 0, 0], + ["r16x.dst : PLUS_HI(base16.base | index16.index)", [2, 1], "leal", 'l', "SImode", 0, 0], + ["r8x.dst : PLUS_QI(base8.base | index8.index)", [2, 1], "leal", 'l', "SImode", 0, 0], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($dst, $base, $index, kid, kids); + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($base->a.base)); + sparseset_set_bit(live, find($index->a.index)); + }, + remat { + flags = 0; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + $base->a.base, true, $index->a.index, $index->a.scale, 0, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src = $order_key /* 64-bit RTL shape weirdness */ + ? gen_rtx_PLUS($rtx_mode, $base->rtl, $index->rtl) + : gen_rtx_PLUS($rtx_mode, $index->rtl, $base->rtl) + ; + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + +plug.plugrule3("leabic", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "scale_factor"], + + ["r64x.dst : PLUS_DI(index64.index | imm32.const)", [2, 3], "leaq", 'q', "DImode", 0], + ["rz32x.dst : PLUS_SI(index32.index | imm32.const)", [2, 2], "leal", 'l', "SImode", 0], + ["r16x.dst : PLUS_HI(index16.index | imm32.const)", [2, 2], "leal", 'l', "SImode", 0], + ["r8x.dst : PLUS_QI(index8.index | imm32.const)", [2, 2], "leal", 'l', "SImode", 0], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($index->freed > 0) { + $dst->extra = $index->extra; + $dst->freed = $index->freed - 1; + } + else { + $dst->extra = $index->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($index->a.index)); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + 0, false, $index->a.index, $index->a.scale, $const->val, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src = gen_rtx_PLUS($rtx_mode, $index->rtl, $const->rtl); + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + +plug.plugrule3("leai", [ + ["rule", "cost", "opcode", "schar", "scale_factor", "rtx_mode"], + + ["r64x.dst : index64.index", [2, 7], "leaq", 'q', 0, "DImode"], + ["rz32x.dst : index32.index", [2, 6], "leal", 'l', 0, "SImode"], + ["r16x.dst : index16.index", [2, 6], "leal", 'l', 0, "SImode"], + ["r8x.dst : index8.index", [2, 6], "leal", 'l', 0, "SImode"], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($index->freed > 0) { + $dst->extra = $index->extra; + $dst->freed = $index->freed - 1; + } + else { + $dst->extra = $index->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($index->a.index)); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dumpMbidR("$opcode", + 0, false, $index->a.index, $index->a.scale, 0, NULL, + $dst->rx, '$schar'); + }, + emit { + rtx src = $index->rtl; + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +""") + + +#---------------------------------------------------------------- +# Sign and zero extension instructions. +# These do not affect the condition codes. +# + +plug.plugrule3("loadcvt", [ + ["rule", "cost", "opcode", "dst_schar", "src_schar", "dst_mode", "src_mode", "rtx_builder", "move_flag"], + + ["r64x.dst : SIGN_EXTEND_DI(r32.src)", [1, 3], "movslq", 'q', 'l', "DImode", "SImode", "gen_rtx_SIGN_EXTEND", 0], + ["r64x.dst : SIGN_EXTEND_DI(r16.src)", [1, 4], "movswq", 'q', 'w', "DImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["r64x.dst : SIGN_EXTEND_DI(r8.src)", [1, 4], "movsbq", 'q', 'b', "DImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["rz32x.dst : SIGN_EXTEND_SI(r16.src)", [1, 3], "movswl", 'l', 'w', "SImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["rz32x.dst : SIGN_EXTEND_SI(r8.src)", [1, 3], "movsbl", 'l', 'b', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["r16x.dst : SIGN_EXTEND_HI(r8.src)", [1, 4], "movsbw", 'w', 'b', "HImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + + # we can save a byte for the 16-bit case + ["rs16x.dst : SIGN_EXTEND_HI(r8.src)", [1, 3], "movsbl", 'l', 'b', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + + # Note the special handling of the rule below. + # There is no movzlq instruction, but the 32-bit instruction automatically zero extends to 64 bits. + ["r64x.dst : ZERO_EXTEND_DI(r32.src)", [1, 2], "movl", 'l', 'l', "SImode", "SImode", "gen_rtx_ZERO_EXTEND", 1], + ["r64x.dst : ZERO_EXTEND_DI(r16.src)", [1, 4], "movzwq", 'q', 'w', "DImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["r64x.dst : ZERO_EXTEND_DI(r8.src)", [1, 4], "movzbq", 'q', 'b', "DImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz32x.dst : ZERO_EXTEND_SI(r16.src)", [1, 3], "movzwl", 'l', 'w', "SImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz32x.dst : ZERO_EXTEND_SI(r8.src)", [1, 3], "movzbl", 'l', 'b', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["r16x.dst : ZERO_EXTEND_HI(r8.src)", [1, 4], "movzbw", 'w', 'b', "HImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + + # we can save a byte for the 16-bit case + ["rz16x.dst : ZERO_EXTEND_HI(r8.src)", [1, 3], "movzbl", 'l', 'b', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + +], """ + $rule $cost + supairs { + if ($dst->freed > 0) + $dst->freed--; + else + $dst->extra++; + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + sparseset_set_bit(live, find($src->r)); + }, + costs { + memorable($src->r); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG($dst_mode, $dst->rx); + rtx src; + if ($move_flag) + src = gen_rtx_REG($src_mode, $src->r); + else + src = $rtx_builder($dst_mode, gen_rtx_REG($src_mode, $src->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("$opcode", $src->r, '$src_schar', $dst->rx, '$dst_schar'); + }; + +""") + + +# The thought behind these next few rules was that we could do an extension +# while making a copy, if it was helpful. Unfortunately, it +# violates conventions for handling r and rx in the same node. +# +# rz32x : r32 [1, 2] +# rz16x : r16 [1, 3] +# rz8x : r8 [1, 3] +# rs16x : r16 [1, 3] +# rs8x : r8 [1, 3] + + + +plug.plugrule3("movcvt", [ + ["rule", "cost", "opcode", "schar", "dst_mode", "src_mode", "rtx_builder", "move_flag"], + + ["r64x.dst : SIGN_EXTEND_DI(MEM_SI(addr))", [4, 2], "movslq", 'q', "DImode", "SImode", "gen_rtx_SIGN_EXTEND", 0], + ["r64x.dst : SIGN_EXTEND_DI(MEM_HI(addr))", [4, 3], "movswq", 'q', "DImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["r64x.dst : SIGN_EXTEND_DI(MEM_QI(addr))", [4, 3], "movsbq", 'q', "DImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["rz32x.dst : SIGN_EXTEND_SI(MEM_HI(addr))", [4, 2], "movswl", 'l', "SImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["rz32x.dst : SIGN_EXTEND_SI(MEM_QI(addr))", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["r16x.dst : SIGN_EXTEND_HI(MEM_QI(addr))", [4, 3], "movsbw", 'w', "HImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + + # we can save a byte for the 16-bit case + ["rs16x.dst : SIGN_EXTEND_HI(MEM_QI(addr))", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + + # Note the special handling of the rule below. + # There is no movzlq instruction, but the 32-bit instruction automatically zero extends to 64 bits. + ["r64x.dst : ZERO_EXTEND_DI(MEM_SI(addr))", [4, 1], "movl", 'l', "SImode", "SImode", "gen_rtx_ZERO_EXTEND", 1], + ["r64x.dst : ZERO_EXTEND_DI(MEM_HI(addr))", [4, 3], "movzwq", 'q', "DImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["r64x.dst : ZERO_EXTEND_DI(MEM_QI(addr))", [4, 3], "movzbq", 'q', "DImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz32x.dst : ZERO_EXTEND_SI(MEM_HI(addr))", [4, 2], "movzwl", 'l', "SImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz32x.dst : ZERO_EXTEND_SI(MEM_QI(addr))", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["r16x.dst : ZERO_EXTEND_HI(MEM_QI(addr))", [4, 3], "movzbw", 'w', "HImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + + # we can save a byte for the 16-bit case + ["rz16x.dst : ZERO_EXTEND_HI(MEM_QI(addr))", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + + + # the rules below are implemented using the sign-extension instructions + ["rs16x.dst : MEM_HI(addr)", [4, 2], "movswl", 'l', "SImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs8x.dst : MEM_QI(addr)", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs16x.dst : SUBREG_HI(MEM_DI(addr), CONST_0)", [4, 2], "movswl", 'l', "SImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs16x.dst : SUBREG_HI(MEM_SI(addr), CONST_0)", [4, 2], "movswl", 'l', "SImode", "HImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs8x.dst : SUBREG_QI(MEM_DI(addr), CONST_0)", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs8x.dst : SUBREG_QI(MEM_SI(addr), CONST_0)", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + ["rs8x.dst : SUBREG_QI(MEM_HI(addr), CONST_0)", [4, 2], "movsbl", 'l', "SImode", "QImode", "gen_rtx_SIGN_EXTEND", 0], + + # the rules below are implemented using the zero-extension instructions + ["rz16x.dst : MEM_HI(addr)", [4, 2], "movzwl", 'l', "SImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz8x.dst : MEM_QI(addr)", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz16x.dst : SUBREG_HI(MEM_DI(addr), CONST_0)", [4, 2], "movzwl", 'l', "SImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz16x.dst : SUBREG_HI(MEM_SI(addr), CONST_0)", [4, 2], "movzwl", 'l', "SImode", "HImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz8x.dst : SUBREG_QI(MEM_DI(addr), CONST_0)", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz8x.dst : SUBREG_QI(MEM_SI(addr), CONST_0)", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + ["rz8x.dst : SUBREG_QI(MEM_HI(addr), CONST_0)", [4, 2], "movzbl", 'l', "SImode", "QImode", "gen_rtx_ZERO_EXTEND", 0], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($addr->freed > 0) { + $dst->extra = $addr->extra; + $dst->freed = $addr->freed - 1; + } + else { + $dst->extra = $addr->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpMR("$opcode", $addr, $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG($dst_mode, $dst->rx); + rtx src; + if ($move_flag) + src = gen_rtx_MEM($src_mode, $addr->rtl); + else + src = $rtx_builder($dst_mode, gen_rtx_MEM($src_mode, $addr->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +#----------------------------------------------------------- +# loads, and load-like instructions +# +# note that the 8 and 16-bit loads are handled above, +# since we may as well sign or zero-extend while loading +# + +plug.plugrule3("loadbasic", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_code"], + + ["r64x.dst : MEM_DI(addr)", [3, 2], "movq", 'q', "DImode", 0], + ["rz32x.dst : MEM_SI(addr)", [3, 1], "movl", 'l', "SImode", 0], + ["rz32x.dst : SUBREG_SI(MEM_DI(addr), CONST_0)", [3, 1], "movl", 'l', "SImode", 0], + + ["r64x.dst : BSF_DI( MEM_DI(addr))", [3, 2], "bsfq", 'q', "DImode", 1], + ["rz32x.dst : BSF_SI( MEM_SI(addr))", [3, 1], "bsfl", 'l', "SImode", 1], + ["rz32x.dst : BSF_SI(SUBREG_SI(MEM_DI(addr), CONST_0))", [3, 1], "bsfl", 'l', "SImode", 1], + + ["r64x.dst : BSR_DI( MEM_DI(addr))", [3, 2], "bsrq", 'q', "DImode", 1], + ["rz32x.dst : BSR_SI( MEM_SI(addr))", [3, 1], "bsrl", 'l', "SImode", 1], + ["rz32x.dst : BSR_SI(SUBREG_SI(MEM_DI(addr), CONST_0))", [3, 1], "bsrl", 'l', "SImode", 1], + + # + # TODO: add CLZ and POPCOUNT from memory + # + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($addr->freed > 0) { + $dst->extra = $addr->extra; + $dst->freed = $addr->freed - 1; + } + else { + $dst->extra = $addr->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpMR("$opcode", $addr, $dst->rx, '$schar'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM($rtx_mode, $addr->rtl); + const rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# +# TODO: this block of rules will need to be broken up into other smaller blocks +# in order to correctly do the semantics of immediate vs register vs memory operands +# and also to handle different arities of the children. +# +plug.plugrule3("memop_unary", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + [" rcc.dst : MEM_NEG_DI(MEM_DI(addr))", [4, 2], "negq", 'q', "DImode", "gen_rtx_NEG", 0], + [" rcc.dst : MEM_NEG_SI(MEM_SI(addr))", [4, 1], "negl", 'l', "SImode", "gen_rtx_NEG", 0], + [" rcc.dst : MEM_NEG_HI(MEM_HI(addr))", [4, 2], "negw", 'w', "HImode", "gen_rtx_NEG", 0], + [" rcc.dst : MEM_NEG_QI(MEM_QI(addr))", [4, 1], "negb", 'b', "QImode", "gen_rtx_NEG", 0], + + ["nocc.dst : MEM_NOT_DI(MEM_DI(addr))", [4, 2], "notq", 'q', "DImode", "gen_rtx_NOT", 1], + ["nocc.dst : MEM_NOT_SI(MEM_SI(addr))", [4, 1], "notl", 'l', "SImode", "gen_rtx_NOT", 1], + ["nocc.dst : MEM_NOT_HI(MEM_HI(addr))", [4, 2], "notw", 'w', "HImode", "gen_rtx_NOT", 1], + ["nocc.dst : MEM_NOT_QI(MEM_QI(addr))", [4, 1], "notb", 'b', "QImode", "gen_rtx_NOT", 1], + +], """ + $rule $cost + build { + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpM("$opcode", $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem /* NOTE: dag */ + ) + )); + }; +""") + +plug.plugrule3("mem_mathop_reg", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + ["rcc.dst : MEM_PLUS_DI(MEM_DI(addr), NEG_DI(r64.src))", [4, 2], "subq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_SI(MEM_SI(addr), NEG_DI(r32.src))", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_HI(MEM_HI(addr), NEG_DI(r16.src))", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_QI(MEM_QI(addr), NEG_DI(r8.src))", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS", 0], + + ["rcc.dst : MEM_MINUS_DI(MEM_DI(addr), NEG_DI(r64.src))", [4, 2], "addq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_SI(MEM_SI(addr), NEG_DI(r32.src))", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_HI(MEM_HI(addr), NEG_DI(r16.src))", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_QI(MEM_QI(addr), NEG_DI(r8.src))", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS", 0], + + ["rcc.dst : MEM_IOR_DI (MEM_DI(addr), r64.src)", [4, 2], "orq", 'q', "DImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_SI (MEM_SI(addr), r32.src)", [4, 1], "orl", 'l', "SImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_HI (MEM_HI(addr), r16.src)", [4, 2], "orw", 'w', "HImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_QI (MEM_QI(addr), r8.src)", [4, 1], "orb", 'b', "QImode", "gen_rtx_IOR", 0], + + ["rcc.dst : MEM_XOR_DI (MEM_DI(addr), r64.src)", [4, 2], "xorq", 'q', "DImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_SI (MEM_SI(addr), r32.src)", [4, 1], "xorl", 'l', "SImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_HI (MEM_HI(addr), r16.src)", [4, 2], "xorw", 'w', "HImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_QI (MEM_QI(addr), r8.src)", [4, 1], "xorb", 'b', "QImode", "gen_rtx_XOR", 0], + + ["rcc.dst : MEM_PLUS_DI (MEM_DI(addr), r64.src)", [4, 2], "addq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_SI (MEM_SI(addr), r32.src)", [4, 1], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_HI (MEM_HI(addr), r16.src)", [4, 2], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_QI (MEM_QI(addr), r8.src)", [4, 1], "addb", 'b', "QImode", "gen_rtx_PLUS", 0], + + ["rcc.dst : MEM_MINUS_DI (MEM_DI(addr), r64.src)", [4, 2], "subq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_SI (MEM_SI(addr), r32.src)", [4, 1], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_HI (MEM_HI(addr), r16.src)", [4, 2], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_QI (MEM_QI(addr), r8.src)", [4, 1], "subb", 'b', "QImode", "gen_rtx_MINUS", 0], + + ["rcc.dst : MEM_AND_DI (MEM_DI(addr), r64.src)", [4, 2], "andq", 'q', "DImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_SI (MEM_SI(addr), r32.src)", [4, 1], "andl", 'l', "SImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_HI (MEM_HI(addr), r16.src)", [4, 2], "andw", 'w', "HImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_QI (MEM_QI(addr), r8.src)", [4, 1], "andb", 'b', "QImode", "gen_rtx_AND", 0], + +], """ + $rule $cost + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($src->r); + }, + build { + sparseset_set_bit(live, find($src->r)); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpRM("$opcode", $src->r, '$schar', $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem, /* NOTE: dag */ + gen_rtx_REG($rtx_mode, $src->r) + ) + )); + }; +""") + +plug.plugrule3("mem_shiftop_reg", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + # + # If there must be a copy, then we want to be sure to copy with + # a movl instruction where we can; 8- and 16-bit moves are expensive. + # The 16-bit move is bigger; both are slower. + # + # By saying "r8x", we think it's more likely that the initial copy into RCX + # will be coalesced. Given this, we'll assume the coalesce will succeed + # and set the costs accordingly. + # + + # + # The shifts and rotates are shown here as clobbering the condition codes. + # even though the condition codes will not get clobbered if the shift count is 0. + # We need to produce RTX that encodes condition codes being clobbered + # so that the downstream gcc+RTL consumer will be happy. + # + ["rcc.dst : MEM_ASHIFT_DI (MEM_DI(addr), r8x.src)", [4, 2], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI (MEM_SI(addr), r8x.src)", [4, 1], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI (MEM_HI(addr), r8x.src)", [4, 2], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI (MEM_QI(addr), r8x.src)", [4, 1], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI (MEM_DI(addr), r8x.src)", [4, 2], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI (MEM_SI(addr), r8x.src)", [4, 1], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI (MEM_HI(addr), r8x.src)", [4, 2], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI (MEM_QI(addr), r8x.src)", [4, 1], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), r8x.src)", [4, 2], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), r8x.src)", [4, 1], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), r8x.src)", [4, 2], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), r8x.src)", [4, 1], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), r8x.src)", [4, 2], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), r8x.src)", [4, 1], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), r8x.src)", [4, 2], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), r8x.src)", [4, 1], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), r8x.src)", [4, 2], "rorq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), r8x.src)", [4, 1], "rorl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), r8x.src)", [4, 2], "rorw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), r8x.src)", [4, 1], "rorb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + + + ["rcc.dst : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "rorq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "rorl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 2], "rorw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r64x.src, CONST_0))", [4, 1], "rorb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + + + ["rcc.dst : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "rorq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "rorl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 2], "rorw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r32x.src, CONST_0))", [4, 1], "rorb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + + + ["rcc.dst : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "rorq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "rorl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 2], "rorw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r16x.src, CONST_0))", [4, 1], "rorb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + +], """ + $rule $cost + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src->rx, REG_RCX); + }, + build { + add_addr(live, $addr); + add_copy_edges(REG_RCX, $src->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($src->rx); /* must be in a register */ + cost_copy(REG_RCX, $src->rx); + }, + debug { + dumpRM("$opcode", $src->rx, '$schar', $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $src->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +""") + +plug.plugrule3("mem_arithop_imm", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + ["rcc.dst : MEM_PLUS_DI(MEM_DI(addr), imm32.const)", [4, 3], "addq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_SI(MEM_SI(addr), imm32.const)", [4, 2], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_HI(MEM_HI(addr), imm16.const)", [4, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_QI(MEM_QI(addr), imm8.const)", [4, 2], "addb", 'b', "QImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_DI(MEM_DI(addr), imm8.const)", [4, 3], "addq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_SI(MEM_SI(addr), imm8.const)", [4, 2], "addl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_HI(MEM_HI(addr), imm8.const)", [4, 3], "addw", 'w', "HImode", "gen_rtx_PLUS", 0], + + ["rcc.dst : MEM_MINUS_DI(MEM_DI(addr), imm32.const)", [4, 3], "subq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_SI(MEM_SI(addr), imm32.const)", [4, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_HI(MEM_HI(addr), imm16.const)", [4, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_QI(MEM_QI(addr), imm8.const)", [4, 2], "subb", 'b', "QImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_DI(MEM_DI(addr), imm8.const)", [4, 3], "subq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_SI(MEM_SI(addr), imm8.const)", [4, 2], "subl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_HI(MEM_HI(addr), imm8.const)", [4, 3], "subw", 'w', "HImode", "gen_rtx_MINUS", 0], + + ["rcc.dst : MEM_AND_DI(MEM_DI(addr), imm32.const)", [4, 3], "andq", 'q', "DImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_SI(MEM_SI(addr), imm32.const)", [4, 2], "andl", 'l', "SImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_HI(MEM_HI(addr), imm16.const)", [4, 3], "andw", 'w', "HImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_QI(MEM_QI(addr), imm8.const)", [4, 2], "andb", 'b', "QImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_DI(MEM_DI(addr), imm8.const)", [4, 3], "andq", 'q', "DImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_SI(MEM_SI(addr), imm8.const)", [4, 2], "andl", 'l', "SImode", "gen_rtx_AND", 0], + ["rcc.dst : MEM_AND_HI(MEM_HI(addr), imm8.const)", [4, 3], "andw", 'w', "HImode", "gen_rtx_AND", 0], + + ["rcc.dst : MEM_IOR_DI(MEM_DI(addr), imm32.const)", [4, 3], "orq", 'q', "DImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_SI(MEM_SI(addr), imm32.const)", [4, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_HI(MEM_HI(addr), imm16.const)", [4, 3], "orw", 'w', "HImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_QI(MEM_QI(addr), imm8.const)", [4, 2], "orb", 'b', "QImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_DI(MEM_DI(addr), imm8.const)", [4, 3], "orq", 'q', "DImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_SI(MEM_SI(addr), imm8.const)", [4, 2], "orl", 'l', "SImode", "gen_rtx_IOR", 0], + ["rcc.dst : MEM_IOR_HI(MEM_HI(addr), imm8.const)", [4, 3], "orw", 'w', "HImode", "gen_rtx_IOR", 0], + + ["rcc.dst : MEM_XOR_DI(MEM_DI(addr), imm32.const)", [4, 3], "xorq", 'q', "DImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_SI(MEM_SI(addr), imm32.const)", [4, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_HI(MEM_HI(addr), imm16.const)", [4, 3], "xorw", 'w', "HImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_QI(MEM_QI(addr), imm8.const)", [4, 2], "xorb", 'b', "QImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_DI(MEM_DI(addr), imm8.const)", [4, 3], "xorq", 'q', "DImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_SI(MEM_SI(addr), imm8.const)", [4, 2], "xorl", 'l', "SImode", "gen_rtx_XOR", 0], + ["rcc.dst : MEM_XOR_HI(MEM_HI(addr), imm8.const)", [4, 3], "xorw", 'w', "HImode", "gen_rtx_XOR", 0], + + # + # shifts and rotates of memory are marked as clobbering the condition codes + # contrast this with shifts and rotates of registers, + # which are marked as NOT clobbering the condition codes + # we must generate RTL that encodes clobbering the condition codes, + # otherwise the gcc+rtl back end will choke. + # + ["rcc.dst : MEM_ASHIFT_DI(MEM_DI(addr), imm8.const)", [4, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI(MEM_SI(addr), imm8.const)", [4, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI(MEM_HI(addr), imm8.const)", [4, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI(MEM_QI(addr), imm8.const)", [4, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI(MEM_DI(addr), imm8.const)", [4, 3], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI(MEM_SI(addr), imm8.const)", [4, 2], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI(MEM_HI(addr), imm8.const)", [4, 3], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI(MEM_QI(addr), imm8.const)", [4, 2], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), imm8.const)", [4, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), imm8.const)", [4, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), imm8.const)", [4, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), imm8.const)", [4, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), imm8.const)", [4, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), imm8.const)", [4, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), imm8.const)", [4, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), imm8.const)", [4, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), imm8.const)", [4, 3], "rorq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), imm8.const)", [4, 2], "rorl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), imm8.const)", [4, 3], "rorw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), imm8.const)", [4, 2], "rorb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + +], """ + $rule $cost + supairs { + /*TODO*/ + }, + build { + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpIM("$opcode", $const, $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($const->val, $const->a.string, $const->rtl) + ) + )); + }; +""") + +# +# increment/decrement memory +# the condition codes are marked as clobbered, and we generate RTX that reflects that. +# Contrast that with shift/rotate by 1. +# +plug.plugrule3("mem_arithop_imm_1", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + ["rcc.dst : MEM_PLUS_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "incq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "incl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "incw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_PLUS_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "incb", 'b', "QImode", "gen_rtx_PLUS", 0], + + ["rcc.dst : MEM_PLUS_DI(MEM_DI(addr), CONST_N1.const)", [4, 3], "decq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_SI(MEM_SI(addr), CONST_N1.const)", [4, 2], "decl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_HI(MEM_HI(addr), CONST_N1.const)", [4, 3], "decw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_PLUS_QI(MEM_QI(addr), CONST_N1.const)", [4, 2], "decb", 'b', "QImode", "gen_rtx_MINUS", 0], + + ["rcc.dst : MEM_MINUS_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "decq", 'q', "DImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "decl", 'l', "SImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "decw", 'w', "HImode", "gen_rtx_MINUS", 0], + ["rcc.dst : MEM_MINUS_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "decb", 'b', "QImode", "gen_rtx_MINUS", 0], + + ["rcc.dst : MEM_MINUS_DI(MEM_DI(addr), CONST_N1.const)", [4, 3], "incq", 'q', "DImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_SI(MEM_SI(addr), CONST_N1.const)", [4, 2], "incl", 'l', "SImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_HI(MEM_HI(addr), CONST_N1.const)", [4, 3], "incw", 'w', "HImode", "gen_rtx_PLUS", 0], + ["rcc.dst : MEM_MINUS_QI(MEM_QI(addr), CONST_N1.const)", [4, 2], "incb", 'b', "QImode", "gen_rtx_PLUS", 0], + +], """ + $rule $cost + supairs { + /*TODO*/ + }, + build { + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpM("$opcode", $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +""") + +# +# Shift or rotate memory by one, which is a special case in the ISA. +# The condition codes are clobbered by the hardware, +# and we have to express that in the RTX we produce. +# Note that for shifts with a register destination the condition codes +# are also clobbered, BUT the rtx we produce doesn't encode clobbered condition codes. +# +plug.plugrule3("mem_shiftop_imm_1", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder", "is_nocc"], + + ["rcc.dst : MEM_ASHIFT_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "salq", 'q', "DImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "sall", 'l', "SImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "salw", 'w', "HImode", "gen_rtx_ASHIFT", 0], + ["rcc.dst : MEM_ASHIFT_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "salb", 'b', "QImode", "gen_rtx_ASHIFT", 0], + + ["rcc.dst : MEM_ROTATE_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "rolq", 'q', "DImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "roll", 'l', "SImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "rolw", 'w', "HImode", "gen_rtx_ROTATE", 0], + ["rcc.dst : MEM_ROTATE_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "rolb", 'b', "QImode", "gen_rtx_ROTATE", 0], + + ["rcc.dst : MEM_LSHIFTRT_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "shrq", 'q', "DImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "shrl", 'l', "SImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "shrw", 'w', "HImode", "gen_rtx_LSHIFTRT", 0], + ["rcc.dst : MEM_LSHIFTRT_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "shrb", 'b', "QImode", "gen_rtx_LSHIFTRT", 0], + + ["rcc.dst : MEM_ASHIFTRT_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "sarq", 'q', "DImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "sarl", 'l', "SImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "sarw", 'w', "HImode", "gen_rtx_ASHIFTRT", 0], + ["rcc.dst : MEM_ASHIFTRT_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "sarb", 'b', "QImode", "gen_rtx_ASHIFTRT", 0], + + ["rcc.dst : MEM_ROTATERT_DI(MEM_DI(addr), CONST_P1.const)", [4, 3], "sarq", 'q', "DImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_SI(MEM_SI(addr), CONST_P1.const)", [4, 2], "sarl", 'l', "SImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_HI(MEM_HI(addr), CONST_P1.const)", [4, 3], "sarw", 'w', "HImode", "gen_rtx_ROTATERT", 0], + ["rcc.dst : MEM_ROTATERT_QI(MEM_QI(addr), CONST_P1.const)", [4, 2], "sarb", 'b', "QImode", "gen_rtx_ROTATERT", 0], + +], """ + $rule $cost + supairs { + /*TODO*/ + }, + build { + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpM("$opcode", $addr); + }, + emit { + const rtx mem = gen_rtx_MEM($rtx_mode, $addr->rtl); + ($is_nocc ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + $rtx_builder($rtx_mode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +""") + +# +# Chain rule to discard top level occurances of MEM_OP +# productions that do not modify the condition code +# +plug.plugrule3("nocc", [ + ["rule", "cost"], + ["stmt : nocc", [100, 100]], # discard top level MEM_OP + ["stmt : rcc", [100, 100]], # discard top level MEM_OP that have set the cc +], """ + $rule $cost + ; +""") + +# +# This rule is used to implement 64-bit division by small constants +# by multiplying by reciprocals. +# The semantics here are more or less identical to the case for "divq". +# +# From the manual page for div (unsigned divide): +# Divides the unsigned value in RDX:RAX by the unsigned value in the specified +# register or memory location, leaves the quotient in RAX and the remainder in RDX. +# +# From the manual page for mul (unsigned multiply): +# Multiplies the quadword value in the specified register or memory location +# by the value in RAX, and stores the result in RDX:RAX. +# +# From the manual page for the most constrained use of imul (signed multiply): +# Multiplies the contents of RAX by the contents of a 64-bit memory +# or register operand, and put the signed result in RDX:RAX +# +# For our purposes, we'll pick up the value in RDX. +# +plug.plugrule3("mulTI", [ + ["rule", "cost", "opcode", "schar", "dst_reg_name", "rtx_mode", "mov_opcode", "extend_opcode", "isRR", "issigned"], + # + # That's right, the destination is reg_rdx: we pluck out the upper 64 bits directly from rdx + # TODO: cost is made up (carried forward from division) + # + ["r64x.dst : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(ZERO_EXTEND_TI(r64x.src1) | ZERO_EXTEND_TI(r64.src2)), CONST8P))", + [4, 4], "mulq", 'q', "REG_RDX", "DImode", "movq", "?xorq?", 1, 0], + ["r64x.dst : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(ZERO_EXTEND_TI(r64x.src1) | ZERO_EXTEND_TI(MEM_QI(addr.src2))), CONST8P))", + [7, 2], "mulq", 'q', "REG_RDX", "DImode", "movq", "?xorq?", 0, 0], + # + # TODO: for the signed case, we just use the imulq insn that does ax *= argument, + # following what was done above with mulq. + # However, imulq is much less constrained regarding the operand locations. + # + ["r64x.dst : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(SIGN_EXTEND_TI(r64x.src1) | SIGN_EXTEND_TI(r64.src2)), CONST8P))", + [4, 4], "imulq", 'q', "REG_RDX", "DImode", "movq", "?xorq?", 1, 1], + ["r64x.dst : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(SIGN_EXTEND_TI(r64x.src1) | SIGN_EXTEND_TI(MEM_QI(addr.src2))), CONST8P))", + [7, 2], "imulq", 'q', "REG_RDX", "DImode", "movq", "?xorq?", 0, 1], +], """ + $rule $cost + supairs { + if ($isRR) { + suOrder2($dst, $src1, $src2, kid, kids); + } else { + suOrder2($dst, $src1, $src2, kid, kids); + } + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $dst->rx, $dst_reg_name); + }, + build { + if ('$schar' != 'b') { + add_copy_edges($dst->rx, REG_RDX, live); + } + if ($isRR) { + sparseset_set_bit(live, find($src2->r)); + } else { + add_addr(live, $src2); + } + if ('$schar' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); /* RDX is always killed on 64,32,16 bit variants */ + } + add_copy_edges(REG_RAX, $src1->rx, live); /* we want these to coalesce */ + }, + remat { + flags = 0; + }, + costs { + cost_copy(REG_RAX, $src1->rx); + if ($isRR) { + memorable($src1->rx); + memorable($src2->r); + } + else + forgettable($src1->rx); + cost_copy($dst_reg_name, $dst->rx); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + dump_copy("$mov_opcode", $src1->rx, REG_RAX, '$schar'); + if ($isRR) + dumpR("$opcode", $src2->r, '$schar'); + else + dumpM("$opcode", $src2); + dump_copy("$mov_opcode", $dst_reg_name, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src1 = gen_rtx_REG($rtx_mode, $src1->rx); + rtx src2 = $isRR + ? gen_rtx_REG($rtx_mode, $src2->r) + : gen_rtx_MEM($rtx_mode, $src2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG($rtx_mode, REG_RAX); + rtx rdx = ('$schar' != 'b') ? gen_rtx_REG($rtx_mode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * unsigned multiply modifes the OF and CF flags, + * so we must use icg_emit_clobber (gen_rtx_CLOBBER) + */ + parset = gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rdx, /* value comes back in rdx, no shifts needed */ + gen_rtx_TRUNCATE(DImode, + gen_rtx_LSHIFTRT(TImode, + gen_rtx_MULT(TImode, + $issigned + ? gen_rtx_SIGN_EXTEND(TImode, rax) + : gen_rtx_ZERO_EXTEND(TImode, rax), + $issigned + ? gen_rtx_SIGN_EXTEND(TImode, src2) + : gen_rtx_ZERO_EXTEND(TImode, src2) + ), + gen_rtx_CONST_INT(QImode, 64) + ))), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(DImode, REG_RAX)), /* perhaps clobber the scratch reg? */ + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, ($dst_reg_name == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +""") + +# +# Two address unary operators that do not clobber the destination register; +# See the rule block for multrri for an analog +# +plug.plugrule3("twooperand", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_builder"], + + #["r64x.dst : BSF_DI(r64.src)", [4, 3], "bsfq", 'q', "DImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + #["rz32x.dst : BSF_SI(r32.src)", [3, 2], "bsfl", 'l', "SImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + #["r16x.dst : BSF_HI(r16.src)", [4, 3], "bsfw", 'w', "HImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + + #["r64x.dst : BSR_DI(r64.src)", [4, 3], "bsrq", 'q', "DImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + #["rz32x.dst : BSR_SI(r32.src)", [3, 2], "bsrl", 'l', "SImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + #["r16x.dst : BSR_HI(r16.src)", [4, 3], "bsrw", 'w', "HImode", "/*BOGUS*/gen_rtx_PLUS"], # TODO + + # CLZ is an x86_64 ABM (advanced bit manipulation) instruction + ["r64x.dst : CLZ_DI(r64.src)", [4, 3], "lzcntq", 'q', "DImode", "gen_rtx_CLZ"], + ["rz32x.dst : CLZ_SI(r32.src)", [3, 2], "lzcntl", 'l', "SImode", "gen_rtx_CLZ"], + ["r16x.dst : CLZ_HI(r16.src)", [4, 3], "lzcntw", 'w', "HImode", "gen_rtx_CLZ"], + + ["r64x.dst : PLUS_DI(CONST_P63, NEG_DI(CLZ_DI(r64.src)))", [4, 3], "bsrq", 'q', "DImode", "gen_rtx_BSR_DI"], + ["rz32x.dst : PLUS_DI(CONST_P31, NEG_DI(CLZ_SI(r32.src)))", [3, 2], "bsrl", 'l', "SImode", "gen_rtx_BSR_SI"], + ["r16x.dst : PLUS_DI(CONST_P15, NEG_DI(CLZ_HI(r16.src)))", [4, 3], "bsrw", 'w', "HImode", "gen_rtx_BSR_HI"], + + # POPCOUNT is an x86_64 ABM (advanced bit manipulation) instruction + ["r64x.dst : POPCOUNT_DI(r64.src)", [4, 3], "popcntq", 'q', "DImode", "gen_rtx_POPCOUNT"], + ["rz32x.dst : POPCOUNT_SI(r32.src)", [3, 2], "popcntl", 'l', "SImode", "gen_rtx_POPCOUNT"], + ["r16x.dst : POPCOUNT_HI(r16.src)", [4, 3], "popcntw", 'w', "HImode", "gen_rtx_POPCOUNT"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; /* think about these */ + $dst->freed = $src->freed; + }, + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + sparseset_set_bit(live, find($src->r)); + }, + costs { + forgettable($src->r); + }, + debug { + dumpRR("$opcode", $src->r, '$schar', $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_REG($rtx_mode, $src->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +# })] +plug.plugrule3("prefetch", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "rtx_code"], + ["stmt : PREFETCH_DI(addr, imm32.coded_value)", [3, 2], "prefetchnta", 'q', "DImode", 0], +], """ + $rule $cost + build { + add_addr(live, $addr); + }, + debug { + dumpM("$opcode", $addr); + }, + emit { + const int k1 = $coded_value->val/10; + const int k2 = $coded_value->val%10; + icg_emit_plain(gen_rtx_PREFETCH($rtx_mode, $addr->rtl, GEN_INT(k1), GEN_INT(k2))); + }; +""") + + + + +#------------------------------------------------------------- +# various peepholes + + +# A peephole optimization discovered during code comparisons. +# This is an incomplete implementation, driven by the limited constants I had lying around +# (1 through 4 and 8). It'll be easy to make it more complete. +# Could also think about opportunities to propagate zero and sign extension info. +# + +plug.plugrule3("peepshifts1", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "andval", "rtx_builder"], + + ["ccr64x.dst : ASHIFT_DI(LSHIFTRT_DI(r64x.src, CONST_P1), CONST_P1)", [1, 8], "andq", 'q', "DImode", -2, "gen_rtx_AND"], + ["ccr64x.dst : ASHIFT_DI(LSHIFTRT_DI(r64x.src, CONST_P2), CONST_P2)", [1, 8], "andq", 'q', "DImode", -4, "gen_rtx_AND"], + ["ccr64x.dst : ASHIFT_DI(LSHIFTRT_DI(r64x.src, CONST_P3), CONST_P3)", [1, 8], "andq", 'q', "DImode", -8, "gen_rtx_AND"], + ["ccr64x.dst : ASHIFT_DI(LSHIFTRT_DI(r64x.src, CONST_P4), CONST_P4)", [1, 8], "andq", 'q', "DImode", -16, "gen_rtx_AND"], + ["ccr64x.dst : ASHIFT_DI(LSHIFTRT_DI(r64x.src, CONST_P8), CONST_P8)", [1, 8], "andq", 'q', "DImode", -256, "gen_rtx_AND"], + + ["ccrz32x.dst : ASHIFT_SI(LSHIFTRT_SI(r32x.src, CONST_P1), CONST_P1)", [1, 7], "andl", 'l', "SImode", -2, "gen_rtx_AND"], + ["ccrz32x.dst : ASHIFT_SI(LSHIFTRT_SI(r32x.src, CONST_P2), CONST_P2)", [1, 7], "andl", 'l', "SImode", -4, "gen_rtx_AND"], + ["ccrz32x.dst : ASHIFT_SI(LSHIFTRT_SI(r32x.src, CONST_P3), CONST_P3)", [1, 7], "andl", 'l', "SImode", -8, "gen_rtx_AND"], + ["ccrz32x.dst : ASHIFT_SI(LSHIFTRT_SI(r32x.src, CONST_P4), CONST_P4)", [1, 7], "andl", 'l', "SImode", -16, "gen_rtx_AND"], + ["ccrz32x.dst : ASHIFT_SI(LSHIFTRT_SI(r32x.src, CONST_P8), CONST_P8)", [1, 7], "andl", 'l', "SImode", -256, "gen_rtx_AND"], + + ["ccr16x.dst : ASHIFT_HI(LSHIFTRT_HI(r16x.src, CONST_P1), CONST_P1)", [1, 8], "andw", 'w', "HImode", -2, "gen_rtx_AND"], + ["ccr16x.dst : ASHIFT_HI(LSHIFTRT_HI(r16x.src, CONST_P2), CONST_P2)", [1, 8], "andw", 'w', "HImode", -4, "gen_rtx_AND"], + ["ccr16x.dst : ASHIFT_HI(LSHIFTRT_HI(r16x.src, CONST_P3), CONST_P3)", [1, 8], "andw", 'w', "HImode", -8, "gen_rtx_AND"], + ["ccr16x.dst : ASHIFT_HI(LSHIFTRT_HI(r16x.src, CONST_P4), CONST_P4)", [1, 8], "andw", 'w', "HImode", -16, "gen_rtx_AND"], + ["ccr16x.dst : ASHIFT_HI(LSHIFTRT_HI(r16x.src, CONST_P8), CONST_P8)", [1, 8], "andw", 'w', "HImode", -256, "gen_rtx_AND"], + + ["ccr8x.dst : ASHIFT_QI(LSHIFTRT_QI(r8x.src, CONST_P1), CONST_P1)", [1, 7], "andb", 'b', "QImode", -2, "gen_rtx_AND"], + ["ccr8x.dst : ASHIFT_QI(LSHIFTRT_QI(r8x.src, CONST_P2), CONST_P2)", [1, 7], "andb", 'b', "QImode", -4, "gen_rtx_AND"], + ["ccr8x.dst : ASHIFT_QI(LSHIFTRT_QI(r8x.src, CONST_P3), CONST_P3)", [1, 7], "andb", 'b', "QImode", -8, "gen_rtx_AND"], + ["ccr8x.dst : ASHIFT_QI(LSHIFTRT_QI(r8x.src, CONST_P4), CONST_P4)", [1, 7], "andb", 'b', "QImode", -16, "gen_rtx_AND"], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIRn("$opcode", $andval, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = $rtx_builder($rtx_mode, + gen_rtx_REG($rtx_mode, $src->rx), + GEN_INT($andval)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + +# +# A peephole optimization discovered during code comparisons. +# +plug.plugrule3("peepshifts2", [ + ["rule", "cost", "opcode", "schar", "rtx_mode", "shift"], + + ["r64x.dst : ASHIFT_DI(ZERO_EXTEND_DI(r32x.src), CONST_P32)", [1, 4], "shlq", 'q', "DImode", 32], + ["r64x.dst : ASHIFT_DI(ZERO_EXTEND_DI(r16x.src), CONST_P48)", [1, 4], "shlq", 'q', "DImode", 48], + ["r64x.dst : ASHIFT_DI(ZERO_EXTEND_DI(r8x.src), CONST_P56)", [1, 4], "shlq", 'q', "DImode", 56], + ["r32x.dst : ASHIFT_SI(ZERO_EXTEND_SI(r16x.src), CONST_P16)", [1, 3], "shll", 'l', "SImode", 16], + ["r32x.dst : ASHIFT_SI(ZERO_EXTEND_SI(r8x.src), CONST_P24)", [1, 3], "shll", 'l', "SImode", 24], + ["r16x.dst : ASHIFT_HI(ZERO_EXTEND_HI(r8x.src), CONST_P8)", [1, 3], "shll", 'l', "SImode", 8], + + ["r64x.dst : ASHIFT_DI(SIGN_EXTEND_DI(r32x.src), CONST_P32)", [1, 4], "shlq", 'q', "DImode", 32], + ["r64x.dst : ASHIFT_DI(SIGN_EXTEND_DI(r16x.src), CONST_P48)", [1, 4], "shlq", 'q', "DImode", 48], + ["r64x.dst : ASHIFT_DI(SIGN_EXTEND_DI(r8x.src), CONST_P56)", [1, 4], "shlq", 'q', "DImode", 56], + ["r32x.dst : ASHIFT_SI(SIGN_EXTEND_SI(r16x.src), CONST_P16)", [1, 3], "shll", 'l', "SImode", 16], + ["r32x.dst : ASHIFT_SI(SIGN_EXTEND_SI(r8x.src), CONST_P24)", [1, 3], "shll", 'l', "SImode", 24], + ["r16x.dst : ASHIFT_HI(SIGN_EXTEND_HI(r8x.src), CONST_P8)", [1, 3], "shll", 'l', "SImode", 8], + +], """ + $rule $cost + supairs { + $dst->extra = $src->extra; + $dst->freed = $src->freed; + }, + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIRn("$opcode", $shift, $dst->rx, '$schar'); + }, + emit { + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + rtx src = gen_rtx_ASHIFT($rtx_mode, + gen_rtx_REG($rtx_mode, $src->rx), + GEN_INT($shift)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + + +# +# A peephole optimization discovered during code comparisons. +# +plug.plugrule3("peepand1", [ + ["rule", "cost"], + + ["r64x.dst : AND_DI( r64.src | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(r32.src) | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(r32.src) | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(r16.src) | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(r16.src) | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(r8.src) | CONST_P255)", [1, 3]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(r8.src) | CONST_P255)", [1, 3]], + + ["rz32x.dst : AND_SI( r32.src | CONST_P255)", [1, 3]], + ["rz32x.dst : AND_SI(ZERO_EXTEND_SI(r16.src) | CONST_P255)", [1, 3]], + ["rz32x.dst : AND_SI(SIGN_EXTEND_SI(r16.src) | CONST_P255)", [1, 3]], + ["rz32x.dst : AND_SI(ZERO_EXTEND_SI(r8.src) | CONST_P255)", [1, 3]], + ["rz32x.dst : AND_SI(SIGN_EXTEND_SI(r8.src) | CONST_P255)", [1, 3]], + + ["rz16x.dst : AND_HI( r16.src | CONST_P255)", [1, 3]], + ["rz16x.dst : AND_HI(ZERO_EXTEND_HI(r8.src) | CONST_P255)", [1, 3]], + ["rz16x.dst : AND_HI(SIGN_EXTEND_HI(r8.src) | CONST_P255)", [1, 3]], + +], """ + $rule $cost + supairs { + if ($dst->freed > 0) + $dst->freed--; + else + $dst->extra++; + }, + names { + $dst->rx = new_reg(); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($dst->rx), live); + sparseset_clear_bit(live, find($dst->rx)); + sparseset_set_bit(live, find($src->r)); + }, + costs { + memorable($src->r); + }, + debug { + dumpRR("movzbl", $src->r, 'b', $dst->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $dst->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $src->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +plug.plugrule3("peepand2", [ + ["rule", "cost"], + + ["r64x.dst : AND_DI( MEM_DI(addr) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(MEM_SI(addr)) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(MEM_SI(addr)) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(MEM_HI(addr)) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(MEM_HI(addr)) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + ["r64x.dst : AND_DI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + + ["rz32x.dst : AND_SI( MEM_SI(addr) | CONST_P255)", [4, 2]], + ["rz32x.dst : AND_SI(ZERO_EXTEND_DI(MEM_HI(addr)) | CONST_P255)", [4, 2]], + ["rz32x.dst : AND_SI(SIGN_EXTEND_DI(MEM_HI(addr)) | CONST_P255)", [4, 2]], + ["rz32x.dst : AND_SI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + ["rz32x.dst : AND_SI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + + ["rz16x.dst : AND_HI( MEM_HI(addr) | CONST_P255)", [4, 2]], + ["rz16x.dst : AND_HI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + ["rz16x.dst : AND_HI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255)", [4, 2]], + +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + supairs { + if ($addr->freed > 0) { + $dst->extra = $addr->extra; + $dst->freed = $addr->freed - 1; + } + else { + $dst->extra = $addr->extra + 1; + $dst->freed = 0; + } + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $addr); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $addr, $dst->rx, 'l'); + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $dst->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $addr->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + diff --git a/iburg/briggs/icg-grammars/x86-64.int.pyout b/iburg/briggs/icg-grammars/x86-64.int.pyout new file mode 100644 index 00000000000..4133261f9d7 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.int.pyout @@ -0,0 +1,39657 @@ +#line 17 "x86-64.int.py" +lhs64 : REGX_DI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 18 "x86-64.int.py" +lhs32 : REGX_SI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 19 "x86-64.int.py" +lhs16 : REGX_HI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 20 "x86-64.int.py" +lhs8 : REGX_QI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 21 "x86-64.int.py" +lhs64 : REG_DI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 22 "x86-64.int.py" +lhs32 : REG_SI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 23 "x86-64.int.py" +lhs16 : REG_HI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 24 "x86-64.int.py" +lhs8 : REG_QI [0, 0] +#line 28 "x86-64.int.py" + names { + $$->spilled = false; + }, + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + remat { + flags |= LHS_REG; + }, + costs { + cost_store($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 53 "x86-64.int.py" +lhs64 : MEM_DI(addr) [3, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 54 "x86-64.int.py" +lhs32 : MEM_SI(addr) [3, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 55 "x86-64.int.py" +lhs16 : MEM_HI(addr) [3, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 56 "x86-64.int.py" +lhs8 : MEM_QI(addr) [3, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 68 "x86-64.int.py" +lhs64 : MEM_DF(addr) [0, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 69 "x86-64.int.py" +lhs32 : MEM_SF(addr) [0, 0] +#line 73 "x86-64.int.py" + names { + $$->spilled = true; + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $1->a.disp; + $$->a.string = $1->a.string; + }, + remat { + flags = 0; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 97 "x86-64.int.py" +stmt : SET_ALL(lhs64, r64) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movq", $2->r, 'q', $1); + else + dump_copy("movq", $2->r, $1->r, 'q'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(DImode, $2->r); + rtx dst = gen_rtx_MEM(DImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(DImode, $2->r); + rtx dst = gen_rtx_REG(DImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 98 "x86-64.int.py" +stmt : SET_ALL(lhs32, r32) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movl", $2->r, 'l', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_MEM(SImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 99 "x86-64.int.py" +stmt : SET_ALL(lhs16, r16) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movw", $2->r, 'w', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(HImode, $2->r); + rtx dst = gen_rtx_MEM(HImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 100 "x86-64.int.py" +stmt : SET_ALL(lhs8, r8) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movb", $2->r, 'b', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(QImode, $2->r); + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 103 "x86-64.int.py" +stmt : SET_ALL(SUBREG_DI(lhs32, CONST_0), r64) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movl", $2->r, 'l', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_MEM(SImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 104 "x86-64.int.py" +stmt : SET_ALL(SUBREG_DI(lhs16, CONST_0), r64) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movw", $2->r, 'w', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(HImode, $2->r); + rtx dst = gen_rtx_MEM(HImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 105 "x86-64.int.py" +stmt : SET_ALL(SUBREG_DI(lhs8, CONST_0), r64) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movb", $2->r, 'b', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(QImode, $2->r); + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 106 "x86-64.int.py" +stmt : SET_ALL(SUBREG_SI(lhs16, CONST_0), r32) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movw", $2->r, 'w', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(HImode, $2->r); + rtx dst = gen_rtx_MEM(HImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 107 "x86-64.int.py" +stmt : SET_ALL(SUBREG_SI(lhs8, CONST_0), r32) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movb", $2->r, 'b', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(QImode, $2->r); + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 108 "x86-64.int.py" +stmt : SET_ALL(SUBREG_HI(lhs8, CONST_0), r16) [0, 0] +#line 112 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + coalesce { + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, $2->r); + }, + build { + if ($1->spilled) { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + } + else + add_copy_edges($1->r, $2->r, live); + }, + costs { + if (!$1->spilled) + cost_copy($2->r, $1->r); + }, + debug { + if ($1->spilled) + dumpRM("movb", $2->r, 'b', $1); + else + dump_copy("movl", $2->r, $1->r, 'l'); + }, + emit { + if ($1->spilled) { + rtx src = gen_rtx_REG(QImode, $2->r); + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + else { + rtx src = gen_rtx_REG(SImode, $2->r); + rtx dst = gen_rtx_REG(SImode, $1->r); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + } + }; +#line 155 "x86-64.int.py" +stmt : SET_ALL(MEM_DI(addr), imm32) [3, 2] +#line 162 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("movq", $2, $1); + }, + emit { + rtx src = gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl); + rtx dst = gen_rtx_MEM(DImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 156 "x86-64.int.py" +stmt : SET_ALL(MEM_SI(addr), imm32) [3, 1] +#line 162 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("movl", $2, $1); + }, + emit { + rtx src = gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl); + rtx dst = gen_rtx_MEM(SImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 157 "x86-64.int.py" +stmt : SET_ALL(MEM_HI(addr), imm16) [3, 2] +#line 162 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("movw", $2, $1); + }, + emit { + rtx src = gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl); + rtx dst = gen_rtx_MEM(HImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 158 "x86-64.int.py" +stmt : SET_ALL(MEM_QI(addr), imm8) [3, 1] +#line 162 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("movb", $2, $1); + }, + emit { + rtx src = gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl); + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 187 "x86-64.int.py" +r64 : REG_DI [0, 0] +#line 194 "x86-64.int.py" + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + costs { + cost_load($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 188 "x86-64.int.py" +r32 : REG_SI [0, 0] +#line 194 "x86-64.int.py" + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + costs { + cost_load($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 189 "x86-64.int.py" +r16 : REG_HI [0, 0] +#line 194 "x86-64.int.py" + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + costs { + cost_load($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 190 "x86-64.int.py" +r8 : REG_QI [0, 0] +#line 194 "x86-64.int.py" + kinds { + icg_reg_vector[$$->r].kind = INT_REGISTER; + }, + costs { + cost_load($$->r); + }, + spill { + dirty |= make_spill_code(find($$->r), $$); + }, + final { + $$->r = icg_reg_vector[find($$->r)].color; + }; +#line 214 "x86-64.int.py" +r64x : REGX_DI [0, 0] +#line 221 "x86-64.int.py" + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; + $$->freed = 0; + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 215 "x86-64.int.py" +r32x : REGX_SI [0, 0] +#line 221 "x86-64.int.py" + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; + $$->freed = 0; + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 216 "x86-64.int.py" +r16x : REGX_HI [0, 0] +#line 221 "x86-64.int.py" + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; + $$->freed = 0; + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 217 "x86-64.int.py" +r8x : REGX_QI [0, 0] +#line 221 "x86-64.int.py" + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + costs { + cost_load($$->rx); + }, + supairs { + $$->extra = 0; + $$->freed = 0; + }, + spill { + dirty |= make_spill_code(find($$->rx), $$); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }; +#line 250 "x86-64.int.py" +r32 : rz32 [0, 0] +#line 282 "x86-64.int.py" + ; +#line 251 "x86-64.int.py" +r16 : rz16 [0, 0] +#line 282 "x86-64.int.py" + ; +#line 252 "x86-64.int.py" +r16 : rs16 [0, 0] +#line 282 "x86-64.int.py" + ; +#line 253 "x86-64.int.py" +r8 : rz8 [0, 0] +#line 282 "x86-64.int.py" + ; +#line 254 "x86-64.int.py" +r8 : rs8 [0, 0] +#line 282 "x86-64.int.py" + ; +#line 256 "x86-64.int.py" +r32x : rz32x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 257 "x86-64.int.py" +r16x : rz16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 258 "x86-64.int.py" +r16x : rs16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 259 "x86-64.int.py" +r8x : rz8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 260 "x86-64.int.py" +r8x : rs8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 262 "x86-64.int.py" +ccr32x : ccrz32x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 263 "x86-64.int.py" +ccr16x : ccrz16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 264 "x86-64.int.py" +ccr16x : ccrs16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 265 "x86-64.int.py" +ccr8x : ccrz8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 266 "x86-64.int.py" +ccr8x : ccrs8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 270 "x86-64.int.py" +r64x : ccr64x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 271 "x86-64.int.py" +r32x : ccr32x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 272 "x86-64.int.py" +rz32x : ccrz32x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 273 "x86-64.int.py" +r16x : ccr16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 274 "x86-64.int.py" +rz16x : ccrz16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 275 "x86-64.int.py" +rs16x : ccrs16x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 276 "x86-64.int.py" +r8x : ccr8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 277 "x86-64.int.py" +rz8x : ccrz8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 278 "x86-64.int.py" +rs8x : ccrs8x [0, 0] +#line 282 "x86-64.int.py" + ; +#line 294 "x86-64.int.py" +r32: TRUNCATE_SI(r64) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 295 "x86-64.int.py" +r16: TRUNCATE_HI(r64) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 296 "x86-64.int.py" +r8: TRUNCATE_QI(r64) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 297 "x86-64.int.py" +r16: TRUNCATE_HI(r32) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 298 "x86-64.int.py" +r8: TRUNCATE_QI(r32) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 299 "x86-64.int.py" +r8: TRUNCATE_QI(r16) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 302 "x86-64.int.py" +r32 : SUBREG_SI(r64, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 303 "x86-64.int.py" +r16 : SUBREG_HI(r64, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 304 "x86-64.int.py" +r8 : SUBREG_QI(r64, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 305 "x86-64.int.py" +r16 : SUBREG_HI(r32, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 306 "x86-64.int.py" +r8 : SUBREG_QI(r32, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 307 "x86-64.int.py" +r8 : SUBREG_QI(r16, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 310 "x86-64.int.py" +r64 : SUBREG_DI(r32, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 311 "x86-64.int.py" +r64 : SUBREG_DI(r16, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 312 "x86-64.int.py" +r64 : SUBREG_DI(r8, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 313 "x86-64.int.py" +r32 : SUBREG_SI(r16, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 314 "x86-64.int.py" +r32 : SUBREG_SI(r8, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 315 "x86-64.int.py" +r16 : SUBREG_HI(r8, CONST_0) [0, 0] +#line 319 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 333 "x86-64.int.py" +r32x: TRUNCATE_SI(r64x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 334 "x86-64.int.py" +r16x: TRUNCATE_HI(r64x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 335 "x86-64.int.py" +r8x: TRUNCATE_QI(r64x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 336 "x86-64.int.py" +r16x: TRUNCATE_HI(r32x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 337 "x86-64.int.py" +r8x: TRUNCATE_QI(r32x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 338 "x86-64.int.py" +r8x: TRUNCATE_QI(r16x) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 340 "x86-64.int.py" +r32x : SUBREG_SI(r64x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 341 "x86-64.int.py" +r16x : SUBREG_HI(r64x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 342 "x86-64.int.py" +r8x : SUBREG_QI(r64x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 343 "x86-64.int.py" +r16x : SUBREG_HI(r32x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 344 "x86-64.int.py" +r8x : SUBREG_QI(r32x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 345 "x86-64.int.py" +r8x : SUBREG_QI(r16x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 347 "x86-64.int.py" +r64x : SUBREG_DI(r32x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 348 "x86-64.int.py" +r64x : SUBREG_DI(r16x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 349 "x86-64.int.py" +r64x : SUBREG_DI(r8x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 350 "x86-64.int.py" +r32x : SUBREG_SI(r16x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 351 "x86-64.int.py" +r32x : SUBREG_SI(r8x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 352 "x86-64.int.py" +r16x : SUBREG_HI(r8x, CONST_0) [0, 0] +#line 356 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 374 "x86-64.int.py" +r64 : r64x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 375 "x86-64.int.py" +r32 : r32x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 376 "x86-64.int.py" +rz32 : rz32x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 377 "x86-64.int.py" +r16 : r16x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 378 "x86-64.int.py" +rz16 : rz16x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 379 "x86-64.int.py" +rs16 : rs16x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 380 "x86-64.int.py" +r8 : r8x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 381 "x86-64.int.py" +rz8 : rz8x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 382 "x86-64.int.py" +rs8 : rs8x [0, 0] +#line 386 "x86-64.int.py" + supairs { + $$->freed++; /* assuming that the register will eventually be freed */ + }, + names { + $$->r = $1->rx; + }, + final { + $$->r = $1->rx; + }; +#line 402 "x86-64.int.py" +r64x : r64 [1, 3] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movq", $1->r, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(DImode, $1->r); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 403 "x86-64.int.py" +rz32x : r32 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 404 "x86-64.int.py" +r16x : r16 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 405 "x86-64.int.py" +rz16x : rz16 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 406 "x86-64.int.py" +rs16x : rs16 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 407 "x86-64.int.py" +r8x : r8 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 408 "x86-64.int.py" +rz8x : rz8 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 409 "x86-64.int.py" +rs8x : rs8 [1, 2] +#line 413 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $$->rx, $1->r); + }, + build { + add_copy_edges($$->rx, $1->r, live); + }, + costs { + cost_copy($$->rx, $1->r); + }, + debug { + dump_copy("movl", $1->r, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_REG(SImode, $1->r); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 454 "x86-64.int.py" +r64 : PLUS_DI(r64 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 455 "x86-64.int.py" +r32 : PLUS_SI(r32 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 456 "x86-64.int.py" +r16 : PLUS_HI(r16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 457 "x86-64.int.py" +r8 : PLUS_QI(r8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 458 "x86-64.int.py" +rz32 : PLUS_SI(rz32 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 459 "x86-64.int.py" +rz16 : PLUS_HI(rz16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 460 "x86-64.int.py" +rz8 : PLUS_QI(rz8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 461 "x86-64.int.py" +rs16 : PLUS_HI(rs16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 462 "x86-64.int.py" +rs8 : PLUS_QI(rs8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 464 "x86-64.int.py" +r64 : MINUS_DI(r64 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 465 "x86-64.int.py" +r32 : MINUS_SI(r32 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 466 "x86-64.int.py" +r16 : MINUS_HI(r16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 467 "x86-64.int.py" +r8 : MINUS_QI(r8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 468 "x86-64.int.py" +rz32 : MINUS_SI(rz32 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 469 "x86-64.int.py" +rz16 : MINUS_HI(rz16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 470 "x86-64.int.py" +rz8 : MINUS_QI(rz8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 471 "x86-64.int.py" +rs16 : MINUS_HI(rs16 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 472 "x86-64.int.py" +rs8 : MINUS_QI(rs8 | CONST_0) [0, 0] +#line 476 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 494 "x86-64.int.py" +r64x : PLUS_DI(r64x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 495 "x86-64.int.py" +r32x : PLUS_SI(r32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 496 "x86-64.int.py" +r16x : PLUS_HI(r16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 497 "x86-64.int.py" +r8x : PLUS_QI(r8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 498 "x86-64.int.py" +rz32x : PLUS_SI(rz32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 499 "x86-64.int.py" +rz16x : PLUS_HI(rz16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 500 "x86-64.int.py" +rz8x : PLUS_QI(rz8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 501 "x86-64.int.py" +rs16x : PLUS_HI(rs16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 502 "x86-64.int.py" +rs8x : PLUS_QI(rs8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 504 "x86-64.int.py" +ccr64x : PLUS_DI(ccr64x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 505 "x86-64.int.py" +ccr32x : PLUS_SI(ccr32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 506 "x86-64.int.py" +ccr16x : PLUS_HI(ccr16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 507 "x86-64.int.py" +ccr8x : PLUS_QI(ccr8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 508 "x86-64.int.py" +ccrz32x : PLUS_SI(ccrz32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 509 "x86-64.int.py" +ccrz16x : PLUS_HI(ccrz16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 510 "x86-64.int.py" +ccrz8x : PLUS_QI(ccrz8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 511 "x86-64.int.py" +ccrs16x : PLUS_HI(ccrs16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 512 "x86-64.int.py" +ccrs8x : PLUS_QI(ccrs8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 514 "x86-64.int.py" +r64x : MINUS_DI(r64x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 515 "x86-64.int.py" +r32x : MINUS_SI(r32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 516 "x86-64.int.py" +r16x : MINUS_HI(r16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 517 "x86-64.int.py" +r8x : MINUS_QI(r8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 518 "x86-64.int.py" +rz32x : MINUS_SI(rz32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 519 "x86-64.int.py" +rz16x : MINUS_HI(rz16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 520 "x86-64.int.py" +rz8x : MINUS_QI(rz8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 521 "x86-64.int.py" +rs16x : MINUS_HI(rs16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 522 "x86-64.int.py" +rs8x : MINUS_QI(rs8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 524 "x86-64.int.py" +ccr64x : MINUS_DI(ccr64x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 525 "x86-64.int.py" +ccr32x : MINUS_SI(ccr32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 526 "x86-64.int.py" +ccr16x : MINUS_HI(ccr16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 527 "x86-64.int.py" +ccr8x : MINUS_QI(ccr8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 528 "x86-64.int.py" +ccrz32x : MINUS_SI(ccrz32x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 529 "x86-64.int.py" +ccrz16x : MINUS_HI(ccrz16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 530 "x86-64.int.py" +ccrz8x : MINUS_QI(ccrz8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 531 "x86-64.int.py" +ccrs16x : MINUS_HI(ccrs16x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 532 "x86-64.int.py" +ccrs8x : MINUS_QI(ccrs8x | CONST_0) [0, 0] +#line 536 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 559 "x86-64.int.py" +ccr64x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 560 "x86-64.int.py" +ccrz32x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 561 "x86-64.int.py" +ccrz16x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 562 "x86-64.int.py" +ccrs16x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 563 "x86-64.int.py" +ccrz8x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 564 "x86-64.int.py" +ccrs8x : CONST_0 [1, 2] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorl", $$->rx, 'l', $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_XOR(SImode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SImode, dst, src)); + }; +#line 559 "x86-64.int.py" +rdx : CONST_0 [2, 4] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorpd", $$->rx, 'x', $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DFmode, $$->rx); + rtx src = gen_rtx_XOR(DFmode, dst, dst); + icg_emit_clobber(gen_rtx_SET(DFmode, dst, src)); + }; +#line 559 "x86-64.int.py" +rfx : CONST_0 [2, 4] +#line 570 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = FLOAT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpRR("xorps", $$->rx, 'x', $$->rx, 'x'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SFmode, $$->rx); + rtx src = gen_rtx_XOR(SFmode, dst, dst); + icg_emit_clobber(gen_rtx_SET(SFmode, dst, src)); + }; +#line 605 "x86-64.int.py" +r64x : imm64 [1, 2] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movabsq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 606 "x86-64.int.py" +r64x : pos32 [1, 1] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 607 "x86-64.int.py" +rz32x : imm32 [1, 1] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 612 "x86-64.int.py" +r16x : imm16 [2, 2] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movw", $1, $$->rx, 'w'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 613 "x86-64.int.py" +r8x : imm8 [2, 1] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movb", $1, $$->rx, 'b'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 617 "x86-64.int.py" +r16x : imm32 [1, 1] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 618 "x86-64.int.py" +rz16x : pos16 [1, 3] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 619 "x86-64.int.py" +r8x : imm32 [1, 1] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 620 "x86-64.int.py" +rz8x : pos8 [1, 4] +#line 624 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + $$->extra = 1; + $$->freed = 0; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + }, + remat { + flags |= RHS_REMAT; + }, + debug { + dumpIR("movl", $1, $$->rx, 'd'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx src = gen_rtx_imm_constant($1->val, $1->a.string, $1->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 670 "x86-64.int.py" +r64x : PLUS_DI(r64x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 671 "x86-64.int.py" +rz32x : PLUS_SI(r32x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 687 "x86-64.int.py" +r16x : PLUS_HI(r16x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 673 "x86-64.int.py" +r8x : PLUS_QI(r8x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 675 "x86-64.int.py" +r64x : PLUS_DI(r64x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 676 "x86-64.int.py" +rz32x : PLUS_SI(r32x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 688 "x86-64.int.py" +r16x : PLUS_HI(r16x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 678 "x86-64.int.py" +r8x : PLUS_QI(r8x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 681 "x86-64.int.py" +rz16x : PLUS_HI(rz16x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 682 "x86-64.int.py" +rz8x : PLUS_QI(rz8x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 683 "x86-64.int.py" +rz16x : PLUS_HI(rz16x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 684 "x86-64.int.py" +rz8x : PLUS_QI(rz8x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 687 "x86-64.int.py" +r16x : PLUS_HI(r16x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 688 "x86-64.int.py" +r16x : PLUS_HI(r16x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 691 "x86-64.int.py" +r64x : MINUS_DI(r64x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 692 "x86-64.int.py" +rz32x : MINUS_SI(r32x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 706 "x86-64.int.py" +r16x : MINUS_HI(r16x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 694 "x86-64.int.py" +r8x : MINUS_QI(r8x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 696 "x86-64.int.py" +r64x : MINUS_DI(r64x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 697 "x86-64.int.py" +rz32x : MINUS_SI(r32x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 707 "x86-64.int.py" +r16x : MINUS_HI(r16x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 699 "x86-64.int.py" +r8x : MINUS_QI(r8x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 701 "x86-64.int.py" +rz16x : MINUS_HI(rz16x | CONST_N1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 702 "x86-64.int.py" +rz8x : MINUS_QI(rz8x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 703 "x86-64.int.py" +rz16x : MINUS_HI(rz16x | CONST_P1) [1, 3] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 704 "x86-64.int.py" +rz8x : MINUS_QI(rz8x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 706 "x86-64.int.py" +r16x : MINUS_HI(r16x | CONST_N1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("incl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 707 "x86-64.int.py" +r16x : MINUS_HI(r16x | CONST_P1) [1, 2] +#line 711 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("decl", $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 742 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 743 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | imm32) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 744 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 745 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | imm32) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 746 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 747 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 748 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 751 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 752 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 753 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 756 "x86-64.int.py" +r16x : PLUS_HI(r16x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 759 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 760 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, imm32) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 761 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 762 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, imm32) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 763 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 764 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 765 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 767 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 768 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 769 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 771 "x86-64.int.py" +r16x : MINUS_HI(r16x, imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 774 "x86-64.int.py" +ccr64x : AND_DI(r64x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_AND(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 775 "x86-64.int.py" +ccr64x : AND_DI(r64x | imm32) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_AND(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 776 "x86-64.int.py" +ccrz32x : AND_SI(r32x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 777 "x86-64.int.py" +ccrz32x : AND_SI(r32x | imm32) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 778 "x86-64.int.py" +ccr16x : AND_HI(r16x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 779 "x86-64.int.py" +ccr16x : AND_HI(r16x | imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 780 "x86-64.int.py" +ccr8x : AND_QI(r8x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 783 "x86-64.int.py" +r16x : AND_HI(r16x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("andl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 786 "x86-64.int.py" +ccr64x : XOR_DI(r64x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_XOR(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 787 "x86-64.int.py" +ccr64x : XOR_DI(r64x | imm32) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_XOR(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 788 "x86-64.int.py" +ccrz32x : XOR_SI(r32x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 789 "x86-64.int.py" +ccrz32x : XOR_SI(r32x | imm32) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 790 "x86-64.int.py" +ccr16x : XOR_HI(r16x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 791 "x86-64.int.py" +ccr16x : XOR_HI(r16x | imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 792 "x86-64.int.py" +ccr8x : XOR_QI(r8x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 794 "x86-64.int.py" +r16x : XOR_HI(r16x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("xorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 797 "x86-64.int.py" +ccr64x : IOR_DI(r64x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_IOR(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 798 "x86-64.int.py" +ccr64x : IOR_DI(r64x | imm32) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_IOR(DImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 799 "x86-64.int.py" +ccrz32x : IOR_SI(r32x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 800 "x86-64.int.py" +ccrz32x : IOR_SI(r32x | imm32) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 801 "x86-64.int.py" +ccr16x : IOR_HI(r16x | imm8) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 802 "x86-64.int.py" +ccr16x : IOR_HI(r16x | imm16) [1, 3] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 803 "x86-64.int.py" +ccr8x : IOR_QI(r8x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 805 "x86-64.int.py" +r16x : IOR_HI(r16x | imm8) [1, 2] +#line 809 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("orl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 840 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | MEM_DI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 841 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | MEM_SI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 842 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 843 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 845 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 846 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 849 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | SUBREG_SI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 850 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 851 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 852 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 853 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 854 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 856 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 857 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 858 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 859 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 860 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 864 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, NEG_DI(MEM_DI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 865 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, NEG_SI(MEM_SI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 866 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, NEG_HI(MEM_HI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 867 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, NEG_QI(MEM_QI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 869 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, NEG_HI(MEM_HI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 870 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, NEG_QI(MEM_QI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 873 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, NEG_SI(SUBREG_SI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 874 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 875 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 876 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 877 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 878 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 880 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 881 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 882 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 883 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 884 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("addb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 888 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, MEM_DI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 889 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, MEM_SI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 890 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 891 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 893 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 894 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 897 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, SUBREG_SI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 898 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 899 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 900 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 901 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 902 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 904 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 905 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 906 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 907 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 908 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 912 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | NEG_DI(MEM_DI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 913 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | NEG_SI(MEM_SI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 914 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | NEG_HI(MEM_HI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 915 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | NEG_QI(MEM_QI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 917 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | NEG_HI(MEM_HI(addr))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 918 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | NEG_QI(MEM_QI(addr))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 921 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | NEG_SI(SUBREG_SI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 922 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 923 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 924 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 925 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 926 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 928 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | NEG_HI(SUBREG_HI(MEM_DI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 929 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | NEG_HI(SUBREG_HI(MEM_SI(addr), CONST_0))) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 930 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | NEG_QI(SUBREG_QI(MEM_DI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 931 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | NEG_QI(SUBREG_QI(MEM_SI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 932 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | NEG_QI(SUBREG_QI(MEM_HI(addr), CONST_0))) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("subb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 937 "x86-64.int.py" +r64x : MULT_DI(r64x | MEM_DI(addr)) [7, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MULT(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 938 "x86-64.int.py" +rz32x : MULT_SI(r32x | MEM_SI(addr)) [6, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imull", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MULT(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 939 "x86-64.int.py" +r16x : MULT_HI(r16x | MEM_HI(addr)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 941 "x86-64.int.py" +rz16x : MULT_HI(rz16x | MEM_HI(addr)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 944 "x86-64.int.py" +rz32x : MULT_SI(r32x | SUBREG_SI(MEM_DI(addr), CONST_0)) [6, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imull", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MULT(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 945 "x86-64.int.py" +r16x : MULT_HI(r16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 946 "x86-64.int.py" +r16x : MULT_HI(r16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 948 "x86-64.int.py" +rz16x : MULT_HI(rz16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 949 "x86-64.int.py" +rz16x : MULT_HI(rz16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [6, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("imulw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 953 "x86-64.int.py" +ccr64x : AND_DI(r64x | MEM_DI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_AND(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 954 "x86-64.int.py" +ccrz32x : AND_SI(r32x | MEM_SI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 955 "x86-64.int.py" +ccr16x : AND_HI(r16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 956 "x86-64.int.py" +ccr8x : AND_QI(r8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 958 "x86-64.int.py" +ccrz16x : AND_HI(rz16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 959 "x86-64.int.py" +ccrz8x : AND_QI(rz8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 962 "x86-64.int.py" +ccrz32x : AND_SI(r32x | SUBREG_SI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 963 "x86-64.int.py" +ccr16x : AND_HI(r16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 964 "x86-64.int.py" +ccr16x : AND_HI(r16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 965 "x86-64.int.py" +ccr8x : AND_QI(r8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 966 "x86-64.int.py" +ccr8x : AND_QI(r8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 967 "x86-64.int.py" +ccr8x : AND_QI(r8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 969 "x86-64.int.py" +ccrz16x : AND_HI(rz16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 970 "x86-64.int.py" +ccrz16x : AND_HI(rz16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 971 "x86-64.int.py" +ccrz8x : AND_QI(rz8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 972 "x86-64.int.py" +ccrz8x : AND_QI(rz8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 973 "x86-64.int.py" +ccrz8x : AND_QI(rz8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("andb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 977 "x86-64.int.py" +ccr64x : IOR_DI(r64x | MEM_DI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_IOR(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 978 "x86-64.int.py" +ccrz32x : IOR_SI(r32x | MEM_SI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 979 "x86-64.int.py" +ccr16x : IOR_HI(r16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 980 "x86-64.int.py" +ccr8x : IOR_QI(r8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 982 "x86-64.int.py" +ccrz16x : IOR_HI(rz16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 983 "x86-64.int.py" +ccrz8x : IOR_QI(rz8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 986 "x86-64.int.py" +ccrz32x : IOR_SI(r32x | SUBREG_SI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 987 "x86-64.int.py" +ccr16x : IOR_HI(r16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 988 "x86-64.int.py" +ccr16x : IOR_HI(r16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 989 "x86-64.int.py" +ccr8x : IOR_QI(r8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 990 "x86-64.int.py" +ccr8x : IOR_QI(r8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 991 "x86-64.int.py" +ccr8x : IOR_QI(r8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 993 "x86-64.int.py" +ccrz16x : IOR_HI(rz16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 994 "x86-64.int.py" +ccrz16x : IOR_HI(rz16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 995 "x86-64.int.py" +ccrz8x : IOR_QI(rz8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 996 "x86-64.int.py" +ccrz8x : IOR_QI(rz8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 997 "x86-64.int.py" +ccrz8x : IOR_QI(rz8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("orb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1001 "x86-64.int.py" +ccr64x : XOR_DI(r64x | MEM_DI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_XOR(DImode, dst, gen_rtx_MEM(DImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1002 "x86-64.int.py" +ccrz32x : XOR_SI(r32x | MEM_SI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1003 "x86-64.int.py" +ccr16x : XOR_HI(r16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1004 "x86-64.int.py" +ccr8x : XOR_QI(r8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1006 "x86-64.int.py" +ccrz16x : XOR_HI(rz16x | MEM_HI(addr)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1007 "x86-64.int.py" +ccrz8x : XOR_QI(rz8x | MEM_QI(addr)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1010 "x86-64.int.py" +ccrz32x : XOR_SI(r32x | SUBREG_SI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_MEM(SImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1011 "x86-64.int.py" +ccr16x : XOR_HI(r16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1012 "x86-64.int.py" +ccr16x : XOR_HI(r16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1013 "x86-64.int.py" +ccr8x : XOR_QI(r8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1014 "x86-64.int.py" +ccr8x : XOR_QI(r8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1015 "x86-64.int.py" +ccr8x : XOR_QI(r8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1017 "x86-64.int.py" +ccrz16x : XOR_HI(rz16x | SUBREG_HI(MEM_DI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1018 "x86-64.int.py" +ccrz16x : XOR_HI(rz16x | SUBREG_HI(MEM_SI(addr), CONST_0)) [4, 2] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_MEM(HImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1019 "x86-64.int.py" +ccrz8x : XOR_QI(rz8x | SUBREG_QI(MEM_DI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1020 "x86-64.int.py" +ccrz8x : XOR_QI(rz8x | SUBREG_QI(MEM_SI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1021 "x86-64.int.py" +ccrz8x : XOR_QI(rz8x | SUBREG_QI(MEM_HI(addr), CONST_0)) [4, 1] +#line 1025 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpMR("xorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_MEM(QImode, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1064 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | r64) [1, 4] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1065 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | r32) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1066 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1067 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | r8) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1070 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1071 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | r8) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1074 "x86-64.int.py" +r16x : PLUS_HI(r16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1077 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, NEG_DI(r64)) [1, 4] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_PLUS(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1078 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, NEG_SI(r32)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1079 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, NEG_HI(r16)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1080 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, NEG_QI(r8)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1083 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, NEG_HI(r16)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_PLUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1084 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, NEG_HI(r8)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_PLUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1087 "x86-64.int.py" +r16x : MINUS_HI(r16x, NEG_HI(r16)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("addl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_PLUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1090 "x86-64.int.py" +ccr64x : PLUS_DI(r64x | NEG_DI(r64)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1091 "x86-64.int.py" +ccrz32x : PLUS_SI(r32x | NEG_SI(r32)) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1092 "x86-64.int.py" +ccr16x : PLUS_HI(r16x | NEG_HI(r16)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1093 "x86-64.int.py" +ccr8x : PLUS_QI(r8x | NEG_QI(r8)) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1096 "x86-64.int.py" +ccrz16x : PLUS_HI(rz16x | NEG_HI(r16)) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1097 "x86-64.int.py" +ccrz8x : PLUS_QI(rz8x | NEG_QI(r8)) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1100 "x86-64.int.py" +r16x : PLUS_HI(r16x | NEG_HI(r16)) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1103 "x86-64.int.py" +ccr64x : MINUS_DI(r64x, r64) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MINUS(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1104 "x86-64.int.py" +ccrz32x : MINUS_SI(r32x, r32) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1105 "x86-64.int.py" +ccr16x : MINUS_HI(r16x, r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1106 "x86-64.int.py" +ccr8x : MINUS_QI(r8x, r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1109 "x86-64.int.py" +ccrz16x : MINUS_HI(rz16x, r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MINUS(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1110 "x86-64.int.py" +ccrz8x : MINUS_QI(rz8x, r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_MINUS(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1113 "x86-64.int.py" +r16x : MINUS_HI(r16x, r16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (0) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("subl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MINUS(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1117 "x86-64.int.py" +r64x : MULT_DI(r64x | r64) [4, 4] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("imulq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_MULT(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1118 "x86-64.int.py" +rz32x : MULT_SI(r32x | r32) [3, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("imull", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MULT(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1119 "x86-64.int.py" +r16x : MULT_HI(r16x | r16) [3, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("imull", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MULT(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1120 "x86-64.int.py" +r8x : MULT_QI(r8x | r8) [3, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("imull", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_MULT(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1123 "x86-64.int.py" +rz16x : MULT_HI(rz16x | r16) [3, 4] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("imulw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_MULT(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1126 "x86-64.int.py" +ccr64x : AND_DI(r64x | r64) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_AND(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1127 "x86-64.int.py" +ccrz32x : AND_SI(r32x | r32) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1128 "x86-64.int.py" +ccr16x : AND_HI(r16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1129 "x86-64.int.py" +ccr8x : AND_QI(r8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1132 "x86-64.int.py" +ccrz16x : AND_HI(rz16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_AND(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1133 "x86-64.int.py" +ccrz8x : AND_QI(rz8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_AND(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1136 "x86-64.int.py" +r16x : AND_HI(r16x | r16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1137 "x86-64.int.py" +rz16x : AND_HI(rz16x | r16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1138 "x86-64.int.py" +rz16x : AND_HI(r16x | rz16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1139 "x86-64.int.py" +rs16x : AND_HI(rs16x | rs16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1140 "x86-64.int.py" +r8x : AND_QI(r8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1141 "x86-64.int.py" +rz8x : AND_QI(rz8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1142 "x86-64.int.py" +rz8x : AND_QI(r8x | rz8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1143 "x86-64.int.py" +rs8x : AND_QI(rs8x | rs8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("andl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_AND(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1146 "x86-64.int.py" +ccr64x : IOR_DI(r64x | r64) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_IOR(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1147 "x86-64.int.py" +ccrz32x : IOR_SI(r32x | r32) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1148 "x86-64.int.py" +ccr16x : IOR_HI(r16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1149 "x86-64.int.py" +ccr8x : IOR_QI(r8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1152 "x86-64.int.py" +ccrz16x : IOR_HI(rz16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_IOR(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1153 "x86-64.int.py" +ccrz8x : IOR_QI(rz8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_IOR(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1157 "x86-64.int.py" +r16x : IOR_HI(r16x | r16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1158 "x86-64.int.py" +rz16x : IOR_HI(rz16x | rz16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1159 "x86-64.int.py" +rs16x : IOR_HI(rs16x | rs16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1160 "x86-64.int.py" +rz8x : IOR_QI(rz8x | rz8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1161 "x86-64.int.py" +rs8x : IOR_QI(rs8x | rs8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("orl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_IOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1165 "x86-64.int.py" +ccr64x : XOR_DI(r64x | r64) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorq", $2->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_XOR(DImode, dst, gen_rtx_REG(DImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1166 "x86-64.int.py" +ccrz32x : XOR_SI(r32x | r32) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1167 "x86-64.int.py" +ccr16x : XOR_HI(r16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1168 "x86-64.int.py" +ccr8x : XOR_QI(r8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1171 "x86-64.int.py" +ccrz16x : XOR_HI(rz16x | r16) [1, 3] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorw", $2->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_XOR(HImode, dst, gen_rtx_REG(HImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1172 "x86-64.int.py" +ccrz8x : XOR_QI(rz8x | r8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorb", $2->r, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_XOR(QImode, dst, gen_rtx_REG(QImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1175 "x86-64.int.py" +r16x : XOR_HI(r16x | r16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1176 "x86-64.int.py" +rz16x : XOR_HI(rz16x | rz16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1177 "x86-64.int.py" +rs16x : XOR_HI(rs16x | rs16) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1178 "x86-64.int.py" +rz8x : XOR_QI(rz8x | rz8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1179 "x86-64.int.py" +rs8x : XOR_QI(rs8x | rs8) [1, 2] +#line 1184 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + if (1) + memorable($1->r); + else + forgettable($1->rx); + memorable($2->r); + }, + debug { + dumpRR("xorl", $2->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_XOR(SImode, dst, gen_rtx_REG(SImode, $2->r)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1223 "x86-64.int.py" +ccr64x : NEG_DI(r64x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_NEG(DImode, gen_rtx_REG(DImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1224 "x86-64.int.py" +ccrz32x : NEG_SI(r32x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NEG(SImode, gen_rtx_REG(SImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1225 "x86-64.int.py" +ccr16x : NEG_HI(r16x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_NEG(HImode, gen_rtx_REG(HImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1226 "x86-64.int.py" +ccr8x : NEG_QI(r8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_NEG(QImode, gen_rtx_REG(QImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1229 "x86-64.int.py" +ccrz16x : NEG_HI(rz16x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_NEG(HImode, gen_rtx_REG(HImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1230 "x86-64.int.py" +ccrz8x : NEG_QI(rz8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_NEG(QImode, gen_rtx_REG(QImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1233 "x86-64.int.py" +r16x : NEG_HI(r16x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NEG(SImode, gen_rtx_REG(SImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1236 "x86-64.int.py" +ccrs16x : NEG_HI(rs16x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NEG(SImode, gen_rtx_REG(SImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1237 "x86-64.int.py" +ccrs8x : NEG_HI(rs8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("negl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NEG(SImode, gen_rtx_REG(SImode, $1->rx)); + (1 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1241 "x86-64.int.py" +r64x : NOT_DI(r64x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx src = gen_rtx_NOT(DImode, gen_rtx_REG(DImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1242 "x86-64.int.py" +rz32x : NOT_SI(r32x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NOT(SImode, gen_rtx_REG(SImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1251 "x86-64.int.py" +r16x : NOT_HI(r16x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_NOT(HImode, gen_rtx_REG(HImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1244 "x86-64.int.py" +r8x : NOT_QI(r8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_NOT(QImode, gen_rtx_REG(QImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1247 "x86-64.int.py" +rz16x : NOT_HI(rz16x) [1, 3] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx src = gen_rtx_NOT(HImode, gen_rtx_REG(HImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1248 "x86-64.int.py" +rz8x : NOT_QI(rz8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx src = gen_rtx_NOT(QImode, gen_rtx_REG(QImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1251 "x86-64.int.py" +r16x : NOT_HI(r16x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NOT(SImode, gen_rtx_REG(SImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1252 "x86-64.int.py" +rs16x : NOT_HI(rs16x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NOT(SImode, gen_rtx_REG(SImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1253 "x86-64.int.py" +rs8x : NOT_QI(rs8x) [1, 2] +#line 1257 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpR("notl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx src = gen_rtx_NOT(SImode, gen_rtx_REG(SImode, $1->rx)); + (0 ? icg_emit_clobber : icg_emit_plain)(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1289 "x86-64.int.py" +r64x : NEG_DI(NEG_DI(r64x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1290 "x86-64.int.py" +r32x : NEG_SI(NEG_SI(r32x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1291 "x86-64.int.py" +rz32x : NEG_SI(NEG_SI(rz32x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1292 "x86-64.int.py" +r16x : NEG_HI(NEG_HI(r16x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1293 "x86-64.int.py" +rz16x : NEG_HI(NEG_HI(rz16x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1294 "x86-64.int.py" +rs16x : NEG_HI(NEG_HI(rs16x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1295 "x86-64.int.py" +r8x : NEG_QI(NEG_QI(r8x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1296 "x86-64.int.py" +rz8x : NEG_QI(NEG_QI(rz8x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1297 "x86-64.int.py" +rs8x : NEG_QI(NEG_QI(rs8x)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1298 "x86-64.int.py" +rdx : NEG_DF(NEG_DF(rdx)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1299 "x86-64.int.py" +rfx : NEG_SF(NEG_SF(rfx)) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1301 "x86-64.int.py" +rz32 : SIGN_EXTEND_SI(rs16) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1302 "x86-64.int.py" +rz32 : SIGN_EXTEND_SI(rs8) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1303 "x86-64.int.py" +rs16 : SIGN_EXTEND_HI(rs8) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1304 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(rs16x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1305 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(rs8x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1306 "x86-64.int.py" +rs16x : SIGN_EXTEND_HI(rs8x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1308 "x86-64.int.py" +rz32 : ZERO_EXTEND_SI(rz16) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1309 "x86-64.int.py" +rz32 : ZERO_EXTEND_SI(rz8) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1310 "x86-64.int.py" +rz16 : ZERO_EXTEND_HI(rz8) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1311 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(rz16x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1312 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(rz8x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1313 "x86-64.int.py" +rz16x : ZERO_EXTEND_HI(rz8x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1321 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(rz32x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1322 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(rz16x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1323 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(rz8x) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1324 "x86-64.int.py" +r64 : ZERO_EXTEND_DI(rz32) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1325 "x86-64.int.py" +r64 : ZERO_EXTEND_DI(rz16) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1326 "x86-64.int.py" +r64 : ZERO_EXTEND_DI(rz8) [0, 0] +#line 1330 "x86-64.int.py" + names { + $$->r = $1->r; + }, + final { + $$->r = $1->r; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }; +#line 1352 "x86-64.int.py" +r64x : MULT_DI(r64 | imm8) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulq", $2, $1->r, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_MULT(DImode, + gen_rtx_REG(DImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1353 "x86-64.int.py" +r64x : MULT_DI(r64 | imm32) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulq", $2, $1->r, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_MULT(DImode, + gen_rtx_REG(DImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1354 "x86-64.int.py" +rz32x : MULT_SI(r32 | imm8) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1355 "x86-64.int.py" +rz32x : MULT_SI(r32 | imm32) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1364 "x86-64.int.py" +r16x : MULT_HI(r16 | imm8) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulw", $2, $1->r, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1357 "x86-64.int.py" +r16x : MULT_HI(r16 | imm16) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulw", $2, $1->r, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1360 "x86-64.int.py" +rz16x : MULT_HI(rz16 | imm8) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulw", $2, $1->r, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1361 "x86-64.int.py" +rz16x : MULT_HI(rz16 | imm16) [4, 3] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imulw", $2, $1->r, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1364 "x86-64.int.py" +r16x : MULT_HI(r16 | imm8) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1365 "x86-64.int.py" +r16x : MULT_HI(r16 | imm32) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1366 "x86-64.int.py" +r8x : MULT_QI(r8 | imm8) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1367 "x86-64.int.py" +r8x : MULT_QI(r8 | imm32) [3, 2] +#line 1371 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIRR("imull", $2, $1->r, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1412 "x86-64.int.py" +r64x : MULT_DI(MEM_DI(addr) | imm8) [8, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulq", $2, $1, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_MULT(DImode, + gen_rtx_MEM(DImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1413 "x86-64.int.py" +r64x : MULT_DI(MEM_DI(addr) | imm32) [8, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulq", $2, $1, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_MULT(DImode, + gen_rtx_MEM(DImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1414 "x86-64.int.py" +rz32x : MULT_SI(MEM_SI(addr) | imm8) [7, 2] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imull", $2, $1, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1415 "x86-64.int.py" +rz32x : MULT_SI(MEM_SI(addr) | imm32) [7, 2] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imull", $2, $1, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1416 "x86-64.int.py" +r16x : MULT_HI(MEM_HI(addr) | imm8) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1417 "x86-64.int.py" +r16x : MULT_HI(MEM_HI(addr) | imm16) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1419 "x86-64.int.py" +rz32x : MULT_SI(SUBREG_SI(MEM_DI(addr), CONST_0) | imm8) [7, 2] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imull", $2, $1, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1420 "x86-64.int.py" +rz32x : MULT_SI(SUBREG_SI(MEM_DI(addr), CONST_0) | imm32) [7, 2] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imull", $2, $1, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_MULT(SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1421 "x86-64.int.py" +r16x : MULT_HI(SUBREG_HI(MEM_DI(addr), CONST_0) | imm8) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1422 "x86-64.int.py" +r16x : MULT_HI(SUBREG_HI(MEM_SI(addr), CONST_0) | imm8) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1423 "x86-64.int.py" +r16x : MULT_HI(SUBREG_HI(MEM_DI(addr), CONST_0) | imm16) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1424 "x86-64.int.py" +r16x : MULT_HI(SUBREG_HI(MEM_SI(addr), CONST_0) | imm16) [7, 3] +#line 1428 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + add_addr(live, $1); + }, + debug { + dumpIMR("imulw", $2, $1, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_MULT(HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1470 "x86-64.int.py" +r64x : DIV_DI(r64x, r64) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (1) { + dump("cqo"); /* such as cqo or cdq */ + } else { + dumpRR("cqo", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("idivq", $2->r, 'q'); + } else { + dumpM("idivq", $2); + } + dump_copy("movq", REG_RAX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1471 "x86-64.int.py" +rz32x : DIV_SI(r32x, r32) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1473 "x86-64.int.py" +r64x : MOD_DI(r64x, r64) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (1) { + dump("cqo"); /* such as cqo or cdq */ + } else { + dumpRR("cqo", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("idivq", $2->r, 'q'); + } else { + dumpM("idivq", $2); + } + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1474 "x86-64.int.py" +rz32x : MOD_SI(r32x, r32) [52, 5] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1476 "x86-64.int.py" +r64x : DIV_DI(r64x, MEM_DI(addr)) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (1) { + dump("cqo"); /* such as cqo or cdq */ + } else { + dumpRR("cqo", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivq", $2->r, 'q'); + } else { + dumpM("idivq", $2); + } + dump_copy("movq", REG_RAX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1477 "x86-64.int.py" +rz32x : DIV_SI(r32x, MEM_SI(addr)) [52, 4] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1478 "x86-64.int.py" +rz32x : DIV_SI(r32x, SUBREG_SI(MEM_DI(addr), CONST_0)) [52, 4] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1480 "x86-64.int.py" +r64x : MOD_DI(r64x, MEM_DI(addr)) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (1) { + dump("cqo"); /* such as cqo or cdq */ + } else { + dumpRR("cqo", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivq", $2->r, 'q'); + } else { + dumpM("idivq", $2); + } + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1481 "x86-64.int.py" +rz32x : MOD_SI(r32x, MEM_SI(addr)) [52, 4] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1482 "x86-64.int.py" +rz32x : MOD_SI(r32x, SUBREG_SI(MEM_DI(addr), CONST_0)) [52, 4] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (1) { + dump("cdq"); /* such as cqo or cdq */ + } else { + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("idivl", $2->r, 'd'); + } else { + dumpM("idivl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1490 "x86-64.int.py" +r64x : UDIV_DI(r64x, r64) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divq", $2->r, 'q'); + } else { + dumpM("divq", $2); + } + dump_copy("movq", REG_RAX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1491 "x86-64.int.py" +rz32x : UDIV_SI(r32x, r32) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1492 "x86-64.int.py" +r16x : UDIV_HI(r16x, r16) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1493 "x86-64.int.py" +r8x : UDIV_QI(r16x, r8) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('b' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'b'); + if ('b' != 'b') { + if (0) { + dump("xor?"); /* such as cqo or cdq */ + } else { + dumpRR("xor?", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divb", $2->r, 'b'); + } else { + dumpM("divb", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src1 = gen_rtx_REG(QImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(QImode, $2->r) + : gen_rtx_MEM(QImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(QImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('b' != 'b') ? gen_rtx_REG(QImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('b' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, QImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1495 "x86-64.int.py" +r64x : UMOD_DI(r64x, r64) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divq", $2->r, 'q'); + } else { + dumpM("divq", $2); + } + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1496 "x86-64.int.py" +rz32x : UMOD_SI(r32x, r32) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1497 "x86-64.int.py" +r16x : UMOD_HI(r16x, r16) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (1) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (1) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1499 "x86-64.int.py" +r64x : UDIV_DI(r64x, MEM_DI(addr)) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divq", $2->r, 'q'); + } else { + dumpM("divq", $2); + } + dump_copy("movq", REG_RAX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1500 "x86-64.int.py" +rz32x : UDIV_SI(r32x, MEM_SI(addr)) [52, 5] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1501 "x86-64.int.py" +rz32x : UDIV_SI(r32x, SUBREG_SI(MEM_DI(addr), CONST_0)) [52, 5] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1502 "x86-64.int.py" +r16x : UDIV_HI(r16x, MEM_HI(addr)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1503 "x86-64.int.py" +r16x : UDIV_HI(r16x, SUBREG_HI(MEM_DI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1504 "x86-64.int.py" +r16x : UDIV_HI(r16x, SUBREG_HI(MEM_SI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1505 "x86-64.int.py" +r8x : UDIV_QI(r16x, SUBREG_QI(MEM_DI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('b' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'b'); + if ('b' != 'b') { + if (0) { + dump("xor?"); /* such as cqo or cdq */ + } else { + dumpRR("xor?", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divb", $2->r, 'b'); + } else { + dumpM("divb", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src1 = gen_rtx_REG(QImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(QImode, $2->r) + : gen_rtx_MEM(QImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(QImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('b' != 'b') ? gen_rtx_REG(QImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('b' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, QImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1506 "x86-64.int.py" +r8x : UDIV_QI(r16x, SUBREG_QI(MEM_SI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('b' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'b'); + if ('b' != 'b') { + if (0) { + dump("xor?"); /* such as cqo or cdq */ + } else { + dumpRR("xor?", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divb", $2->r, 'b'); + } else { + dumpM("divb", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src1 = gen_rtx_REG(QImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(QImode, $2->r) + : gen_rtx_MEM(QImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(QImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('b' != 'b') ? gen_rtx_REG(QImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('b' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, QImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1507 "x86-64.int.py" +r8x : UDIV_QI(r16x, SUBREG_QI(MEM_HI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RAX); + }, + build { + if (REG_RAX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('b' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RAX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'b'); + if ('b' != 'b') { + if (0) { + dump("xor?"); /* such as cqo or cdq */ + } else { + dumpRR("xor?", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divb", $2->r, 'b'); + } else { + dumpM("divb", $2); + } + dump_copy("movl", REG_RAX, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src1 = gen_rtx_REG(QImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(QImode, $2->r) + : gen_rtx_MEM(QImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(QImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('b' != 'b') ? gen_rtx_REG(QImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('b' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, QImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, QImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RAX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1509 "x86-64.int.py" +r64x : UMOD_DI(r64x, MEM_DI(addr)) [52, 8] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if ('q' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divq", $2->r, 'q'); + } else { + dumpM("divq", $2); + } + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('q' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1510 "x86-64.int.py" +rz32x : UMOD_SI(r32x, MEM_SI(addr)) [52, 5] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1511 "x86-64.int.py" +rz32x : UMOD_SI(r32x, SUBREG_SI(MEM_DI(addr), CONST_0)) [52, 5] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('d' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'd'); + if ('d' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divl", $2->r, 'd'); + } else { + dumpM("divl", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'd'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $2->r) + : gen_rtx_MEM(SImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('d' != 'b') ? gen_rtx_REG(SImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('d' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1512 "x86-64.int.py" +r16x : UMOD_HI(r16x, MEM_HI(addr)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1513 "x86-64.int.py" +r16x : UMOD_HI(r16x, SUBREG_HI(MEM_DI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1514 "x86-64.int.py" +r16x : UMOD_HI(r16x, SUBREG_HI(MEM_SI(addr), CONST_0)) [52, 6] +#line 1518 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if (REG_RDX == REG_RAX) + add_copy_edges($$->rx, REG_RAX, live); + + else + add_copy_edges($$->rx, REG_RDX, live); + + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($2->r)); + else + add_addr(live, $2); + + if ('w' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + } + + add_copy_edges(REG_RAX, $1->rx, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($1->rx, REG_RAX); + memorable($1->rx); + if (0) + memorable($2->r); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movl", $1->rx, REG_RAX, 'w'); + if ('w' != 'b') { + if (0) { + dump("xorl"); /* such as cqo or cdq */ + } else { + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* xorl */ + } + } + if (0) { + dumpR("divw", $2->r, 'w'); + } else { + dumpM("divw", $2); + } + dump_copy("movl", REG_RDX, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src1 = gen_rtx_REG(HImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(HImode, $2->r) + : gen_rtx_MEM(HImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rax1 = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = ('w' != 'b') ? gen_rtx_REG(HImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * TODO? emit RTL for the sign_extend (true sign extend, or zero fill with xor) using rdx/rdxm + */ + parset = ('w' == 'b') + ? gen_rtvec(2, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax1, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + : gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, HImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))) + ; + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs64, DIV_DI(r64, r64)), +#line 1660 "x86-64.int.py" + SET_ALL(lhs64, MOD_DI(r64, r64))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (1) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + + if (1) + dump("cqo"); + else + dumpRR("cqo", REG_RDX, 'q', REG_RDX, 'q'); + + if (1) + dumpR("idivq", $3->r, 'q'); + else + dumpM("idivq", $3); + + if ($1->spilled) + dumpRM("movq", REG_RAX, 'q', $1); + else + dump_copy("movq", REG_RAX, $1->r, 'q'); + + if ($1->spilled) + dumpRM("movq", REG_RDX, 'q', $4); + else + dump_copy("movq", REG_RDX, $4->r, 'q'); + }, + emit { + rtx src1 = gen_rtx_REG(DImode, $2->r); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $3->r) + : gen_rtx_MEM(DImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(DImode, $4->rtl) + : gen_rtx_REG(DImode, $4->r); + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = gen_rtx_REG(DImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, DIV_SI(r32, r32)), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, MOD_SI(r32, r32))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (1) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (1) + dump("cdq"); + else + dumpRR("cdq", REG_RDX, 'd', REG_RDX, 'd'); + + if (1) + dumpR("idivl", $3->r, 'd'); + else + dumpM("idivl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs64, UDIV_DI(r64, r64)), +#line 1660 "x86-64.int.py" + SET_ALL(lhs64, UMOD_DI(r64, r64))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (1) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + + if (0) + dump("xorl"); + else + dumpRR("xorl", REG_RDX, 'q', REG_RDX, 'q'); + + if (1) + dumpR("divq", $3->r, 'q'); + else + dumpM("divq", $3); + + if ($1->spilled) + dumpRM("movq", REG_RAX, 'q', $1); + else + dump_copy("movq", REG_RAX, $1->r, 'q'); + + if ($1->spilled) + dumpRM("movq", REG_RDX, 'q', $4); + else + dump_copy("movq", REG_RDX, $4->r, 'q'); + }, + emit { + rtx src1 = gen_rtx_REG(DImode, $2->r); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $3->r) + : gen_rtx_MEM(DImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(DImode, $4->rtl) + : gen_rtx_REG(DImode, $4->r); + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = gen_rtx_REG(DImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, UDIV_SI(r32, r32)), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, UMOD_SI(r32, r32))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (1) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (1) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (0) + dump("xorl"); + else + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); + + if (1) + dumpR("divl", $3->r, 'd'); + else + dumpM("divl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 1 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs64, DIV_DI(r64, MEM_DI(addr))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs64, MOD_DI(r64, MEM_DI(addr)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + + if (1) + dump("cqo"); + else + dumpRR("cqo", REG_RDX, 'q', REG_RDX, 'q'); + + if (0) + dumpR("idivq", $3->r, 'q'); + else + dumpM("idivq", $3); + + if ($1->spilled) + dumpRM("movq", REG_RAX, 'q', $1); + else + dump_copy("movq", REG_RAX, $1->r, 'q'); + + if ($1->spilled) + dumpRM("movq", REG_RDX, 'q', $4); + else + dump_copy("movq", REG_RDX, $4->r, 'q'); + }, + emit { + rtx src1 = gen_rtx_REG(DImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $3->r) + : gen_rtx_MEM(DImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(DImode, $4->rtl) + : gen_rtx_REG(DImode, $4->r); + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = gen_rtx_REG(DImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, DIV_SI(r32, MEM_SI(addr))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, MOD_SI(r32, MEM_SI(addr)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (1) + dump("cltd"); + else + dumpRR("cltd", REG_RDX, 'd', REG_RDX, 'd'); + + if (0) + dumpR("idivl", $3->r, 'd'); + else + dumpM("idivl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, DIV_SI(r32, SUBREG_SI(MEM_DI(addr), CONST_0))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, MOD_SI(r32, SUBREG_SI(MEM_DI(addr), CONST_0)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (1) + dump("cltd"); + else + dumpRR("cltd", REG_RDX, 'd', REG_RDX, 'd'); + + if (0) + dumpR("idivl", $3->r, 'd'); + else + dumpM("idivl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(1, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(1, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs64, UDIV_DI(r64, MEM_DI(addr))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs64, UMOD_DI(r64, MEM_DI(addr)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + + if (0) + dump("xorl"); + else + dumpRR("xorl", REG_RDX, 'q', REG_RDX, 'q'); + + if (0) + dumpR("divq", $3->r, 'q'); + else + dumpM("divq", $3); + + if ($1->spilled) + dumpRM("movq", REG_RAX, 'q', $1); + else + dump_copy("movq", REG_RAX, $1->r, 'q'); + + if ($1->spilled) + dumpRM("movq", REG_RDX, 'q', $4); + else + dump_copy("movq", REG_RDX, $4->r, 'q'); + }, + emit { + rtx src1 = gen_rtx_REG(DImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $3->r) + : gen_rtx_MEM(DImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(DImode, $4->rtl) + : gen_rtx_REG(DImode, $4->r); + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = gen_rtx_REG(DImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, DImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, DImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, UDIV_SI(r32, MEM_SI(addr))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, UMOD_SI(r32, MEM_SI(addr)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (0) + dump("xorl"); + else + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); + + if (0) + dumpR("divl", $3->r, 'd'); + else + dumpM("divl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1647 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs32, UDIV_SI(r32, SUBREG_SI(MEM_DI(addr), CONST_0))), +#line 1660 "x86-64.int.py" + SET_ALL(lhs32, UMOD_SI(r32, SUBREG_SI(MEM_DI(addr), CONST_0)))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + if (0) + sparseset_set_bit(live, find($3->r)); + else + add_addr(live, $3); + + /* extension instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + if (0) + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); + + if (0) + dump("xorl"); + else + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); + + if (0) + dumpR("divl", $3->r, 'd'); + else + dumpM("divl", $3); + + if ($1->spilled) + dumpRM("movl", REG_RAX, 'd', $1); + else + dump_copy("movl", REG_RAX, $1->r, 'd'); + + if ($1->spilled) + dumpRM("movl", REG_RDX, 'd', $4); + else + dump_copy("movl", REG_RDX, $4->r, 'd'); + }, + emit { + rtx src1 = gen_rtx_REG(SImode, $2->r); + rtx src2 = 0 + ? gen_rtx_REG(SImode, $3->r) + : gen_rtx_MEM(SImode, $3->rtl); + rtx dst1 = $1->spilled + ? gen_rtx_MEM(SImode, $1->rtl) + : gen_rtx_REG(SImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(SImode, $4->rtl) + : gen_rtx_REG(SImode, $4->r); + rtx rax = gen_rtx_REG(SImode, REG_RAX); + rtx rdx = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, rax, gen_rtx_DIV_helper(0, SImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_MOD_helper(0, SImode, rax, src2)), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1766 "x86-64.int.py" +stmt : PARALLEL_ALL(SET_ALL(lhs16, UDIV_HI(r16, r16)), +#line 1770 "x86-64.int.py" + PARALLEL_ALL(SET_ALL(lhs16, UMOD_HI(r16, r16)), + USE_ALL(CONST_0))) [52, 8] + supairs { + /* suOrder2($$, $1, $2, kid, kids); */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RAX); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RDX); + }, + build { + /* final copy instruction */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RDX); + add_addr(live, $4); + } + else + add_copy_edges($4->r, REG_RDX, live); + + /* penultimate copy instruction */ + if ($1->spilled) { + sparseset_set_bit(live, REG_RAX); + add_addr(live, $1); + } + else + add_copy_edges($1->r, REG_RAX, live); + + /* divide instruction */ + add_edges(REG_RAX, live); + sparseset_set_bit(live, find($3->r)); + + /* xor instruction */ + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); + + /* final copy instruction */ + add_copy_edges(REG_RAX, $2->r, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + cost_copy($2->r, REG_RAX); + memorable($3->r); + if (!$1->spilled) + cost_copy($1->r, REG_RAX); + if (!$4->spilled) + cost_copy(REG_RDX, $4->r); + }, + debug { + dump_copy("movl", $2->r, REG_RAX, 'd'); /* use movw? no, movl is preferred */ + dumpRR("xorl", REG_RDX, 'd', REG_RDX, 'd'); /* use xorw? no, xorl is preferred */ + dumpR("divw", $3->r, 'w'); + dump_copy("movl", REG_RAX, $1->r, 'd'); /* use movw? no, movl is preferred */ + dump_copy("movl", REG_RDX, $4->r, 'd'); /* use movw? no, movl is preferred */ + }, + emit { + rtx dst1 = $1->spilled + ? gen_rtx_MEM(HImode, $1->rtl) + : gen_rtx_REG(HImode, $1->r); + rtx dst2 = $4->spilled + ? gen_rtx_MEM(HImode, $4->rtl) + : gen_rtx_REG(HImode, $4->r); + + rtx src1 = gen_rtx_REG(HImode, $2->r); + rtx src2 = gen_rtx_REG(HImode, $3->r); + rtx rax = gen_rtx_REG(HImode, REG_RAX); + rtx rdx = gen_rtx_REG(HImode, REG_RDX); + rtx rdxm = gen_rtx_REG(SImode, REG_RDX); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, rdxm, + gen_rtx_XOR(SImode, rdxm, rdxm))); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(4, + gen_rtx_SET(VOIDmode, rax, gen_rtx_UDIV(HImode, rax, src2)), + gen_rtx_SET(VOIDmode, rdx, gen_rtx_UMOD(HImode, rax, src2)), + gen_rtx_USE(VOIDmode, rdx), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG))))); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1, rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst2, rdx)); + }; +#line 1883 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1884 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1893 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1886 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1889 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1890 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1893 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1896 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1897 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1898 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1900 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1901 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1902 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1922 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1923 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1924 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1908 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1909 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1910 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1913 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1914 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1915 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1917 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1918 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1919 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("salb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1922 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1923 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1924 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sall", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1929 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1930 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1931 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1932 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1935 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1936 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1939 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1940 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1943 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1944 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1945 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1947 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1948 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1949 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1951 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1952 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1953 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1955 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1956 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1957 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1960 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1961 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1962 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1964 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1965 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1966 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1969 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1970 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1971 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1973 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1974 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1975 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("sarb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ASHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1979 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1980 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1981 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1982 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1985 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1986 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1989 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1990 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1991 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1993 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1994 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1995 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1997 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, SUBREG_QI(r64x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1998 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, SUBREG_QI(r32x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1999 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, SUBREG_QI(r16x, CONST_0)) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2001 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2002 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2003 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2006 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2007 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2008 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2010 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, SUBREG_QI(r64x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2011 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, SUBREG_QI(r32x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2012 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, SUBREG_QI(r16x, CONST_0)) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("shrb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_LSHIFTRT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2015 "x86-64.int.py" +r64x : ROTATE_DI(r64x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rolq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATE(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2016 "x86-64.int.py" +r32x : ROTATE_SI(r32x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("roll", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATE(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2017 "x86-64.int.py" +r16x : ROTATE_HI(r16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rolw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATE(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2018 "x86-64.int.py" +r8x : ROTATE_QI(r8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rolb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATE(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2021 "x86-64.int.py" +r64x : ROTATERT_DI(r64x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rorq", REG_RCX, 'b', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATERT(DImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2022 "x86-64.int.py" +r32x : ROTATERT_SI(r32x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rorl", REG_RCX, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATERT(SImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2023 "x86-64.int.py" +r16x : ROTATERT_HI(r16x, r8x) [1, 3] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rorw", REG_RCX, 'b', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATERT(HImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2024 "x86-64.int.py" +r8x : ROTATERT_QI(r8x, r8x) [1, 2] +#line 2028 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + forgettable($2->rx); + cost_copy(REG_RCX, $2->rx); + }, + debug { + dump_copy("movl", $2->rx, REG_RCX, 'd'); + dumpRR("rorb", REG_RCX, 'b', $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $1->rx); + rtx rcx = gen_rtx_REG(SImode, REG_RCX); + rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + src = gen_rtx_ROTATERT(QImode, dst, gen_rtx_REG(QImode, REG_RCX)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2077 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("salq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2078 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sall", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2087 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("salw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2080 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("salb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2083 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("salw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2084 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("salb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2087 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sall", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2091 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(DImode, + gen_rtx_REG(DImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2092 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarw", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2093 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2094 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2097 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2098 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2101 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2102 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("sarb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2106 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(DImode, + gen_rtx_REG(DImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2107 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2108 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2109 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2112 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2113 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("shrb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2118 "x86-64.int.py" +r64x : ROTATE_DI(r64x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rolq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ROTATE(DImode, + gen_rtx_REG(DImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2119 "x86-64.int.py" +r32x : ROTATE_SI(r32x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("roll", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ROTATE(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2120 "x86-64.int.py" +r16x : ROTATE_HI(r16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rolw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ROTATE(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2121 "x86-64.int.py" +r8x : ROTATE_QI(r8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rolb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ROTATE(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2123 "x86-64.int.py" +r64x : ROTATERT_DI(r64x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rorq", $2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ROTATERT(DImode, + gen_rtx_REG(DImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2124 "x86-64.int.py" +r32x : ROTATERT_SI(r32x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rorl", $2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ROTATERT(SImode, + gen_rtx_REG(SImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2125 "x86-64.int.py" +r16x : ROTATERT_HI(r16x, imm8) [1, 3] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rorw", $2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ROTATERT(HImode, + gen_rtx_REG(HImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2126 "x86-64.int.py" +r8x : ROTATERT_QI(r8x, imm8) [1, 2] +#line 2130 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR("rorb", $2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ROTATERT(QImode, + gen_rtx_REG(QImode, $1->rx), + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2170 "x86-64.int.py" +r64x : ASHIFT_DI(r64x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("salq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2171 "x86-64.int.py" +rz32x : ASHIFT_SI(r32x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sall", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2180 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("salw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2173 "x86-64.int.py" +r8x : ASHIFT_QI(r8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("salb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2176 "x86-64.int.py" +rz16x : ASHIFT_HI(rz16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("salw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2177 "x86-64.int.py" +rz8x : ASHIFT_QI(rz8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("salb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2180 "x86-64.int.py" +r16x : ASHIFT_HI(r16x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sall", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2184 "x86-64.int.py" +r64x : ASHIFTRT_DI(r64x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2185 "x86-64.int.py" +rz32x : ASHIFTRT_SI(r32x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2186 "x86-64.int.py" +r16x : ASHIFTRT_HI(r16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2187 "x86-64.int.py" +r8x : ASHIFTRT_QI(r8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2190 "x86-64.int.py" +rz16x : ASHIFTRT_HI(rz16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2191 "x86-64.int.py" +rz8x : ASHIFTRT_QI(rz8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2194 "x86-64.int.py" +rs16x : ASHIFTRT_HI(rs16x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2195 "x86-64.int.py" +rs8x : ASHIFTRT_QI(rs8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("sarb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ASHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2199 "x86-64.int.py" +r64x : LSHIFTRT_DI(r64x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2200 "x86-64.int.py" +rz32x : LSHIFTRT_SI(r32x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2201 "x86-64.int.py" +r16x : LSHIFTRT_HI(r16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2202 "x86-64.int.py" +r8x : LSHIFTRT_QI(r8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2205 "x86-64.int.py" +rz16x : LSHIFTRT_HI(rz16x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2206 "x86-64.int.py" +rz8x : LSHIFTRT_QI(rz8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("shrb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_LSHIFTRT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2208 "x86-64.int.py" +r64x : ROTATE_DI(r64x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rolq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ROTATE(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2209 "x86-64.int.py" +r32x : ROTATE_SI(r32x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("roll", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ROTATE(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2210 "x86-64.int.py" +r16x : ROTATE_HI(r16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rolw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ROTATE(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2211 "x86-64.int.py" +r8x : ROTATE_QI(r8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rolb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ROTATE(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2212 "x86-64.int.py" +r64x : ROTATERT_DI(r64x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rorq", $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ROTATERT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2213 "x86-64.int.py" +r32x : ROTATERT_SI(r32x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rorl", $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ROTATERT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2214 "x86-64.int.py" +r16x : ROTATERT_HI(r16x, CONST_P1) [1, 3] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rorw", $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_ROTATERT(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2215 "x86-64.int.py" +r8x : ROTATERT_QI(r8x, CONST_P1) [1, 2] +#line 2219 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIR1("rorb", $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_ROTATERT(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(1)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2274 "x86-64.int.py" +r64x : PLUS_DI(base64 | disp) [1, 2] +#line 2281 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + }, + remat { + unsigned r = find($1->a.base); + if (r == REG_FP || r == REG_ARGP) + flags |= RHS_REMAT; + else + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, 0, 0, $2->a.disp, $2->a.string, + $$->rx, 'q'); + }, + emit { + rtx src = gen_rtx_PLUS(DImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2275 "x86-64.int.py" +rz32x : PLUS_SI(base32 | disp) [1, 1] +#line 2281 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + }, + remat { + unsigned r = find($1->a.base); + if (r == REG_FP || r == REG_ARGP) + flags |= RHS_REMAT; + else + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, 0, 0, $2->a.disp, $2->a.string, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2276 "x86-64.int.py" +r16x : PLUS_HI(base16 | disp) [1, 1] +#line 2281 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + }, + remat { + unsigned r = find($1->a.base); + if (r == REG_FP || r == REG_ARGP) + flags |= RHS_REMAT; + else + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, 0, 0, $2->a.disp, $2->a.string, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2277 "x86-64.int.py" +r8x : PLUS_QI(base8 | disp) [1, 1] +#line 2281 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + }, + remat { + unsigned r = find($1->a.base); + if (r == REG_FP || r == REG_ARGP) + flags |= RHS_REMAT; + else + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, 0, 0, $2->a.disp, $2->a.string, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2329 "x86-64.int.py" +r64x : PLUS_DI(r64 | r64) [1, 3] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'q'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->r); + rtx src2 = gen_rtx_REG(DImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(DImode, src1, src2); + else + src = gen_rtx_PLUS(DImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2330 "x86-64.int.py" +rz32x : PLUS_SI(r32 | r32) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2331 "x86-64.int.py" +r16x : PLUS_HI(r16 | r16) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2332 "x86-64.int.py" +r8x : PLUS_QI(r8 | r8) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2334 "x86-64.int.py" +r64x : MINUS_DI(r64, NEG_DI(r64)) [1, 3] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'q'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->r); + rtx src2 = gen_rtx_REG(DImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(DImode, src1, src2); + else + src = gen_rtx_PLUS(DImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2335 "x86-64.int.py" +rz32x : MINUS_SI(r32, NEG_SI(r32)) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2336 "x86-64.int.py" +r16x : MINUS_HI(r16, NEG_HI(r16)) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2337 "x86-64.int.py" +r8x : MINUS_QI(r8, NEG_QI(r8)) [1, 2] +#line 2341 "x86-64.int.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->r, true, $2->r, 1, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src1 = gen_rtx_REG(SImode, $1->r); + rtx src2 = gen_rtx_REG(SImode, $2->r); + if ($1->a.base == $$->rx) + src = gen_rtx_PLUS(SImode, src1, src2); + else + src = gen_rtx_PLUS(SImode, src2, src1); + icg_emit_clobber_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "clobber", not "plain" */ + }; +#line 2389 "x86-64.int.py" +r64x : PLUS_DI(base64 | index64 | disp) [2, 2] +#line 2396 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->a.index, $2->a.scale, $3->a.disp, $3->a.string, + $$->rx, 'q'); + }, + emit { + /* + * for some reason, 64 bit leaq must have the gcc tree + * built slightly differently, or the back end of gcc will + * not be able to match it. gen_rtx_addr will build a tree + * from two gen_rtx_PLUS, but with a different permutation + * than we use for the other kinds of lea instruction. + */ + const rtx src = ('q' == 'q') + ? gen_rtx_addr(DImode, $1->rtl, $2->rtl, $3->rtl) + : gen_rtx_PLUS(SImode, gen_rtx_PLUS(DImode, $2->rtl, $1->rtl), $3->rtl) + ; + const rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2390 "x86-64.int.py" +rz32x : PLUS_SI(base32 | index32 | disp) [2, 1] +#line 2396 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, $3->a.disp, $3->a.string, + $$->rx, 'l'); + }, + emit { + /* + * for some reason, 64 bit leaq must have the gcc tree + * built slightly differently, or the back end of gcc will + * not be able to match it. gen_rtx_addr will build a tree + * from two gen_rtx_PLUS, but with a different permutation + * than we use for the other kinds of lea instruction. + */ + const rtx src = ('l' == 'q') + ? gen_rtx_addr(SImode, $1->rtl, $2->rtl, $3->rtl) + : gen_rtx_PLUS(SImode, gen_rtx_PLUS(SImode, $2->rtl, $1->rtl), $3->rtl) + ; + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2391 "x86-64.int.py" +r16x : PLUS_HI(base16 | index16 | disp) [2, 1] +#line 2396 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, $3->a.disp, $3->a.string, + $$->rx, 'l'); + }, + emit { + /* + * for some reason, 64 bit leaq must have the gcc tree + * built slightly differently, or the back end of gcc will + * not be able to match it. gen_rtx_addr will build a tree + * from two gen_rtx_PLUS, but with a different permutation + * than we use for the other kinds of lea instruction. + */ + const rtx src = ('l' == 'q') + ? gen_rtx_addr(SImode, $1->rtl, $2->rtl, $3->rtl) + : gen_rtx_PLUS(SImode, gen_rtx_PLUS(SImode, $2->rtl, $1->rtl), $3->rtl) + ; + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2392 "x86-64.int.py" +r8x : PLUS_QI(base8 | index8 | disp) [2, 1] +#line 2396 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, $3->a.disp, $3->a.string, + $$->rx, 'l'); + }, + emit { + /* + * for some reason, 64 bit leaq must have the gcc tree + * built slightly differently, or the back end of gcc will + * not be able to match it. gen_rtx_addr will build a tree + * from two gen_rtx_PLUS, but with a different permutation + * than we use for the other kinds of lea instruction. + */ + const rtx src = ('l' == 'q') + ? gen_rtx_addr(SImode, $1->rtl, $2->rtl, $3->rtl) + : gen_rtx_PLUS(SImode, gen_rtx_PLUS(SImode, $2->rtl, $1->rtl), $3->rtl) + ; + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2450 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm5) | CONST_P8)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2451 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm29) | CONST_P8)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2452 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm6) | CONST_P4)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2453 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm30) | CONST_P4)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2454 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm7) | CONST_P2)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2455 "x86-64.int.py" +r64x : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm31) | CONST_P2)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2457 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm5), CONST_P3)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2458 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm29), CONST_P3)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2459 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm6), CONST_P2)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2460 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm30), CONST_P2)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2461 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm7), CONST_P1)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2462 "x86-64.int.py" +r64x : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm31), CONST_P1)) [2, 2] +#line 2466 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2510 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm5) | CONST_P8)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2511 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm29) | CONST_P8)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2512 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm5) | CONST_P8)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2513 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm13) | CONST_P8)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2514 "x86-64.int.py" +r8x : PLUS_QI(base8 | MULT_QI(PLUS_QI(r8 | imm5) | CONST_P8)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2515 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm6) | CONST_P4)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2516 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm30) | CONST_P4)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2517 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm6) | CONST_P4)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2518 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm14) | CONST_P4)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2519 "x86-64.int.py" +r8x : PLUS_QI(base8 | MULT_QI(PLUS_QI(r8 | imm6) | CONST_P4)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2520 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm7) | CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2521 "x86-64.int.py" +rz32x : PLUS_SI(base32 | MULT_SI(PLUS_SI(r32 | imm31) | CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2522 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm7) | CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2523 "x86-64.int.py" +r16x : PLUS_HI(base16 | MULT_HI(PLUS_HI(r16 | imm15) | CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2524 "x86-64.int.py" +r8x : PLUS_QI(base8 | MULT_QI(PLUS_QI(r8 | imm7) | CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2526 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm5), CONST_P3)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2527 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm29), CONST_P3)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2528 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm5), CONST_P3)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2529 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm13), CONST_P3)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2530 "x86-64.int.py" +r8x : PLUS_QI(base8 | ASHIFT_QI(PLUS_QI(r8 | imm5), CONST_P3)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 8, $3->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($3->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2531 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm6), CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2532 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm30), CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2533 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm6), CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2534 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm14), CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2535 "x86-64.int.py" +r8x : PLUS_QI(base8 | ASHIFT_QI(PLUS_QI(r8 | imm6), CONST_P2)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 4, $3->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($3->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2536 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm7), CONST_P1)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2537 "x86-64.int.py" +rz32x : PLUS_SI(base32 | ASHIFT_SI(PLUS_SI(r32 | imm31), CONST_P1)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2538 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm7), CONST_P1)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2539 "x86-64.int.py" +r16x : PLUS_HI(base16 | ASHIFT_HI(PLUS_HI(r16 | imm15), CONST_P1)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2540 "x86-64.int.py" +r8x : PLUS_QI(base8 | ASHIFT_QI(PLUS_QI(r8 | imm7), CONST_P1)) [2, 1] +#line 2544 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->r, 2, $3->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $2->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($3->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2592 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm4) | CONST_P8)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2593 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm28) | CONST_P8)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2594 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm5) | CONST_P4)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2595 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm29) | CONST_P4)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2596 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm6) | CONST_P2)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2597 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm30) | CONST_P2)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2599 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm4), CONST_P3)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2600 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm28), CONST_P3)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2601 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm5), CONST_P2)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2602 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm29), CONST_P2)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2603 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm6), CONST_P1)) [2, 1] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2604 "x86-64.int.py" +r64x : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm30), CONST_P1)) [2, 0] +#line 2608 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'q'); + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + rtx src = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2654 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | MULT_SI(PLUS_SI(r32 | imm4) | CONST_P8)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2655 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | MULT_SI(PLUS_SI(r32 | imm28) | CONST_P8)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2656 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | MULT_HI(PLUS_HI(r16 | imm5) | CONST_P8)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2657 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | MULT_HI(PLUS_HI(r16 | imm13) | CONST_P8)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2658 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | MULT_QI(PLUS_QI(r8 | imm5) | CONST_P8)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2659 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | MULT_SI(PLUS_SI(r32 | imm6) | CONST_P4)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2660 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | MULT_SI(PLUS_SI(r32 | imm30) | CONST_P4)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2661 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | MULT_HI(PLUS_HI(r16 | imm6) | CONST_P4)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2662 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | MULT_HI(PLUS_HI(r16 | imm14) | CONST_P4)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2663 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | MULT_QI(PLUS_QI(r8 | imm6) | CONST_P4)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2664 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | MULT_SI(PLUS_SI(r32 | imm7) | CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2665 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | MULT_SI(PLUS_SI(r32 | imm31) | CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2666 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | MULT_HI(PLUS_HI(r16 | imm7) | CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2667 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | MULT_HI(PLUS_HI(r16 | imm15) | CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2668 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | MULT_QI(PLUS_QI(r8 | imm7) | CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2670 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | ASHIFT_SI(PLUS_SI(r32 | imm5), CONST_P3)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2671 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | ASHIFT_SI(PLUS_SI(r32 | imm29), CONST_P3)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2672 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | ASHIFT_HI(PLUS_HI(r16 | imm5), CONST_P3)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2673 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | ASHIFT_HI(PLUS_HI(r16 | imm13), CONST_P3)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2674 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | ASHIFT_QI(PLUS_QI(r8 | imm5), CONST_P3)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 8, $2->val + $4->val*8, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(8)), + $1->rtl), + GEN_INT($2->val + $4->val*8)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2675 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | ASHIFT_SI(PLUS_SI(r32 | imm6), CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2676 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | ASHIFT_SI(PLUS_SI(r32 | imm30), CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2677 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | ASHIFT_HI(PLUS_HI(r16 | imm6), CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2678 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | ASHIFT_HI(PLUS_HI(r16 | imm14), CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2679 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | ASHIFT_QI(PLUS_QI(r8 | imm6), CONST_P2)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 4, $2->val + $4->val*4, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(4)), + $1->rtl), + GEN_INT($2->val + $4->val*4)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2680 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm7 | ASHIFT_SI(PLUS_SI(r32 | imm7), CONST_P1)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2681 "x86-64.int.py" +rz32x : PLUS_SI(base32 | imm31 | ASHIFT_SI(PLUS_SI(r32 | imm31), CONST_P1)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2682 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm7 | ASHIFT_HI(PLUS_HI(r16 | imm7), CONST_P1)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2683 "x86-64.int.py" +r16x : PLUS_HI(base16 | imm15 | ASHIFT_HI(PLUS_HI(r16 | imm15), CONST_P1)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2684 "x86-64.int.py" +r8x : PLUS_QI(base8 | imm7 | ASHIFT_QI(PLUS_QI(r8 | imm7), CONST_P1)) [2, 0] +#line 2688 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($3->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $3->r, 2, $2->val + $4->val*2, NULL, + $$->rx, 'l'); + }, + emit { + rtx src2 = gen_rtx_REG(SImode, $3->r); + rtx src = gen_rtx_PLUS(SImode, + gen_rtx_PLUS(SImode, + gen_rtx_MULT(SImode, src2, GEN_INT(2)), + $1->rtl), + GEN_INT($2->val + $4->val*2)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2737 "x86-64.int.py" +r64x : PLUS_DI(base64 | index64) [2, 2] +#line 2744 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + $1->a.base, true, $2->a.index, $2->a.scale, 0, NULL, + $$->rx, 'q'); + }, + emit { + rtx src = 1 /* 64-bit RTL shape weirdness */ + ? gen_rtx_PLUS(DImode, $1->rtl, $2->rtl) + : gen_rtx_PLUS(DImode, $2->rtl, $1->rtl) + ; + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2738 "x86-64.int.py" +rz32x : PLUS_SI(base32 | index32) [2, 1] +#line 2744 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = 0 /* 64-bit RTL shape weirdness */ + ? gen_rtx_PLUS(SImode, $1->rtl, $2->rtl) + : gen_rtx_PLUS(SImode, $2->rtl, $1->rtl) + ; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2739 "x86-64.int.py" +r16x : PLUS_HI(base16 | index16) [2, 1] +#line 2744 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = 0 /* 64-bit RTL shape weirdness */ + ? gen_rtx_PLUS(SImode, $1->rtl, $2->rtl) + : gen_rtx_PLUS(SImode, $2->rtl, $1->rtl) + ; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2740 "x86-64.int.py" +r8x : PLUS_QI(base8 | index8) [2, 1] +#line 2744 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.base)); + sparseset_set_bit(live, find($2->a.index)); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + $1->a.base, true, $2->a.index, $2->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = 0 /* 64-bit RTL shape weirdness */ + ? gen_rtx_PLUS(SImode, $1->rtl, $2->rtl) + : gen_rtx_PLUS(SImode, $2->rtl, $1->rtl) + ; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2785 "x86-64.int.py" +r64x : PLUS_DI(index64 | imm32) [2, 3] +#line 2792 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + 0, false, $1->a.index, $1->a.scale, $2->val, NULL, + $$->rx, 'q'); + }, + emit { + rtx src = gen_rtx_PLUS(DImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2786 "x86-64.int.py" +rz32x : PLUS_SI(index32 | imm32) [2, 2] +#line 2792 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, $2->val, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2787 "x86-64.int.py" +r16x : PLUS_HI(index16 | imm32) [2, 2] +#line 2792 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, $2->val, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2788 "x86-64.int.py" +r8x : PLUS_QI(index8 | imm32) [2, 2] +#line 2792 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, $2->val, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = gen_rtx_PLUS(SImode, $1->rtl, $2->rtl); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2833 "x86-64.int.py" +r64x : index64 [2, 7] +#line 2840 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leaq", + 0, false, $1->a.index, $1->a.scale, 0, NULL, + $$->rx, 'q'); + }, + emit { + rtx src = $1->rtl; + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2834 "x86-64.int.py" +rz32x : index32 [2, 6] +#line 2840 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = $1->rtl; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2835 "x86-64.int.py" +r16x : index16 [2, 6] +#line 2840 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = $1->rtl; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2836 "x86-64.int.py" +r8x : index8 [2, 6] +#line 2840 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + add_edges(rd, live); + sparseset_clear_bit(live, rd); + sparseset_set_bit(live, find($1->a.index)); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dumpMbidR("leal", + 0, false, $1->a.index, $1->a.scale, 0, NULL, + $$->rx, 'l'); + }, + emit { + rtx src = $1->rtl; + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain_tagged(gen_rtx_SET(VOIDmode, dst, src), __FILE__, __LINE__); + /* the above line must be "plain", not "clobber" */ + }; +#line 2887 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(r32) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(SImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_REG(SImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movslq", $1->r, 'l', $$->rx, 'q'); + }; +#line 2888 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(r16) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(HImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_REG(HImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movswq", $1->r, 'w', $$->rx, 'q'); + }; +#line 2889 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(r8) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movsbq", $1->r, 'b', $$->rx, 'q'); + }; +#line 2890 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(r16) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(HImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_REG(HImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movswl", $1->r, 'w', $$->rx, 'l'); + }; +#line 2891 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(r8) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movsbl", $1->r, 'b', $$->rx, 'l'); + }; +#line 2892 "x86-64.int.py" +r16x : SIGN_EXTEND_HI(r8) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(HImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movsbw", $1->r, 'b', $$->rx, 'w'); + }; +#line 2895 "x86-64.int.py" +rs16x : SIGN_EXTEND_HI(r8) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movsbl", $1->r, 'b', $$->rx, 'l'); + }; +#line 2899 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(r32) [1, 2] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (1) + src = gen_rtx_REG(SImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(SImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movl", $1->r, 'l', $$->rx, 'l'); + }; +#line 2900 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(r16) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(HImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(DImode, gen_rtx_REG(HImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzwq", $1->r, 'w', $$->rx, 'q'); + }; +#line 2901 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(r8) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(DImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzbq", $1->r, 'b', $$->rx, 'q'); + }; +#line 2902 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(r16) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(HImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(HImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzwl", $1->r, 'w', $$->rx, 'l'); + }; +#line 2903 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(r8) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }; +#line 2904 "x86-64.int.py" +r16x : ZERO_EXTEND_HI(r8) [1, 4] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(HImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzbw", $1->r, 'b', $$->rx, 'w'); + }; +#line 2907 "x86-64.int.py" +rz16x : ZERO_EXTEND_HI(r8) [1, 3] +#line 2911 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_REG(QImode, $1->r); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }; +#line 2965 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(MEM_SI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movslq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(SImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_MEM(SImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2966 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(MEM_HI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movswq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2967 "x86-64.int.py" +r64x : SIGN_EXTEND_DI(MEM_QI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(DImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2968 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(MEM_HI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movswl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2969 "x86-64.int.py" +rz32x : SIGN_EXTEND_SI(MEM_QI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2970 "x86-64.int.py" +r16x : SIGN_EXTEND_HI(MEM_QI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbw", $1, $$->rx, 'w'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(HImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2973 "x86-64.int.py" +rs16x : SIGN_EXTEND_HI(MEM_QI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2977 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(MEM_SI(addr)) [4, 1] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (1) + src = gen_rtx_MEM(SImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(SImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2978 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(MEM_HI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzwq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(DImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2979 "x86-64.int.py" +r64x : ZERO_EXTEND_DI(MEM_QI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(DImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2980 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(MEM_HI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzwl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2981 "x86-64.int.py" +rz32x : ZERO_EXTEND_SI(MEM_QI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2982 "x86-64.int.py" +r16x : ZERO_EXTEND_HI(MEM_QI(addr)) [4, 3] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbw", $1, $$->rx, 'w'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(HImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2985 "x86-64.int.py" +rz16x : ZERO_EXTEND_HI(MEM_QI(addr)) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2989 "x86-64.int.py" +rs16x : MEM_HI(addr) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movswl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2990 "x86-64.int.py" +rs8x : MEM_QI(addr) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2991 "x86-64.int.py" +rs16x : SUBREG_HI(MEM_DI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movswl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2992 "x86-64.int.py" +rs16x : SUBREG_HI(MEM_SI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movswl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2993 "x86-64.int.py" +rs8x : SUBREG_QI(MEM_DI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2994 "x86-64.int.py" +rs8x : SUBREG_QI(MEM_SI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2995 "x86-64.int.py" +rs8x : SUBREG_QI(MEM_HI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movsbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_SIGN_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2998 "x86-64.int.py" +rz16x : MEM_HI(addr) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzwl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 2999 "x86-64.int.py" +rz8x : MEM_QI(addr) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3000 "x86-64.int.py" +rz16x : SUBREG_HI(MEM_DI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzwl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3001 "x86-64.int.py" +rz16x : SUBREG_HI(MEM_SI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzwl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(HImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(HImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3002 "x86-64.int.py" +rz8x : SUBREG_QI(MEM_DI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3003 "x86-64.int.py" +rz8x : SUBREG_QI(MEM_SI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3004 "x86-64.int.py" +rz8x : SUBREG_QI(MEM_HI(addr), CONST_0) [4, 2] +#line 3008 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src; + if (0) + src = gen_rtx_MEM(QImode, $1->rtl); + else + src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3061 "x86-64.int.py" +r64x : MEM_DI(addr) [3, 2] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(DImode, $1->rtl); + const rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3062 "x86-64.int.py" +rz32x : MEM_SI(addr) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3063 "x86-64.int.py" +rz32x : SUBREG_SI(MEM_DI(addr), CONST_0) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3065 "x86-64.int.py" +r64x : BSF_DI( MEM_DI(addr)) [3, 2] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsfq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(DImode, $1->rtl); + const rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3066 "x86-64.int.py" +rz32x : BSF_SI( MEM_SI(addr)) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsfl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3067 "x86-64.int.py" +rz32x : BSF_SI(SUBREG_SI(MEM_DI(addr), CONST_0)) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsfl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3069 "x86-64.int.py" +r64x : BSR_DI( MEM_DI(addr)) [3, 2] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsrq", $1, $$->rx, 'q'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(DImode, $1->rtl); + const rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3070 "x86-64.int.py" +rz32x : BSR_SI( MEM_SI(addr)) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsrl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3071 "x86-64.int.py" +rz32x : BSR_SI(SUBREG_SI(MEM_DI(addr), CONST_0)) [3, 1] +#line 3079 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("bsrl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + /* TODO: handle BSF and BSR in the rtx IL, perhaps as asm */ + const rtx src = gen_rtx_MEM(SImode, $1->rtl); + const rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3127 "x86-64.int.py" +rcc : MEM_NEG_DI(MEM_DI(addr)) [4, 2] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("negq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NEG(DImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3128 "x86-64.int.py" +rcc : MEM_NEG_SI(MEM_SI(addr)) [4, 1] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("negl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NEG(SImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3129 "x86-64.int.py" +rcc : MEM_NEG_HI(MEM_HI(addr)) [4, 2] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("negw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NEG(HImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3130 "x86-64.int.py" +rcc : MEM_NEG_QI(MEM_QI(addr)) [4, 1] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("negb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NEG(QImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3132 "x86-64.int.py" +nocc : MEM_NOT_DI(MEM_DI(addr)) [4, 2] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("notq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (1 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NOT(DImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3133 "x86-64.int.py" +nocc : MEM_NOT_SI(MEM_SI(addr)) [4, 1] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("notl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (1 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NOT(SImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3134 "x86-64.int.py" +nocc : MEM_NOT_HI(MEM_HI(addr)) [4, 2] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("notw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (1 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NOT(HImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3135 "x86-64.int.py" +nocc : MEM_NOT_QI(MEM_QI(addr)) [4, 1] +#line 3139 "x86-64.int.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("notb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (1 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_NOT(QImode, + mem /* NOTE: dag */ + ) + )); + }; +#line 3162 "x86-64.int.py" +rcc : MEM_PLUS_DI(MEM_DI(addr), NEG_DI(r64)) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3163 "x86-64.int.py" +rcc : MEM_PLUS_SI(MEM_SI(addr), NEG_DI(r32)) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3164 "x86-64.int.py" +rcc : MEM_PLUS_HI(MEM_HI(addr), NEG_DI(r16)) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3165 "x86-64.int.py" +rcc : MEM_PLUS_QI(MEM_QI(addr), NEG_DI(r8)) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3167 "x86-64.int.py" +rcc : MEM_MINUS_DI(MEM_DI(addr), NEG_DI(r64)) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3168 "x86-64.int.py" +rcc : MEM_MINUS_SI(MEM_SI(addr), NEG_DI(r32)) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3169 "x86-64.int.py" +rcc : MEM_MINUS_HI(MEM_HI(addr), NEG_DI(r16)) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3170 "x86-64.int.py" +rcc : MEM_MINUS_QI(MEM_QI(addr), NEG_DI(r8)) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3172 "x86-64.int.py" +rcc : MEM_IOR_DI (MEM_DI(addr), r64) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("orq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3173 "x86-64.int.py" +rcc : MEM_IOR_SI (MEM_SI(addr), r32) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("orl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3174 "x86-64.int.py" +rcc : MEM_IOR_HI (MEM_HI(addr), r16) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("orw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3175 "x86-64.int.py" +rcc : MEM_IOR_QI (MEM_QI(addr), r8) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("orb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3177 "x86-64.int.py" +rcc : MEM_XOR_DI (MEM_DI(addr), r64) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("xorq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3178 "x86-64.int.py" +rcc : MEM_XOR_SI (MEM_SI(addr), r32) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("xorl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3179 "x86-64.int.py" +rcc : MEM_XOR_HI (MEM_HI(addr), r16) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("xorw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3180 "x86-64.int.py" +rcc : MEM_XOR_QI (MEM_QI(addr), r8) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("xorb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3182 "x86-64.int.py" +rcc : MEM_PLUS_DI (MEM_DI(addr), r64) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3183 "x86-64.int.py" +rcc : MEM_PLUS_SI (MEM_SI(addr), r32) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3184 "x86-64.int.py" +rcc : MEM_PLUS_HI (MEM_HI(addr), r16) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3185 "x86-64.int.py" +rcc : MEM_PLUS_QI (MEM_QI(addr), r8) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("addb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3187 "x86-64.int.py" +rcc : MEM_MINUS_DI (MEM_DI(addr), r64) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3188 "x86-64.int.py" +rcc : MEM_MINUS_SI (MEM_SI(addr), r32) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3189 "x86-64.int.py" +rcc : MEM_MINUS_HI (MEM_HI(addr), r16) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3190 "x86-64.int.py" +rcc : MEM_MINUS_QI (MEM_QI(addr), r8) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("subb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3192 "x86-64.int.py" +rcc : MEM_AND_DI (MEM_DI(addr), r64) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("andq", $2->r, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(DImode, $2->r) + ) + )); + }; +#line 3193 "x86-64.int.py" +rcc : MEM_AND_SI (MEM_SI(addr), r32) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("andl", $2->r, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(SImode, $2->r) + ) + )); + }; +#line 3194 "x86-64.int.py" +rcc : MEM_AND_HI (MEM_HI(addr), r16) [4, 2] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("andw", $2->r, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(HImode, $2->r) + ) + )); + }; +#line 3195 "x86-64.int.py" +rcc : MEM_AND_QI (MEM_QI(addr), r8) [4, 1] +#line 3199 "x86-64.int.py" + supairs { + /*TODO*/ + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->r); + }, + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpRM("andb", $2->r, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, $2->r) + ) + )); + }; +#line 3250 "x86-64.int.py" +rcc : MEM_ASHIFT_DI (MEM_DI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3251 "x86-64.int.py" +rcc : MEM_ASHIFT_SI (MEM_SI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sall", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3252 "x86-64.int.py" +rcc : MEM_ASHIFT_HI (MEM_HI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3253 "x86-64.int.py" +rcc : MEM_ASHIFT_QI (MEM_QI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3255 "x86-64.int.py" +rcc : MEM_ROTATE_DI (MEM_DI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3256 "x86-64.int.py" +rcc : MEM_ROTATE_SI (MEM_SI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("roll", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3257 "x86-64.int.py" +rcc : MEM_ROTATE_HI (MEM_HI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3258 "x86-64.int.py" +rcc : MEM_ROTATE_QI (MEM_QI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3260 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3261 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3262 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3263 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3265 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3266 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3267 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3268 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3270 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3271 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3272 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), r8x) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3273 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), r8x) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3276 "x86-64.int.py" +rcc : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3277 "x86-64.int.py" +rcc : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sall", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3278 "x86-64.int.py" +rcc : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3279 "x86-64.int.py" +rcc : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3281 "x86-64.int.py" +rcc : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3282 "x86-64.int.py" +rcc : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("roll", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3283 "x86-64.int.py" +rcc : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3284 "x86-64.int.py" +rcc : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3286 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3287 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3288 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3289 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3291 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3292 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3293 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3294 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3296 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3297 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3298 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r64x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3299 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r64x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3302 "x86-64.int.py" +rcc : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3303 "x86-64.int.py" +rcc : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sall", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3304 "x86-64.int.py" +rcc : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3305 "x86-64.int.py" +rcc : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3307 "x86-64.int.py" +rcc : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3308 "x86-64.int.py" +rcc : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("roll", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3309 "x86-64.int.py" +rcc : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3310 "x86-64.int.py" +rcc : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3312 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3313 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3314 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3315 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3317 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3318 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3319 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3320 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3322 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3323 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3324 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r32x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3325 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r32x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3328 "x86-64.int.py" +rcc : MEM_ASHIFT_DI (MEM_DI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3329 "x86-64.int.py" +rcc : MEM_ASHIFT_SI (MEM_SI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sall", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3330 "x86-64.int.py" +rcc : MEM_ASHIFT_HI (MEM_HI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3331 "x86-64.int.py" +rcc : MEM_ASHIFT_QI (MEM_QI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("salb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3333 "x86-64.int.py" +rcc : MEM_ROTATE_DI (MEM_DI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3334 "x86-64.int.py" +rcc : MEM_ROTATE_SI (MEM_SI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("roll", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3335 "x86-64.int.py" +rcc : MEM_ROTATE_HI (MEM_HI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3336 "x86-64.int.py" +rcc : MEM_ROTATE_QI (MEM_QI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rolb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3338 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3339 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3340 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3341 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("sarb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3343 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3344 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3345 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3346 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("shrb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3348 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorq", $2->rx, 'q', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3349 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorl", $2->rx, 'l', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3350 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), SUBREG_QI(r16x, CONST_0)) [4, 2] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorw", $2->rx, 'w', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3351 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), SUBREG_QI(r16x, CONST_0)) [4, 1] +#line 3355 "x86-64.int.py" + supairs { + /*TODO*/ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->rx, REG_RCX); + }, + build { + add_addr(live, $1); + add_copy_edges(REG_RCX, $2->rx, live); + }, + remat { + flags = 0; + }, + costs { + /* + * the src register can not be directly replaced + * with a spill memory reference, so this is "forgettable". + */ + forgettable($2->rx); /* must be in a register */ + cost_copy(REG_RCX, $2->rx); + }, + debug { + dumpRM("rorb", $2->rx, 'b', $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + const rtx rcx = gen_rtx_REG(SImode, REG_RCX); + const rtx src = gen_rtx_REG(SImode, $2->rx); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src)); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + gen_rtx_REG(QImode, REG_RCX) + ) + )); + }; +#line 3397 "x86-64.int.py" +rcc : MEM_PLUS_DI(MEM_DI(addr), imm32) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3398 "x86-64.int.py" +rcc : MEM_PLUS_SI(MEM_SI(addr), imm32) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3399 "x86-64.int.py" +rcc : MEM_PLUS_HI(MEM_HI(addr), imm16) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3400 "x86-64.int.py" +rcc : MEM_PLUS_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3401 "x86-64.int.py" +rcc : MEM_PLUS_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3402 "x86-64.int.py" +rcc : MEM_PLUS_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3403 "x86-64.int.py" +rcc : MEM_PLUS_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("addw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3405 "x86-64.int.py" +rcc : MEM_MINUS_DI(MEM_DI(addr), imm32) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3406 "x86-64.int.py" +rcc : MEM_MINUS_SI(MEM_SI(addr), imm32) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3407 "x86-64.int.py" +rcc : MEM_MINUS_HI(MEM_HI(addr), imm16) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3408 "x86-64.int.py" +rcc : MEM_MINUS_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3409 "x86-64.int.py" +rcc : MEM_MINUS_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3410 "x86-64.int.py" +rcc : MEM_MINUS_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3411 "x86-64.int.py" +rcc : MEM_MINUS_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("subw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3413 "x86-64.int.py" +rcc : MEM_AND_DI(MEM_DI(addr), imm32) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3414 "x86-64.int.py" +rcc : MEM_AND_SI(MEM_SI(addr), imm32) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3415 "x86-64.int.py" +rcc : MEM_AND_HI(MEM_HI(addr), imm16) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3416 "x86-64.int.py" +rcc : MEM_AND_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3417 "x86-64.int.py" +rcc : MEM_AND_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3418 "x86-64.int.py" +rcc : MEM_AND_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3419 "x86-64.int.py" +rcc : MEM_AND_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("andw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_AND(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3421 "x86-64.int.py" +rcc : MEM_IOR_DI(MEM_DI(addr), imm32) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3422 "x86-64.int.py" +rcc : MEM_IOR_SI(MEM_SI(addr), imm32) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3423 "x86-64.int.py" +rcc : MEM_IOR_HI(MEM_HI(addr), imm16) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3424 "x86-64.int.py" +rcc : MEM_IOR_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3425 "x86-64.int.py" +rcc : MEM_IOR_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3426 "x86-64.int.py" +rcc : MEM_IOR_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3427 "x86-64.int.py" +rcc : MEM_IOR_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("orw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_IOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3429 "x86-64.int.py" +rcc : MEM_XOR_DI(MEM_DI(addr), imm32) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3430 "x86-64.int.py" +rcc : MEM_XOR_SI(MEM_SI(addr), imm32) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3431 "x86-64.int.py" +rcc : MEM_XOR_HI(MEM_HI(addr), imm16) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3432 "x86-64.int.py" +rcc : MEM_XOR_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3433 "x86-64.int.py" +rcc : MEM_XOR_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3434 "x86-64.int.py" +rcc : MEM_XOR_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3435 "x86-64.int.py" +rcc : MEM_XOR_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("xorw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_XOR(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3444 "x86-64.int.py" +rcc : MEM_ASHIFT_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("salq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3445 "x86-64.int.py" +rcc : MEM_ASHIFT_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("sall", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3446 "x86-64.int.py" +rcc : MEM_ASHIFT_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("salw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3447 "x86-64.int.py" +rcc : MEM_ASHIFT_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("salb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3449 "x86-64.int.py" +rcc : MEM_ROTATE_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rolq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3450 "x86-64.int.py" +rcc : MEM_ROTATE_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("roll", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3451 "x86-64.int.py" +rcc : MEM_ROTATE_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rolw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3452 "x86-64.int.py" +rcc : MEM_ROTATE_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rolb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3454 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("shrq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3455 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("shrl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3456 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("shrw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3457 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("shrb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3459 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("sarq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3460 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("sarl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3461 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("sarw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3462 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("sarb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3464 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rorq", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3465 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rorl", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3466 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), imm8) [4, 3] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rorw", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3467 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), imm8) [4, 2] +#line 3471 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("rorb", $2, $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl) + ) + )); + }; +#line 3503 "x86-64.int.py" +rcc : MEM_PLUS_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3504 "x86-64.int.py" +rcc : MEM_PLUS_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3505 "x86-64.int.py" +rcc : MEM_PLUS_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3506 "x86-64.int.py" +rcc : MEM_PLUS_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3508 "x86-64.int.py" +rcc : MEM_PLUS_DI(MEM_DI(addr), CONST_N1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3509 "x86-64.int.py" +rcc : MEM_PLUS_SI(MEM_SI(addr), CONST_N1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3510 "x86-64.int.py" +rcc : MEM_PLUS_HI(MEM_HI(addr), CONST_N1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3511 "x86-64.int.py" +rcc : MEM_PLUS_QI(MEM_QI(addr), CONST_N1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3513 "x86-64.int.py" +rcc : MEM_MINUS_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3514 "x86-64.int.py" +rcc : MEM_MINUS_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3515 "x86-64.int.py" +rcc : MEM_MINUS_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3516 "x86-64.int.py" +rcc : MEM_MINUS_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("decb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_MINUS(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3518 "x86-64.int.py" +rcc : MEM_MINUS_DI(MEM_DI(addr), CONST_N1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3519 "x86-64.int.py" +rcc : MEM_MINUS_SI(MEM_SI(addr), CONST_N1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3520 "x86-64.int.py" +rcc : MEM_MINUS_HI(MEM_HI(addr), CONST_N1) [4, 3] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3521 "x86-64.int.py" +rcc : MEM_MINUS_QI(MEM_QI(addr), CONST_N1) [4, 2] +#line 3525 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("incb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_PLUS(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3559 "x86-64.int.py" +rcc : MEM_ASHIFT_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("salq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3560 "x86-64.int.py" +rcc : MEM_ASHIFT_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sall", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3561 "x86-64.int.py" +rcc : MEM_ASHIFT_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("salw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3562 "x86-64.int.py" +rcc : MEM_ASHIFT_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("salb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFT(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3564 "x86-64.int.py" +rcc : MEM_ROTATE_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("rolq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3565 "x86-64.int.py" +rcc : MEM_ROTATE_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("roll", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3566 "x86-64.int.py" +rcc : MEM_ROTATE_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("rolw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3567 "x86-64.int.py" +rcc : MEM_ROTATE_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("rolb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATE(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3569 "x86-64.int.py" +rcc : MEM_LSHIFTRT_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("shrq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3570 "x86-64.int.py" +rcc : MEM_LSHIFTRT_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("shrl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3571 "x86-64.int.py" +rcc : MEM_LSHIFTRT_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("shrw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3572 "x86-64.int.py" +rcc : MEM_LSHIFTRT_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("shrb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_LSHIFTRT(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3574 "x86-64.int.py" +rcc : MEM_ASHIFTRT_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3575 "x86-64.int.py" +rcc : MEM_ASHIFTRT_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3576 "x86-64.int.py" +rcc : MEM_ASHIFTRT_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3577 "x86-64.int.py" +rcc : MEM_ASHIFTRT_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ASHIFTRT(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3579 "x86-64.int.py" +rcc : MEM_ROTATERT_DI(MEM_DI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarq", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(DImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(DImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3580 "x86-64.int.py" +rcc : MEM_ROTATERT_SI(MEM_SI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarl", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(SImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(SImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3581 "x86-64.int.py" +rcc : MEM_ROTATERT_HI(MEM_HI(addr), CONST_P1) [4, 3] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarw", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(HImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(HImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3582 "x86-64.int.py" +rcc : MEM_ROTATERT_QI(MEM_QI(addr), CONST_P1) [4, 2] +#line 3586 "x86-64.int.py" + supairs { + /*TODO*/ + }, + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpM("sarb", $1); + }, + emit { + const rtx mem = gen_rtx_MEM(QImode, $1->rtl); + (0 ? icg_emit_plain : icg_emit_clobber)(gen_rtx_SET(VOIDmode, + mem, /* NOTE: dag */ + gen_rtx_ROTATERT(QImode, + mem, /* NOTE: dag */ + GEN_INT(1) + ) + )); + }; +#line 3616 "x86-64.int.py" +stmt : nocc [100, 100] +#line 3620 "x86-64.int.py" + ; +#line 3617 "x86-64.int.py" +stmt : rcc [100, 100] +#line 3620 "x86-64.int.py" + ; +#line 3648 "x86-64.int.py" +r64x : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(ZERO_EXTEND_TI(r64x) | ZERO_EXTEND_TI(r64)), CONST8P)) [4, 4] +#line 3663 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if ('q' != 'b') { + add_copy_edges($$->rx, REG_RDX, live); + } + if (1) { + sparseset_set_bit(live, find($2->r)); + } else { + add_addr(live, $2); + } + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); /* RDX is always killed on 64,32,16 bit variants */ + } + add_copy_edges(REG_RAX, $1->rx, live); /* we want these to coalesce */ + }, + remat { + flags = 0; + }, + costs { + cost_copy(REG_RAX, $1->rx); + if (1) { + memorable($1->rx); + memorable($2->r); + } + else + forgettable($1->rx); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if (1) + dumpR("mulq", $2->r, 'q'); + else + dumpM("mulq", $2); + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * unsigned multiply modifes the OF and CF flags, + * so we must use icg_emit_clobber (gen_rtx_CLOBBER) + */ + parset = gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rdx, /* value comes back in rdx, no shifts needed */ + gen_rtx_TRUNCATE(DImode, + gen_rtx_LSHIFTRT(TImode, + gen_rtx_MULT(TImode, + 0 + ? gen_rtx_SIGN_EXTEND(TImode, rax) + : gen_rtx_ZERO_EXTEND(TImode, rax), + 0 + ? gen_rtx_SIGN_EXTEND(TImode, src2) + : gen_rtx_ZERO_EXTEND(TImode, src2) + ), + gen_rtx_CONST_INT(QImode, 64) + ))), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(DImode, REG_RAX)), /* perhaps clobber the scratch reg? */ + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 3650 "x86-64.int.py" +r64x : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(ZERO_EXTEND_TI(r64x) | ZERO_EXTEND_TI(MEM_QI(addr))), CONST8P)) [7, 2] +#line 3663 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if ('q' != 'b') { + add_copy_edges($$->rx, REG_RDX, live); + } + if (0) { + sparseset_set_bit(live, find($2->r)); + } else { + add_addr(live, $2); + } + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); /* RDX is always killed on 64,32,16 bit variants */ + } + add_copy_edges(REG_RAX, $1->rx, live); /* we want these to coalesce */ + }, + remat { + flags = 0; + }, + costs { + cost_copy(REG_RAX, $1->rx); + if (0) { + memorable($1->rx); + memorable($2->r); + } + else + forgettable($1->rx); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if (0) + dumpR("mulq", $2->r, 'q'); + else + dumpM("mulq", $2); + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * unsigned multiply modifes the OF and CF flags, + * so we must use icg_emit_clobber (gen_rtx_CLOBBER) + */ + parset = gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rdx, /* value comes back in rdx, no shifts needed */ + gen_rtx_TRUNCATE(DImode, + gen_rtx_LSHIFTRT(TImode, + gen_rtx_MULT(TImode, + 0 + ? gen_rtx_SIGN_EXTEND(TImode, rax) + : gen_rtx_ZERO_EXTEND(TImode, rax), + 0 + ? gen_rtx_SIGN_EXTEND(TImode, src2) + : gen_rtx_ZERO_EXTEND(TImode, src2) + ), + gen_rtx_CONST_INT(QImode, 64) + ))), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(DImode, REG_RAX)), /* perhaps clobber the scratch reg? */ + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 3657 "x86-64.int.py" +r64x : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(SIGN_EXTEND_TI(r64x) | SIGN_EXTEND_TI(r64)), CONST8P)) [4, 4] +#line 3663 "x86-64.int.py" + supairs { + if (1) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if ('q' != 'b') { + add_copy_edges($$->rx, REG_RDX, live); + } + if (1) { + sparseset_set_bit(live, find($2->r)); + } else { + add_addr(live, $2); + } + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); /* RDX is always killed on 64,32,16 bit variants */ + } + add_copy_edges(REG_RAX, $1->rx, live); /* we want these to coalesce */ + }, + remat { + flags = 0; + }, + costs { + cost_copy(REG_RAX, $1->rx); + if (1) { + memorable($1->rx); + memorable($2->r); + } + else + forgettable($1->rx); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if (1) + dumpR("imulq", $2->r, 'q'); + else + dumpM("imulq", $2); + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 1 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * unsigned multiply modifes the OF and CF flags, + * so we must use icg_emit_clobber (gen_rtx_CLOBBER) + */ + parset = gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rdx, /* value comes back in rdx, no shifts needed */ + gen_rtx_TRUNCATE(DImode, + gen_rtx_LSHIFTRT(TImode, + gen_rtx_MULT(TImode, + 1 + ? gen_rtx_SIGN_EXTEND(TImode, rax) + : gen_rtx_ZERO_EXTEND(TImode, rax), + 1 + ? gen_rtx_SIGN_EXTEND(TImode, src2) + : gen_rtx_ZERO_EXTEND(TImode, src2) + ), + gen_rtx_CONST_INT(QImode, 64) + ))), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(DImode, REG_RAX)), /* perhaps clobber the scratch reg? */ + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 3659 "x86-64.int.py" +r64x : TRUNCATE_DI(LSHIFTRT_TI(MULT_TI(SIGN_EXTEND_TI(r64x) | SIGN_EXTEND_TI(MEM_QI(addr))), CONST8P)) [7, 2] +#line 3663 "x86-64.int.py" + supairs { + if (0) { + suOrder2($$, $1, $2, kid, kids); + } else { + suOrder2($$, $1, $2, kid, kids); + } + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + coalesce { + coalesces += attempt_coalesce(pass, $1->rx, REG_RAX); + coalesces += attempt_coalesce(pass, $$->rx, REG_RDX); + }, + build { + if ('q' != 'b') { + add_copy_edges($$->rx, REG_RDX, live); + } + if (0) { + sparseset_set_bit(live, find($2->r)); + } else { + add_addr(live, $2); + } + if ('q' != 'b') { + sparseset_clear_bit(live, REG_RDX); + add_edges(REG_RDX, live); /* RDX is always killed on 64,32,16 bit variants */ + } + add_copy_edges(REG_RAX, $1->rx, live); /* we want these to coalesce */ + }, + remat { + flags = 0; + }, + costs { + cost_copy(REG_RAX, $1->rx); + if (0) { + memorable($1->rx); + memorable($2->r); + } + else + forgettable($1->rx); + cost_copy(REG_RDX, $$->rx); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + dump_copy("movq", $1->rx, REG_RAX, 'q'); + if (0) + dumpR("imulq", $2->r, 'q'); + else + dumpM("imulq", $2); + dump_copy("movq", REG_RDX, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src1 = gen_rtx_REG(DImode, $1->rx); + rtx src2 = 0 + ? gen_rtx_REG(DImode, $2->r) + : gen_rtx_MEM(DImode, $2->rtl); + /* + * TODO: raxm, which is the wider mode + * TODO: rdxm, which is the wider mode + */ + rtx rax = gen_rtx_REG(DImode, REG_RAX); + rtx rdx = ('q' != 'b') ? gen_rtx_REG(DImode, REG_RDX) : 0; + rtvec parset = 0; + icg_emit_plain(gen_rtx_SET(VOIDmode, rax/*raxm?*/, src1)); + /* + * unsigned multiply modifes the OF and CF flags, + * so we must use icg_emit_clobber (gen_rtx_CLOBBER) + */ + parset = gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rdx, /* value comes back in rdx, no shifts needed */ + gen_rtx_TRUNCATE(DImode, + gen_rtx_LSHIFTRT(TImode, + gen_rtx_MULT(TImode, + 1 + ? gen_rtx_SIGN_EXTEND(TImode, rax) + : gen_rtx_ZERO_EXTEND(TImode, rax), + 1 + ? gen_rtx_SIGN_EXTEND(TImode, src2) + : gen_rtx_ZERO_EXTEND(TImode, src2) + ), + gen_rtx_CONST_INT(QImode, 64) + ))), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(DImode, REG_RAX)), /* perhaps clobber the scratch reg? */ + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ); + + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, parset)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, (REG_RDX == REG_RAX) ? rax/*raxm?*/ : rdx/*rdxm*/)); + }; +#line 3777 "x86-64.int.py" +r64x : CLZ_DI(r64) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("lzcntq", $1->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_CLZ(DImode, + gen_rtx_REG(DImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3778 "x86-64.int.py" +rz32x : CLZ_SI(r32) [3, 2] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("lzcntl", $1->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_CLZ(SImode, + gen_rtx_REG(SImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3779 "x86-64.int.py" +r16x : CLZ_HI(r16) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("lzcntw", $1->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_CLZ(HImode, + gen_rtx_REG(HImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3781 "x86-64.int.py" +r64x : PLUS_DI(CONST_P63, NEG_DI(CLZ_DI(r64))) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("bsrq", $1->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_BSR_DI(DImode, + gen_rtx_REG(DImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3782 "x86-64.int.py" +rz32x : PLUS_DI(CONST_P31, NEG_DI(CLZ_SI(r32))) [3, 2] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("bsrl", $1->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_BSR_SI(SImode, + gen_rtx_REG(SImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3783 "x86-64.int.py" +r16x : PLUS_DI(CONST_P15, NEG_DI(CLZ_HI(r16))) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("bsrw", $1->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_BSR_HI(HImode, + gen_rtx_REG(HImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3786 "x86-64.int.py" +r64x : POPCOUNT_DI(r64) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("popcntq", $1->r, 'q', $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_POPCOUNT(DImode, + gen_rtx_REG(DImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3787 "x86-64.int.py" +rz32x : POPCOUNT_SI(r32) [3, 2] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("popcntl", $1->r, 'l', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_POPCOUNT(SImode, + gen_rtx_REG(SImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3788 "x86-64.int.py" +r16x : POPCOUNT_HI(r16) [4, 3] +#line 3792 "x86-64.int.py" + supairs { + $$->extra = $1->extra; /* think about these */ + $$->freed = $1->freed; + }, + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + forgettable($1->r); + }, + debug { + dumpRR("popcntw", $1->r, 'w', $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_POPCOUNT(HImode, + gen_rtx_REG(HImode, $1->r) + ); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3828 "x86-64.int.py" +stmt : PREFETCH_DI(addr, imm32) [3, 2] +#line 3831 "x86-64.int.py" + build { + add_addr(live, $1); + }, + debug { + dumpM("prefetchnta", $1); + }, + emit { + const int k1 = $2->val/10; + const int k2 = $2->val%10; + icg_emit_plain(gen_rtx_PREFETCH(DImode, $1->rtl, GEN_INT(k1), GEN_INT(k2))); + }; +#line 3860 "x86-64.int.py" +ccr64x : ASHIFT_DI(LSHIFTRT_DI(r64x, CONST_P1), CONST_P1) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andq", -2, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_AND(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(-2)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3861 "x86-64.int.py" +ccr64x : ASHIFT_DI(LSHIFTRT_DI(r64x, CONST_P2), CONST_P2) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andq", -4, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_AND(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(-4)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3862 "x86-64.int.py" +ccr64x : ASHIFT_DI(LSHIFTRT_DI(r64x, CONST_P3), CONST_P3) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andq", -8, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_AND(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(-8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3863 "x86-64.int.py" +ccr64x : ASHIFT_DI(LSHIFTRT_DI(r64x, CONST_P4), CONST_P4) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andq", -16, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_AND(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(-16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3864 "x86-64.int.py" +ccr64x : ASHIFT_DI(LSHIFTRT_DI(r64x, CONST_P8), CONST_P8) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andq", -256, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_AND(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(-256)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3866 "x86-64.int.py" +ccrz32x : ASHIFT_SI(LSHIFTRT_SI(r32x, CONST_P1), CONST_P1) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andl", -2, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_AND(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(-2)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3867 "x86-64.int.py" +ccrz32x : ASHIFT_SI(LSHIFTRT_SI(r32x, CONST_P2), CONST_P2) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andl", -4, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_AND(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(-4)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3868 "x86-64.int.py" +ccrz32x : ASHIFT_SI(LSHIFTRT_SI(r32x, CONST_P3), CONST_P3) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andl", -8, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_AND(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(-8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3869 "x86-64.int.py" +ccrz32x : ASHIFT_SI(LSHIFTRT_SI(r32x, CONST_P4), CONST_P4) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andl", -16, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_AND(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(-16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3870 "x86-64.int.py" +ccrz32x : ASHIFT_SI(LSHIFTRT_SI(r32x, CONST_P8), CONST_P8) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andl", -256, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_AND(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(-256)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3872 "x86-64.int.py" +ccr16x : ASHIFT_HI(LSHIFTRT_HI(r16x, CONST_P1), CONST_P1) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andw", -2, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_AND(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(-2)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3873 "x86-64.int.py" +ccr16x : ASHIFT_HI(LSHIFTRT_HI(r16x, CONST_P2), CONST_P2) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andw", -4, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_AND(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(-4)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3874 "x86-64.int.py" +ccr16x : ASHIFT_HI(LSHIFTRT_HI(r16x, CONST_P3), CONST_P3) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andw", -8, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_AND(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(-8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3875 "x86-64.int.py" +ccr16x : ASHIFT_HI(LSHIFTRT_HI(r16x, CONST_P4), CONST_P4) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andw", -16, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_AND(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(-16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3876 "x86-64.int.py" +ccr16x : ASHIFT_HI(LSHIFTRT_HI(r16x, CONST_P8), CONST_P8) [1, 8] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andw", -256, $$->rx, 'w'); + }, + emit { + rtx dst = gen_rtx_REG(HImode, $$->rx); + rtx src = gen_rtx_AND(HImode, + gen_rtx_REG(HImode, $1->rx), + GEN_INT(-256)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3878 "x86-64.int.py" +ccr8x : ASHIFT_QI(LSHIFTRT_QI(r8x, CONST_P1), CONST_P1) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andb", -2, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_AND(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(-2)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3879 "x86-64.int.py" +ccr8x : ASHIFT_QI(LSHIFTRT_QI(r8x, CONST_P2), CONST_P2) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andb", -4, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_AND(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(-4)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3880 "x86-64.int.py" +ccr8x : ASHIFT_QI(LSHIFTRT_QI(r8x, CONST_P3), CONST_P3) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andb", -8, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_AND(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(-8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3881 "x86-64.int.py" +ccr8x : ASHIFT_QI(LSHIFTRT_QI(r8x, CONST_P4), CONST_P4) [1, 7] +#line 3885 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("andb", -16, $$->rx, 'b'); + }, + emit { + rtx dst = gen_rtx_REG(QImode, $$->rx); + rtx src = gen_rtx_AND(QImode, + gen_rtx_REG(QImode, $1->rx), + GEN_INT(-16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3923 "x86-64.int.py" +r64x : ASHIFT_DI(ZERO_EXTEND_DI(r32x), CONST_P32) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 32, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(32)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3924 "x86-64.int.py" +r64x : ASHIFT_DI(ZERO_EXTEND_DI(r16x), CONST_P48) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 48, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(48)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3925 "x86-64.int.py" +r64x : ASHIFT_DI(ZERO_EXTEND_DI(r8x), CONST_P56) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 56, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(56)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3926 "x86-64.int.py" +r32x : ASHIFT_SI(ZERO_EXTEND_SI(r16x), CONST_P16) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 16, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3927 "x86-64.int.py" +r32x : ASHIFT_SI(ZERO_EXTEND_SI(r8x), CONST_P24) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 24, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(24)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3928 "x86-64.int.py" +r16x : ASHIFT_HI(ZERO_EXTEND_HI(r8x), CONST_P8) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 8, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3930 "x86-64.int.py" +r64x : ASHIFT_DI(SIGN_EXTEND_DI(r32x), CONST_P32) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 32, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(32)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3931 "x86-64.int.py" +r64x : ASHIFT_DI(SIGN_EXTEND_DI(r16x), CONST_P48) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 48, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(48)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3932 "x86-64.int.py" +r64x : ASHIFT_DI(SIGN_EXTEND_DI(r8x), CONST_P56) [1, 4] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shlq", 56, $$->rx, 'q'); + }, + emit { + rtx dst = gen_rtx_REG(DImode, $$->rx); + rtx src = gen_rtx_ASHIFT(DImode, + gen_rtx_REG(DImode, $1->rx), + GEN_INT(56)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3933 "x86-64.int.py" +r32x : ASHIFT_SI(SIGN_EXTEND_SI(r16x), CONST_P16) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 16, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(16)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3934 "x86-64.int.py" +r32x : ASHIFT_SI(SIGN_EXTEND_SI(r8x), CONST_P24) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 24, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(24)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3935 "x86-64.int.py" +r16x : ASHIFT_HI(SIGN_EXTEND_HI(r8x), CONST_P8) [1, 3] +#line 3939 "x86-64.int.py" + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRn("shll", 8, $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ASHIFT(SImode, + gen_rtx_REG(SImode, $1->rx), + GEN_INT(8)); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3978 "x86-64.int.py" +r64x : AND_DI( r64 | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3979 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(r32) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3980 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(r32) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3981 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(r16) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3982 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(r16) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3983 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3984 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3986 "x86-64.int.py" +rz32x : AND_SI( r32 | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3987 "x86-64.int.py" +rz32x : AND_SI(ZERO_EXTEND_SI(r16) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3988 "x86-64.int.py" +rz32x : AND_SI(SIGN_EXTEND_SI(r16) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3989 "x86-64.int.py" +rz32x : AND_SI(ZERO_EXTEND_SI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3990 "x86-64.int.py" +rz32x : AND_SI(SIGN_EXTEND_SI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3992 "x86-64.int.py" +rz16x : AND_HI( r16 | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3993 "x86-64.int.py" +rz16x : AND_HI(ZERO_EXTEND_HI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 3994 "x86-64.int.py" +rz16x : AND_HI(SIGN_EXTEND_HI(r8) | CONST_P255) [1, 3] +#line 3998 "x86-64.int.py" + supairs { + if ($$->freed > 0) + $$->freed--; + else + $$->extra++; + }, + names { + $$->rx = new_reg(); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + add_edges(find($$->rx), live); + sparseset_clear_bit(live, find($$->rx)); + sparseset_set_bit(live, find($1->r)); + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("movzbl", $1->r, 'b', $$->rx, 'l'); + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_REG(QImode, $1->r)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4035 "x86-64.int.py" +r64x : AND_DI( MEM_DI(addr) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4036 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(MEM_SI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4037 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(MEM_SI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4038 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(MEM_HI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4039 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(MEM_HI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4040 "x86-64.int.py" +r64x : AND_DI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4041 "x86-64.int.py" +r64x : AND_DI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4043 "x86-64.int.py" +rz32x : AND_SI( MEM_SI(addr) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4044 "x86-64.int.py" +rz32x : AND_SI(ZERO_EXTEND_DI(MEM_HI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4045 "x86-64.int.py" +rz32x : AND_SI(SIGN_EXTEND_DI(MEM_HI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4046 "x86-64.int.py" +rz32x : AND_SI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4047 "x86-64.int.py" +rz32x : AND_SI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4049 "x86-64.int.py" +rz16x : AND_HI( MEM_HI(addr) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4050 "x86-64.int.py" +rz16x : AND_HI(ZERO_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 4051 "x86-64.int.py" +rz16x : AND_HI(SIGN_EXTEND_DI(MEM_QI(addr)) | CONST_P255) [4, 2] +#line 4055 "x86-64.int.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + supairs { + if ($1->freed > 0) { + $$->extra = $1->extra; + $$->freed = $1->freed - 1; + } + else { + $$->extra = $1->extra + 1; + $$->freed = 0; + } + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpMR("movzbl", $1, $$->rx, 'l'); + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + emit { + rtx dst = gen_rtx_REG(SImode, $$->rx); + rtx src = gen_rtx_ZERO_EXTEND(SImode, gen_rtx_MEM(QImode, $1->rtl)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; diff --git a/iburg/briggs/icg-grammars/x86-64.misc.py b/iburg/briggs/icg-grammars/x86-64.misc.py new file mode 100644 index 00000000000..07e2d06d6c1 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.misc.py @@ -0,0 +1,1884 @@ +# {([ + +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +# -*- mode: python -*- + +import plug + +# global_print_plug_decls = 0; execfile("x86-64.gr.py") + +#------------------------------------------------------------------------ +# addressing modes + +plug.plugrule3("addrbid", [ + ["rule", "cost"], + ["addr : PLUS_DI(base64.base | index64.index | disp.disp)", [0, 0]], +], """ + $rule $cost + supairs { + suOrder2($addr, $base, $index, kid, kids); + }, + names { + $addr->a.base = $base->a.base; + $addr->a.base_valid = $base->a.base_valid; + $addr->a.index = $index->a.index; + $addr->a.scale = $index->a.scale; + $addr->a.disp = $disp->a.disp; + $addr->a.string = $disp->a.string; + }, + final { + $addr->a.base = $base->a.base; + $addr->a.index = $index->a.index; + }, + emit { + $addr->rtl = gen_rtx_addr(DImode, $base->rtl, $index->rtl, $disp->rtl); + }; +""") + +plug.plugrule3("addrbio", [ + ["rule", "cost", "scalefactor"], + + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm5.offset) | CONST_P8))", [0, 1], 8], + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm29.offset) | CONST_P8))", [0, 1], 8], + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm6.offset) | CONST_P4))", [0, 1], 4], + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm30.offset) | CONST_P4))", [0, 1], 4], + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm7.offset) | CONST_P2))", [0, 1], 2], + ["addr : PLUS_DI(base64.base | MULT_DI(PLUS_DI(r64.index | imm31.offset) | CONST_P2))", [0, 1], 2], + + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm5.offset), CONST_P3))", [0, 1], 8], + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm29.offset), CONST_P3))", [0, 1], 8], + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm6.offset), CONST_P2))", [0, 1], 4], + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm30.offset), CONST_P2))", [0, 1], 4], + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm7.offset), CONST_P1))", [0, 1], 2], + ["addr : PLUS_DI(base64.base | ASHIFT_DI(PLUS_DI(r64.index | imm31.offset), CONST_P1))", [0, 1], 2], + +], """ + $rule $cost + supairs { + suOrder2($addr, $base, $index, kid, kids); + }, + names { + $addr->a.base = $base->a.base; + $addr->a.base_valid = $base->a.base_valid; + $addr->a.index = $index->r; + $addr->a.scale = $scalefactor; + $addr->a.disp = $offset->val * $scalefactor; + $addr->a.string = NULL; + }, + costs { + forgettable($index->r); + }, + final { + $addr->a.base = $base->a.base; + $addr->a.index = $index->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $index->r); + $addr->rtl = gen_rtx_addr(DImode, $base->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT($scalefactor)), + GEN_INT($offset->val * $scalefactor)); + }; +""") + + +# The costs here are strange because there are 2 immediates feeding into each rule. +# Maybe I need to introduce negative costs. +plug.plugrule3("addrbio1", [ + ["rule", "cost", "scalefactor"], + + ["addr : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm4.const2) | CONST_P8))", [0, 0], 8], + ["addr : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm28.const2) | CONST_P8))", [0, 0], 8], + ["addr : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm5.const2) | CONST_P4))", [0, 0], 4], + ["addr : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm29.const2) | CONST_P4))", [0, 0], 4], + ["addr : PLUS_DI(base64.base | imm7.const1 | MULT_DI(PLUS_DI(r64.index | imm6.const2) | CONST_P2))", [0, 0], 2], + ["addr : PLUS_DI(base64.base | imm31.const1 | MULT_DI(PLUS_DI(r64.index | imm30.const2) | CONST_P2))", [0, 0], 2], + + ["addr : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm4.const2), CONST_P3))", [0, 0], 8], + ["addr : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm28.const2), CONST_P3))", [0, 0], 8], + ["addr : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm5.const2), CONST_P2))", [0, 0], 4], + ["addr : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm29.const2), CONST_P2))", [0, 0], 4], + ["addr : PLUS_DI(base64.base | imm7.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm6.const2), CONST_P1))", [0, 0], 2], + ["addr : PLUS_DI(base64.base | imm31.const1 | ASHIFT_DI(PLUS_DI(r64.index | imm30.const2), CONST_P1))", [0, 0], 2], + +], """ + $rule $cost + supairs { + suOrder2($addr, $base, $index, kid, kids); + }, + names { + $addr->a.base = $base->a.base; + $addr->a.base_valid = $base->a.base_valid; + $addr->a.index = $index->r; + $addr->a.scale = $scalefactor; + $addr->a.disp = $const1->val + $const2->val * $scalefactor; + $addr->a.string = NULL; + }, + costs { + forgettable($index->r); + }, + final { + $addr->a.base = $base->a.base; + $addr->a.index = $index->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $index->r); + $addr->rtl = gen_rtx_addr(DImode, $base->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT($scalefactor)), + GEN_INT($const1->val + $const2->val * $scalefactor)); + }; +""") + +plug.plugrule3("addrbi", [ + ["rule", "cost"], + ["addr : PLUS_DI(base64.base | index64.index)", [0, 0]], +], """ + $rule $cost + supairs { + suOrder2($addr, $base, $index, kid, kids); + }, + names { + $addr->a.base = $base->a.base; + $addr->a.base_valid = $base->a.base_valid; + $addr->a.index = $index->a.index; + $addr->a.scale = $index->a.scale; + $addr->a.disp = 0; + $addr->a.string = NULL; + }, + final { + $addr->a.base = $base->a.base; + $addr->a.index = $index->a.index; + }, + emit { + $addr->rtl = gen_rtx_PLUS(DImode, $base->rtl, $index->rtl); + }; +""") + +plug.plugrule3("addrbd", [ + ["rule", "cost"], + ["addr : PLUS_DI(base64.base | disp.disp)", [0, 0]], +], """ + $rule $cost + names { + $addr->a.base = $base->a.base; + $addr->a.base_valid = $base->a.base_valid; + $addr->a.index = 0; + $addr->a.scale = 0; + $addr->a.disp = $disp->a.disp; + $addr->a.string = $disp->a.string; + }, + final { + $addr->a.base = $base->a.base; + }, + supairs { + $addr->extra = $base->extra; + $addr->freed = $base->freed; + }, + emit { + $addr->rtl = gen_rtx_PLUS(DImode, $base->rtl, $disp->rtl); + }; +""") + +plug.plugrule3("addrid", [ + ["rule", "cost"], + ["addr : PLUS_DI(index64.index | imm32.disp)", [0, 1]], +], """ + $rule $cost + names { + $addr->a.base_valid = 0; + $addr->a.index = $index->a.index; + $addr->a.scale = $index->a.scale; + $addr->a.disp = $disp->val; + $addr->a.string = $disp->a.string; + }, + final { + $addr->a.index = $index->a.index; + }, + supairs { + $addr->extra = $index->extra; + $addr->freed = $index->freed; + }, + emit { + $addr->rtl = gen_rtx_PLUS(DImode, + $index->rtl, + gen_rtx_imm_constant($disp->val, $disp->a.string, $disp->rtl)); + }; +""") + +plug.plugrule3("addrbase", [ + ["rule", "cost"], + ["addr : base64.base", [0, 0]], +], """ + $rule $cost + names { + $addr->a.index = 0; + $addr->a.scale = 0; + $addr->a.disp = 0; + $addr->a.string = NULL; + }, + emit { + $addr->rtl = $base->rtl; + }; +""") + +plug.plugrule3("addrindex", [ + ["rule", "cost"], + ["addr : index64.index", [0, 5]], +], """ + $rule $cost + names { + $addr->a.base_valid = 0; + $addr->a.disp = 0; + $addr->a.string = NULL; + }, + emit { + $addr->rtl = $index->rtl; + }; +""") + +# +# This chain rule "addr -> symbol" will hopefully be used preferentially +# to avoid a double chain rule application "addr -> imm32 -> symbol". +# The double chain rule will discard semantic information about the symbol. +# +plug.plugrule3("addrimm32", [ + ["rule", "cost"], + ["addr.dst : symbol32.const", [0, 1]], + ["addr.dst : symbol64.const", [0, 1]], +], """ + $rule $cost + names { + $dst->a = $const->a; /* preserve all semantic info */ + }, + emit { + rtx expr = $dst->rtl; /* RTL from original tree (thin ice!) */ + $dst->rtl = gen_rtx_imm_constant($dst->a.disp, $dst->a.string, expr); + }; +""") + +plug.plugrule3("addrimm32", [ + ["rule", "cost"], + ["addr.dst : imm32.const", [0, 1]], +], """ + $rule $cost + names { + $dst->a.base_valid = 0; + $dst->a.index = 0; + $dst->a.scale = 0; + $dst->a.disp = $const->val; + }, + emit { + rtx expr = $dst->rtl; /* RTL from original tree (thin ice!) */ + $dst->rtl = gen_rtx_imm_constant($dst->a.disp, $dst->a.string, expr); + }; +""") + +plug.plugrule3("dispimm8", [ + ["rule", "cost"], + ["disp : imm8.const", [0, 0]], + ["disp : imm32.const", [0, 0]], +], """ + $rule $cost + names { + $disp->a.disp = $const->val; + }, + emit { + $disp->rtl = gen_rtx_imm_constant($disp->a.disp, $disp->a.string, $disp->rtl); + }; +""") + +plug.plugrule3("basereg", [ + ["rule", "cost", "rtx_mode"], + ["base64.base : r64.src", [0, 1], "DImode"], + ["base32.base : r32.src", [0, 1], "SImode"], # address reg accessed as a SI + ["base16.base : r16.src", [0, 1], "SImode"], # address reg accessed as a SI + ["base8.base : r8.src", [0, 1], "SImode"], # address reg accessed as a SI +], """ + $rule $cost + names { + $base->a.base = $src->r; + $base->a.base_valid = 1; + $base->a.base_rip = 0; + }, + costs { + forgettable($src->r); + }, + final { + $base->a.base = $src->r; + }, + emit { + $base->rtl = gen_rtx_REG($rtx_mode, $src->r); + }; +""") + +plug.plugrule3("indexreg", [ + ["rule", "cost", "rtx_mode"], + ["index64.index : r64.src", [0, 1], "DImode"], + ["index32.index : r32.src", [0, 1], "SImode"], + ["index16.index : r16.src", [0, 1], "SImode"], + ["index8.index : r8.src", [0, 1], "SImode"], +], """ + $rule $cost + names { + $index->a.index = $src->r; + $index->a.scale = 1; + }, + costs { + forgettable($src->r); + }, + final { + $index->a.index = $src->r; + }, + emit { + $index->rtl = gen_rtx_REG($rtx_mode, $src->r); + }; +""") + +plug.plugrule3("indexscalereg", [ + ["rule", "cost", "rtx_mode", "is_shift"], + + ["index64.index : ASHIFT_DI(r64.src, scon.const)", [0, 1], "DImode", 1], + ["index32.index : ASHIFT_SI(r32.src, scon.const)", [0, 1], "SImode", 1], + ["index16.index : ASHIFT_HI(r16.src, scon.const)", [0, 1], "HImode", 1], + ["index8.index : ASHIFT_QI(r8.src, scon.const)", [0, 1], "QImode", 1], + + ["index64.index : MULT_DI(r64.src | mcon.const)", [0, 1], "DImode", 0], + ["index32.index : MULT_SI(r32.src | mcon.const)", [0, 1], "SImode", 0], + ["index16.index : MULT_HI(r16.src | mcon.const)", [0, 1], "HImode", 0], + ["index8.index : MULT_QI(r8.src | mcon.const)", [0, 1], "QImode", 0], + + ["index16.index : SUBREG_HI(ASHIFT_SI(SIGN_EXTEND_SI(r16.src), scon.const), CONST_0)", [0, 1], "HImode", 1], + ["index16.index : SUBREG_HI(ASHIFT_SI(ZERO_EXTEND_SI(r16.src), scon.const), CONST_0)", [0, 1], "HImode", 1], + ["index8.index : SUBREG_QI(ASHIFT_SI(SIGN_EXTEND_SI(r8.src), scon.const), CONST_0)", [0, 1], "QImode", 1], + ["index8.index : SUBREG_QI(ASHIFT_SI(ZERO_EXTEND_SI(r8.src), scon.const), CONST_0)", [0, 1], "QImode", 1], + +], """ + $rule $cost + names { + $index->a.index = $src->r; + $index->a.scale = $is_shift ? (1 << $const->val) : $const->val; + }, + final { + $index->a.index = $src->r; + }, + costs { + forgettable($src->r); + }, + supairs { + $index->extra = $src->extra; + $index->freed = $src->freed; + }, + emit { + $index->rtl = gen_rtx_MULT($rtx_mode, + gen_rtx_REG($rtx_mode, $src->r), + GEN_INT($is_shift ? (1 << $const->val) : $const->val)); + }; +""") + + +#-------------------------------------------------------------- +# constants +plug.plugrule3("constants", [ + ["rule", "cost"], + + ["scon.dst : CONST_0", [0, 0]], + ["scon.dst : CONST_P1", [0, 0]], + ["scon.dst : CONST_P2", [0, 0]], + ["scon.dst : CONST_P3", [0, 0]], + + ["mcon.dst : CONST_P1", [0, 0]], + ["mcon.dst : CONST_P2", [0, 0]], + ["mcon.dst : CONST_P4", [0, 0]], + ["mcon.dst : CONST_P8", [0, 0]], + + ["imm4.dst : CONST_N1", [0, 1]], + ["imm4.dst : CONST_0", [0, 1]], + ["imm4.dst : CONST_P1", [0, 1]], + ["imm4.dst : CONST_P2", [0, 1]], + ["imm4.dst : CONST_P3", [0, 1]], + ["imm4.dst : CONST_P4", [0, 0]], + ["imm4.dst : CONST4P", [0, 1]], + ["imm4.dst : CONST4N", [0, 1]], + + ["imm5.dst : imm4.src", [0, 0]], + ["imm5.dst : CONST_P8", [0, 1]], + ["imm5.dst : CONST_P15", [0, 1]], + ["imm5.dst : CONST5P", [0, 1]], + ["imm5.dst : CONST5N", [0, 1]], + + ["imm6.dst : imm5.src", [0, 0]], + ["imm5.dst : CONST_P16", [0, 1]], + ["imm5.dst : CONST_P24", [0, 1]], + ["imm5.dst : CONST_P31", [0, 1]], + ["imm6.dst : CONST_P32", [0, 1]], + ["imm6.dst : CONST6P", [0, 1]], + ["imm6.dst : CONST6N", [0, 1]], + + ["imm7.dst : imm6.src", [0, 0]], + ["imm6.dst : CONST_P48", [0, 1]], + ["imm6.dst : CONST_P56", [0, 1]], + ["imm6.dst : CONST_P63", [0, 1]], + ["imm7.dst : CONST7P", [0, 1]], + ["imm7.dst : CONST7N", [0, 1]], + + ["imm8.dst : imm7.src", [0, 0]], + ["imm8.dst : CONST8P", [0, 1]], + ["imm8.dst : CONST8N", [0, 1]], + + ["imm12.dst : imm8.src", [0, 1]], + ["imm12.dst : CONST_P255", [0, 2]], + ["imm12.dst : CONST12P", [0, 2]], + ["imm12.dst : CONST12N", [0, 2]], + + ["imm13.dst : imm12.src", [0, 0]], + ["imm13.dst : CONST13P", [0, 2]], + ["imm13.dst : CONST13N", [0, 2]], + + ["imm14.dst : imm13.src", [0, 0]], + ["imm14.dst : CONST14P", [0, 2]], + ["imm14.dst : CONST14N", [0, 2]], + + ["imm15.dst : imm14.src", [0, 0]], + ["imm15.dst : CONST15P", [0, 2]], + ["imm15.dst : CONST15N", [0, 2]], + + ["imm16.dst : imm15.src", [0, 0]], + ["imm16.dst : CONST16P", [0, 2]], + ["imm16.dst : CONST16N", [0, 2]], + + ["imm28.dst : imm16.src", [0, 2]], + ["imm28.dst : CONST28P", [0, 4]], + ["imm28.dst : CONST28N", [0, 4]], + + ["imm29.dst : imm28.src", [0, 2]], + ["imm29.dst : CONST29P", [0, 4]], + ["imm29.dst : CONST29N", [0, 4]], + + ["imm30.dst : imm29.src", [0, 0]], + ["imm30.dst : CONST30P", [0, 4]], + ["imm30.dst : CONST30N", [0, 4]], + + ["imm31.dst : imm30.src", [0, 0]], + ["imm31.dst : CONST31P", [0, 4]], + ["imm31.dst : CONST31N", [0, 4]], + + ["imm32.dst : pureimm32.src", [0, 0]], + ["pureimm32.dst : imm31.src", [0, 0]], + ["pureimm32.dst : CONST32P", [0, 4]], + ["pureimm32.dst : CONST32N", [0, 4]], + ["pureimm32.dst : CONSTIEEE32", [0, 8]], + + ["imm64.dst : imm32.src", [0, 4]], + ["imm64.dst : CONST64P", [0, 8]], + ["imm64.dst : CONST64N", [0, 8]], + ["imm64.dst : CONSTIEEE64", [0, 8]], + + ["pos8.dst : mcon.src", [0, 1]], + ["pos8.dst : scon.src", [0, 1]], + ["pos8.dst : CONST4P", [0, 1]], + ["pos8.dst : CONST5P", [0, 1]], + ["pos8.dst : CONST6P", [0, 1]], + ["pos8.dst : CONST7P", [0, 1]], + ["pos8.dst : CONST8P", [0, 1]], + ["pos16.dst : pos8.src", [0, 1]], + ["pos16.dst : CONST12P", [0, 2]], + ["pos16.dst : CONST13P", [0, 2]], + ["pos16.dst : CONST14P", [0, 2]], + ["pos16.dst : CONST15P", [0, 2]], + ["pos16.dst : CONST16P", [0, 2]], + ["pos32.dst : pos16.src", [0, 2]], + ["pos32.dst : CONST28P", [0, 4]], + ["pos32.dst : CONST29P", [0, 4]], + ["pos32.dst : CONST30P", [0, 4]], + ["pos32.dst : CONST31P", [0, 4]], + ["pos32.dst : CONST32P", [0, 4]], + +], """ + $rule $cost + ; +""") + +#-------------------------------------------------------------- +# relocatable constants + + +plug.plugrule3("relocconstants", [ + ["rule", "cost"], + ["symbol32.dst : SYMBOL_REF_32", [0, 0]], + ["symbol64.dst : SYMBOL_REF_64", [0, 0]], +], """ + $rule $cost + names { + $dst->a.base_rip = 1; /* %rip usage */ + }; +""") + +plug.plugrule3("relocconstants", [ + ["rule", "cost"], + ["symbol32.dst : LABEL_REF_DI", [0, 0]], +], """ + $rule $cost + names { + $dst->a.base_rip = 1; /* %rip usage(?) */ + }; +""") + + +plug.plugrule3("symbolmix",[ + ["rule", "cost"], + ["symbol.dst : symbol32.src", [0, 0]], + ["symbol.dst : symbol64.src", [0, 0]], +], """ + $rule $cost + ; +""") + +plug.plugrule3("symbolconst1",[ + ["rule", "cost"], + ["symbol32.dst : pureimm32.src", [0, 0]], + ["symbol64.dst : pureimm32.src", [0, 0]], +], """ + $rule $cost + ; +""") + +# +# The upstream part gcc sometimes has CONST_DI, and sometimes they don't. +# So we let them have as many as they want; it all seems somewhat random. +# +plug.plugrule3("symbolconst2", [ + ["rule", "cost"], + ["symbol32.dst : CONST_DI(symbol32.src)", [0, 0]], + ["symbol64.dst : CONST_DI(symbol64.src)", [0, 0]], +], """ + $rule $cost + names { + $dst->a.string = $src->a.string; + $dst->val = $src->val; + $dst->a.base_rip = 1; /* %rip usage */ + }; +""") + +plug.plugrule3("symbolsymconstplus", [ + ["rule", "cost"], + ["symbol32.dst : PLUS_DI(symbol32.src | pureimm32.const)", [0, 0]], + ["symbol64.dst : PLUS_DI(symbol64.src | pureimm32.const)", [0, 0]], +], """ + $rule $cost + names { + $dst->a.string = $src->a.string; + $dst->val = $src->val + $const->val; + $dst->a.base_rip = 1; /* %rip usage */ + }; +""") + +plug.plugrule3("symbolsymconstminus", [ + ["rule", "cost"], + ["symbol32.dst : MINUS_DI(symbol32.src, pureimm32.const)", [0, 0]], + ["symbol64.dst : MINUS_DI(symbol64.src, pureimm32.const)", [0, 0]], +], """ + $rule $cost + names { + $dst->a.string = $src->a.string; + $dst->val = $src->val - $const->val; + $dst->a.base_rip = 1; /* %rip usage */ + }; +""") + +plug.plugrule3("immsym", [ + ["rule", "cost"], + ["imm32.dst : symbol32.src", [0, 4]], + ["imm64.dst : symbol64.src", [0, 8]], +], """ + $rule $cost + names { + /* this transfers the "a" attribute from src to dst */ + } + ; +""") + + +#-------------------------------------------------------------- +# control flow + +# we don't do anything for jmps and branches; +# just use the old instruction. + +# TODO: need some odd expressions to deal with case statements. + +# Need to do tests to be sure these are accurate. +# How are floats compared? +# +# Later, when we compare r64 to immediate, +# remember to try reverse tests too. +# +# May want to do these inline with IF_THEN_ELSE +# so that SU numbering can take advantage of all registers. + + +plug.plugrule3("label", [ + ["rule", "cost"], + ["label : LABEL_REF_DI", [0, 0]], +], """ + $rule $cost + ; +""") + +#-------------------------------------------------------------- +# non-computed unconditional branch (simple) +# +plug.plugrule3("jmp", [ + ["rule", "cost"], + # TODO: bogus cost + ["stmt : SET_ALL(PC_ALL, label.target)", [0, 0]], +], """ + $rule $cost + debug { + dump_jump("jmp", $target); + }, + emit { + rtx label = XEXP ($target->rtl, 0); + rtx new_jump = emit_jump_insn (gen_jump (label)); + LABEL_NUSES (label) += 1; + JUMP_LABEL (new_jump) = label; + }; +""") + +#-------------------------------------------------------------- +# computed unconditional branch (indirect goto) +# +plug.plugrule3("jmp", [ + ["rule", "cost"], + # TODO: bogus cost + ["stmt : PARALLEL_ALL(SET_ALL(PC_ALL, r64.src1), USE_ALL(label.target))", [0, 0]], +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($src1->r); + }, + debug { + dump_jumpR("jmp", $src1->r, 'q'); + }, + emit { + rtx label = XEXP ($target->rtl, 0); + rtx new_jump = emit_jump_insn( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, + gen_rtx_PC(VOIDmode), + gen_rtx_REG(DImode, $src1->r)), + gen_rtx_USE(VOIDmode, + $target->rtl)))); + LABEL_NUSES (label) += 1; + JUMP_LABEL (new_jump) = label; + }; +""") + + + +""" +A note on the x86 conditionals. +This information was lifted directly from the pdf version +of the AMD64 Programmer's Reference Manual, Volume 3. +jo overflow (of = 1). + +jno not overflow (of = 0). + +jb below (cf = 1). unsigned < +jc carry (cf = 1). unsigned < +jnae not above or equal (cf = 1). unsigned < + +jnb not below (cf = 0). unsigned >= +jnc not carry (cf = 0). unsigned >= +jae above or equal (cf = 0). unsigned >= + +jz zero (zf = 1). +je equal (zf = 1). + +jnz not zero (zf = 0). +jne not equal (zf = 0). + +jbe below or equal (cf = 1 or zf = 1). unsigned <= +jna not above (cf = 1 or zf = 1). unsigned <= + +jnbe not below or equal (cf = 0 and zf = 0). unsigned > +ja above (cf = 0 and zf = 0). unsigned > + +js sign (sf = 1). + +jns not sign (sf = 0). + +jp parity (pf = 1). +jpe parity even (pf = 1). + +jnp not parity (pf = 0). +jpo parity odd (pf = 0). + +jl less (sf <> of). signed < +jnge not greater or equal (sf <> of). signed < + +jnl not less (sf = of). signed >= +jge greater or equal (sf = of). signed >= + +jle less or equal (zf = 1 or sf <> of). signed <= +jng not greater (zf = 1 or sf <> of). signed <= + +jnle not less or equal (zf = 0 and sf = of). signed > +jg greater (zf = 0 and sf = of). signed > + +""" + +#-------------------------------------------------------------- +# conditional branches +# + +plug.plugrule3("jcc", [ + ["rule", "cost"], + ["stmt : SET_ALL(PC_ALL, COND_MOVE(condition.cond, PAIR_ALL(label.target, PC_ALL)))", [0, 0]], +], """ + $rule $cost + debug { + const enum rtx_code code = $cond->code; + switch (code) { + case UNEQ: /* unordered equality testing */ + dump_jump("je", $target); + dump_jump("jp", $target); /* jump if unordered */ + break; + case LTGT: /* unordered inequality testing */ + dump_jump("jne", $target); + dump_jump("jp", $target); /* jump if unordered */ + break; + case UNGE: dump_jump("jae", $target); break; + case UNGT: dump_jump("ja", $target); break; + case UNLE: dump_jump("jbe", $target); break; + case UNLT: dump_jump("jb", $target); break; + case UNORDERED: dump_jump("jp", $target); break; + case ORDERED: dump_jump("jnp", $target); break; + + case EQ: dump_jump("je", $target); break; + case NE: dump_jump("jne", $target); break; + case GE: dump_jump("jge", $target); break; + case GT: dump_jump("jg", $target); break; + case LE: dump_jump("jle", $target); break; + case LT: dump_jump("jl", $target); break; + + case GEU: dump_jump("jae", $target); break; + case GTU: dump_jump("ja", $target); break; + case LEU: dump_jump("jbe", $target); break; + case LTU: dump_jump("jb", $target); break; + + default: + icg_nyi("unrecognized condition code %d for jump", code); + } + }; +""") + + +#-------------------------------------------------------------- +# conditional moves in the GPR set. +# These are implemented via CMOVcc. +# Aook at attribute indicating kind of condition. + +plug.plugrule3("cmovreg", [ + ["rule", "cost", "schar", "rtx_mode", "is_normal"], + + ["r64x.dst : COND_MOVE(condition.cond, PAIR_ALL(r64x.src1, r64.src2))", [1, 4], 'q', "DImode", 1], + ["r32x.dst : COND_MOVE(condition.cond, PAIR_ALL(r32x.src1, r32.src2))", [1, 3], 'd', "SImode", 1], + ["r16x.dst : COND_MOVE(condition.cond, PAIR_ALL(r16x.src1, r16.src2))", [1, 3], 'd', "SImode", 1], + ["r8x.dst : COND_MOVE(condition.cond, PAIR_ALL(r8x.src1, r8.src2))", [1, 3], 'd', "SImode", 1], + +], """ + $rule $cost + names { + $dst->rx = $src1->rx; + if ($is_normal) { + /* + * set the order the children are visited; + * when su ordering is working, this will force a Sethi-Ullman traversal. + */ + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + } + }, + final { + $dst->rx = $src1->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($src2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1->rx); + memorable($src2->r); + }, + debug { + const enum rtx_code code = $cond->code; + switch (code) { + /* + * NOTE A: + * There is empirical evidence suggesting that the conditions and the cmov opcodes + * must be inverted relative to each other. This will make the icg+asm + * path produce identical asm code to the icg+rtl path. + * 03Nov08: After 4 hours of searching, rrh does not have an explanation for this. + * Alternatively, try swapping the fsrc and tsrc args to gen_rtx_IF_THEN_ELSE + * perhaps this is because of the evaluation permutation that is induced? + * By swapping fsrc and tsrc to the gen_rtx_IF_THEN_ELSE + * we get identical code icg+asm and icg+rtl. + */ + case EQ: dumpRR("cmove", $src2->r, '$schar', $dst->rx, '$schar'); break; + case NE: dumpRR("cmovne", $src2->r, '$schar', $dst->rx, '$schar'); break; + case GE: dumpRR("cmovge", $src2->r, '$schar', $dst->rx, '$schar'); break; + case GT: dumpRR("cmovg", $src2->r, '$schar', $dst->rx, '$schar'); break; + case LE: dumpRR("cmovle", $src2->r, '$schar', $dst->rx, '$schar'); break; + case LT: dumpRR("cmovl", $src2->r, '$schar', $dst->rx, '$schar'); break; + case GEU: dumpRR("cmovae", $src2->r, '$schar', $dst->rx, '$schar'); break; + case GTU: dumpRR("cmova", $src2->r, '$schar', $dst->rx, '$schar'); break; + case LEU: dumpRR("cmovbe", $src2->r, '$schar', $dst->rx, '$schar'); break; + case LTU: dumpRR("cmovb", $src2->r, '$schar', $dst->rx, '$schar'); break; + case UNLE: dumpRR("cmovbe", $src2->r, '$schar', $dst->rx, '$schar'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG($rtx_mode, $src1->rx); + rtx fsrc = gen_rtx_REG($rtx_mode, $src2->r); + rtx dst = tsrc; + const enum rtx_code code = $cond->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE($rtx_mode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + +# +# TODO preston, extend these cases +# are there compare from memory for the integral types? + +plug.plugrule3("cmovmem", [ + ["rule", "cost", "schar", "rtx_mode"], + ["r64x.dst : COND_MOVE(condition.cond, PAIR_ALL(r64x.src1, MEM_DI(addr.src2)))", [4, 3], 'q', "DImode"], + # + # TODO: compare from memory with other data types; see above specification + # +], """ + $rule $cost + names { + $dst->rx = $src1->rx; + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + }, + final { + $dst->rx = $src1->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $src2); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1->rx); + }, + debug { + const enum rtx_code code = $cond->code; + switch (code) { + /* + * See + * NOTE A + * above + */ + case EQ: dumpMR("cmove", $src2, $dst->rx, '$schar'); break; + case NE: dumpMR("cmovne", $src2, $dst->rx, '$schar'); break; + case GE: dumpMR("cmovge", $src2, $dst->rx, '$schar'); break; + case GT: dumpMR("cmovg", $src2, $dst->rx, '$schar'); break; + case LE: dumpMR("cmovle", $src2, $dst->rx, '$schar'); break; + case LT: dumpMR("cmovl", $src2, $dst->rx, '$schar'); break; + case GEU: dumpMR("cmovae", $src2, $dst->rx, '$schar'); break; + case GTU: dumpMR("cmova", $src2, $dst->rx, '$schar'); break; + case LEU: dumpMR("cmovbe", $src2, $dst->rx, '$schar'); break; + case LTU: dumpMR("cmovb", $src2, $dst->rx, '$schar'); break; + case UNLE: dumpMR("cmovbe", $src2, $dst->rx, '$schar'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG($rtx_mode, $src1->rx); + rtx fsrc = gen_rtx_MEM($rtx_mode, $src2->rtl); + rtx dst = tsrc; + const enum rtx_code code = $cond->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE($rtx_mode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + +#-------------------------------------------------------------- +# conditional value + +# implemented via SETcc + +plug.plugrule3("setccreg", [ + ["rule", "cost", "schar", "rtx_mode"], + ["r8x.dst : condition.cond", [1, 3], 'b', "QImode"], +], """ + $rule $cost + names { + $dst->rx = new_reg(); + }, + kinds { + icg_reg_vector[$dst->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($dst->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + final { + $dst->rx = icg_reg_vector[find($dst->rx)].color; + }, + debug { + const enum rtx_code code = $cond->code; + const enum machine_mode cc_code = $cond->cc_code; + switch (code) { + case EQ: dumpR("sete", $dst->rx, '$schar'); break; + case NE: dumpR("setne", $dst->rx, '$schar'); break; + case GE: dumpR(cc_code == CCFPUmode ? "setae" : "setge", $dst->rx, '$schar'); break; + case GT: dumpR(cc_code == CCFPUmode ? "seta" : "setg", $dst->rx, '$schar'); break; + case LE: dumpR(cc_code == CCFPUmode ? "setbe" : "setle", $dst->rx, '$schar'); break; + case LT: dumpR(cc_code == CCFPUmode ? "setb" : "setl", $dst->rx, '$schar'); break; + + case GEU: dumpR("setae", $dst->rx, '$schar'); break; + case GTU: dumpR("seta", $dst->rx, '$schar'); break; + case LEU: dumpR("setbe", $dst->rx, '$schar'); break; + case LTU: dumpR("setb", $dst->rx, '$schar'); break; + + /* + * UNEQ (unordered ==) and LTGT (unordered !=) are problematic + * LTGT in flow context will generate 2 conditional jumps, + * one for jne and the other jp (jump unordered) + * Empirically, when we see LTGT in value context it + * is as a child of an IOR, where the other child + * is a test of UNORDERED, so we can just handle the jne case here. + */ + case UNEQ: dumpR("sete", $dst->rx, '$schar'); break; + case LTGT: dumpR("setne", $dst->rx, '$schar'); break; + + case UNGE: dumpR("setae", $dst->rx, '$schar'); break; + case UNGT: dumpR("seta", $dst->rx, '$schar'); break; + case UNLE: dumpR("setbe", $dst->rx, '$schar'); break; + case UNLT: dumpR("setb", $dst->rx, '$schar'); break; + case UNORDERED: dumpR("setp", $dst->rx, '$schar'); break; + case ORDERED: dumpR("setnp", $dst->rx, '$schar'); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + }, + emit { + rtx src; + rtx dst = gen_rtx_REG($rtx_mode, $dst->rx); + const enum rtx_code code = $cond->code; + switch (code) { + case EQ: src = gen_rtx_EQ ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case NE: src = gen_rtx_NE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GE: src = gen_rtx_GE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GT: src = gen_rtx_GT ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LE: src = gen_rtx_LE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LT: src = gen_rtx_LT ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + case GEU: src = gen_rtx_GEU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: src = gen_rtx_GTU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: src = gen_rtx_LEU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: src = gen_rtx_LTU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + case UNEQ: src = gen_rtx_UNEQ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTGT: src = gen_rtx_LTGT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNGE: src = gen_rtx_UNGE($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNGT: src = gen_rtx_UNGT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: src = gen_rtx_UNLE($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLT: src = gen_rtx_UNLT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNORDERED: src = gen_rtx_UNORDERED($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case ORDERED: src = gen_rtx_ORDERED($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + +plug.plugrule3("setccmem", [ + ["rule", "cost", "schar", "rtx_mode"], + ["stmt : SET_ALL(MEM_QI(addr.dst), condition.cond)", [3, 2], 'b', "QImode"], +], """ + $rule $cost + build { + add_addr(live, $dst); + }, + remat { + flags = 0; + }, + debug { + const enum rtx_code code = $cond->code; + const enum machine_mode cc_code = $cond->cc_code; + switch (code) { + case EQ: dumpM("sete", $dst); break; + case NE: dumpM("setne", $dst); break; + case GE: dumpM(cc_code == CCFPUmode ? "setae" : "setge", $dst); break; + case GT: dumpM(cc_code == CCFPUmode ? "seta" : "setg", $dst); break; + case LE: dumpM(cc_code == CCFPUmode ? "setbe" : "setle", $dst); break; + case LT: dumpM(cc_code == CCFPUmode ? "setb" : "setl", $dst); break; + + case GEU: dumpM("setae", $dst); break; + case GTU: dumpM("seta", $dst); break; + case LEU: dumpM("setbe", $dst); break; + case LTU: dumpM("setb", $dst); break; + + case UNEQ: dumpM("sete", $dst); break; + case LTGT: dumpM("setne", $dst); break; + case UNGE: dumpM("setae", $dst); break; + case UNGT: dumpM("seta", $dst); break; + case UNLE: dumpM("setbe", $dst); break; + case UNLT: dumpM("setb", $dst); break; + case UNORDERED: dumpM("setp", $dst); break; + case ORDERED: dumpM("setnp", $dst); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + }, + emit { + rtx src; + rtx dst = gen_rtx_MEM($rtx_mode, $dst->rtl); + const enum rtx_code code = $cond->code; + switch (code) { + case EQ: src = gen_rtx_EQ ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case NE: src = gen_rtx_NE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GE: src = gen_rtx_GE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GT: src = gen_rtx_GT ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LE: src = gen_rtx_LE ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LT: src = gen_rtx_LT ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + case GEU: src = gen_rtx_GEU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: src = gen_rtx_GTU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: src = gen_rtx_LEU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: src = gen_rtx_LTU($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + case UNEQ: src = gen_rtx_UNEQ($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case LTGT: src = gen_rtx_LTGT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNGE: src = gen_rtx_UNGE($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNGT: src = gen_rtx_UNGT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: src = gen_rtx_UNLE($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNLT: src = gen_rtx_UNLT($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case UNORDERED: src = gen_rtx_UNORDERED($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + case ORDERED: src = gen_rtx_ORDERED($rtx_mode, gen_rtx_REG($cond->cc_code, REG_CC), GEN_INT(0)); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +""") + + + + +#-------------------------------------------------------------- +# a peephole optimization involving the carry bit +# somebody upstream of us is finding opportunities to conditionally modify a variable by 1 +# by using sbb (sub borrow) or adc (add carry) +# + +plug.plugrule3("sbb", [ + ["rule", "cost", "op", "mode", "schar", "bias"], + + ["r64x.dst : PLUS_DI(r64x.src | NEG_DI(PLUS_DI(LTU_ALL(rcc.cc, CONST_0), CONST_N1)))", [1, 4], "sbbq", "DImode", 'q', -1], + ["r32x.dst : PLUS_SI(r32x.src | NEG_SI(PLUS_SI(LTU_ALL(rcc.cc, CONST_0), CONST_N1)))", [1, 3], "sbbl", "SImode", 'd', -1], + ["r16x.dst : PLUS_HI(r16x.src | NEG_HI(PLUS_HI(LTU_ALL(rcc.cc, CONST_0), CONST_N1)))", [1, 4], "sbbw", "HImode", 'w', -1], + ["r8x.dst : PLUS_QI(r8x.src | NEG_QI(PLUS_QI(LTU_ALL(rcc.cc, CONST_0), CONST_N1)))", [1, 4], "sbbb", "QImode", 'b', -1], + + ["r64x.dst : PLUS_DI(r64x.src | NEG_DI(PLUS_DI(LTU_ALL(rcc.cc, CONST_0), CONST_0)))", [1, 4], "sbbq", "DImode", 'q', 0], + ["r32x.dst : PLUS_SI(r32x.src | NEG_SI(PLUS_SI(LTU_ALL(rcc.cc, CONST_0), CONST_0)))", [1, 3], "sbbl", "SImode", 'd', 0], + ["r16x.dst : PLUS_HI(r16x.src | NEG_HI(PLUS_HI(LTU_ALL(rcc.cc, CONST_0), CONST_0)))", [1, 4], "sbbw", "HImode", 'w', 0], + ["r8x.dst : PLUS_QI(r8x.src | NEG_QI(PLUS_QI(LTU_ALL(rcc.cc, CONST_0), CONST_0)))", [1, 4], "sbbb", "QImode", 'b', 0], + +], """ + $rule $cost + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIRm1("$op", $dst->rx, '$schar'); + }, + emit { + rtx ltu = gen_rtx_LTU($mode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS($mode, ltu, GEN_INT($bias)); + rtx minus = gen_rtx_MINUS($mode, gen_rtx_REG($mode, $src->rx), plus); + rtx dst = gen_rtx_REG($mode, $dst->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +""") + +plug.plugrule3("adc", [ + ["rule", "cost", "op", "mode", "schar", "bias"], + + ["r64x.dst : PLUS_DI(r64x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_0)", [1, 4], "adcq", "DImode", 'q', 0], + ["r32x.dst : PLUS_SI(r32x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_0)", [1, 3], "adcl", "SImode", 'd', 0], + ["r16x.dst : PLUS_HI(r16x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_0)", [1, 4], "adcw", "HImode", 'w', 0], + ["r8x.dst : PLUS_QI(r8x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_0)", [1, 4], "adcb", "QImode", 'b', 0], + + ["r64x.dst : PLUS_DI(r64x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_N1)", [1, 4], "adcq", "DImode", 'q', -1], + ["r32x.dst : PLUS_SI(r32x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_N1)", [1, 3], "adcl", "SImode", 'd', -1], + ["r16x.dst : PLUS_HI(r16x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_N1)", [1, 4], "adcw", "HImode", 'w', -1], + ["r8x.dst : PLUS_QI(r8x.src | LTU_ALL(rcc.cc, CONST_0) | CONST_N1)", [1, 4], "adcb", "QImode", 'b', -1], + +], """ + $rule $cost + names { + $dst->rx = $src->rx; + }, + final { + $dst->rx = $src->rx; + }, + build { + unsigned rd = find($dst->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($src->rx); + }, + debug { + dumpIRm1("$op", $dst->rx, '$schar'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU($mode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS($mode, ltu, gen_rtx_REG($mode, $src->rx)); + rtx plus1 = gen_rtx_PLUS($mode, plus0, GEN_INT($bias)); + rtx dst = gen_rtx_REG($mode, $dst->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +""") + + +#-------------------------------------------------------------- +# conditions + +# set attribute indicating kind of condition + +plug.plugrule3("condition", [ + ["rule", "cost", "op", "cc_mode"], + + # + # ordered signed and unsigned comparisions + # + ["condition.dst : EQ_ALL ( rcc.src, CONST_0)", [0, 0], "EQ", "CCmode"], + ["condition.dst : NE_ALL ( rcc.src, CONST_0)", [0, 0], "NE", "CCmode"], + ["condition.dst : GE_ALL ( rcc.src, CONST_0)", [0, 0], "GE", "CCmode"], + ["condition.dst : GT_ALL ( rcc.src, CONST_0)", [0, 0], "GT", "CCmode"], + ["condition.dst : LE_ALL ( rcc.src, CONST_0)", [0, 0], "LE", "CCmode"], + ["condition.dst : LT_ALL ( rcc.src, CONST_0)", [0, 0], "LT", "CCmode"], + ["condition.dst : GEU_ALL( rcc.src, CONST_0)", [0, 0], "GEU", "CCmode"], # unsigned + ["condition.dst : GTU_ALL( rcc.src, CONST_0)", [0, 0], "GTU", "CCmode"], # unsigned + ["condition.dst : LEU_ALL( rcc.src, CONST_0)", [0, 0], "LEU", "CCmode"], # unsigned + ["condition.dst : LTU_ALL( rcc.src, CONST_0)", [0, 0], "LTU", "CCmode"], # unsigned + + # + # ordered floating point comparisions + # Watchout: this is a tarpit. + # These rule is here by analog with the signed/unsigned cases. + # These may never happen in practice. + # We have seen: + # COND_MOVE((NE_ALL REG_SF REG_SF) (PAIR_ALL LABEL PC)) + # to implement conditional branches based on floating point compares. + + # + # under what circumstances do we put the "UN" (unordered) modifier on the requested test? + # + ["condition.dst : EQ_ALL(urcc.src, CONST_0)", [0, 0], "EQ", "CCFPUmode"], + ["condition.dst : NE_ALL(urcc.src, CONST_0)", [0, 0], "NE", "CCFPUmode"], + ["condition.dst : GE_ALL(urcc.src, CONST_0)", [0, 0], "GE", "CCFPUmode"], + ["condition.dst : GT_ALL(urcc.src, CONST_0)", [0, 0], "GT", "CCFPUmode"], + ["condition.dst : LE_ALL(urcc.src, CONST_0)", [0, 0], "LE", "CCFPUmode"], + ["condition.dst : LT_ALL(urcc.src, CONST_0)", [0, 0], "LT", "CCFPUmode"], + + # + # TODO: these unordered floating comparisions not fully flensed out. + # Watchout: this is a tarpit. + # + ["condition.dst : UNEQ_ALL(urcc.src, CONST_0)", [0, 0], "UNEQ", "CCFPUmode"], # unordered FP + ["condition.dst : UNGE_ALL(urcc.src, CONST_0)", [0, 0], "UNGE", "CCFPUmode"], # unordered FP + ["condition.dst : UNGT_ALL(urcc.src, CONST_0)", [0, 0], "UNGT", "CCFPUmode"], # unordered FP + ["condition.dst : UNLE_ALL(urcc.src, CONST_0)", [0, 0], "UNLE", "CCFPUmode"], # unordered FP + ["condition.dst : UNLT_ALL(urcc.src, CONST_0)", [0, 0], "UNLT", "CCFPUmode"], # unordered FP + ["condition.dst : LTGT_ALL(urcc.src, CONST_0)", [0, 0], "LTGT", "CCFPUmode"], # unordered FP + ["condition.dst : UNORDERED_ALL(urcc.src, CONST_0)", [0, 0], "UNORDERED", "CCFPUmode"], # unordered FP + ["condition.dst : ORDERED_ALL(urcc.src, CONST_0)", [0, 0], "ORDERED", "CCFPUmode"], # unordered FP + +], """ + $rule $cost + names { + $dst->code = $op; + $dst->cc_code = $cc_mode; + }; +""") + +#-------------------------------------------------------------- +# condition codes + +# The next two sets of special rules +# are used to overcome some weaknesses in gcc. +# +# The 1st problem is that gcc sometimes provides us with dead code +# of the form (SET_ALL (REGX_DI r17) (COMPARE_CC ...)) +# Later passes of gcc will clean it up, though it'd be better if +# if it were removed before allocation. +# Keeping the first set of rules allows the dead code to be +# recognized by the grammar. +# +# The 2nd problem is that we don't know how to provoke gcc into +# generating conditional branches. Therefore, we sometimes see +# things like +# +# insn 7: SET_ALL +# REGX_DI:17[flags] +# COMPARE_CC +# REG_SI:60 +# REG_SI:61 +# insn 8: SET_ALL +# PC_ALL +# COND_MOVE +# GE_ALL +# REGX_DI:17[flags] +# CONST_0:0 +# PAIR_ALL +# LABEL_REF_DI +# PC_ALL +# +# Someday, it'd be great to have the COMPARE forward +# propagated into the conditional branch. For today, +# we leave it alone. + +plug.plugrule3("stmtcc", [ + ["rule", "cost"], + # + # The high cost on these rules is to prevent these from + # being used unless there's no alternative. + # + ["stmt : SET_ALL(REGCCX_DI.dst, rcc.src)", [20, 20]], + ["stmt : SET_ALL(REGCCFPUX_DI.dst, urcc.src)", [20, 20]], +], """ + $rule $cost + ; +""") + + +plug.plugrule3("rccr64", [ + ["rule", "cost"], + # + # TODO: what does this/these rule really mean? + # Apparently the flags register comes to us as the terminal symbol + # REGX_DI:17[flags] the reduction chain REGX_DI:17[flags] --> r64 + # + ["rcc.dst : REGCCX_DI", [0, 0]], + ["rcc.dst : REGCC_DI", [0, 0]], # TODO: perhaps (needed for some -O3 code) + # + # By analogy with the previous rule, + # It is tempting to allow r64 to reduce to a urcc, + # but that is not correct, as a computation of a r64 + # doesn't implicitly do any unordered floating point comparisons; + # all floating point compares must be done explicitly. + # + ["urcc.dst : REGCCFPUX_DI", [0, 0]], + ["urcc.dst : REGCCFPU_DI", [0, 0]], # TODO: perhaps (needed for some -O3 code) +], """ + $rule $cost + costs { + /*forgettable($src->rx);*/ + }; +""") + +# End of sets of special rules + + + + +plug.plugrule3("rcc_compare0", [ + ["rule", "cost"], + ["rcc.dst : COMPARE_CC(ccr64x, CONST_0)", [0, 0]], + ["rcc.dst : COMPARE_CC(ccr32x, CONST_0)", [0, 0]], + ["rcc.dst : COMPARE_CC(ccr16x, CONST_0)", [0, 0]], + ["rcc.dst : COMPARE_CC(ccr8x, CONST_0)", [0, 0]], +], """ + $rule $cost + debug { + /* fprintf(dump_file, "; IMPLICIT USE OF PREVIOUSLY SET CONDITION CODE\\n"); */ + }; +""") + +plug.plugrule3("urcc_comparereg", [ + ["rule", "cost", "opcode", "schar", "cc_mode", "rtx_mode", "is_test_variant"], + + ["urcc.dst : COMPARE_CC(rd.src1, rd.src2)", [1, 3], "ucomisd", 'x', "CCFPUmode", "DFmode", 0], + ["urcc.dst : COMPARE_CC(rf.src1, rf.src2)", [1, 3], "ucomiss", 'x', "CCFPUmode", "SFmode", 0], + + ["rcc.dst : COMPARE_CC(r64.src1, r64.src2)", [1, 3], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(r32.src1, r32.src2)", [1, 2], "cmpl", 'd', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(r16.src1, r16.src2)", [1, 2], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(r8.src1, r8.src2)", [1, 2], "cmpb", 'b', "CCmode", "QImode", 0], + + # + # I don't understand why this has to be CCZmode, except that's what the stock gcc RTL uses. + # + ["rcc.dst : COMPARE_CC(AND_DI(r64.src1, r64.src2), CONST_0)", [1, 3], "testq", 'q', "CCZmode", "DImode", 1], + ["rcc.dst : COMPARE_CC(AND_SI(r32.src1, r32.src2), CONST_0)", [1, 2], "testq", 'd', "CCZmode", "SImode", 1], + ["rcc.dst : COMPARE_CC(AND_HI(r16.src1, r16.src2), CONST_0)", [1, 2], "testq", 'w', "CCZmode", "HImode", 1], + ["rcc.dst : COMPARE_CC(AND_QI(r8.src1, r8.src2), CONST_0)", [1, 2], "testq", 'b', "CCZmode", "QImode", 1], + +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src1->r)); + sparseset_set_bit(live, find($src2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($src1->r); + memorable($src2->r); + }, + debug { + dumpRR("$opcode", $src2->r, '$schar', $src1->r, '$schar'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist($is_test_variant, $cc_mode, $rtx_mode, + gen_rtx_REG($rtx_mode, $src1->r), + gen_rtx_REG($rtx_mode, $src2->r)))); + }; +""") + +plug.plugrule3("rcc_compare_regimm", [ + ["rule", "cost", "opcode", "schar", "cc_mode", "rtx_mode", "is_test_variant"], + + ["rcc.dst : COMPARE_CC(r64.src1, imm32.src2)", [1, 3], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(r64.src1, imm8.src2)", [1, 3], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(r32.src1, imm32.src2)", [1, 2], "cmpl", 'd', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(r32.src1, imm8.src2)", [1, 2], "cmpl", 'd', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(r16.src1, imm16.src2)", [1, 3], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(r16.src1, imm8.src2)", [1, 3], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(r8.src1, imm8.src2)", [1, 2], "cmpb", 'b', "CCmode", "QImode", 0], + + # + # I don't understand why this has to be CCZmode, except that's what the stock gcc RTL uses. + # + ["rcc.dst : COMPARE_CC(AND_DI(r64.src1, imm32.src2), CONST_0)", [1, 3], "testq", 'q', "CCZmode", "DImode", 1], + ["rcc.dst : COMPARE_CC(AND_SI(r32.src1, imm32.src2), CONST_0)", [1, 2], "testl", 'd', "CCZmode", "SImode", 1], + ["rcc.dst : COMPARE_CC(AND_HI(r16.src1, imm16.src2), CONST_0)", [1, 3], "testw", 'w', "CCZmode", "HImode", 1], + ["rcc.dst : COMPARE_CC(AND_QI(r8.src1, imm8.src2), CONST_0)", [1, 2], "testb", 'b', "CCZmode", "QImode", 1], + +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($src1->r); + }, + debug { + dumpIR("$opcode", $src2, $src1->r, '$schar'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist($is_test_variant, $cc_mode, $rtx_mode, + gen_rtx_REG($rtx_mode, $src1->r), + GEN_INT($src2->val)))); + }; +""") + + + + +# we can save a byte by using "test r,r" in place of "cmp $0,r" + +plug.plugrule3("rcc_compare_reg_zero", [ + ["rule", "cost", "opcode", "schar", "rtx_mode"], + + ["rcc.dst : COMPARE_CC(r64.src1, CONST_0)", [1, 3], "testq", 'q', "DImode"], + ["rcc.dst : COMPARE_CC(r32.src1, CONST_0)", [1, 2], "testl", 'd', "SImode"], + ["rcc.dst : COMPARE_CC(r16.src1, CONST_0)", [1, 3], "testw", 'w', "HImode"], + ["rcc.dst : COMPARE_CC(r8.src1, CONST_0)", [1, 2], "testb", 'b', "QImode"], + +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($src1->r); + }, + debug { + dumpRR("$opcode", $src1->r, '$schar', $src1->r, '$schar'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCNOmode, REG_CC), + gen_rtx_COMPARE(CCNOmode, + gen_rtx_REG($rtx_mode, $src1->r), + GEN_INT(0)))); + }; +""") + + + + + +plug.plugrule3("rcc_compare_memimm", [ + ["rule", "cost", "opcode", "schar", "cc_mode", "rtx_mode", "is_test_variant"], + + ["rcc.dst : COMPARE_CC(MEM_DI(addr.src1), imm32.src2)", [4, 3], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(MEM_DI(addr.src1), imm8.src2)", [4, 3], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(MEM_SI(addr.src1), imm32.src2)", [4, 2], "cmpl", 'l', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(MEM_SI(addr.src1), imm8.src2)", [4, 2], "cmpl", 'l', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(MEM_HI(addr.src1), imm16.src2)", [4, 3], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(MEM_HI(addr.src1), imm8.src2)", [4, 3], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(MEM_QI(addr.src1), imm8.src2)", [4, 2], "cmpb", 'b', "CCmode", "QImode", 0], + + # + # I don't understand why this has to be CCZmode, except that's what the stock gcc RTL uses. + # + ["rcc.dst : COMPARE_CC(AND_DI(MEM_DI(addr.src1), imm32.src2), CONST_0)", [4, 3], "testq", 'q', "CCZmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(AND_SI(MEM_SI(addr.src1), imm32.src2), CONST_0)", [4, 2], "testl", 'l', "CCZmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(AND_HI(MEM_HI(addr.src1), imm16.src2), CONST_0)", [4, 3], "testw", 'w', "CCZmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(AND_QI(MEM_QI(addr.src1), imm8.src2), CONST_0)", [4, 2], "testb", 'b', "CCZmode", "QImode", 0], + +], """ + $rule $cost + build { + add_addr(live, $src1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("$opcode", $src2, $src1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist($is_test_variant, $cc_mode, $rtx_mode, + gen_rtx_MEM($rtx_mode, $src1->rtl), + GEN_INT($src2->val)))); + }; +""") + +plug.plugrule3("rcc_compare_regmem", [ + ["rule", "cost", "opcode", "schar", "cc_mode", "rtx_mode", "is_test_variant"], + + ["urcc.dst : COMPARE_CC(rd.src, MEM_DF(addr.mem))", [4, 2], "ucomisd", 'x', "CCFPUmode", "DFmode", 0], + ["urcc.dst : COMPARE_CC(rf.src, MEM_SF(addr.mem))", [4, 2], "ucomiss", 'x', "CCFPUmode", "SFmode", 0], + + ["rcc.dst : COMPARE_CC(r64.src, MEM_DI(addr.mem))", [4, 2], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(r32.src, MEM_SI(addr.mem))", [4, 1], "cmpl", 'd', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(r16.src, MEM_HI(addr.mem))", [4, 2], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(r8.src, MEM_QI(addr.mem))", [4, 1], "cmpb", 'b', "CCmode", "QImode", 0], + +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src->r)); + add_addr(live, $mem); + }, + remat { + flags = 0; + }, + costs { + forgettable($src->r); + }, + debug { + dumpMR("$opcode", $mem, $src->r, '$schar'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist($is_test_variant, $cc_mode, $rtx_mode, + gen_rtx_REG($rtx_mode, $src->r), + gen_rtx_MEM($rtx_mode, $mem->rtl)))); + }; +""") + +plug.plugrule3("rcc_compare_memreg", [ + ["rule", "cost", "opcode", "schar", "cc_mode", "rtx_mode", "is_test_variant"], + + ["rcc.dst : COMPARE_CC(MEM_DI(addr.mem), r64.src)", [4, 2], "cmpq", 'q', "CCmode", "DImode", 0], + ["rcc.dst : COMPARE_CC(MEM_SI(addr.mem), r32.src)", [4, 1], "cmpl", 'd', "CCmode", "SImode", 0], + ["rcc.dst : COMPARE_CC(MEM_HI(addr.mem), r16.src)", [4, 2], "cmpw", 'w', "CCmode", "HImode", 0], + ["rcc.dst : COMPARE_CC(MEM_QI(addr.mem), r8.src)", [4, 1], "cmpb", 'b', "CCmode", "QImode", 0], + + # + # I don't understand why this has to be CCZmode, except that's what the stock gcc RTL uses. + # + ["rcc.dst : COMPARE_CC(AND_DI(MEM_DI(addr.mem), r64.src), CONST_0)", [4, 2], "testq", 'q', "CCZmode", "DImode", 1], + ["rcc.dst : COMPARE_CC(AND_SI(MEM_SI(addr.mem), r32.src), CONST_0)", [4, 1], "testl", 'd', "CCZmode", "SImode", 1], + ["rcc.dst : COMPARE_CC(AND_HI(MEM_HI(addr.mem), r16.src), CONST_0)", [4, 2], "testw", 'w', "CCZmode", "HImode", 1], + ["rcc.dst : COMPARE_CC(AND_QI(MEM_QI(addr.mem), r8.src), CONST_0)", [4, 1], "testb", 'b', "CCZmode", "QImode", 1], + +], """ + $rule $cost + + build { + sparseset_set_bit(live, find($src->r)); + add_addr(live, $mem); + }, + remat { + flags = 0; + }, + costs { + forgettable($src->r); + }, + debug { + dumpRM("$opcode", $src->r, '$schar', $mem); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist($is_test_variant, $cc_mode, $rtx_mode, + gen_rtx_MEM($rtx_mode, $mem->rtl), + gen_rtx_REG($rtx_mode, $src->r)))); + }; +""") + + + +# +# calls +# Calls always call to a byte address, hence their left child is ALWAYS a MEM_QI. +# +# addrtype == 0 ==> function address held in register (general indirect call) +# addrtype == 1 ==> function address held in memory (simple indirect call) +# addrtype == 2 ==> function address is literal in istream (normal case) +# +# valuetype == 0 ==> no return value +# valuetype == 1 ==> scalar return value +# valuetype == 2 ==> struct return value +# +# +plug.plugrule3("callvalueRM", [ + ["rule", "cost", "rtx_mode", "addrtype", "valuetype"], + + # + # These CALL types occur when a scalar is returned eg, valuetype==1. + #! + ["stmt : SET_ALL(r64.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DImode", 0, 1], + ["stmt : SET_ALL(r64.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DImode", 1, 1], + ["stmt : SET_ALL(r64.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "DImode", 2, 1], + + ["stmt : SET_ALL(r32.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DImode", 0, 1], + ["stmt : SET_ALL(r32.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DImode", 1, 1], + ["stmt : SET_ALL(r32.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "DImode", 2, 1], + + ["stmt : SET_ALL(r16.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DImode", 0, 1], + ["stmt : SET_ALL(r16.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DImode", 1, 1], + ["stmt : SET_ALL(r16.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "DImode", 2, 1], + + ["stmt : SET_ALL(r8.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DImode", 0, 1], + ["stmt : SET_ALL(r8.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DImode", 1, 1], + ["stmt : SET_ALL(r8.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "DImode", 2, 1], + + ["stmt : SET_ALL(rf.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "SFmode", 0, 1], + ["stmt : SET_ALL(rf.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "SFmode", 1, 1], + ["stmt : SET_ALL(rf.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "DFmode", 2, 1], + + ["stmt : SET_ALL(rd.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DFmode", 0, 1], + ["stmt : SET_ALL(rd.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DFmode", 1, 1], + ["stmt : SET_ALL(rd.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "SFmode", 2, 1], + + # + # The CALL form occurs when returning a structure, eg valuetype==2. + # This implementation is potentially fragile because it relies on the set + # destination which is a PARALLEL of expr_lists (register defs) + # to be exactly what is desired at the end. + # Likely it is OK because we would never be changing what registers the CALL defs. + # + ["stmt : SET_ALL(def_list.dst, CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list))", [0, 0], "DFmode", 0, 2], + ["stmt : SET_ALL(def_list.dst, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list))", [0, 0], "DFmode", 1, 2], + ["stmt : SET_ALL(def_list.dst, CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list))", [0, 0], "SFmode", 2, 2], + + # + # This CALL form happens when nothing is returned, eg valuetype==0. + # There is no $dst to reference. + # + ["stmt : CALL_ALL(PAIR_ALL(MEM_QI(r64.addr), imm64.const), use_list)", [0, 0], "DFmode", 0, 0], + ["stmt : CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr.addr)), imm64.const), use_list)", [0, 0], "DFmode", 1, 0], + ["stmt : CALL_ALL(PAIR_ALL(MEM_QI(symbol.addr), imm64.const), use_list)", [0, 0], "SFmode", 2, 0], + +], """ + $rule $cost + build { + handle_call_kills(add_edges, live); + if ($addrtype == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($addr->r)); + } else if ($addrtype == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $addr); + } else if ($addrtype == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if ($addrtype == 0) { + dump_callR($addr->r); + } else if ($addrtype == 1) { + dump_callM($addr->a); + } else if ($addrtype == 2) { + dump_call($addr->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($stmt->insn); + rtx addr = 0; + rtx dst = 0; + if ($addrtype == 0) { + addr = gen_rtx_REG(DImode, $addr->r); + } else if ($addrtype == 1) { + addr = gen_rtx_MEM(DImode, $addr->rtl); + } else if ($addrtype == 2) { + addr = $addr->rtl; + } else { + gcc_assert(0); + } + if ($valuetype == 0) { /* no value return */ + dst = 0; /* unused */ + } else if ($valuetype == 1) { /* scalar return */ + # if ($valuetype == 1) /* $dst otherwise undefined */ + dst = gen_rtx_REG($rtx_mode, $dst->r); + # endif + } else if ($valuetype == 2) { /* structure return */ + dst = SET_DEST($stmt->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($const->val)); + rtx dst_call = ($valuetype == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +""") + + +# +# defs and uses +# + +plug.plugrule3("userecur", [ + ["rule", "cost"], + ["use_list.dst : LIST_ALL(use.src1, use_list.src2)", [0, 0]], + ["def_list.dst : LIST_ALL(def.src1, def_list.src2)", [0, 0]], +], """ + $rule $cost + ; +""") + +plug.plugrule3("usebasis", [ + ["rule", "cost"], + ["use_list.dst : END_OF_LIST", [0, 0]], + ["def_list.dst : END_OF_LIST", [0, 0]], +], """ + $rule $cost + ; +""") + +plug.plugrule3("stmtuse", [ + ["rule", "cost"], + ["stmt.dst : use.src", [0, 0]], + ["stmt.dst : def.src", [0, 0]], +], """ + $rule $cost + ; +""") + +plug.plugrule3("use", [ + ["rule", "cost"], + ["use.dst : USE_ALL(r64.src)", [0, 0]], + ["use.dst : USE_ALL(r32.src)", [0, 0]], + ["use.dst : USE_ALL(r16.src)", [0, 0]], + ["use.dst : USE_ALL(r8.src)", [0, 0]], + ["use.dst : USE_ALL(rd.src)", [0, 0]], + ["use.dst : USE_ALL(rf.src)", [0, 0]], +], """ + $rule $cost + build { + sparseset_set_bit(live, find($src->r)); + }, + remat { + flags = 0; + }, + emit { + $dst->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $src->r)); + }; +""") + +# +# Preston changed these from, e.g. r64d to r64. +# He wonders if they can ever be spilled. +# That would require some thought. +# +plug.plugrule3("def", [ + ["rule", "cost"], + ["def.dst : DEF_ALL(r64.src)", [0, 0]], + ["def.dst : DEF_ALL(r32.src)", [0, 0]], + ["def.dst : DEF_ALL(r16.src)", [0, 0]], + ["def.dst : DEF_ALL(r8.src)", [0, 0]], + ["def.dst : DEF_ALL(rd.src)", [0, 0]], + ["def.dst : DEF_ALL(rf.src)", [0, 0]], +], """ + $rule $cost + ; +""") + +# +# These rules are added to support condition branches on floating point values. +# the tree we are presented with is: +# +# SET_ALL(PC_ALL,COND_MOVE(NE_ALL(REG_SF, REG_SF), PAIR_ALL(LABEL_REF_DI, PC_ALL))) +# +# TODO: add memory variants +# TODO: The RTL tree out the back end is missing the SET_ALL and more, so icg+rtl output is mangled +# TODO: add missing comparision operators (such as LT_ALL, etc) +# TODO: For NE_ALL, stock gcc will produce both a jne and a jp (if unordered) to the same target +# +plug.plugrule3("condition_float", [ + ["rule", "cost", "opcode", "schar", "op", "cc_mode", "rtx_mode"], + ["condition.dst : EQ_ALL(rd.src1, rd.src2)", [1, 3], "ucomisd", 'x', "UNEQ", "CCFPUmode", "DFmode"], + ["condition.dst : NE_ALL(rd.src1, rd.src2)", [1, 3], "ucomisd", 'x', "LTGT", "CCFPUmode", "DFmode"], + ["condition.dst : EQ_ALL(rf.src1, rf.src2)", [1, 3], "ucomiss", 'x', "UNEQ", "CCFPUmode", "SFmode"], + ["condition.dst : NE_ALL(rf.src1, rf.src2)", [1, 3], "ucomiss", 'x', "LTGT", "CCFPUmode", "SFmode"], +], """ + $rule $cost + names { + $dst->code = $op; + $dst->cc_code = $cc_mode; + }, + build { + sparseset_set_bit(live, find($src1->r)); + sparseset_set_bit(live, find($src2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($src1->r); + memorable($src2->r); + }, + debug { + dumpRR("$opcode", $src2->r, '$schar', $src1->r, '$schar'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG($cc_mode, REG_CC), + gen_rtx_COMPARE_assist(/*is_test_variant*/0, $cc_mode, $rtx_mode, + gen_rtx_REG($rtx_mode, $src1->r), + gen_rtx_REG($rtx_mode, $src2->r)))); + }; +""") + +# })] diff --git a/iburg/briggs/icg-grammars/x86-64.misc.pyout b/iburg/briggs/icg-grammars/x86-64.misc.pyout new file mode 100644 index 00000000000..47d50fc4951 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.misc.pyout @@ -0,0 +1,5978 @@ +#line 19 "x86-64.misc.py" +addr : PLUS_DI(base64 | index64 | disp) [0, 0] +#line 22 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->a.index; + $$->a.scale = $2->a.scale; + $$->a.disp = $3->a.disp; + $$->a.string = $3->a.string; + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->a.index; + }, + emit { + $$->rtl = gen_rtx_addr(DImode, $1->rtl, $2->rtl, $3->rtl); + }; +#line 45 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm5) | CONST_P8)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 8; + $$->a.disp = $3->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val * 8)); + }; +#line 46 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm29) | CONST_P8)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 8; + $$->a.disp = $3->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val * 8)); + }; +#line 47 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm6) | CONST_P4)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 4; + $$->a.disp = $3->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val * 4)); + }; +#line 48 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm30) | CONST_P4)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 4; + $$->a.disp = $3->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val * 4)); + }; +#line 49 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm7) | CONST_P2)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 2; + $$->a.disp = $3->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val * 2)); + }; +#line 50 "x86-64.misc.py" +addr : PLUS_DI(base64 | MULT_DI(PLUS_DI(r64 | imm31) | CONST_P2)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 2; + $$->a.disp = $3->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val * 2)); + }; +#line 52 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm5), CONST_P3)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 8; + $$->a.disp = $3->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val * 8)); + }; +#line 53 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm29), CONST_P3)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 8; + $$->a.disp = $3->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($3->val * 8)); + }; +#line 54 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm6), CONST_P2)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 4; + $$->a.disp = $3->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val * 4)); + }; +#line 55 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm30), CONST_P2)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 4; + $$->a.disp = $3->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($3->val * 4)); + }; +#line 56 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm7), CONST_P1)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 2; + $$->a.disp = $3->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val * 2)); + }; +#line 57 "x86-64.misc.py" +addr : PLUS_DI(base64 | ASHIFT_DI(PLUS_DI(r64 | imm31), CONST_P1)) [0, 1] +#line 61 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->r; + $$->a.scale = 2; + $$->a.disp = $3->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($2->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $2->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($3->val * 2)); + }; +#line 93 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm4) | CONST_P8)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 8; + $$->a.disp = $2->val + $4->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($2->val + $4->val * 8)); + }; +#line 94 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm28) | CONST_P8)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 8; + $$->a.disp = $2->val + $4->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($2->val + $4->val * 8)); + }; +#line 95 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm5) | CONST_P4)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 4; + $$->a.disp = $2->val + $4->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($2->val + $4->val * 4)); + }; +#line 96 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm29) | CONST_P4)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 4; + $$->a.disp = $2->val + $4->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($2->val + $4->val * 4)); + }; +#line 97 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | MULT_DI(PLUS_DI(r64 | imm6) | CONST_P2)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 2; + $$->a.disp = $2->val + $4->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val * 2)); + }; +#line 98 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | MULT_DI(PLUS_DI(r64 | imm30) | CONST_P2)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 2; + $$->a.disp = $2->val + $4->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val * 2)); + }; +#line 100 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm4), CONST_P3)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 8; + $$->a.disp = $2->val + $4->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($2->val + $4->val * 8)); + }; +#line 101 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm28), CONST_P3)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 8; + $$->a.disp = $2->val + $4->val * 8; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(8)), + GEN_INT($2->val + $4->val * 8)); + }; +#line 102 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm5), CONST_P2)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 4; + $$->a.disp = $2->val + $4->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($2->val + $4->val * 4)); + }; +#line 103 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm29), CONST_P2)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 4; + $$->a.disp = $2->val + $4->val * 4; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(4)), + GEN_INT($2->val + $4->val * 4)); + }; +#line 104 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm7 | ASHIFT_DI(PLUS_DI(r64 | imm6), CONST_P1)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 2; + $$->a.disp = $2->val + $4->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val * 2)); + }; +#line 105 "x86-64.misc.py" +addr : PLUS_DI(base64 | imm31 | ASHIFT_DI(PLUS_DI(r64 | imm30), CONST_P1)) [0, 0] +#line 109 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $3, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $3->r; + $$->a.scale = 2; + $$->a.disp = $2->val + $4->val * 2; + $$->a.string = NULL; + }, + costs { + forgettable($3->r); + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $3->r; + }, + emit { + rtx src2 = gen_rtx_REG(DImode, $3->r); + $$->rtl = gen_rtx_addr(DImode, $1->rtl, + gen_rtx_MULT(DImode, src2, GEN_INT(2)), + GEN_INT($2->val + $4->val * 2)); + }; +#line 137 "x86-64.misc.py" +addr : PLUS_DI(base64 | index64) [0, 0] +#line 140 "x86-64.misc.py" + supairs { + suOrder2($$, $1, $2, kid, kids); + }, + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = $2->a.index; + $$->a.scale = $2->a.scale; + $$->a.disp = 0; + $$->a.string = NULL; + }, + final { + $$->a.base = $1->a.base; + $$->a.index = $2->a.index; + }, + emit { + $$->rtl = gen_rtx_PLUS(DImode, $1->rtl, $2->rtl); + }; +#line 162 "x86-64.misc.py" +addr : PLUS_DI(base64 | disp) [0, 0] +#line 165 "x86-64.misc.py" + names { + $$->a.base = $1->a.base; + $$->a.base_valid = $1->a.base_valid; + $$->a.index = 0; + $$->a.scale = 0; + $$->a.disp = $2->a.disp; + $$->a.string = $2->a.string; + }, + final { + $$->a.base = $1->a.base; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_PLUS(DImode, $1->rtl, $2->rtl); + }; +#line 187 "x86-64.misc.py" +addr : PLUS_DI(index64 | imm32) [0, 1] +#line 190 "x86-64.misc.py" + names { + $$->a.base_valid = 0; + $$->a.index = $1->a.index; + $$->a.scale = $1->a.scale; + $$->a.disp = $2->val; + $$->a.string = $2->a.string; + }, + final { + $$->a.index = $1->a.index; + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_PLUS(DImode, + $1->rtl, + gen_rtx_imm_constant($2->val, $2->a.string, $2->rtl)); + }; +#line 213 "x86-64.misc.py" +addr : base64 [0, 0] +#line 216 "x86-64.misc.py" + names { + $$->a.index = 0; + $$->a.scale = 0; + $$->a.disp = 0; + $$->a.string = NULL; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 229 "x86-64.misc.py" +addr : index64 [0, 5] +#line 232 "x86-64.misc.py" + names { + $$->a.base_valid = 0; + $$->a.disp = 0; + $$->a.string = NULL; + }, + emit { + $$->rtl = $1->rtl; + }; +#line 249 "x86-64.misc.py" +addr : symbol32 [0, 1] +#line 253 "x86-64.misc.py" + names { + $$->a = $1->a; /* preserve all semantic info */ + }, + emit { + rtx expr = $$->rtl; /* RTL from original tree (thin ice!) */ + $$->rtl = gen_rtx_imm_constant($$->a.disp, $$->a.string, expr); + }; +#line 250 "x86-64.misc.py" +addr : symbol64 [0, 1] +#line 253 "x86-64.misc.py" + names { + $$->a = $1->a; /* preserve all semantic info */ + }, + emit { + rtx expr = $$->rtl; /* RTL from original tree (thin ice!) */ + $$->rtl = gen_rtx_imm_constant($$->a.disp, $$->a.string, expr); + }; +#line 264 "x86-64.misc.py" +addr : imm32 [0, 1] +#line 267 "x86-64.misc.py" + names { + $$->a.base_valid = 0; + $$->a.index = 0; + $$->a.scale = 0; + $$->a.disp = $1->val; + }, + emit { + rtx expr = $$->rtl; /* RTL from original tree (thin ice!) */ + $$->rtl = gen_rtx_imm_constant($$->a.disp, $$->a.string, expr); + }; +#line 281 "x86-64.misc.py" +disp : imm8 [0, 0] +#line 285 "x86-64.misc.py" + names { + $$->a.disp = $1->val; + }, + emit { + $$->rtl = gen_rtx_imm_constant($$->a.disp, $$->a.string, $$->rtl); + }; +#line 282 "x86-64.misc.py" +disp : imm32 [0, 0] +#line 285 "x86-64.misc.py" + names { + $$->a.disp = $1->val; + }, + emit { + $$->rtl = gen_rtx_imm_constant($$->a.disp, $$->a.string, $$->rtl); + }; +#line 295 "x86-64.misc.py" +base64 : r64 [0, 1] +#line 301 "x86-64.misc.py" + names { + $$->a.base = $1->r; + $$->a.base_valid = 1; + $$->a.base_rip = 0; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.base = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(DImode, $1->r); + }; +#line 296 "x86-64.misc.py" +base32 : r32 [0, 1] +#line 301 "x86-64.misc.py" + names { + $$->a.base = $1->r; + $$->a.base_valid = 1; + $$->a.base_rip = 0; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.base = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 297 "x86-64.misc.py" +base16 : r16 [0, 1] +#line 301 "x86-64.misc.py" + names { + $$->a.base = $1->r; + $$->a.base_valid = 1; + $$->a.base_rip = 0; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.base = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 298 "x86-64.misc.py" +base8 : r8 [0, 1] +#line 301 "x86-64.misc.py" + names { + $$->a.base = $1->r; + $$->a.base_valid = 1; + $$->a.base_rip = 0; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.base = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 319 "x86-64.misc.py" +index64 : r64 [0, 1] +#line 325 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.index = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(DImode, $1->r); + }; +#line 320 "x86-64.misc.py" +index32 : r32 [0, 1] +#line 325 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.index = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 321 "x86-64.misc.py" +index16 : r16 [0, 1] +#line 325 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.index = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 322 "x86-64.misc.py" +index8 : r8 [0, 1] +#line 325 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1; + }, + costs { + forgettable($1->r); + }, + final { + $$->a.index = $1->r; + }, + emit { + $$->rtl = gen_rtx_REG(SImode, $1->r); + }; +#line 343 "x86-64.misc.py" +index64 : ASHIFT_DI(r64, scon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(DImode, + gen_rtx_REG(DImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 344 "x86-64.misc.py" +index32 : ASHIFT_SI(r32, scon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 345 "x86-64.misc.py" +index16 : ASHIFT_HI(r16, scon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 346 "x86-64.misc.py" +index8 : ASHIFT_QI(r8, scon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 348 "x86-64.misc.py" +index64 : MULT_DI(r64 | mcon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 0 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(DImode, + gen_rtx_REG(DImode, $1->r), + GEN_INT(0 ? (1 << $2->val) : $2->val)); + }; +#line 349 "x86-64.misc.py" +index32 : MULT_SI(r32 | mcon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 0 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(SImode, + gen_rtx_REG(SImode, $1->r), + GEN_INT(0 ? (1 << $2->val) : $2->val)); + }; +#line 350 "x86-64.misc.py" +index16 : MULT_HI(r16 | mcon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 0 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT(0 ? (1 << $2->val) : $2->val)); + }; +#line 351 "x86-64.misc.py" +index8 : MULT_QI(r8 | mcon) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 0 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT(0 ? (1 << $2->val) : $2->val)); + }; +#line 353 "x86-64.misc.py" +index16 : SUBREG_HI(ASHIFT_SI(SIGN_EXTEND_SI(r16), scon), CONST_0) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 354 "x86-64.misc.py" +index16 : SUBREG_HI(ASHIFT_SI(ZERO_EXTEND_SI(r16), scon), CONST_0) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 355 "x86-64.misc.py" +index8 : SUBREG_QI(ASHIFT_SI(SIGN_EXTEND_SI(r8), scon), CONST_0) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 356 "x86-64.misc.py" +index8 : SUBREG_QI(ASHIFT_SI(ZERO_EXTEND_SI(r8), scon), CONST_0) [0, 1] +#line 360 "x86-64.misc.py" + names { + $$->a.index = $1->r; + $$->a.scale = 1 ? (1 << $2->val) : $2->val; + }, + final { + $$->a.index = $1->r; + }, + costs { + forgettable($1->r); + }, + supairs { + $$->extra = $1->extra; + $$->freed = $1->freed; + }, + emit { + $$->rtl = gen_rtx_MULT(QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT(1 ? (1 << $2->val) : $2->val)); + }; +#line 387 "x86-64.misc.py" +scon : CONST_0 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 388 "x86-64.misc.py" +scon : CONST_P1 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 389 "x86-64.misc.py" +scon : CONST_P2 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 390 "x86-64.misc.py" +scon : CONST_P3 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 392 "x86-64.misc.py" +mcon : CONST_P1 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 393 "x86-64.misc.py" +mcon : CONST_P2 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 394 "x86-64.misc.py" +mcon : CONST_P4 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 395 "x86-64.misc.py" +mcon : CONST_P8 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 397 "x86-64.misc.py" +imm4 : CONST_N1 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 398 "x86-64.misc.py" +imm4 : CONST_0 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 399 "x86-64.misc.py" +imm4 : CONST_P1 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 400 "x86-64.misc.py" +imm4 : CONST_P2 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 401 "x86-64.misc.py" +imm4 : CONST_P3 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 402 "x86-64.misc.py" +imm4 : CONST_P4 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 403 "x86-64.misc.py" +imm4 : CONST4P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 404 "x86-64.misc.py" +imm4 : CONST4N [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 406 "x86-64.misc.py" +imm5 : imm4 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 407 "x86-64.misc.py" +imm5 : CONST_P8 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 408 "x86-64.misc.py" +imm5 : CONST_P15 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 409 "x86-64.misc.py" +imm5 : CONST5P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 410 "x86-64.misc.py" +imm5 : CONST5N [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 412 "x86-64.misc.py" +imm6 : imm5 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 413 "x86-64.misc.py" +imm5 : CONST_P16 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 414 "x86-64.misc.py" +imm5 : CONST_P24 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 415 "x86-64.misc.py" +imm5 : CONST_P31 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 416 "x86-64.misc.py" +imm6 : CONST_P32 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 417 "x86-64.misc.py" +imm6 : CONST6P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 418 "x86-64.misc.py" +imm6 : CONST6N [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 420 "x86-64.misc.py" +imm7 : imm6 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 421 "x86-64.misc.py" +imm6 : CONST_P48 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 422 "x86-64.misc.py" +imm6 : CONST_P56 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 423 "x86-64.misc.py" +imm6 : CONST_P63 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 424 "x86-64.misc.py" +imm7 : CONST7P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 425 "x86-64.misc.py" +imm7 : CONST7N [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 427 "x86-64.misc.py" +imm8 : imm7 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 428 "x86-64.misc.py" +imm8 : CONST8P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 429 "x86-64.misc.py" +imm8 : CONST8N [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 431 "x86-64.misc.py" +imm12 : imm8 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 432 "x86-64.misc.py" +imm12 : CONST_P255 [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 433 "x86-64.misc.py" +imm12 : CONST12P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 434 "x86-64.misc.py" +imm12 : CONST12N [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 436 "x86-64.misc.py" +imm13 : imm12 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 437 "x86-64.misc.py" +imm13 : CONST13P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 438 "x86-64.misc.py" +imm13 : CONST13N [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 440 "x86-64.misc.py" +imm14 : imm13 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 441 "x86-64.misc.py" +imm14 : CONST14P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 442 "x86-64.misc.py" +imm14 : CONST14N [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 444 "x86-64.misc.py" +imm15 : imm14 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 445 "x86-64.misc.py" +imm15 : CONST15P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 446 "x86-64.misc.py" +imm15 : CONST15N [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 448 "x86-64.misc.py" +imm16 : imm15 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 449 "x86-64.misc.py" +imm16 : CONST16P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 450 "x86-64.misc.py" +imm16 : CONST16N [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 452 "x86-64.misc.py" +imm28 : imm16 [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 453 "x86-64.misc.py" +imm28 : CONST28P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 454 "x86-64.misc.py" +imm28 : CONST28N [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 456 "x86-64.misc.py" +imm29 : imm28 [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 457 "x86-64.misc.py" +imm29 : CONST29P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 458 "x86-64.misc.py" +imm29 : CONST29N [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 460 "x86-64.misc.py" +imm30 : imm29 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 461 "x86-64.misc.py" +imm30 : CONST30P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 462 "x86-64.misc.py" +imm30 : CONST30N [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 464 "x86-64.misc.py" +imm31 : imm30 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 465 "x86-64.misc.py" +imm31 : CONST31P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 466 "x86-64.misc.py" +imm31 : CONST31N [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 468 "x86-64.misc.py" +imm32 : pureimm32 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 469 "x86-64.misc.py" +pureimm32 : imm31 [0, 0] +#line 501 "x86-64.misc.py" + ; +#line 470 "x86-64.misc.py" +pureimm32 : CONST32P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 471 "x86-64.misc.py" +pureimm32 : CONST32N [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 472 "x86-64.misc.py" +pureimm32 : CONSTIEEE32 [0, 8] +#line 501 "x86-64.misc.py" + ; +#line 474 "x86-64.misc.py" +imm64 : imm32 [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 475 "x86-64.misc.py" +imm64 : CONST64P [0, 8] +#line 501 "x86-64.misc.py" + ; +#line 476 "x86-64.misc.py" +imm64 : CONST64N [0, 8] +#line 501 "x86-64.misc.py" + ; +#line 477 "x86-64.misc.py" +imm64 : CONSTIEEE64 [0, 8] +#line 501 "x86-64.misc.py" + ; +#line 479 "x86-64.misc.py" +pos8 : mcon [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 480 "x86-64.misc.py" +pos8 : scon [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 481 "x86-64.misc.py" +pos8 : CONST4P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 482 "x86-64.misc.py" +pos8 : CONST5P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 483 "x86-64.misc.py" +pos8 : CONST6P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 484 "x86-64.misc.py" +pos8 : CONST7P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 485 "x86-64.misc.py" +pos8 : CONST8P [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 486 "x86-64.misc.py" +pos16 : pos8 [0, 1] +#line 501 "x86-64.misc.py" + ; +#line 487 "x86-64.misc.py" +pos16 : CONST12P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 488 "x86-64.misc.py" +pos16 : CONST13P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 489 "x86-64.misc.py" +pos16 : CONST14P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 490 "x86-64.misc.py" +pos16 : CONST15P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 491 "x86-64.misc.py" +pos16 : CONST16P [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 492 "x86-64.misc.py" +pos32 : pos16 [0, 2] +#line 501 "x86-64.misc.py" + ; +#line 493 "x86-64.misc.py" +pos32 : CONST28P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 494 "x86-64.misc.py" +pos32 : CONST29P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 495 "x86-64.misc.py" +pos32 : CONST30P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 496 "x86-64.misc.py" +pos32 : CONST31P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 497 "x86-64.misc.py" +pos32 : CONST32P [0, 4] +#line 501 "x86-64.misc.py" + ; +#line 510 "x86-64.misc.py" +symbol32 : SYMBOL_REF_32 [0, 0] +#line 514 "x86-64.misc.py" + names { + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 511 "x86-64.misc.py" +symbol64 : SYMBOL_REF_64 [0, 0] +#line 514 "x86-64.misc.py" + names { + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 521 "x86-64.misc.py" +symbol32 : LABEL_REF_DI [0, 0] +#line 524 "x86-64.misc.py" + names { + $$->a.base_rip = 1; /* %rip usage(?) */ + }; +#line 532 "x86-64.misc.py" +symbol : symbol32 [0, 0] +#line 536 "x86-64.misc.py" + ; +#line 533 "x86-64.misc.py" +symbol : symbol64 [0, 0] +#line 536 "x86-64.misc.py" + ; +#line 541 "x86-64.misc.py" +symbol32 : pureimm32 [0, 0] +#line 545 "x86-64.misc.py" + ; +#line 542 "x86-64.misc.py" +symbol64 : pureimm32 [0, 0] +#line 545 "x86-64.misc.py" + ; +#line 554 "x86-64.misc.py" +symbol32 : CONST_DI(symbol32) [0, 0] +#line 558 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 555 "x86-64.misc.py" +symbol64 : CONST_DI(symbol64) [0, 0] +#line 558 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 567 "x86-64.misc.py" +symbol32 : PLUS_DI(symbol32 | pureimm32) [0, 0] +#line 571 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val + $2->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 568 "x86-64.misc.py" +symbol64 : PLUS_DI(symbol64 | pureimm32) [0, 0] +#line 571 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val + $2->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 580 "x86-64.misc.py" +symbol32 : MINUS_DI(symbol32, pureimm32) [0, 0] +#line 584 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val - $2->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 581 "x86-64.misc.py" +symbol64 : MINUS_DI(symbol64, pureimm32) [0, 0] +#line 584 "x86-64.misc.py" + names { + $$->a.string = $1->a.string; + $$->val = $1->val - $2->val; + $$->a.base_rip = 1; /* %rip usage */ + }; +#line 593 "x86-64.misc.py" +imm32 : symbol32 [0, 4] +#line 597 "x86-64.misc.py" + names { + /* this transfers the "a" attribute from src to dst */ + } + ; +#line 594 "x86-64.misc.py" +imm64 : symbol64 [0, 8] +#line 597 "x86-64.misc.py" + names { + /* this transfers the "a" attribute from src to dst */ + } + ; +#line 624 "x86-64.misc.py" +label : LABEL_REF_DI [0, 0] +#line 627 "x86-64.misc.py" + ; +#line 636 "x86-64.misc.py" +stmt : SET_ALL(PC_ALL, label) [0, 0] +#line 639 "x86-64.misc.py" + debug { + dump_jump("jmp", $1); + }, + emit { + rtx label = XEXP ($1->rtl, 0); + rtx new_jump = emit_jump_insn (gen_jump (label)); + LABEL_NUSES (label) += 1; + JUMP_LABEL (new_jump) = label; + }; +#line 656 "x86-64.misc.py" +stmt : PARALLEL_ALL(SET_ALL(PC_ALL, r64), USE_ALL(label)) [0, 0] +#line 659 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dump_jumpR("jmp", $1->r, 'q'); + }, + emit { + rtx label = XEXP ($2->rtl, 0); + rtx new_jump = emit_jump_insn( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, + gen_rtx_PC(VOIDmode), + gen_rtx_REG(DImode, $1->r)), + gen_rtx_USE(VOIDmode, + $2->rtl)))); + LABEL_NUSES (label) += 1; + JUMP_LABEL (new_jump) = label; + }; +#line 746 "x86-64.misc.py" +stmt : SET_ALL(PC_ALL, COND_MOVE(condition, PAIR_ALL(label, PC_ALL))) [0, 0] +#line 749 "x86-64.misc.py" + debug { + const enum rtx_code code = $1->code; + switch (code) { + case UNEQ: /* unordered equality testing */ + dump_jump("je", $2); + dump_jump("jp", $2); /* jump if unordered */ + break; + case LTGT: /* unordered inequality testing */ + dump_jump("jne", $2); + dump_jump("jp", $2); /* jump if unordered */ + break; + case UNGE: dump_jump("jae", $2); break; + case UNGT: dump_jump("ja", $2); break; + case UNLE: dump_jump("jbe", $2); break; + case UNLT: dump_jump("jb", $2); break; + case UNORDERED: dump_jump("jp", $2); break; + case ORDERED: dump_jump("jnp", $2); break; + + case EQ: dump_jump("je", $2); break; + case NE: dump_jump("jne", $2); break; + case GE: dump_jump("jge", $2); break; + case GT: dump_jump("jg", $2); break; + case LE: dump_jump("jle", $2); break; + case LT: dump_jump("jl", $2); break; + + case GEU: dump_jump("jae", $2); break; + case GTU: dump_jump("ja", $2); break; + case LEU: dump_jump("jbe", $2); break; + case LTU: dump_jump("jb", $2); break; + + default: + icg_nyi("unrecognized condition code %d for jump", code); + } + }; +#line 794 "x86-64.misc.py" +r64x : COND_MOVE(condition, PAIR_ALL(r64x, r64)) [1, 4] +#line 801 "x86-64.misc.py" + names { + $$->rx = $2->rx; + if (1) { + /* + * set the order the children are visited; + * when su ordering is working, this will force a Sethi-Ullman traversal. + */ + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + } + }, + final { + $$->rx = $2->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->rx); + memorable($3->r); + }, + debug { + const enum rtx_code code = $1->code; + switch (code) { + /* + * NOTE A: + * There is empirical evidence suggesting that the conditions and the cmov opcodes + * must be inverted relative to each other. This will make the icg+asm + * path produce identical asm code to the icg+rtl path. + * 03Nov08: After 4 hours of searching, rrh does not have an explanation for this. + * Alternatively, try swapping the fsrc and tsrc args to gen_rtx_IF_THEN_ELSE + * perhaps this is because of the evaluation permutation that is induced? + * By swapping fsrc and tsrc to the gen_rtx_IF_THEN_ELSE + * we get identical code icg+asm and icg+rtl. + */ + case EQ: dumpRR("cmove", $3->r, 'q', $$->rx, 'q'); break; + case NE: dumpRR("cmovne", $3->r, 'q', $$->rx, 'q'); break; + case GE: dumpRR("cmovge", $3->r, 'q', $$->rx, 'q'); break; + case GT: dumpRR("cmovg", $3->r, 'q', $$->rx, 'q'); break; + case LE: dumpRR("cmovle", $3->r, 'q', $$->rx, 'q'); break; + case LT: dumpRR("cmovl", $3->r, 'q', $$->rx, 'q'); break; + case GEU: dumpRR("cmovae", $3->r, 'q', $$->rx, 'q'); break; + case GTU: dumpRR("cmova", $3->r, 'q', $$->rx, 'q'); break; + case LEU: dumpRR("cmovbe", $3->r, 'q', $$->rx, 'q'); break; + case LTU: dumpRR("cmovb", $3->r, 'q', $$->rx, 'q'); break; + case UNLE: dumpRR("cmovbe", $3->r, 'q', $$->rx, 'q'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG(DImode, $2->rx); + rtx fsrc = gen_rtx_REG(DImode, $3->r); + rtx dst = tsrc; + const enum rtx_code code = $1->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE(DImode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 795 "x86-64.misc.py" +r32x : COND_MOVE(condition, PAIR_ALL(r32x, r32)) [1, 3] +#line 801 "x86-64.misc.py" + names { + $$->rx = $2->rx; + if (1) { + /* + * set the order the children are visited; + * when su ordering is working, this will force a Sethi-Ullman traversal. + */ + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + } + }, + final { + $$->rx = $2->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->rx); + memorable($3->r); + }, + debug { + const enum rtx_code code = $1->code; + switch (code) { + /* + * NOTE A: + * There is empirical evidence suggesting that the conditions and the cmov opcodes + * must be inverted relative to each other. This will make the icg+asm + * path produce identical asm code to the icg+rtl path. + * 03Nov08: After 4 hours of searching, rrh does not have an explanation for this. + * Alternatively, try swapping the fsrc and tsrc args to gen_rtx_IF_THEN_ELSE + * perhaps this is because of the evaluation permutation that is induced? + * By swapping fsrc and tsrc to the gen_rtx_IF_THEN_ELSE + * we get identical code icg+asm and icg+rtl. + */ + case EQ: dumpRR("cmove", $3->r, 'd', $$->rx, 'd'); break; + case NE: dumpRR("cmovne", $3->r, 'd', $$->rx, 'd'); break; + case GE: dumpRR("cmovge", $3->r, 'd', $$->rx, 'd'); break; + case GT: dumpRR("cmovg", $3->r, 'd', $$->rx, 'd'); break; + case LE: dumpRR("cmovle", $3->r, 'd', $$->rx, 'd'); break; + case LT: dumpRR("cmovl", $3->r, 'd', $$->rx, 'd'); break; + case GEU: dumpRR("cmovae", $3->r, 'd', $$->rx, 'd'); break; + case GTU: dumpRR("cmova", $3->r, 'd', $$->rx, 'd'); break; + case LEU: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + case LTU: dumpRR("cmovb", $3->r, 'd', $$->rx, 'd'); break; + case UNLE: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG(SImode, $2->rx); + rtx fsrc = gen_rtx_REG(SImode, $3->r); + rtx dst = tsrc; + const enum rtx_code code = $1->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE(SImode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 796 "x86-64.misc.py" +r16x : COND_MOVE(condition, PAIR_ALL(r16x, r16)) [1, 3] +#line 801 "x86-64.misc.py" + names { + $$->rx = $2->rx; + if (1) { + /* + * set the order the children are visited; + * when su ordering is working, this will force a Sethi-Ullman traversal. + */ + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + } + }, + final { + $$->rx = $2->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->rx); + memorable($3->r); + }, + debug { + const enum rtx_code code = $1->code; + switch (code) { + /* + * NOTE A: + * There is empirical evidence suggesting that the conditions and the cmov opcodes + * must be inverted relative to each other. This will make the icg+asm + * path produce identical asm code to the icg+rtl path. + * 03Nov08: After 4 hours of searching, rrh does not have an explanation for this. + * Alternatively, try swapping the fsrc and tsrc args to gen_rtx_IF_THEN_ELSE + * perhaps this is because of the evaluation permutation that is induced? + * By swapping fsrc and tsrc to the gen_rtx_IF_THEN_ELSE + * we get identical code icg+asm and icg+rtl. + */ + case EQ: dumpRR("cmove", $3->r, 'd', $$->rx, 'd'); break; + case NE: dumpRR("cmovne", $3->r, 'd', $$->rx, 'd'); break; + case GE: dumpRR("cmovge", $3->r, 'd', $$->rx, 'd'); break; + case GT: dumpRR("cmovg", $3->r, 'd', $$->rx, 'd'); break; + case LE: dumpRR("cmovle", $3->r, 'd', $$->rx, 'd'); break; + case LT: dumpRR("cmovl", $3->r, 'd', $$->rx, 'd'); break; + case GEU: dumpRR("cmovae", $3->r, 'd', $$->rx, 'd'); break; + case GTU: dumpRR("cmova", $3->r, 'd', $$->rx, 'd'); break; + case LEU: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + case LTU: dumpRR("cmovb", $3->r, 'd', $$->rx, 'd'); break; + case UNLE: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG(SImode, $2->rx); + rtx fsrc = gen_rtx_REG(SImode, $3->r); + rtx dst = tsrc; + const enum rtx_code code = $1->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE(SImode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 797 "x86-64.misc.py" +r8x : COND_MOVE(condition, PAIR_ALL(r8x, r8)) [1, 3] +#line 801 "x86-64.misc.py" + names { + $$->rx = $2->rx; + if (1) { + /* + * set the order the children are visited; + * when su ordering is working, this will force a Sethi-Ullman traversal. + */ + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + } + }, + final { + $$->rx = $2->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + sparseset_set_bit(live, find($3->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->rx); + memorable($3->r); + }, + debug { + const enum rtx_code code = $1->code; + switch (code) { + /* + * NOTE A: + * There is empirical evidence suggesting that the conditions and the cmov opcodes + * must be inverted relative to each other. This will make the icg+asm + * path produce identical asm code to the icg+rtl path. + * 03Nov08: After 4 hours of searching, rrh does not have an explanation for this. + * Alternatively, try swapping the fsrc and tsrc args to gen_rtx_IF_THEN_ELSE + * perhaps this is because of the evaluation permutation that is induced? + * By swapping fsrc and tsrc to the gen_rtx_IF_THEN_ELSE + * we get identical code icg+asm and icg+rtl. + */ + case EQ: dumpRR("cmove", $3->r, 'd', $$->rx, 'd'); break; + case NE: dumpRR("cmovne", $3->r, 'd', $$->rx, 'd'); break; + case GE: dumpRR("cmovge", $3->r, 'd', $$->rx, 'd'); break; + case GT: dumpRR("cmovg", $3->r, 'd', $$->rx, 'd'); break; + case LE: dumpRR("cmovle", $3->r, 'd', $$->rx, 'd'); break; + case LT: dumpRR("cmovl", $3->r, 'd', $$->rx, 'd'); break; + case GEU: dumpRR("cmovae", $3->r, 'd', $$->rx, 'd'); break; + case GTU: dumpRR("cmova", $3->r, 'd', $$->rx, 'd'); break; + case LEU: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + case LTU: dumpRR("cmovb", $3->r, 'd', $$->rx, 'd'); break; + case UNLE: dumpRR("cmovbe", $3->r, 'd', $$->rx, 'd'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG(SImode, $2->rx); + rtx fsrc = gen_rtx_REG(SImode, $3->r); + rtx dst = tsrc; + const enum rtx_code code = $1->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE(SImode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 891 "x86-64.misc.py" +r64x : COND_MOVE(condition, PAIR_ALL(r64x, MEM_DI(addr))) [4, 3] +#line 897 "x86-64.misc.py" + names { + $$->rx = $2->rx; + p->perm[0] = 1; + p->perm[1] = 2; + p->perm[2] = 0; /* ensuring that condition is evaluated last */ + }, + final { + $$->rx = $2->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + add_addr(live, $3); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->rx); + }, + debug { + const enum rtx_code code = $1->code; + switch (code) { + /* + * See + * NOTE A + * above + */ + case EQ: dumpMR("cmove", $3, $$->rx, 'q'); break; + case NE: dumpMR("cmovne", $3, $$->rx, 'q'); break; + case GE: dumpMR("cmovge", $3, $$->rx, 'q'); break; + case GT: dumpMR("cmovg", $3, $$->rx, 'q'); break; + case LE: dumpMR("cmovle", $3, $$->rx, 'q'); break; + case LT: dumpMR("cmovl", $3, $$->rx, 'q'); break; + case GEU: dumpMR("cmovae", $3, $$->rx, 'q'); break; + case GTU: dumpMR("cmova", $3, $$->rx, 'q'); break; + case LEU: dumpMR("cmovbe", $3, $$->rx, 'q'); break; + case LTU: dumpMR("cmovb", $3, $$->rx, 'q'); break; + case UNLE: dumpMR("cmovbe", $3, $$->rx, 'q'); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + }, + emit { + rtx cond, src; + rtx tsrc = gen_rtx_REG(DImode, $2->rx); + rtx fsrc = gen_rtx_MEM(DImode, $3->rtl); + rtx dst = tsrc; + const enum rtx_code code = $1->code; + switch (code) { + case EQ: cond = gen_rtx_EQ (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: cond = gen_rtx_NE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: cond = gen_rtx_GE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: cond = gen_rtx_GT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: cond = gen_rtx_LE (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: cond = gen_rtx_LT (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GEU: cond = gen_rtx_GEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: cond = gen_rtx_GTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: cond = gen_rtx_LEU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: cond = gen_rtx_LTU (VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: cond = gen_rtx_UNLE(VOIDmode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + default: + icg_nyi("unrecognized condition code %d for cmov", code); + } + src = gen_rtx_IF_THEN_ELSE(DImode, cond, tsrc, fsrc); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 976 "x86-64.misc.py" +r8x : condition [1, 3] +#line 979 "x86-64.misc.py" + names { + $$->rx = new_reg(); + }, + kinds { + icg_reg_vector[$$->rx].kind = INT_REGISTER; + }, + build { + unsigned rd = find($$->rx); + sparseset_clear_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + final { + $$->rx = icg_reg_vector[find($$->rx)].color; + }, + debug { + const enum rtx_code code = $1->code; + const enum machine_mode cc_code = $1->cc_code; + switch (code) { + case EQ: dumpR("sete", $$->rx, 'b'); break; + case NE: dumpR("setne", $$->rx, 'b'); break; + case GE: dumpR(cc_code == CCFPUmode ? "setae" : "setge", $$->rx, 'b'); break; + case GT: dumpR(cc_code == CCFPUmode ? "seta" : "setg", $$->rx, 'b'); break; + case LE: dumpR(cc_code == CCFPUmode ? "setbe" : "setle", $$->rx, 'b'); break; + case LT: dumpR(cc_code == CCFPUmode ? "setb" : "setl", $$->rx, 'b'); break; + + case GEU: dumpR("setae", $$->rx, 'b'); break; + case GTU: dumpR("seta", $$->rx, 'b'); break; + case LEU: dumpR("setbe", $$->rx, 'b'); break; + case LTU: dumpR("setb", $$->rx, 'b'); break; + + /* + * UNEQ (unordered ==) and LTGT (unordered !=) are problematic + * LTGT in flow context will generate 2 conditional jumps, + * one for jne and the other jp (jump unordered) + * Empirically, when we see LTGT in value context it + * is as a child of an IOR, where the other child + * is a test of UNORDERED, so we can just handle the jne case here. + */ + case UNEQ: dumpR("sete", $$->rx, 'b'); break; + case LTGT: dumpR("setne", $$->rx, 'b'); break; + + case UNGE: dumpR("setae", $$->rx, 'b'); break; + case UNGT: dumpR("seta", $$->rx, 'b'); break; + case UNLE: dumpR("setbe", $$->rx, 'b'); break; + case UNLT: dumpR("setb", $$->rx, 'b'); break; + case UNORDERED: dumpR("setp", $$->rx, 'b'); break; + case ORDERED: dumpR("setnp", $$->rx, 'b'); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + }, + emit { + rtx src; + rtx dst = gen_rtx_REG(QImode, $$->rx); + const enum rtx_code code = $1->code; + switch (code) { + case EQ: src = gen_rtx_EQ (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case NE: src = gen_rtx_NE (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GE: src = gen_rtx_GE (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GT: src = gen_rtx_GT (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LE: src = gen_rtx_LE (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LT: src = gen_rtx_LT (QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + + case GEU: src = gen_rtx_GEU(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: src = gen_rtx_GTU(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: src = gen_rtx_LEU(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: src = gen_rtx_LTU(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + + case UNEQ: src = gen_rtx_UNEQ(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case LTGT: src = gen_rtx_LTGT(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNGE: src = gen_rtx_UNGE(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNGT: src = gen_rtx_UNGT(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: src = gen_rtx_UNLE(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNLT: src = gen_rtx_UNLT(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case UNORDERED: src = gen_rtx_UNORDERED(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + case ORDERED: src = gen_rtx_ORDERED(QImode, gen_rtx_REG($1->cc_code, REG_CC), GEN_INT(0)); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1069 "x86-64.misc.py" +stmt : SET_ALL(MEM_QI(addr), condition) [3, 2] +#line 1072 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + const enum rtx_code code = $2->code; + const enum machine_mode cc_code = $2->cc_code; + switch (code) { + case EQ: dumpM("sete", $1); break; + case NE: dumpM("setne", $1); break; + case GE: dumpM(cc_code == CCFPUmode ? "setae" : "setge", $1); break; + case GT: dumpM(cc_code == CCFPUmode ? "seta" : "setg", $1); break; + case LE: dumpM(cc_code == CCFPUmode ? "setbe" : "setle", $1); break; + case LT: dumpM(cc_code == CCFPUmode ? "setb" : "setl", $1); break; + + case GEU: dumpM("setae", $1); break; + case GTU: dumpM("seta", $1); break; + case LEU: dumpM("setbe", $1); break; + case LTU: dumpM("setb", $1); break; + + case UNEQ: dumpM("sete", $1); break; + case LTGT: dumpM("setne", $1); break; + case UNGE: dumpM("setae", $1); break; + case UNGT: dumpM("seta", $1); break; + case UNLE: dumpM("setbe", $1); break; + case UNLT: dumpM("setb", $1); break; + case UNORDERED: dumpM("setp", $1); break; + case ORDERED: dumpM("setnp", $1); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + }, + emit { + rtx src; + rtx dst = gen_rtx_MEM(QImode, $1->rtl); + const enum rtx_code code = $2->code; + switch (code) { + case EQ: src = gen_rtx_EQ (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case NE: src = gen_rtx_NE (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case GE: src = gen_rtx_GE (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case GT: src = gen_rtx_GT (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case LE: src = gen_rtx_LE (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case LT: src = gen_rtx_LT (QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + + case GEU: src = gen_rtx_GEU(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case GTU: src = gen_rtx_GTU(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case LEU: src = gen_rtx_LEU(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case LTU: src = gen_rtx_LTU(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + + case UNEQ: src = gen_rtx_UNEQ(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case LTGT: src = gen_rtx_LTGT(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case UNGE: src = gen_rtx_UNGE(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case UNGT: src = gen_rtx_UNGT(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case UNLE: src = gen_rtx_UNLE(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case UNLT: src = gen_rtx_UNLT(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case UNORDERED: src = gen_rtx_UNORDERED(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + case ORDERED: src = gen_rtx_ORDERED(QImode, gen_rtx_REG($2->cc_code, REG_CC), GEN_INT(0)); break; + + default: + icg_nyi("unrecognized condition code %d for set", code); + } + icg_emit_plain(gen_rtx_SET(VOIDmode, dst, src)); + }; +#line 1152 "x86-64.misc.py" +r64x : PLUS_DI(r64x | NEG_DI(PLUS_DI(LTU_ALL(rcc, CONST_0), CONST_N1))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbq", $$->rx, 'q'); + }, + emit { + rtx ltu = gen_rtx_LTU(DImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(DImode, ltu, GEN_INT(-1)); + rtx minus = gen_rtx_MINUS(DImode, gen_rtx_REG(DImode, $1->rx), plus); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1153 "x86-64.misc.py" +r32x : PLUS_SI(r32x | NEG_SI(PLUS_SI(LTU_ALL(rcc, CONST_0), CONST_N1))) [1, 3] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbl", $$->rx, 'd'); + }, + emit { + rtx ltu = gen_rtx_LTU(SImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(SImode, ltu, GEN_INT(-1)); + rtx minus = gen_rtx_MINUS(SImode, gen_rtx_REG(SImode, $1->rx), plus); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1154 "x86-64.misc.py" +r16x : PLUS_HI(r16x | NEG_HI(PLUS_HI(LTU_ALL(rcc, CONST_0), CONST_N1))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbw", $$->rx, 'w'); + }, + emit { + rtx ltu = gen_rtx_LTU(HImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(HImode, ltu, GEN_INT(-1)); + rtx minus = gen_rtx_MINUS(HImode, gen_rtx_REG(HImode, $1->rx), plus); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1155 "x86-64.misc.py" +r8x : PLUS_QI(r8x | NEG_QI(PLUS_QI(LTU_ALL(rcc, CONST_0), CONST_N1))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbb", $$->rx, 'b'); + }, + emit { + rtx ltu = gen_rtx_LTU(QImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(QImode, ltu, GEN_INT(-1)); + rtx minus = gen_rtx_MINUS(QImode, gen_rtx_REG(QImode, $1->rx), plus); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1157 "x86-64.misc.py" +r64x : PLUS_DI(r64x | NEG_DI(PLUS_DI(LTU_ALL(rcc, CONST_0), CONST_0))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbq", $$->rx, 'q'); + }, + emit { + rtx ltu = gen_rtx_LTU(DImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(DImode, ltu, GEN_INT(0)); + rtx minus = gen_rtx_MINUS(DImode, gen_rtx_REG(DImode, $1->rx), plus); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1158 "x86-64.misc.py" +r32x : PLUS_SI(r32x | NEG_SI(PLUS_SI(LTU_ALL(rcc, CONST_0), CONST_0))) [1, 3] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbl", $$->rx, 'd'); + }, + emit { + rtx ltu = gen_rtx_LTU(SImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(SImode, ltu, GEN_INT(0)); + rtx minus = gen_rtx_MINUS(SImode, gen_rtx_REG(SImode, $1->rx), plus); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1159 "x86-64.misc.py" +r16x : PLUS_HI(r16x | NEG_HI(PLUS_HI(LTU_ALL(rcc, CONST_0), CONST_0))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbw", $$->rx, 'w'); + }, + emit { + rtx ltu = gen_rtx_LTU(HImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(HImode, ltu, GEN_INT(0)); + rtx minus = gen_rtx_MINUS(HImode, gen_rtx_REG(HImode, $1->rx), plus); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1160 "x86-64.misc.py" +r8x : PLUS_QI(r8x | NEG_QI(PLUS_QI(LTU_ALL(rcc, CONST_0), CONST_0))) [1, 4] +#line 1164 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("sbbb", $$->rx, 'b'); + }, + emit { + rtx ltu = gen_rtx_LTU(QImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus = gen_rtx_PLUS(QImode, ltu, GEN_INT(0)); + rtx minus = gen_rtx_MINUS(QImode, gen_rtx_REG(QImode, $1->rx), plus); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, minus)); + }; +#line 1196 "x86-64.misc.py" +r64x : PLUS_DI(r64x | LTU_ALL(rcc, CONST_0) | CONST_0) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcq", $$->rx, 'q'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(DImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(DImode, ltu, gen_rtx_REG(DImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(DImode, plus0, GEN_INT(0)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1197 "x86-64.misc.py" +r32x : PLUS_SI(r32x | LTU_ALL(rcc, CONST_0) | CONST_0) [1, 3] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcl", $$->rx, 'd'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(SImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(SImode, ltu, gen_rtx_REG(SImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(SImode, plus0, GEN_INT(0)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1198 "x86-64.misc.py" +r16x : PLUS_HI(r16x | LTU_ALL(rcc, CONST_0) | CONST_0) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcw", $$->rx, 'w'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(HImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(HImode, ltu, gen_rtx_REG(HImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(HImode, plus0, GEN_INT(0)); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1199 "x86-64.misc.py" +r8x : PLUS_QI(r8x | LTU_ALL(rcc, CONST_0) | CONST_0) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcb", $$->rx, 'b'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(QImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(QImode, ltu, gen_rtx_REG(QImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(QImode, plus0, GEN_INT(0)); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1201 "x86-64.misc.py" +r64x : PLUS_DI(r64x | LTU_ALL(rcc, CONST_0) | CONST_N1) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcq", $$->rx, 'q'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(DImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(DImode, ltu, gen_rtx_REG(DImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(DImode, plus0, GEN_INT(-1)); + rtx dst = gen_rtx_REG(DImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1202 "x86-64.misc.py" +r32x : PLUS_SI(r32x | LTU_ALL(rcc, CONST_0) | CONST_N1) [1, 3] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcl", $$->rx, 'd'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(SImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(SImode, ltu, gen_rtx_REG(SImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(SImode, plus0, GEN_INT(-1)); + rtx dst = gen_rtx_REG(SImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1203 "x86-64.misc.py" +r16x : PLUS_HI(r16x | LTU_ALL(rcc, CONST_0) | CONST_N1) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcw", $$->rx, 'w'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(HImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(HImode, ltu, gen_rtx_REG(HImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(HImode, plus0, GEN_INT(-1)); + rtx dst = gen_rtx_REG(HImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1204 "x86-64.misc.py" +r8x : PLUS_QI(r8x | LTU_ALL(rcc, CONST_0) | CONST_N1) [1, 4] +#line 1208 "x86-64.misc.py" + names { + $$->rx = $1->rx; + }, + final { + $$->rx = $1->rx; + }, + build { + unsigned rd = find($$->rx); + sparseset_set_bit(live, rd); + add_edges(rd, live); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->rx); + }, + debug { + dumpIRm1("adcb", $$->rx, 'b'); + }, + emit { + /* careflly reassemble a tree canonicalized for what the downstream ICG+RTL wants */ + rtx ltu = gen_rtx_LTU(QImode, gen_rtx_REG(CCmode, REG_CC), GEN_INT(0)); + rtx plus0 = gen_rtx_PLUS(QImode, ltu, gen_rtx_REG(QImode, $1->rx)); + rtx plus1 = gen_rtx_PLUS(QImode, plus0, GEN_INT(-1)); + rtx dst = gen_rtx_REG(QImode, $$->rx); + icg_emit_clobber(gen_rtx_SET(VOIDmode, dst, plus1)); + }; +#line 1250 "x86-64.misc.py" +condition : EQ_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = EQ; + $$->cc_code = CCmode; + }; +#line 1251 "x86-64.misc.py" +condition : NE_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = NE; + $$->cc_code = CCmode; + }; +#line 1252 "x86-64.misc.py" +condition : GE_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GE; + $$->cc_code = CCmode; + }; +#line 1253 "x86-64.misc.py" +condition : GT_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GT; + $$->cc_code = CCmode; + }; +#line 1254 "x86-64.misc.py" +condition : LE_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LE; + $$->cc_code = CCmode; + }; +#line 1255 "x86-64.misc.py" +condition : LT_ALL ( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LT; + $$->cc_code = CCmode; + }; +#line 1256 "x86-64.misc.py" +condition : GEU_ALL( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GEU; + $$->cc_code = CCmode; + }; +#line 1257 "x86-64.misc.py" +condition : GTU_ALL( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GTU; + $$->cc_code = CCmode; + }; +#line 1258 "x86-64.misc.py" +condition : LEU_ALL( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LEU; + $$->cc_code = CCmode; + }; +#line 1259 "x86-64.misc.py" +condition : LTU_ALL( rcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LTU; + $$->cc_code = CCmode; + }; +#line 1273 "x86-64.misc.py" +condition : EQ_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = EQ; + $$->cc_code = CCFPUmode; + }; +#line 1274 "x86-64.misc.py" +condition : NE_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = NE; + $$->cc_code = CCFPUmode; + }; +#line 1275 "x86-64.misc.py" +condition : GE_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GE; + $$->cc_code = CCFPUmode; + }; +#line 1276 "x86-64.misc.py" +condition : GT_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = GT; + $$->cc_code = CCFPUmode; + }; +#line 1277 "x86-64.misc.py" +condition : LE_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LE; + $$->cc_code = CCFPUmode; + }; +#line 1278 "x86-64.misc.py" +condition : LT_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LT; + $$->cc_code = CCFPUmode; + }; +#line 1284 "x86-64.misc.py" +condition : UNEQ_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNEQ; + $$->cc_code = CCFPUmode; + }; +#line 1285 "x86-64.misc.py" +condition : UNGE_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNGE; + $$->cc_code = CCFPUmode; + }; +#line 1286 "x86-64.misc.py" +condition : UNGT_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNGT; + $$->cc_code = CCFPUmode; + }; +#line 1287 "x86-64.misc.py" +condition : UNLE_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNLE; + $$->cc_code = CCFPUmode; + }; +#line 1288 "x86-64.misc.py" +condition : UNLT_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNLT; + $$->cc_code = CCFPUmode; + }; +#line 1289 "x86-64.misc.py" +condition : LTGT_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = LTGT; + $$->cc_code = CCFPUmode; + }; +#line 1290 "x86-64.misc.py" +condition : UNORDERED_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = UNORDERED; + $$->cc_code = CCFPUmode; + }; +#line 1291 "x86-64.misc.py" +condition : ORDERED_ALL(urcc, CONST_0) [0, 0] +#line 1295 "x86-64.misc.py" + names { + $$->code = ORDERED; + $$->cc_code = CCFPUmode; + }; +#line 1343 "x86-64.misc.py" +stmt : SET_ALL(REGCCX_DI, rcc) [20, 20] +#line 1347 "x86-64.misc.py" + ; +#line 1344 "x86-64.misc.py" +stmt : SET_ALL(REGCCFPUX_DI, urcc) [20, 20] +#line 1347 "x86-64.misc.py" + ; +#line 1358 "x86-64.misc.py" +rcc : REGCCX_DI [0, 0] +#line 1371 "x86-64.misc.py" + costs { + /*forgettable($src->rx);*/ + }; +#line 1359 "x86-64.misc.py" +rcc : REGCC_DI [0, 0] +#line 1371 "x86-64.misc.py" + costs { + /*forgettable($src->rx);*/ + }; +#line 1367 "x86-64.misc.py" +urcc : REGCCFPUX_DI [0, 0] +#line 1371 "x86-64.misc.py" + costs { + /*forgettable($src->rx);*/ + }; +#line 1368 "x86-64.misc.py" +urcc : REGCCFPU_DI [0, 0] +#line 1371 "x86-64.misc.py" + costs { + /*forgettable($src->rx);*/ + }; +#line 1383 "x86-64.misc.py" +rcc : COMPARE_CC(ccr64x, CONST_0) [0, 0] +#line 1389 "x86-64.misc.py" + debug { + /* fprintf(dump_file, "; IMPLICIT USE OF PREVIOUSLY SET CONDITION CODE\n"); */ + }; +#line 1384 "x86-64.misc.py" +rcc : COMPARE_CC(ccr32x, CONST_0) [0, 0] +#line 1389 "x86-64.misc.py" + debug { + /* fprintf(dump_file, "; IMPLICIT USE OF PREVIOUSLY SET CONDITION CODE\n"); */ + }; +#line 1385 "x86-64.misc.py" +rcc : COMPARE_CC(ccr16x, CONST_0) [0, 0] +#line 1389 "x86-64.misc.py" + debug { + /* fprintf(dump_file, "; IMPLICIT USE OF PREVIOUSLY SET CONDITION CODE\n"); */ + }; +#line 1386 "x86-64.misc.py" +rcc : COMPARE_CC(ccr8x, CONST_0) [0, 0] +#line 1389 "x86-64.misc.py" + debug { + /* fprintf(dump_file, "; IMPLICIT USE OF PREVIOUSLY SET CONDITION CODE\n"); */ + }; +#line 1397 "x86-64.misc.py" +urcc : COMPARE_CC(rd, rd) [1, 3] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomisd", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCFPUmode, DFmode, + gen_rtx_REG(DFmode, $1->r), + gen_rtx_REG(DFmode, $2->r)))); + }; +#line 1398 "x86-64.misc.py" +urcc : COMPARE_CC(rf, rf) [1, 3] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomiss", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCFPUmode, SFmode, + gen_rtx_REG(SFmode, $1->r), + gen_rtx_REG(SFmode, $2->r)))); + }; +#line 1400 "x86-64.misc.py" +rcc : COMPARE_CC(r64, r64) [1, 3] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("cmpq", $2->r, 'q', $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_REG(DImode, $1->r), + gen_rtx_REG(DImode, $2->r)))); + }; +#line 1401 "x86-64.misc.py" +rcc : COMPARE_CC(r32, r32) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("cmpl", $2->r, 'd', $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_REG(SImode, $2->r)))); + }; +#line 1402 "x86-64.misc.py" +rcc : COMPARE_CC(r16, r16) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("cmpw", $2->r, 'w', $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_REG(HImode, $2->r)))); + }; +#line 1403 "x86-64.misc.py" +rcc : COMPARE_CC(r8, r8) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("cmpb", $2->r, 'b', $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, QImode, + gen_rtx_REG(QImode, $1->r), + gen_rtx_REG(QImode, $2->r)))); + }; +#line 1408 "x86-64.misc.py" +rcc : COMPARE_CC(AND_DI(r64, r64), CONST_0) [1, 3] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("testq", $2->r, 'q', $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, DImode, + gen_rtx_REG(DImode, $1->r), + gen_rtx_REG(DImode, $2->r)))); + }; +#line 1409 "x86-64.misc.py" +rcc : COMPARE_CC(AND_SI(r32, r32), CONST_0) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("testq", $2->r, 'd', $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_REG(SImode, $2->r)))); + }; +#line 1410 "x86-64.misc.py" +rcc : COMPARE_CC(AND_HI(r16, r16), CONST_0) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("testq", $2->r, 'w', $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_REG(HImode, $2->r)))); + }; +#line 1411 "x86-64.misc.py" +rcc : COMPARE_CC(AND_QI(r8, r8), CONST_0) [1, 2] +#line 1415 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + memorable($2->r); + }, + debug { + dumpRR("testq", $2->r, 'b', $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, QImode, + gen_rtx_REG(QImode, $1->r), + gen_rtx_REG(QImode, $2->r)))); + }; +#line 1441 "x86-64.misc.py" +rcc : COMPARE_CC(r64, imm32) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpq", $2, $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_REG(DImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1442 "x86-64.misc.py" +rcc : COMPARE_CC(r64, imm8) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpq", $2, $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_REG(DImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1443 "x86-64.misc.py" +rcc : COMPARE_CC(r32, imm32) [1, 2] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpl", $2, $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_REG(SImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1444 "x86-64.misc.py" +rcc : COMPARE_CC(r32, imm8) [1, 2] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpl", $2, $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_REG(SImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1445 "x86-64.misc.py" +rcc : COMPARE_CC(r16, imm16) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpw", $2, $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1446 "x86-64.misc.py" +rcc : COMPARE_CC(r16, imm8) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpw", $2, $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1447 "x86-64.misc.py" +rcc : COMPARE_CC(r8, imm8) [1, 2] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("cmpb", $2, $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1452 "x86-64.misc.py" +rcc : COMPARE_CC(AND_DI(r64, imm32), CONST_0) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("testq", $2, $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, DImode, + gen_rtx_REG(DImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1453 "x86-64.misc.py" +rcc : COMPARE_CC(AND_SI(r32, imm32), CONST_0) [1, 2] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("testl", $2, $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, SImode, + gen_rtx_REG(SImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1454 "x86-64.misc.py" +rcc : COMPARE_CC(AND_HI(r16, imm16), CONST_0) [1, 3] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("testw", $2, $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, HImode, + gen_rtx_REG(HImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1455 "x86-64.misc.py" +rcc : COMPARE_CC(AND_QI(r8, imm8), CONST_0) [1, 2] +#line 1459 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpIR("testb", $2, $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, QImode, + gen_rtx_REG(QImode, $1->r), + GEN_INT($2->val)))); + }; +#line 1488 "x86-64.misc.py" +rcc : COMPARE_CC(r64, CONST_0) [1, 3] +#line 1495 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("testq", $1->r, 'q', $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCNOmode, REG_CC), + gen_rtx_COMPARE(CCNOmode, + gen_rtx_REG(DImode, $1->r), + GEN_INT(0)))); + }; +#line 1489 "x86-64.misc.py" +rcc : COMPARE_CC(r32, CONST_0) [1, 2] +#line 1495 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("testl", $1->r, 'd', $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCNOmode, REG_CC), + gen_rtx_COMPARE(CCNOmode, + gen_rtx_REG(SImode, $1->r), + GEN_INT(0)))); + }; +#line 1490 "x86-64.misc.py" +rcc : COMPARE_CC(r16, CONST_0) [1, 3] +#line 1495 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("testw", $1->r, 'w', $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCNOmode, REG_CC), + gen_rtx_COMPARE(CCNOmode, + gen_rtx_REG(HImode, $1->r), + GEN_INT(0)))); + }; +#line 1491 "x86-64.misc.py" +rcc : COMPARE_CC(r8, CONST_0) [1, 2] +#line 1495 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + }, + debug { + dumpRR("testb", $1->r, 'b', $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCNOmode, REG_CC), + gen_rtx_COMPARE(CCNOmode, + gen_rtx_REG(QImode, $1->r), + GEN_INT(0)))); + }; +#line 1523 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_DI(addr), imm32) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpq", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_MEM(DImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1524 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_DI(addr), imm8) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpq", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_MEM(DImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1525 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_SI(addr), imm32) [4, 2] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpl", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_MEM(SImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1526 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_SI(addr), imm8) [4, 2] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpl", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_MEM(SImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1527 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_HI(addr), imm16) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpw", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_MEM(HImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1528 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_HI(addr), imm8) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpw", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_MEM(HImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1529 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_QI(addr), imm8) [4, 2] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("cmpb", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, QImode, + gen_rtx_MEM(QImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1534 "x86-64.misc.py" +rcc : COMPARE_CC(AND_DI(MEM_DI(addr), imm32), CONST_0) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("testq", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCZmode, DImode, + gen_rtx_MEM(DImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1535 "x86-64.misc.py" +rcc : COMPARE_CC(AND_SI(MEM_SI(addr), imm32), CONST_0) [4, 2] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("testl", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCZmode, SImode, + gen_rtx_MEM(SImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1536 "x86-64.misc.py" +rcc : COMPARE_CC(AND_HI(MEM_HI(addr), imm16), CONST_0) [4, 3] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("testw", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCZmode, HImode, + gen_rtx_MEM(HImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1537 "x86-64.misc.py" +rcc : COMPARE_CC(AND_QI(MEM_QI(addr), imm8), CONST_0) [4, 2] +#line 1541 "x86-64.misc.py" + build { + add_addr(live, $1); + }, + remat { + flags = 0; + }, + debug { + dumpIM("testb", $2, $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCZmode, QImode, + gen_rtx_MEM(QImode, $1->rtl), + GEN_INT($2->val)))); + }; +#line 1562 "x86-64.misc.py" +urcc : COMPARE_CC(rd, MEM_DF(addr)) [4, 2] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("ucomisd", $2, $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCFPUmode, DFmode, + gen_rtx_REG(DFmode, $1->r), + gen_rtx_MEM(DFmode, $2->rtl)))); + }; +#line 1563 "x86-64.misc.py" +urcc : COMPARE_CC(rf, MEM_SF(addr)) [4, 2] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("ucomiss", $2, $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCFPUmode, SFmode, + gen_rtx_REG(SFmode, $1->r), + gen_rtx_MEM(SFmode, $2->rtl)))); + }; +#line 1565 "x86-64.misc.py" +rcc : COMPARE_CC(r64, MEM_DI(addr)) [4, 2] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("cmpq", $2, $1->r, 'q'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_REG(DImode, $1->r), + gen_rtx_MEM(DImode, $2->rtl)))); + }; +#line 1566 "x86-64.misc.py" +rcc : COMPARE_CC(r32, MEM_SI(addr)) [4, 1] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("cmpl", $2, $1->r, 'd'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_REG(SImode, $1->r), + gen_rtx_MEM(SImode, $2->rtl)))); + }; +#line 1567 "x86-64.misc.py" +rcc : COMPARE_CC(r16, MEM_HI(addr)) [4, 2] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("cmpw", $2, $1->r, 'w'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_REG(HImode, $1->r), + gen_rtx_MEM(HImode, $2->rtl)))); + }; +#line 1568 "x86-64.misc.py" +rcc : COMPARE_CC(r8, MEM_QI(addr)) [4, 1] +#line 1572 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + add_addr(live, $2); + }, + remat { + flags = 0; + }, + costs { + forgettable($1->r); + }, + debug { + dumpMR("cmpb", $2, $1->r, 'b'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, QImode, + gen_rtx_REG(QImode, $1->r), + gen_rtx_MEM(QImode, $2->rtl)))); + }; +#line 1597 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_DI(addr), r64) [4, 2] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("cmpq", $2->r, 'q', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, DImode, + gen_rtx_MEM(DImode, $1->rtl), + gen_rtx_REG(DImode, $2->r)))); + }; +#line 1598 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_SI(addr), r32) [4, 1] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("cmpl", $2->r, 'd', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_REG(SImode, $2->r)))); + }; +#line 1599 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_HI(addr), r16) [4, 2] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("cmpw", $2->r, 'w', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_REG(HImode, $2->r)))); + }; +#line 1600 "x86-64.misc.py" +rcc : COMPARE_CC(MEM_QI(addr), r8) [4, 1] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("cmpb", $2->r, 'b', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCmode, REG_CC), + gen_rtx_COMPARE_assist(0, CCmode, QImode, + gen_rtx_MEM(QImode, $1->rtl), + gen_rtx_REG(QImode, $2->r)))); + }; +#line 1605 "x86-64.misc.py" +rcc : COMPARE_CC(AND_DI(MEM_DI(addr), r64), CONST_0) [4, 2] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("testq", $2->r, 'q', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, DImode, + gen_rtx_MEM(DImode, $1->rtl), + gen_rtx_REG(DImode, $2->r)))); + }; +#line 1606 "x86-64.misc.py" +rcc : COMPARE_CC(AND_SI(MEM_SI(addr), r32), CONST_0) [4, 1] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("testl", $2->r, 'd', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, SImode, + gen_rtx_MEM(SImode, $1->rtl), + gen_rtx_REG(SImode, $2->r)))); + }; +#line 1607 "x86-64.misc.py" +rcc : COMPARE_CC(AND_HI(MEM_HI(addr), r16), CONST_0) [4, 2] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("testw", $2->r, 'w', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, HImode, + gen_rtx_MEM(HImode, $1->rtl), + gen_rtx_REG(HImode, $2->r)))); + }; +#line 1608 "x86-64.misc.py" +rcc : COMPARE_CC(AND_QI(MEM_QI(addr), r8), CONST_0) [4, 1] +#line 1612 "x86-64.misc.py" + + build { + sparseset_set_bit(live, find($2->r)); + add_addr(live, $1); + }, + remat { + flags = 0; + }, + costs { + forgettable($2->r); + }, + debug { + dumpRM("testb", $2->r, 'b', $1); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCZmode, REG_CC), + gen_rtx_COMPARE_assist(1, CCZmode, QImode, + gen_rtx_MEM(QImode, $1->rtl), + gen_rtx_REG(QImode, $2->r)))); + }; +#line 1656 "x86-64.misc.py" +stmt : SET_ALL(r64, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1657 "x86-64.misc.py" +stmt : SET_ALL(r64, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1658 "x86-64.misc.py" +stmt : SET_ALL(r64, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1660 "x86-64.misc.py" +stmt : SET_ALL(r32, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1661 "x86-64.misc.py" +stmt : SET_ALL(r32, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1662 "x86-64.misc.py" +stmt : SET_ALL(r32, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1664 "x86-64.misc.py" +stmt : SET_ALL(r16, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1665 "x86-64.misc.py" +stmt : SET_ALL(r16, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1666 "x86-64.misc.py" +stmt : SET_ALL(r16, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1668 "x86-64.misc.py" +stmt : SET_ALL(r8, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1669 "x86-64.misc.py" +stmt : SET_ALL(r8, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1670 "x86-64.misc.py" +stmt : SET_ALL(r8, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DImode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1672 "x86-64.misc.py" +stmt : SET_ALL(rf, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(SFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1673 "x86-64.misc.py" +stmt : SET_ALL(rf, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(SFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1674 "x86-64.misc.py" +stmt : SET_ALL(rf, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1676 "x86-64.misc.py" +stmt : SET_ALL(rd, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1677 "x86-64.misc.py" +stmt : SET_ALL(rd, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1678 "x86-64.misc.py" +stmt : SET_ALL(rd, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (1 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (1 == 1) { /* scalar return */ + # if (1 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(SFmode, $1->r); + # endif + } else if (1 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (1 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1687 "x86-64.misc.py" +stmt : SET_ALL(def_list, CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($2->r); + } else if (0 == 1) { + dump_callM($2->a); + } else if (0 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (0 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (2 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (2 == 1) { /* scalar return */ + # if (2 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DFmode, $1->r); + # endif + } else if (2 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (2 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1688 "x86-64.misc.py" +stmt : SET_ALL(def_list, CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($2->r); + } else if (1 == 1) { + dump_callM($2->a); + } else if (1 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (1 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (2 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (2 == 1) { /* scalar return */ + # if (2 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(DFmode, $1->r); + # endif + } else if (2 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (2 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1689 "x86-64.misc.py" +stmt : SET_ALL(def_list, CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list)) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($2->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $2); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($2->r); + } else if (2 == 1) { + dump_callM($2->a); + } else if (2 == 2) { + dump_call($2->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $2->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $2->rtl); + } else if (2 == 2) { + addr = $2->rtl; + } else { + gcc_assert(0); + } + if (2 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (2 == 1) { /* scalar return */ + # if (2 == 1) /* $1 otherwise undefined */ + dst = gen_rtx_REG(SFmode, $1->r); + # endif + } else if (2 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($3->val)); + rtx dst_call = (2 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1695 "x86-64.misc.py" +stmt : CALL_ALL(PAIR_ALL(MEM_QI(r64), imm64), use_list) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (0 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($1->r)); + } else if (0 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $1); + } else if (0 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (0 == 0) { + dump_callR($1->r); + } else if (0 == 1) { + dump_callM($1->a); + } else if (0 == 2) { + dump_call($1->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (0 == 0) { + addr = gen_rtx_REG(DImode, $1->r); + } else if (0 == 1) { + addr = gen_rtx_MEM(DImode, $1->rtl); + } else if (0 == 2) { + addr = $1->rtl; + } else { + gcc_assert(0); + } + if (0 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (0 == 1) { /* scalar return */ + # if (0 == 1) /* $dst otherwise undefined */ + dst = gen_rtx_REG(DFmode, $dst->r); + # endif + } else if (0 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($2->val)); + rtx dst_call = (0 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1696 "x86-64.misc.py" +stmt : CALL_ALL(PAIR_ALL(MEM_QI(MEM_DI(addr)), imm64), use_list) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (1 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($1->r)); + } else if (1 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $1); + } else if (1 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (1 == 0) { + dump_callR($1->r); + } else if (1 == 1) { + dump_callM($1->a); + } else if (1 == 2) { + dump_call($1->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (1 == 0) { + addr = gen_rtx_REG(DImode, $1->r); + } else if (1 == 1) { + addr = gen_rtx_MEM(DImode, $1->rtl); + } else if (1 == 2) { + addr = $1->rtl; + } else { + gcc_assert(0); + } + if (0 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (0 == 1) { /* scalar return */ + # if (0 == 1) /* $dst otherwise undefined */ + dst = gen_rtx_REG(DFmode, $dst->r); + # endif + } else if (0 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($2->val)); + rtx dst_call = (0 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1697 "x86-64.misc.py" +stmt : CALL_ALL(PAIR_ALL(MEM_QI(symbol), imm64), use_list) [0, 0] +#line 1701 "x86-64.misc.py" + build { + handle_call_kills(add_edges, live); + if (2 == 0) { + /* indirect call to an address held in a register */ + sparseset_set_bit(live, find($1->r)); + } else if (2 == 1) { + /* indirect call to an address held in a symbol */ + add_addr(live, $1); + } else if (2 == 2) { + /* direct call to an immediate address (normal) */ + } else { + gcc_assert(0); + } + }, + remat { + flags = 0; + }, + debug { + if (2 == 0) { + dump_callR($1->r); + } else if (2 == 1) { + dump_callM($1->a); + } else if (2 == 2) { + dump_call($1->a.string); + } else { + gcc_assert(0); + } + }, + emit { + rtx call_fusage = CALL_INSN_FUNCTION_USAGE($$->insn); + rtx addr = 0; + rtx dst = 0; + if (2 == 0) { + addr = gen_rtx_REG(DImode, $1->r); + } else if (2 == 1) { + addr = gen_rtx_MEM(DImode, $1->rtl); + } else if (2 == 2) { + addr = $1->rtl; + } else { + gcc_assert(0); + } + if (0 == 0) { /* no value return */ + dst = 0; /* unused */ + } else if (0 == 1) { /* scalar return */ + # if (0 == 1) /* $dst otherwise undefined */ + dst = gen_rtx_REG(SFmode, $dst->r); + # endif + } else if (0 == 2) { /* structure return */ + dst = SET_DEST($$->rtl); + } else { + gcc_assert(0); + } + { + rtx pure_call = gen_rtx_CALL(VOIDmode, + gen_rtx_MEM(QImode, addr), /* call to a byte address */ + GEN_INT($2->val)); + rtx dst_call = (0 == 0) + ? pure_call /* void return value */ + : gen_rtx_SET(VOIDmode, dst, pure_call) /* scalar or structure */ + ; + rtx call_insn = emit_call_insn(dst_call); + add_function_usage_to(call_insn, call_fusage); + } + }; +#line 1774 "x86-64.misc.py" +use_list : LIST_ALL(use, use_list) [0, 0] +#line 1778 "x86-64.misc.py" + ; +#line 1775 "x86-64.misc.py" +def_list : LIST_ALL(def, def_list) [0, 0] +#line 1778 "x86-64.misc.py" + ; +#line 1783 "x86-64.misc.py" +use_list : END_OF_LIST [0, 0] +#line 1787 "x86-64.misc.py" + ; +#line 1784 "x86-64.misc.py" +def_list : END_OF_LIST [0, 0] +#line 1787 "x86-64.misc.py" + ; +#line 1792 "x86-64.misc.py" +stmt : use [0, 0] +#line 1796 "x86-64.misc.py" + ; +#line 1793 "x86-64.misc.py" +stmt : def [0, 0] +#line 1796 "x86-64.misc.py" + ; +#line 1801 "x86-64.misc.py" +use : USE_ALL(r64) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1802 "x86-64.misc.py" +use : USE_ALL(r32) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1803 "x86-64.misc.py" +use : USE_ALL(r16) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1804 "x86-64.misc.py" +use : USE_ALL(r8) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1805 "x86-64.misc.py" +use : USE_ALL(rd) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1806 "x86-64.misc.py" +use : USE_ALL(rf) [0, 0] +#line 1809 "x86-64.misc.py" + build { + sparseset_set_bit(live, find($1->r)); + }, + remat { + flags = 0; + }, + emit { + $$->rtl = gen_rtx_USE(VOIDmode, gen_rtx_REG(DImode, $1->r)); + }; +#line 1827 "x86-64.misc.py" +def : DEF_ALL(r64) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1828 "x86-64.misc.py" +def : DEF_ALL(r32) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1829 "x86-64.misc.py" +def : DEF_ALL(r16) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1830 "x86-64.misc.py" +def : DEF_ALL(r8) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1831 "x86-64.misc.py" +def : DEF_ALL(rd) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1832 "x86-64.misc.py" +def : DEF_ALL(rf) [0, 0] +#line 1835 "x86-64.misc.py" + ; +#line 1851 "x86-64.misc.py" +condition : EQ_ALL(rd, rd) [1, 3] +#line 1857 "x86-64.misc.py" + names { + $$->code = UNEQ; + $$->cc_code = CCFPUmode; + }, + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomisd", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(/*is_test_variant*/0, CCFPUmode, DFmode, + gen_rtx_REG(DFmode, $1->r), + gen_rtx_REG(DFmode, $2->r)))); + }; +#line 1852 "x86-64.misc.py" +condition : NE_ALL(rd, rd) [1, 3] +#line 1857 "x86-64.misc.py" + names { + $$->code = LTGT; + $$->cc_code = CCFPUmode; + }, + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomisd", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(/*is_test_variant*/0, CCFPUmode, DFmode, + gen_rtx_REG(DFmode, $1->r), + gen_rtx_REG(DFmode, $2->r)))); + }; +#line 1853 "x86-64.misc.py" +condition : EQ_ALL(rf, rf) [1, 3] +#line 1857 "x86-64.misc.py" + names { + $$->code = UNEQ; + $$->cc_code = CCFPUmode; + }, + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomiss", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(/*is_test_variant*/0, CCFPUmode, SFmode, + gen_rtx_REG(SFmode, $1->r), + gen_rtx_REG(SFmode, $2->r)))); + }; +#line 1854 "x86-64.misc.py" +condition : NE_ALL(rf, rf) [1, 3] +#line 1857 "x86-64.misc.py" + names { + $$->code = LTGT; + $$->cc_code = CCFPUmode; + }, + build { + sparseset_set_bit(live, find($1->r)); + sparseset_set_bit(live, find($2->r)); + }, + remat { + flags = 0; + }, + costs { + memorable($1->r); + memorable($2->r); + }, + debug { + dumpRR("ucomiss", $2->r, 'x', $1->r, 'x'); + }, + emit { + emit_insn(gen_rtx_SET(VOIDmode, + gen_rtx_REG(CCFPUmode, REG_CC), + gen_rtx_COMPARE_assist(/*is_test_variant*/0, CCFPUmode, SFmode, + gen_rtx_REG(SFmode, $1->r), + gen_rtx_REG(SFmode, $2->r)))); + }; diff --git a/iburg/briggs/icg-grammars/x86-64.string.py b/iburg/briggs/icg-grammars/x86-64.string.py new file mode 100644 index 00000000000..25be0bcd049 --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.string.py @@ -0,0 +1,1052 @@ +# {([ + +# +# Copyright (c) 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +# -*- mode: python -*- + +import plug + +# global_print_plug_decls = 0; execfile("x86-64.gr.py") + +# +# memmove allows for overlapping strings; it isn't clear +# how/when the gcc front end will convert memmove to memcpy +# perhaps only under the strictest non-overlap detection. +# +# memcpy allows for non-overlapping strings +# +# A translation of builtin_memcpy comes +# to us as a parallel tree that encodes all +# of the side effects on registers that are expected from +# executing a "rep movsq" (repeat move string quad) instruction sequence. +# +# Our strategy relies on DF being set to 0 (cleared), +# so that autoincrement semantics are used; this is assumed +# by the x86_64 ABI on function entry/exit. +# +# For example, this is the GCC IL that appears for memcpy: +# (parallel [ +# (set (reg:DI 79) +# (const_int 0 [0x0])) +# (set (reg/f:DI 70 [ D.89782 ]) +# (plus:DI (ashift:DI (reg:DI 78) +# (const_int 3 [0x3])) +# (reg/f:DI 70 [ D.89782 ]))) +# (set (reg/f:DI 71 [ __beg ]) +# (plus:DI (ashift:DI (reg:DI 78) +# (const_int 3 [0x3])) +# (reg/f:DI 71 [ __beg ]))) +# (set (mem:BLK (reg/f:DI 70 [ D.89782 ]) [0 A8]) +# (mem:BLK (reg/f:DI 71 [ __beg ]) [0 A8])) +# (use (reg:DI 78)) +# ]) 842 {*rep_movdi_rex64} (expr_list:REG_DEAD (reg:DI 78) +# (expr_list:REG_UNUSED (reg:DI 79) +# (nil))) +# +# (reg:DI 78) presumably holds the initial value of the C register, which is the count in uint64 words +# (reg:DI 79) maps to the rcx (count) register; when done, the C register is 0 +# (reg:DI 70) maps to the rdi (dst ) register; when done, it has value rdi += r78<<3 +# (reg:DI 71) maps to the rsi (src ) register; when done, it has value rsi += r78<<3 +# and then there's a final use of r78 +# +# The assignment (set (reg:DI 79) (const_int 0)) appears to be elided by something upstream of us +# possibly from icg-ssa.c? +# + +plug.plugrule3("memcpy0", [ + ["rule", "cost"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(lhs64.dst_rdi, PLUS_DI(ASHIFT_DI(r64.src1_rcx, CONST_P3), r64.src1_rdi)), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rsi, PLUS_DI(ASHIFT_DI(r64.src2_rcx, CONST_P3), r64.src1_rsi)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64.src2_rdi), MEMB_DI(r64.src2_rsi)), + USE_ALL(r64.src3_rcx) + ) + ) + ) + """, + [10, 10] # TODO: bogus cost + ], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src1_rsi->r, REG_RSI); + if (!$dst_rdi->spilled) + coalesces += attempt_coalesce(pass, $dst_rdi->r, REG_RDI); + if (!$dst_rsi->spilled) + coalesces += attempt_coalesce(pass, $dst_rsi->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst_rsi->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $dst_rsi); + } + else + add_copy_edges(/*dst*/$dst_rsi->r, /*src*/REG_RSI, live); + if ($dst_rdi->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $dst_rdi); + } + else + add_copy_edges(/*dst*/$dst_rdi->r, /*src*/REG_RDI, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$src1_rsi->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src1_rcx->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rsi->r, REG_RSI); + cost_copy($src1_rdi->r, REG_RDI); + cost_copy($src1_rcx->r, REG_RCX); + forgettable($src1_rsi->r); + forgettable($src1_rdi->r); + forgettable($src1_rcx->r); + if (!$dst_rsi->spilled) + cost_copy($dst_rsi->r, REG_RSI); + if (!$dst_rdi->spilled) + cost_copy($dst_rdi->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $src1_rcx, $src2_rcx should be identical + * by construction upstream of icg: $dst_rdi, $src1_rdi, $src2_rdi should be identical + * by construction upstream of icg: $dst_rsi, $src1_rsi, $src2_rsi should be identical + */ + dump_copy("movq", $src1_rsi->r, REG_RSI, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump_copy("movq", $src1_rcx->r, REG_RCX, 'q'); + dump("rep movsq"); + if ($dst_rsi->spilled) + dumpRM("movq", REG_RSI, 'q', $dst_rsi); + else + dump_copy("movq", REG_RSI, $dst_rsi->r, 'q'); + if ($dst_rdi->spilled) + dumpRM("movq", REG_RDI, 'q', $dst_rdi); + else + dump_copy("movq", REG_RDI, $dst_rdi->r, 'q'); + }, + emit { + const rtx src1_rcx = gen_rtx_REG(DImode, $src1_rcx->r); + const rtx src1_rsi = gen_rtx_REG(DImode, $src1_rsi->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst_rdi = $dst_rdi->spilled + ? gen_rtx_MEM(DImode, $dst_rdi->rtl) + : gen_rtx_REG(DImode, $dst_rdi->r); + const rtx dst_rsi = $dst_rsi->spilled + ? gen_rtx_MEM(DImode, $dst_rsi->rtl) + : gen_rtx_REG(DImode, $dst_rsi->r); + + const rtx three = gen_rtx_CONST_INT(DImode, 3); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rdi)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rsi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_MEM(BLKmode, rsi)), + gen_rtx_USE(VOIDmode, rcx) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +""") + +# +# Contrast this with rule named memcpy0 +# This pattern matches a subject perhaps from prologue/epilogue block moves, perhaps rep_movdi_rex64, +# to get a "rep movsq"; this from memory_region_map.ii +# +plug.plugrule3("memcpy1", [ + ["rule", "cost"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64.src_rdi), MEMB_DI(r64.src_rsi)), + USE_ALL(r64.src_rcx) + ) + """, + [10, 10] # TODO: bogus cost + ], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src_rsi->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$src_rsi->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src_rcx->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src_rsi->r, REG_RSI); + cost_copy($src_rdi->r, REG_RDI); + cost_copy($src_rcx->r, REG_RCX); + forgettable($src_rsi->r); + forgettable($src_rdi->r); + forgettable($src_rcx->r); + }, + debug { + /* + * by construction upstream of icg: $src1_rcx, $src2_rcx should be identical + * by construction upstream of icg: $dst_rdi, $src1_rdi, $src2_rdi should be identical + * by construction upstream of icg: $dst_rsi, $src1_rsi, $src2_rsi should be identical + */ + dump_copy("movq", $src_rsi->r, REG_RSI, 'q'); + dump_copy("movq", $src_rdi->r, REG_RDI, 'q'); + dump_copy("movq", $src_rcx->r, REG_RCX, 'q'); + dump("rep movsq"); + }, + emit { + const rtx src_rsi = gen_rtx_REG(DImode, $src_rsi->r); + const rtx src_rdi = gen_rtx_REG(DImode, $src_rdi->r); + const rtx src_rcx = gen_rtx_REG(DImode, $src_rcx->r); + + const rtx three = gen_rtx_CONST_INT(DImode, 3); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + /* here we take a short cut and generate the rtx for the memcpy0 pattern */ + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rdi)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rsi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_MEM(BLKmode, rsi)), + gen_rtx_USE(VOIDmode, rcx) + ) + )); + /*icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi));*/ + /*icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi));*/ + } + ; +""") + + +# matches strmovqi_rex_1, strmovhi_rex_1, strmovsi_rex_1 +plug.plugrule3("memcpy2", [ + ["rule", "cost", "opcode", "rtx_mode", "scale"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(MEM_QI(r64.src2_rdi), MEM_QI(r64.src2_rsi)), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rsi, PLUS_DI(r64.src1_rsi, CONST_P1)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src1_rdi, CONST_P1)) + ) + ) + """, + [10, 10], "movsb", "QImode", 1, + ], + ["""stmt: + PARALLEL_ALL( + SET_ALL(MEM_HI(r64.src2_rdi), MEM_HI(r64.src2_rsi)), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rsi, PLUS_DI(r64.src1_rsi, CONST_P2)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src1_rdi, CONST_P2)) + ) + ) + """, + [10, 10], "movsw", "HImode", 2, + ], + ["""stmt: + PARALLEL_ALL( + SET_ALL(MEM_SI(r64.src2_rdi), MEM_SI(r64.src2_rsi)), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rsi, PLUS_DI(r64.src1_rsi, CONST_P4)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src1_rdi, CONST_P4)) + ) + ) + """, + [10, 10], "movsl", "SImode", 4, + ] + +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src1_rsi->r, REG_RSI); + if (!$dst_rdi->spilled) + coalesces += attempt_coalesce(pass, $dst_rdi->r, REG_RDI); + if (!$dst_rsi->spilled) + coalesces += attempt_coalesce(pass, $dst_rsi->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst_rsi->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $dst_rsi); + } + else + add_copy_edges(/*dst*/$dst_rsi->r, /*src*/REG_RSI, live); + if ($dst_rdi->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $dst_rdi); + } + else + add_copy_edges(/*dst*/$dst_rdi->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$src1_rsi->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rsi->r, REG_RSI); + cost_copy($src1_rdi->r, REG_RDI); + forgettable($src1_rsi->r); + forgettable($src1_rdi->r); + if (!$dst_rsi->spilled) + cost_copy($dst_rsi->r, REG_RSI); + if (!$dst_rdi->spilled) + cost_copy($dst_rdi->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $dst_rdi, $src1_rdi, $src2_rdi should be identical + * by construction upstream of icg: $dst_rsi, $src1_rsi, $src2_rsi should be identical + */ + dump_copy("movq", $src1_rsi->r, REG_RSI, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump("$opcode"); + if ($dst_rsi->spilled) + dumpRM("movq", REG_RSI, 'q', $dst_rsi); + else + dump_copy("movq", REG_RSI, $dst_rsi->r, 'q'); + if ($dst_rdi->spilled) + dumpRM("movq", REG_RDI, 'q', $dst_rdi); + else + dump_copy("movq", REG_RDI, $dst_rdi->r, 'q'); + }, + emit { + const rtx src1_rsi = gen_rtx_REG(DImode, $src1_rsi->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst_rdi = $dst_rdi->spilled + ? gen_rtx_MEM(DImode, $dst_rdi->rtl) + : gen_rtx_REG(DImode, $dst_rdi->r); + const rtx dst_rsi = $dst_rsi->spilled + ? gen_rtx_MEM(DImode, $dst_rsi->rtl) + : gen_rtx_REG(DImode, $dst_rsi->r); + + const rtx incr = gen_rtx_CONST_INT(DImode, $scale); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, gen_rtx_MEM($rtx_mode, rdi), gen_rtx_MEM($rtx_mode, rsi)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, incr)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, rsi, incr)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +""") + + +# +# A translation of builtin_memset comes +# to us as a parallel tree that encodes all +# of the side effects on registers that are expected from +# executing a "rep stosq" (repeat store string quad) instruction sequence. +# +# For example, this is the GCC IL that appears for memset: +# (parallel [ +# (set (reg:DI 92) +# (const_int 0 [0x0])) +# (set (reg/f:DI 84 [ D.83744 ]) +# (plus:DI (ashift:DI (reg:DI 91) +# (const_int 3 [0x3])) +# (reg/f:DI 84 [ D.83744 ]))) +# (set (mem:BLK (reg/f:DI 84 [ D.83744 ]) [0 A8]) +# (const_int 0 [0x0])) +# (use (reg:DI 87)) +# (use (reg:DI 91)) +# ]) 854 {*rep_stosdi_rex64} +# (expr_list:REG_DEAD (reg:DI 91) +# (expr_list:REG_DEAD (reg:DI 87) +# (expr_list:REG_UNUSED (reg:DI 92) +# (nil)))) + +# +# (reg:DI 91) presumably holds the initial value of the C register, which is the count in uint64 words +# (reg:DI 92) maps to the rcx (count) register; when done, the C register is 0 +# (reg:DI 84) maps to the rdi (dst ) register; when done, it has value rdi += r91<<3 +# and then there's a final use of r87 and r91 +# +# We're not entirely sure about reg 91. +# My best guess is that it's set to 0 somewhere earlier +# so that we don't have to synthesize the 0 here. +# Instead, we hope that it's been usefully commoned. +# +# The stosq instruction does (here from the manual): +# Copies a quadword from the RAX register to the memory locations pointed +# to by RDI and increments/decrements RDI by 8 according to the value of DF. +# +# Alas, but the RTL backend to gcc has a pattern that only allows +# constant 0 to be the source operand to the block move, +# not some arbitrary value held in a register (rax). +# +# note that costs seem irrelevant here. +# + +""" +PARALLEL_ALL + SET_ALL + REGX_DI:62 + CONST_0:0 + PARALLEL_ALL + SET_ALL + REGX_DI:63 + PLUS_DI + ASHIFT_DI + REG_DI:61 + CONST_P3:3 + REG_DI:64 + PARALLEL_ALL + SET_ALL + MEMB_DI + REG_DI:64 + CONST_0:0 + PARALLEL_ALL + USE_ALL + REG_DI:60 + USE_ALL + REG_DI:61 +""" + +plug.plugrule3("memset0", [ + ["rule", "cost", "mode", "shift"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(lhs64.dst_rcx, CONST_0), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rdi, PLUS_DI(ASHIFT_DI(r64.src1_rcx, CONST_P3), r64.src1_rdi)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64.src2_rdi), CONST_0), + PARALLEL_ALL( + USE_ALL(r64.src1_rax), + USE_ALL(r64.src2_rcx)))))""", [10, 10], "DImode", 3], + ["""stmt: + PARALLEL_ALL( + SET_ALL(lhs64.dst_rcx, CONST_0), + PARALLEL_ALL( + SET_ALL(lhs64.dst_rdi, PLUS_DI(ASHIFT_DI(r64.src1_rcx, CONST_P2), r64.src1_rdi)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64.src2_rdi), CONST_0), + PARALLEL_ALL( + USE_ALL(r32.src1_rax), + USE_ALL(r64.src2_rcx)))))""", [10, 10], "SImode", 2], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rax->r, REG_RAX); + coalesces += attempt_coalesce(pass, $src1_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + if (!$dst_rdi->spilled) + coalesces += attempt_coalesce(pass, $dst_rdi->r, REG_RDI); + if (!$dst_rcx->spilled) + coalesces += attempt_coalesce(pass, $dst_rcx->r, REG_RCX); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst_rdi->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $dst_rdi); + } + else + add_copy_edges(/*dst*/$dst_rdi->r, /*src*/REG_RDI, live); + if ($dst_rcx->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $dst_rcx); + } + else + add_copy_edges(/*dst*/$dst_rcx->r, /*src*/REG_RCX, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src1_rcx->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$src1_rax->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rax->r, REG_RAX); + cost_copy($src1_rcx->r, REG_RCX); + cost_copy($src1_rdi->r, REG_RDI); + forgettable($src1_rax->r); + forgettable($src1_rdi->r); + forgettable($src1_rcx->r); + if (!$dst_rdi->spilled) + cost_copy($dst_rdi->r, REG_RDI); + if (!$dst_rcx->spilled) + cost_copy($dst_rcx->r, REG_RCX); + }, + debug { + dump_copy("movq", $src1_rax->r, REG_RAX, 'q'); /* get zero into rax */ + dump_copy("movq", $src1_rcx->r, REG_RCX, 'q'); /* get count into rcx */ + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); /* get address into rdi */ + dump("rep stosq"); + if ($dst_rcx->spilled) + dumpRM("movq", REG_RCX, 'q', $dst_rcx); + else + dump_copy("movq", REG_RCX, $dst_rcx->r, 'q'); + if ($dst_rdi->spilled) + dumpRM("movq", REG_RDI, 'q', $dst_rdi); + else + dump_copy("movq", REG_RDI, $dst_rdi->r, 'q'); + }, + emit { + #if 0 + We want something like this; ordering of parallel kids is evidently important: + (parallel [ + (set (reg:DI 2 cx [92]) + (const_int 0 [0x0])) + (set (reg/f:DI 5 di [orig:84 D.83744 ] [84]) + (plus:DI (ashift:DI (reg:DI 2 cx [91]) + (const_int 3 [0x3])) + (reg/f:DI 5 di [orig:84 D.83744 ] [84]))) + (set (mem:BLK (reg/f:DI 5 di [orig:84 D.83744 ] [84]) [0 A8]) + (const_int 0 [0x0])) + (use (reg:DI 0 ax [87])) + (use (reg:DI 2 cx [91])) + ]) 854 {*rep_stosdi_rex64} (nil) + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $src1_rcx->r); + const rtx src1_rax = gen_rtx_REG($mode, $src1_rax->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst_rdi = $dst_rdi->spilled + ? gen_rtx_MEM(DImode, $dst_rdi->rtl) + : gen_rtx_REG(DImode, $dst_rdi->r); + const rtx dst_rcx = $dst_rcx->spilled + ? gen_rtx_MEM(DImode, $dst_rcx->rtl) + : gen_rtx_REG(DImode, $dst_rcx->r); + + const rtx shift = gen_rtx_CONST_INT(DImode, $shift); + const rtx rax = gen_rtx_REG($mode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, shift), rdi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_USE(VOIDmode, rax), /* must be 1st use */ + gen_rtx_USE(VOIDmode, rcx) /* must be 2nd use */ + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rcx, rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +""") + + +# this next one was surprising. +# it's apparently an encoding of the STOSD instruction, +# without the REP prefix. Seems to be used to get alignment, +# sometimes, before using a REP STOSQ. I'll make it as much +# as possible like the memset sequences above. +# costs here are again irrelevant. + +plug.plugrule3("memset1", [ + ["rule", "cost", "mode", "stride"], + ["""stmt: PARALLEL_ALL( + SET_ALL(MEM_SI(r64.src1_rdi), SUBREG_SI(r64.src_rax, CONST_0)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src2_rdi, CONST_P4)))""", [1, 1], "SImode", 4], + ["""stmt: PARALLEL_ALL( + SET_ALL(MEM_HI(r64.src1_rdi), SUBREG_HI(r64.src_rax, CONST_0)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src2_rdi, CONST_P2)))""", [1, 1], "HImode", 2], + ["""stmt: PARALLEL_ALL( + SET_ALL(MEM_QI(r64.src1_rdi), SUBREG_QI(r64.src_rax, CONST_0)), + SET_ALL(lhs64.dst_rdi, PLUS_DI(r64.src2_rdi, CONST_P1)))""", [1, 1], "QImode", 1], + ], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src_rax->r, REG_RAX); + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + if (!$dst_rdi->spilled) + coalesces += attempt_coalesce(pass, $dst_rdi->r, REG_RDI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst_rdi->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $dst_rdi); + } + else + add_copy_edges(/*dst*/$dst_rdi->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$src_rax->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src_rax->r, REG_RAX); + cost_copy($src1_rdi->r, REG_RDI); + forgettable($src_rax->r); + forgettable($src1_rdi->r); + if (!$dst_rdi->spilled) + cost_copy($dst_rdi->r, REG_RDI); + }, + debug { + dump_copy("movq", $src_rax->r, REG_RAX, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump("stosl"); + if ($dst_rdi->spilled) + dumpRM("movq", REG_RDI, 'q', $dst_rdi); + else + dump_copy("movq", REG_RDI, $dst_rdi->r, 'q'); + }, + emit { + const rtx src_rax = gen_rtx_REG(DImode, $src_rax->r); + const rtx src_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst_rdi = $dst_rdi->spilled + ? gen_rtx_MEM(DImode, $dst_rdi->rtl) + : gen_rtx_REG(DImode, $dst_rdi->r); + + const rtx stride = gen_rtx_CONST_INT(DImode, $stride); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, gen_rtx_MEM($mode, rdi), gen_rtx_SUBREG($mode, rax, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, stride)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +""") + +# +# A translation of __builtin_strlen comes to us as +# UNSPEC code 30 (UNSPEC_SCAS) +# +# For example, this is the GCC IL that appears: + +# (parallel [ +# (set (reg:DI 61 [ D.94029 ]) +# (plus:DI (not:DI (unspec:DI [ +# (mem:BLK (reg/v/f:DI 71 [ names ]) [0 A8]) ; src +# (const_int 0 [0x0]) ; eos +# (const_int 1 [0x1]) ; align (unused?); also see CONST_P8 +# (const_int -1 [0xffffffffffffffff]) ; scratch RCX, UINTMAX; initial RCX value +# ] 30)) +# (const_int -1 [0xffffffffffffffff]))) +# (clobber (reg:CC 17 flags)) +# ]) + +# +# child 0 is the source pointer (reg:DI 71) +# child 1 is the end of string character (always const 0?) +# child 3 holds the value UINT_MAX, and may always be const? +# +# The scasb instruction does (here from the manual): +# Compares the al register with the byte pointed to by RDI, +# sets the status flags according to result, +# increments RDI by 1. +# The repnz instruction does: +# Repeat associated string instruction the number of times +# spec in RCX; the repetition terminates when RCX is 0 +# or when the ZF is set to 1. +# +plug.plugrule3("strlen", [ + ["rule", "cost"], + ["""r64.dst1_rcx: + ICG_UNSPEC_SCAS( + MEMB_DI(r64.src1_rdi), + ICG_UNSPEC_SCAS( + r8.src1_rax, + ICG_UNSPEC_SCAS( + imm5.align, + r64.src1_rcx + ) + ) + ) + """, + [10, 10] # TODO: bogus cost + ], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src1_rax->r, REG_RAX); + if (!$dst1_rcx->spilled) + coalesces += attempt_coalesce(pass, $dst1_rcx->r, REG_RCX); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst1_rcx->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $dst1_rcx); + } + else + add_copy_edges(/*dst*/$dst1_rcx->r, /*src*/REG_RCX, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RAX, live); + + add_copy_edges(/*dst*/REG_RAX, /*src*/$src1_rax->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src1_rcx->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rcx->r, REG_RCX); + cost_copy($src1_rdi->r, REG_RDI); + cost_copy($src1_rax->r, REG_RAX); + forgettable($src1_rax->r); + forgettable($src1_rdi->r); + forgettable($src1_rcx->r); + if (!$dst1_rcx->spilled) + cost_copy($dst1_rcx->r, REG_RCX); + }, + debug { + dump_copy("movq", $src1_rcx->r, REG_RCX, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump_copy("movb", $src1_rax->r, REG_RAX, 'b'); /* comparand */ + dump("repnz scasb"); + if ($dst1_rcx->spilled) + dumpRM("movq", REG_RCX, 'q', $dst1_rcx); + else + dump_copy("movq", REG_RCX, $dst1_rcx->r, 'q'); + }, + emit { + #if 0 + We want something like this + (unspec:DI [ + (mem:BLK (reg/v/f:DI 71 [ names ]) [0 A8]) + (const_int 0 [0x0]) + (const_int 1 [0x1]) + (const_int -1 [0xffffffffffffffff]) + ] 30 ) + + The i386.md file contains this pattern; we have to make a tree that exactly matches this: + (define_insn "*strlenqi_rex_1" + [(set (match_operand:DI 0 "register_operand" "=&c") + (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) + (match_operand:QI 2 "register_operand" "a") + (match_operand:DI 3 "immediate_operand" "i") + (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) + (clobber (match_operand:DI 1 "register_operand" "=D")) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "repnz scasb" + [(set_attr "type" "str") + (set_attr "mode" "QI") + (set_attr "prefix_rep" "1")]) + + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $src1_rcx->r); + const rtx src1_rax = gen_rtx_REG(QImode, $src1_rax->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst1_rcx = $dst1_rcx->spilled + ? gen_rtx_MEM(DImode, $dst1_rcx->rtl) + : gen_rtx_REG(DImode, $dst1_rcx->r); + + const rtx rax = gen_rtx_REG(QImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rcx, + gen_rtx_UNSPEC(DImode, + gen_rtvec(4, + gen_rtx_MEM(BLKmode, rdi), + 1 ? rax : gen_rtx_CONST_INT(DImode, 0), + gen_rtx_CONST_INT(DImode, 1), + 1 ? rcx : gen_rtx_CONST_INT(DImode, ~0ULL) + ), + UNSPEC_SCAS + )), + gen_rtx_CLOBBER(VOIDmode, rdi), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ) + ) + ); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1_rcx, rcx)); + } + ; +""") + + +# +# A translation of __builtin_memcmp comes to us as +# a COMPARE_CC involving MEMB_DI. +# +# The cmpsb instruction does (here from the manual): +# Compares the bytes pointed bo by the RSI and RDI +# registers, sets/clears the status flags of rFLAGS, +# increments RSI and RDI according to DF. +# +# The repz instruction does: +# Repeat associated string instruction the number of times +# spec in RCX; the repetition terminates when RCX is 0 +# or when the ZF is set to 0. +# +plug.plugrule3("memcmp", [ + ["rule", "cost"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(rcc.dst_rcc, + COND_MOVE( + NE_ALL(r64.src1_rcx, CONST_0), + PAIR_ALL( + COMPARE_CC(MEMB_DI(r64.src1_rdi), MEMB_DI(r64.src1_rsi)), + CONST_0 + ) + )), + PARALLEL_ALL( + USE_ALL(CONST_P1), + USE_ALL(COMPARE_CC(r64.src2_rcx, r64.src3_rcx)) + ) + ) + """, + [10, 10] # TODO: bogus cost + ], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src2_rcx->r, REG_RCX); /* TODO: redundant? */ + coalesces += attempt_coalesce(pass, $src3_rcx->r, REG_RCX); /* TODO: redundant? */ + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src1_rsi->r, REG_RSI); + #if 0 + if (!$dst1_rcx->spilled) + coalesces += attempt_coalesce(pass, $dst1_rcx->r, REG_RCX); + #endif + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + #if 0 + if ($dst1_rcx->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $dst1_rcx); + } + else + add_copy_edges(/*dst*/$dst1_rcx->r, /*src*/REG_RCX, live); + #endif + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$src1_rsi->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src1_rcx->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rcx->r, REG_RCX); + cost_copy($src1_rdi->r, REG_RDI); + cost_copy($src1_rsi->r, REG_RSI); + forgettable($src1_rsi->r); + forgettable($src1_rdi->r); + forgettable($src1_rcx->r); + #if 0 + if (!$dst1_rcx->spilled) + cost_copy($dst1_rcx->r, REG_RCX); + #endif + }, + debug { + dump_copy("movq", $src1_rcx->r, REG_RCX, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump_copy("movq", $src1_rsi->r, REG_RSI, 'q'); + dump("repz cmpsb"); + #if 0 + if ($dst1_rcx->spilled) + dumpRM("movq", REG_RCX, 'q', $dst1_rcx); + else + dump_copy("movq", REG_RCX, $dst1_rcx->r, 'q'); + #endif + }, + emit { + #if 0 + We want something like this + (unspec:DI [ + (mem:BLK (reg/v/f:DI 71 [ names ]) [0 A8]) + (const_int 0 [0x0]) + (const_int 1 [0x1]) + (const_int -1 [0xffffffffffffffff]) + ] 30 ) + + The i386.md file contains this pattern; we have to make a tree that exactly matches this: + + (define_insn "*cmpstrnqi_rex_1" + [(set (reg:CC FLAGS_REG) + (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") + (const_int 0)) + (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) + (mem:BLK (match_operand:DI 5 "register_operand" "1"))) + (const_int 0))) + (use (match_operand:SI 3 "immediate_operand" "i")) + (use (reg:CC FLAGS_REG)) + (clobber (match_operand:DI 0 "register_operand" "=S")) + (clobber (match_operand:DI 1 "register_operand" "=D")) + (clobber (match_operand:DI 2 "register_operand" "=c"))] + "TARGET_64BIT" + "repz cmpsb" + [(set_attr "type" "str") + (set_attr "mode" "QI") + (set_attr "prefix_rep" "1")]) + + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $src1_rcx->r); + const rtx src1_rsi = gen_rtx_REG(DImode, $src1_rsi->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + #if 0 + const rtx dst1_rcx = $dst1_rcx->spilled + ? gen_rtx_MEM(DImode, $dst1_rcx->rtl) + : gen_rtx_REG(DImode, $dst1_rcx->r); + #endif + + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + #if 0 + TODO + icg_emit_plain( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rcx, + gen_rtx_UNSPEC(DImode, + gen_rtvec(4, + gen_rtx_MEM(BLKmode, rdi), + 1 ? rax : gen_rtx_CONST_INT(DImode, 0), + gen_rtx_CONST_INT(DImode, 1), + 1 ? rcx : gen_rtx_CONST_INT(DImode, ~0ULL) + ), + UNSPEC_SCAS + )), + gen_rtx_CLOBBER(VOIDmode, rdi), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ) + ) + ); + #endif + #if 0 + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1_rcx, rcx)); + #endif + } + ; +""") + +# +# We also see trees like this for some form of string compare instruction +# +""" +PARALLEL_ALL <iburg handle 0x94faca8> {node 0x94ca4c0} + SET_ALL <iburg handle 0x94fa6e8> {node 0x94ca544} + REGCCX_DI <iburg handle 0x907e380> {node 0x94ca5c8} + COMPARE_CC <iburg handle 0x94fa578> {node 0x94ca64c} + MEMB_DI <iburg handle 0x94fa298> {node 0x94ca6d0} + PLUS_DI <iburg handle 0x94fa128> {node 0x94ca754} + REG_DI:66 <iburg handle 0x9080780> {node 0x94ca7d8} + REG_DI:76 <iburg handle 0x9080780> {node 0x94ca85c} + MEMB_DI <iburg handle 0x94fa408> {node 0x94ca8e0} + REG_DI:77 <iburg handle 0x9080780> {node 0x94ca964} + PARALLEL_ALL <iburg handle 0x94fab38> {node 0x94ca2bc} + USE_ALL <iburg handle 0x94fa858> {node 0x94ca340} + REG_DI:78 <iburg handle 0x9080780> {node 0x94ca3c4} + USE_ALL <iburg handle 0x94fa9c8> {node 0x94ca1b4} + CONST_P1:1 <iburg handle 0x906dd00> {node 0x94ca238} +""" + +# })] diff --git a/iburg/briggs/icg-grammars/x86-64.string.pyout b/iburg/briggs/icg-grammars/x86-64.string.pyout new file mode 100644 index 00000000000..52a63f837fb --- /dev/null +++ b/iburg/briggs/icg-grammars/x86-64.string.pyout @@ -0,0 +1,1221 @@ +#line 73 "x86-64.string.py" +stmt: +#line 77 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(ASHIFT_DI(r64, CONST_P3), r64)), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(ASHIFT_DI(r64, CONST_P3), r64)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64), MEMB_DI(r64)), + USE_ALL(r64) + ) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RCX); + coalesces += attempt_coalesce(pass, $3->r, REG_RDI); + coalesces += attempt_coalesce(pass, $6->r, REG_RSI); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + if (!$4->spilled) + coalesces += attempt_coalesce(pass, $4->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($4->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $4); + } + else + add_copy_edges(/*dst*/$4->r, /*src*/REG_RSI, live); + if ($1->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $1); + } + else + add_copy_edges(/*dst*/$1->r, /*src*/REG_RDI, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$6->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$3->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$2->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($6->r, REG_RSI); + cost_copy($3->r, REG_RDI); + cost_copy($2->r, REG_RCX); + forgettable($6->r); + forgettable($3->r); + forgettable($2->r); + if (!$4->spilled) + cost_copy($4->r, REG_RSI); + if (!$1->spilled) + cost_copy($1->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $2, $5 should be identical + * by construction upstream of icg: $1, $3, $7 should be identical + * by construction upstream of icg: $4, $6, $8 should be identical + */ + dump_copy("movq", $6->r, REG_RSI, 'q'); + dump_copy("movq", $3->r, REG_RDI, 'q'); + dump_copy("movq", $2->r, REG_RCX, 'q'); + dump("rep movsq"); + if ($4->spilled) + dumpRM("movq", REG_RSI, 'q', $4); + else + dump_copy("movq", REG_RSI, $4->r, 'q'); + if ($1->spilled) + dumpRM("movq", REG_RDI, 'q', $1); + else + dump_copy("movq", REG_RDI, $1->r, 'q'); + }, + emit { + const rtx src1_rcx = gen_rtx_REG(DImode, $2->r); + const rtx src1_rsi = gen_rtx_REG(DImode, $6->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $3->r); + const rtx dst_rdi = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + const rtx dst_rsi = $4->spilled + ? gen_rtx_MEM(DImode, $4->rtl) + : gen_rtx_REG(DImode, $4->r); + + const rtx three = gen_rtx_CONST_INT(DImode, 3); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rdi)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rsi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_MEM(BLKmode, rsi)), + gen_rtx_USE(VOIDmode, rcx) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +#line 193 "x86-64.string.py" +stmt: +#line 197 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64), MEMB_DI(r64)), + USE_ALL(r64) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $3->r, REG_RCX); + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + coalesces += attempt_coalesce(pass, $2->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$2->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$1->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$3->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($2->r, REG_RSI); + cost_copy($1->r, REG_RDI); + cost_copy($3->r, REG_RCX); + forgettable($2->r); + forgettable($1->r); + forgettable($3->r); + }, + debug { + /* + * by construction upstream of icg: $src1_rcx, $src2_rcx should be identical + * by construction upstream of icg: $dst_rdi, $src1_rdi, $src2_rdi should be identical + * by construction upstream of icg: $dst_rsi, $src1_rsi, $src2_rsi should be identical + */ + dump_copy("movq", $2->r, REG_RSI, 'q'); + dump_copy("movq", $1->r, REG_RDI, 'q'); + dump_copy("movq", $3->r, REG_RCX, 'q'); + dump("rep movsq"); + }, + emit { + const rtx src_rsi = gen_rtx_REG(DImode, $2->r); + const rtx src_rdi = gen_rtx_REG(DImode, $1->r); + const rtx src_rcx = gen_rtx_REG(DImode, $3->r); + + const rtx three = gen_rtx_CONST_INT(DImode, 3); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + /* here we take a short cut and generate the rtx for the memcpy0 pattern */ + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rdi)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rsi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_MEM(BLKmode, rsi)), + gen_rtx_USE(VOIDmode, rcx) + ) + )); + /*icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi));*/ + /*icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi));*/ + } + ; +#line 300 "x86-64.string.py" +stmt: +#line 306 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(MEM_QI(r64), MEM_QI(r64)), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(r64, CONST_P1)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P1)) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $6->r, REG_RDI); + coalesces += attempt_coalesce(pass, $4->r, REG_RSI); + if (!$5->spilled) + coalesces += attempt_coalesce(pass, $5->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RSI, live); + if ($5->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $5); + } + else + add_copy_edges(/*dst*/$5->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$6->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($4->r, REG_RSI); + cost_copy($6->r, REG_RDI); + forgettable($4->r); + forgettable($6->r); + if (!$3->spilled) + cost_copy($3->r, REG_RSI); + if (!$5->spilled) + cost_copy($5->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $5, $6, $1 should be identical + * by construction upstream of icg: $3, $4, $2 should be identical + */ + dump_copy("movq", $4->r, REG_RSI, 'q'); + dump_copy("movq", $6->r, REG_RDI, 'q'); + dump("movsb"); + if ($3->spilled) + dumpRM("movq", REG_RSI, 'q', $3); + else + dump_copy("movq", REG_RSI, $3->r, 'q'); + if ($5->spilled) + dumpRM("movq", REG_RDI, 'q', $5); + else + dump_copy("movq", REG_RDI, $5->r, 'q'); + }, + emit { + const rtx src1_rsi = gen_rtx_REG(DImode, $4->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $6->r); + const rtx dst_rdi = $5->spilled + ? gen_rtx_MEM(DImode, $5->rtl) + : gen_rtx_REG(DImode, $5->r); + const rtx dst_rsi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx incr = gen_rtx_CONST_INT(DImode, 1); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(QImode, rdi), gen_rtx_MEM(QImode, rsi)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, incr)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, rsi, incr)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +#line 300 "x86-64.string.py" +stmt: +#line 306 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(MEM_HI(r64), MEM_HI(r64)), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(r64, CONST_P2)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P2)) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $6->r, REG_RDI); + coalesces += attempt_coalesce(pass, $4->r, REG_RSI); + if (!$5->spilled) + coalesces += attempt_coalesce(pass, $5->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RSI, live); + if ($5->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $5); + } + else + add_copy_edges(/*dst*/$5->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$6->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($4->r, REG_RSI); + cost_copy($6->r, REG_RDI); + forgettable($4->r); + forgettable($6->r); + if (!$3->spilled) + cost_copy($3->r, REG_RSI); + if (!$5->spilled) + cost_copy($5->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $5, $6, $1 should be identical + * by construction upstream of icg: $3, $4, $2 should be identical + */ + dump_copy("movq", $4->r, REG_RSI, 'q'); + dump_copy("movq", $6->r, REG_RDI, 'q'); + dump("movsw"); + if ($3->spilled) + dumpRM("movq", REG_RSI, 'q', $3); + else + dump_copy("movq", REG_RSI, $3->r, 'q'); + if ($5->spilled) + dumpRM("movq", REG_RDI, 'q', $5); + else + dump_copy("movq", REG_RDI, $5->r, 'q'); + }, + emit { + const rtx src1_rsi = gen_rtx_REG(DImode, $4->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $6->r); + const rtx dst_rdi = $5->spilled + ? gen_rtx_MEM(DImode, $5->rtl) + : gen_rtx_REG(DImode, $5->r); + const rtx dst_rsi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx incr = gen_rtx_CONST_INT(DImode, 2); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(HImode, rdi), gen_rtx_MEM(HImode, rsi)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, incr)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, rsi, incr)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +#line 300 "x86-64.string.py" +stmt: +#line 306 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(MEM_SI(r64), MEM_SI(r64)), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(r64, CONST_P4)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P4)) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $6->r, REG_RDI); + coalesces += attempt_coalesce(pass, $4->r, REG_RSI); + if (!$5->spilled) + coalesces += attempt_coalesce(pass, $5->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RSI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RSI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RSI, live); + if ($5->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $5); + } + else + add_copy_edges(/*dst*/$5->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$6->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($4->r, REG_RSI); + cost_copy($6->r, REG_RDI); + forgettable($4->r); + forgettable($6->r); + if (!$3->spilled) + cost_copy($3->r, REG_RSI); + if (!$5->spilled) + cost_copy($5->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $5, $6, $1 should be identical + * by construction upstream of icg: $3, $4, $2 should be identical + */ + dump_copy("movq", $4->r, REG_RSI, 'q'); + dump_copy("movq", $6->r, REG_RDI, 'q'); + dump("movsl"); + if ($3->spilled) + dumpRM("movq", REG_RSI, 'q', $3); + else + dump_copy("movq", REG_RSI, $3->r, 'q'); + if ($5->spilled) + dumpRM("movq", REG_RDI, 'q', $5); + else + dump_copy("movq", REG_RDI, $5->r, 'q'); + }, + emit { + const rtx src1_rsi = gen_rtx_REG(DImode, $4->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $6->r); + const rtx dst_rdi = $5->spilled + ? gen_rtx_MEM(DImode, $5->rtl) + : gen_rtx_REG(DImode, $5->r); + const rtx dst_rsi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx incr = gen_rtx_CONST_INT(DImode, 4); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(SImode, rdi), gen_rtx_MEM(SImode, rsi)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, incr)), + gen_rtx_SET(VOIDmode, rsi, gen_rtx_PLUS(DImode, rsi, incr)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rsi, rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +#line 488 "x86-64.string.py" +stmt: +#line 493 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(lhs64, CONST_0), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(ASHIFT_DI(r64, CONST_P3), r64)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64), CONST_0), + PARALLEL_ALL( + USE_ALL(r64), + USE_ALL(r64))))) [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $6->r, REG_RAX); + coalesces += attempt_coalesce(pass, $3->r, REG_RCX); + coalesces += attempt_coalesce(pass, $4->r, REG_RDI); + if (!$2->spilled) + coalesces += attempt_coalesce(pass, $2->r, REG_RDI); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RCX); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($2->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $2); + } + else + add_copy_edges(/*dst*/$2->r, /*src*/REG_RDI, live); + if ($1->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $1); + } + else + add_copy_edges(/*dst*/$1->r, /*src*/REG_RCX, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$3->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$6->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($6->r, REG_RAX); + cost_copy($3->r, REG_RCX); + cost_copy($4->r, REG_RDI); + forgettable($6->r); + forgettable($4->r); + forgettable($3->r); + if (!$2->spilled) + cost_copy($2->r, REG_RDI); + if (!$1->spilled) + cost_copy($1->r, REG_RCX); + }, + debug { + dump_copy("movq", $6->r, REG_RAX, 'q'); /* get zero into rax */ + dump_copy("movq", $3->r, REG_RCX, 'q'); /* get count into rcx */ + dump_copy("movq", $4->r, REG_RDI, 'q'); /* get address into rdi */ + dump("rep stosq"); + if ($1->spilled) + dumpRM("movq", REG_RCX, 'q', $1); + else + dump_copy("movq", REG_RCX, $1->r, 'q'); + if ($2->spilled) + dumpRM("movq", REG_RDI, 'q', $2); + else + dump_copy("movq", REG_RDI, $2->r, 'q'); + }, + emit { + #if 0 + We want something like this; ordering of parallel kids is evidently important: + (parallel [ + (set (reg:DI 2 cx [92]) + (const_int 0 [0x0])) + (set (reg/f:DI 5 di [orig:84 D.83744 ] [84]) + (plus:DI (ashift:DI (reg:DI 2 cx [91]) + (const_int 3 [0x3])) + (reg/f:DI 5 di [orig:84 D.83744 ] [84]))) + (set (mem:BLK (reg/f:DI 5 di [orig:84 D.83744 ] [84]) [0 A8]) + (const_int 0 [0x0])) + (use (reg:DI 0 ax [87])) + (use (reg:DI 2 cx [91])) + ]) 854 {*rep_stosdi_rex64} (nil) + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $3->r); + const rtx src1_rax = gen_rtx_REG(DImode, $6->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $4->r); + const rtx dst_rdi = $2->spilled + ? gen_rtx_MEM(DImode, $2->rtl) + : gen_rtx_REG(DImode, $2->r); + const rtx dst_rcx = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + + const rtx shift = gen_rtx_CONST_INT(DImode, 3); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, shift), rdi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_USE(VOIDmode, rax), /* must be 1st use */ + gen_rtx_USE(VOIDmode, rcx) /* must be 2nd use */ + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rcx, rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +#line 488 "x86-64.string.py" +stmt: +#line 493 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(lhs64, CONST_0), + PARALLEL_ALL( + SET_ALL(lhs64, PLUS_DI(ASHIFT_DI(r64, CONST_P2), r64)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64), CONST_0), + PARALLEL_ALL( + USE_ALL(r32), + USE_ALL(r64))))) [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $6->r, REG_RAX); + coalesces += attempt_coalesce(pass, $3->r, REG_RCX); + coalesces += attempt_coalesce(pass, $4->r, REG_RDI); + if (!$2->spilled) + coalesces += attempt_coalesce(pass, $2->r, REG_RDI); + if (!$1->spilled) + coalesces += attempt_coalesce(pass, $1->r, REG_RCX); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($2->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $2); + } + else + add_copy_edges(/*dst*/$2->r, /*src*/REG_RDI, live); + if ($1->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $1); + } + else + add_copy_edges(/*dst*/$1->r, /*src*/REG_RCX, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$3->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$6->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($6->r, REG_RAX); + cost_copy($3->r, REG_RCX); + cost_copy($4->r, REG_RDI); + forgettable($6->r); + forgettable($4->r); + forgettable($3->r); + if (!$2->spilled) + cost_copy($2->r, REG_RDI); + if (!$1->spilled) + cost_copy($1->r, REG_RCX); + }, + debug { + dump_copy("movq", $6->r, REG_RAX, 'q'); /* get zero into rax */ + dump_copy("movq", $3->r, REG_RCX, 'q'); /* get count into rcx */ + dump_copy("movq", $4->r, REG_RDI, 'q'); /* get address into rdi */ + dump("rep stosq"); + if ($1->spilled) + dumpRM("movq", REG_RCX, 'q', $1); + else + dump_copy("movq", REG_RCX, $1->r, 'q'); + if ($2->spilled) + dumpRM("movq", REG_RDI, 'q', $2); + else + dump_copy("movq", REG_RDI, $2->r, 'q'); + }, + emit { + #if 0 + We want something like this; ordering of parallel kids is evidently important: + (parallel [ + (set (reg:DI 2 cx [92]) + (const_int 0 [0x0])) + (set (reg/f:DI 5 di [orig:84 D.83744 ] [84]) + (plus:DI (ashift:DI (reg:DI 2 cx [91]) + (const_int 3 [0x3])) + (reg/f:DI 5 di [orig:84 D.83744 ] [84]))) + (set (mem:BLK (reg/f:DI 5 di [orig:84 D.83744 ] [84]) [0 A8]) + (const_int 0 [0x0])) + (use (reg:DI 0 ax [87])) + (use (reg:DI 2 cx [91])) + ]) 854 {*rep_stosdi_rex64} (nil) + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $3->r); + const rtx src1_rax = gen_rtx_REG(SImode, $6->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $4->r); + const rtx dst_rdi = $2->spilled + ? gen_rtx_MEM(DImode, $2->rtl) + : gen_rtx_REG(DImode, $2->r); + const rtx dst_rcx = $1->spilled + ? gen_rtx_MEM(DImode, $1->rtl) + : gen_rtx_REG(DImode, $1->r); + + const rtx shift = gen_rtx_CONST_INT(DImode, 2); + const rtx rax = gen_rtx_REG(SImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, shift), rdi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_USE(VOIDmode, rax), /* must be 1st use */ + gen_rtx_USE(VOIDmode, rcx) /* must be 2nd use */ + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rcx, rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +#line 620 "x86-64.string.py" +stmt: PARALLEL_ALL( +#line 626 "x86-64.string.py" + SET_ALL(MEM_SI(r64), SUBREG_SI(r64, CONST_0)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P4))) [1, 1] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RDI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$1->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$2->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($2->r, REG_RAX); + cost_copy($1->r, REG_RDI); + forgettable($2->r); + forgettable($1->r); + if (!$3->spilled) + cost_copy($3->r, REG_RDI); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + dump_copy("movq", $1->r, REG_RDI, 'q'); + dump("stosl"); + if ($3->spilled) + dumpRM("movq", REG_RDI, 'q', $3); + else + dump_copy("movq", REG_RDI, $3->r, 'q'); + }, + emit { + const rtx src_rax = gen_rtx_REG(DImode, $2->r); + const rtx src_rdi = gen_rtx_REG(DImode, $1->r); + const rtx dst_rdi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx stride = gen_rtx_CONST_INT(DImode, 4); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(SImode, rdi), gen_rtx_SUBREG(SImode, rax, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, stride)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +#line 620 "x86-64.string.py" +stmt: PARALLEL_ALL( +#line 626 "x86-64.string.py" + SET_ALL(MEM_HI(r64), SUBREG_HI(r64, CONST_0)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P2))) [1, 1] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RDI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$1->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$2->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($2->r, REG_RAX); + cost_copy($1->r, REG_RDI); + forgettable($2->r); + forgettable($1->r); + if (!$3->spilled) + cost_copy($3->r, REG_RDI); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + dump_copy("movq", $1->r, REG_RDI, 'q'); + dump("stosl"); + if ($3->spilled) + dumpRM("movq", REG_RDI, 'q', $3); + else + dump_copy("movq", REG_RDI, $3->r, 'q'); + }, + emit { + const rtx src_rax = gen_rtx_REG(DImode, $2->r); + const rtx src_rdi = gen_rtx_REG(DImode, $1->r); + const rtx dst_rdi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx stride = gen_rtx_CONST_INT(DImode, 2); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(HImode, rdi), gen_rtx_SUBREG(HImode, rax, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, stride)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +#line 620 "x86-64.string.py" +stmt: PARALLEL_ALL( +#line 626 "x86-64.string.py" + SET_ALL(MEM_QI(r64), SUBREG_QI(r64, CONST_0)), + SET_ALL(lhs64, PLUS_DI(r64, CONST_P1))) [1, 1] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + if (!$3->spilled) + coalesces += attempt_coalesce(pass, $3->r, REG_RDI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($3->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $3); + } + else + add_copy_edges(/*dst*/$3->r, /*src*/REG_RDI, live); + + add_edges(REG_RDI, live); + + add_copy_edges(/*dst*/REG_RDI, /*src*/$1->r, live); + add_copy_edges(/*dst*/REG_RAX, /*src*/$2->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($2->r, REG_RAX); + cost_copy($1->r, REG_RDI); + forgettable($2->r); + forgettable($1->r); + if (!$3->spilled) + cost_copy($3->r, REG_RDI); + }, + debug { + dump_copy("movq", $2->r, REG_RAX, 'q'); + dump_copy("movq", $1->r, REG_RDI, 'q'); + dump("stosl"); + if ($3->spilled) + dumpRM("movq", REG_RDI, 'q', $3); + else + dump_copy("movq", REG_RDI, $3->r, 'q'); + }, + emit { + const rtx src_rax = gen_rtx_REG(DImode, $2->r); + const rtx src_rdi = gen_rtx_REG(DImode, $1->r); + const rtx dst_rdi = $3->spilled + ? gen_rtx_MEM(DImode, $3->rtl) + : gen_rtx_REG(DImode, $3->r); + + const rtx stride = gen_rtx_CONST_INT(DImode, 1); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(2, + gen_rtx_SET(VOIDmode, gen_rtx_MEM(QImode, rdi), gen_rtx_SUBREG(QImode, rax, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, rdi, stride)) + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + }; +#line 738 "x86-64.string.py" +r64: +#line 742 "x86-64.string.py" + ICG_UNSPEC_SCAS( + MEMB_DI(r64), + ICG_UNSPEC_SCAS( + r8, + ICG_UNSPEC_SCAS( + imm5, + r64 + ) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $4->r, REG_RCX); + coalesces += attempt_coalesce(pass, $1->r, REG_RDI); + coalesces += attempt_coalesce(pass, $2->r, REG_RAX); + if (!$$->spilled) + coalesces += attempt_coalesce(pass, $$->r, REG_RCX); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($$->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $$); + } + else + add_copy_edges(/*dst*/$$->r, /*src*/REG_RCX, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RAX, live); + + add_copy_edges(/*dst*/REG_RAX, /*src*/$2->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$1->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$4->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($4->r, REG_RCX); + cost_copy($1->r, REG_RDI); + cost_copy($2->r, REG_RAX); + forgettable($2->r); + forgettable($1->r); + forgettable($4->r); + if (!$$->spilled) + cost_copy($$->r, REG_RCX); + }, + debug { + dump_copy("movq", $4->r, REG_RCX, 'q'); + dump_copy("movq", $1->r, REG_RDI, 'q'); + dump_copy("movb", $2->r, REG_RAX, 'b'); /* comparand */ + dump("repnz scasb"); + if ($$->spilled) + dumpRM("movq", REG_RCX, 'q', $$); + else + dump_copy("movq", REG_RCX, $$->r, 'q'); + }, + emit { + #if 0 + We want something like this + (unspec:DI [ + (mem:BLK (reg/v/f:DI 71 [ names ]) [0 A8]) + (const_int 0 [0x0]) + (const_int 1 [0x1]) + (const_int -1 [0xffffffffffffffff]) + ] 30 ) + + The i386.md file contains this pattern; we have to make a tree that exactly matches this: + (define_insn "*strlenqi_rex_1" + [(set (match_operand:DI 0 "register_operand" "=&c") + (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) + (match_operand:QI 2 "register_operand" "a") + (match_operand:DI 3 "immediate_operand" "i") + (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) + (clobber (match_operand:DI 1 "register_operand" "=D")) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "repnz scasb" + [(set_attr "type" "str") + (set_attr "mode" "QI") + (set_attr "prefix_rep" "1")]) + + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $4->r); + const rtx src1_rax = gen_rtx_REG(QImode, $2->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $1->r); + const rtx dst1_rcx = $$->spilled + ? gen_rtx_MEM(DImode, $$->rtl) + : gen_rtx_REG(DImode, $$->r); + + const rtx rax = gen_rtx_REG(QImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rcx, + gen_rtx_UNSPEC(DImode, + gen_rtvec(4, + gen_rtx_MEM(BLKmode, rdi), + 1 ? rax : gen_rtx_CONST_INT(DImode, 0), + gen_rtx_CONST_INT(DImode, 1), + 1 ? rcx : gen_rtx_CONST_INT(DImode, ~0ULL) + ), + UNSPEC_SCAS + )), + gen_rtx_CLOBBER(VOIDmode, rdi), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ) + ) + ); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1_rcx, rcx)); + } + ; +#line 890 "x86-64.string.py" +stmt: +#line 894 "x86-64.string.py" + PARALLEL_ALL( + SET_ALL(rcc, + COND_MOVE( + NE_ALL(r64, CONST_0), + PAIR_ALL( + COMPARE_CC(MEMB_DI(r64), MEMB_DI(r64)), + CONST_0 + ) + )), + PARALLEL_ALL( + USE_ALL(CONST_P1), + USE_ALL(COMPARE_CC(r64, r64)) + ) + ) + [10, 10] + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $2->r, REG_RCX); + coalesces += attempt_coalesce(pass, $5->r, REG_RCX); /* TODO: redundant? */ + coalesces += attempt_coalesce(pass, $6->r, REG_RCX); /* TODO: redundant? */ + coalesces += attempt_coalesce(pass, $3->r, REG_RDI); + coalesces += attempt_coalesce(pass, $4->r, REG_RSI); + #if 0 + if (!$dst1_rcx->spilled) + coalesces += attempt_coalesce(pass, $dst1_rcx->r, REG_RCX); + #endif + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + #if 0 + if ($dst1_rcx->spilled) { + sparseset_set_bit(live, REG_RCX); + add_addr(live, $dst1_rcx); + } + else + add_copy_edges(/*dst*/$dst1_rcx->r, /*src*/REG_RCX, live); + #endif + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RSI, live); + + add_copy_edges(/*dst*/REG_RSI, /*src*/$4->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$3->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$2->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($2->r, REG_RCX); + cost_copy($3->r, REG_RDI); + cost_copy($4->r, REG_RSI); + forgettable($4->r); + forgettable($3->r); + forgettable($2->r); + #if 0 + if (!$dst1_rcx->spilled) + cost_copy($dst1_rcx->r, REG_RCX); + #endif + }, + debug { + dump_copy("movq", $2->r, REG_RCX, 'q'); + dump_copy("movq", $3->r, REG_RDI, 'q'); + dump_copy("movq", $4->r, REG_RSI, 'q'); + dump("repz cmpsb"); + #if 0 + if ($dst1_rcx->spilled) + dumpRM("movq", REG_RCX, 'q', $dst1_rcx); + else + dump_copy("movq", REG_RCX, $dst1_rcx->r, 'q'); + #endif + }, + emit { + #if 0 + We want something like this + (unspec:DI [ + (mem:BLK (reg/v/f:DI 71 [ names ]) [0 A8]) + (const_int 0 [0x0]) + (const_int 1 [0x1]) + (const_int -1 [0xffffffffffffffff]) + ] 30 ) + + The i386.md file contains this pattern; we have to make a tree that exactly matches this: + + (define_insn "*cmpstrnqi_rex_1" + [(set (reg:CC FLAGS_REG) + (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") + (const_int 0)) + (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) + (mem:BLK (match_operand:DI 5 "register_operand" "1"))) + (const_int 0))) + (use (match_operand:SI 3 "immediate_operand" "i")) + (use (reg:CC FLAGS_REG)) + (clobber (match_operand:DI 0 "register_operand" "=S")) + (clobber (match_operand:DI 1 "register_operand" "=D")) + (clobber (match_operand:DI 2 "register_operand" "=c"))] + "TARGET_64BIT" + "repz cmpsb" + [(set_attr "type" "str") + (set_attr "mode" "QI") + (set_attr "prefix_rep" "1")]) + + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $2->r); + const rtx src1_rsi = gen_rtx_REG(DImode, $4->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $3->r); + #if 0 + const rtx dst1_rcx = $dst1_rcx->spilled + ? gen_rtx_MEM(DImode, $dst1_rcx->rtl) + : gen_rtx_REG(DImode, $dst1_rcx->r); + #endif + + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rsi = gen_rtx_REG(DImode, REG_RSI); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rsi, src1_rsi)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + #if 0 + TODO + icg_emit_plain( + gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(3, + gen_rtx_SET(VOIDmode, + rcx, + gen_rtx_UNSPEC(DImode, + gen_rtvec(4, + gen_rtx_MEM(BLKmode, rdi), + 1 ? rax : gen_rtx_CONST_INT(DImode, 0), + gen_rtx_CONST_INT(DImode, 1), + 1 ? rcx : gen_rtx_CONST_INT(DImode, ~0ULL) + ), + UNSPEC_SCAS + )), + gen_rtx_CLOBBER(VOIDmode, rdi), + gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, FLAGS_REG)) + ) + ) + ); + #endif + #if 0 + icg_emit_plain(gen_rtx_SET(VOIDmode, dst1_rcx, rcx)); + #endif + } + ; diff --git a/iburg/briggs/icg-grammars/zap b/iburg/briggs/icg-grammars/zap new file mode 100644 index 00000000000..53aef5070ef --- /dev/null +++ b/iburg/briggs/icg-grammars/zap @@ -0,0 +1,189 @@ +# A translation of builtin_memset comes +# to us as a parallel tree that encodes all +# of the side effects on registers that are expected from +# executing a "rep stosq" (repeat store string quad) instruction sequence. +# +# For example, this is the GCC IL that appears for memset: +# (parallel [ +# (set (reg:DI 92) +# (const_int 0 [0x0])) +# (set (reg/f:DI 84 [ D.83744 ]) +# (plus:DI (ashift:DI (reg:DI 91) +# (const_int 3 [0x3])) +# (reg/f:DI 84 [ D.83744 ]))) +# (set (mem:BLK (reg/f:DI 84 [ D.83744 ]) [0 A8]) +# (const_int 0 [0x0])) +# (use (reg:DI 87)) +# (use (reg:DI 91)) +# ]) 854 {*rep_stosdi_rex64} +# (expr_list:REG_DEAD (reg:DI 91) +# (expr_list:REG_DEAD (reg:DI 87) +# (expr_list:REG_UNUSED (reg:DI 92) +# (nil)))) + +# +# (reg:DI 91) presumably holds the initial value of the C register, which is the count in uint64 words +# (reg:DI 92) maps to the rcx (count) register; when done, the C register is 0 +# (reg:DI 84) maps to the rdi (dst ) register; when done, it has value rdi += r91<<3 +# and then there's a final use of r87 and r91 +# +# The assignment to the C register (set (reg:DI 92) (const_int 0)) +# appears to be elided by something upstream of us possibly from icg-ssa.c? +# +# The stosq instruction does (here from the manual): +# Copies a quadword from the RAX register to the memory locations pointed +# to by RDI and increments/decrements RDI by 8 according to the value of DF. +# +# Alas, but the RTL backend to gcc has a pattern that only allows +# constant 0 to be the source operand to the block move, +# not some arbitrary value held in a register (rax). +# + +""" +Presumably memset + This comes from RE::TryMatch + Constants have been(?) forwarded propagated by icg-ssa.c. + PARALLEL_ALL <iburg handle 0x933ec98> {node 0x93082f4} + SET_ALL <iburg handle 0x933e6d8> {node 0x9308378} + MEMB_DI <iburg handle 0x933e568> {node 0x93083fc} + REG_DI:65 <iburg handle 0x9077400> {node 0x9308480} + CONST_0:0 <iburg handle 0x9067b00> {node 0x9308504} + PARALLEL_ALL <iburg handle 0x933eb28> {node 0x93080f0} + USE_ALL <iburg handle 0x933e848> {node 0x9308174} + CONST_0:0 <iburg handle 0x9067b00> {node 0x9308270} + USE_ALL <iburg handle 0x933e9b8> {node 0x9307fe8} + CONST5P:11 <iburg handle 0x9067080> {node 0x930806c} + The original rtx tree is: + (insn 58 57 60 8 util/regexp/regexp.cc:412 (parallel [ + (set (reg:DI 100) + (const_int 0 [0x0])) + (set (reg:DI 97) + (plus:DI (ashift:DI (reg:DI 100) + (const_int 3 [0x3])) + (reg:DI 97))) + (set (mem/s/c:BLK (reg:DI 97) [0 extra+0 S48 A64]) + (const_int 0 [0x0])) + (use (reg:DI 98)) + (use (reg:DI 100)) + ]) 854 {*rep_stosdi_rex64} (nil)) + +""" + +plug.plugrule3("memset0", [ + ["rule", "cost"], + ["""stmt: + PARALLEL_ALL( + SET_ALL(lhs64.dst_rdi, PLUS_DI(ASHIFT_DI(r64.src1_rcx, CONST_P3), r64.src1_rdi)), + PARALLEL_ALL( + SET_ALL(MEMB_DI(r64.src2_rdi), r64.src1_rax), + PARALLEL_ALL( + USE_ALL(r64.src3_rcx), + USE_ALL(r64.src2_rax) + ) + ) + ) + """, + [10, 10] # TODO: bogus cost + ], +], """ + $rule $cost + supairs { + /* TODO */ + }, + coalesce { + coalesces += attempt_coalesce(pass, $src1_rcx->r, REG_RCX); + coalesces += attempt_coalesce(pass, $src1_rdi->r, REG_RDI); + coalesces += attempt_coalesce(pass, $src1_rax->r, REG_RAX); + if (!$dst_rdi->spilled) + coalesces += attempt_coalesce(pass, $dst_rdi->r, REG_RDI); + }, + build { + /* start at back, working forward (reverse order from things are emitted) */ + if ($dst_rdi->spilled) { + sparseset_set_bit(live, REG_RDI); + add_addr(live, $dst_rdi); + } + else + add_copy_edges(/*dst*/$dst_rdi->r, /*src*/REG_RDI, live); + + add_edges(REG_RCX, live); + add_edges(REG_RDI, live); + add_edges(REG_RAX, live); + + add_copy_edges(/*dst*/REG_RAX, /*src*/$src1_rax->r, live); + add_copy_edges(/*dst*/REG_RDI, /*src*/$src1_rdi->r, live); + add_copy_edges(/*dst*/REG_RCX, /*src*/$src1_rcx->r, live); + }, + remat { + flags = 0; + }, + costs { + cost_copy($src1_rcx->r, REG_RCX); + cost_copy($src1_rdi->r, REG_RDI); + cost_copy($src1_rax->r, REG_RAX); + forgettable($src1_rax->r); + forgettable($src1_rdi->r); + forgettable($src1_rcx->r); + if (!$dst_rdi->spilled) + cost_copy($dst_rdi->r, REG_RDI); + }, + debug { + /* + * by construction upstream of icg: $src1_rcx, $src3_rcx should be identical + * by construction upstream of icg: $src1_rax, $src2_rax should be identical + * by construction upstream of icg: $dst_rdi, $src1_rdi, $src2_rdi should be identical + */ + dump_copy("movq", $src1_rcx->r, REG_RCX, 'q'); + dump_copy("movq", $src1_rdi->r, REG_RDI, 'q'); + dump_copy("movq", $src1_rax->r, REG_RAX, 'q'); + dump("rep stosq"); + if ($dst_rdi->spilled) + dumpRM("movq", REG_RDI, 'q', $dst_rdi); + else + dump_copy("movq", REG_RDI, $dst_rdi->r, 'q'); + }, + emit { + #if 0 + We want something like this; ordering of parallel kids is evidently important: + (parallel [ + (set (reg:DI 2 cx [92]) + (const_int 0 [0x0])) + (set (reg/f:DI 5 di [orig:84 D.83744 ] [84]) + (plus:DI (ashift:DI (reg:DI 2 cx [91]) + (const_int 3 [0x3])) + (reg/f:DI 5 di [orig:84 D.83744 ] [84]))) + (set (mem:BLK (reg/f:DI 5 di [orig:84 D.83744 ] [84]) [0 A8]) + (const_int 0 [0x0])) + (use (reg:DI 0 ax [87])) + (use (reg:DI 2 cx [91])) + ]) 854 {*rep_stosdi_rex64} (nil) + #endif + + const rtx src1_rcx = gen_rtx_REG(DImode, $src1_rcx->r); + const rtx src1_rax = gen_rtx_REG(DImode, $src1_rax->r); + const rtx src1_rdi = gen_rtx_REG(DImode, $src1_rdi->r); + const rtx dst_rdi = $dst_rdi->spilled + ? gen_rtx_MEM(DImode, $dst_rdi->rtl) + : gen_rtx_REG(DImode, $dst_rdi->r); + + const rtx three = gen_rtx_CONST_INT(DImode, 3); + const rtx rax = gen_rtx_REG(DImode, REG_RAX); + const rtx rdi = gen_rtx_REG(DImode, REG_RDI); + const rtx rcx = gen_rtx_REG(DImode, REG_RCX); + + icg_emit_plain(gen_rtx_SET(VOIDmode, rcx, src1_rcx)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rax, src1_rax)); + icg_emit_plain(gen_rtx_SET(VOIDmode, rdi, src1_rdi)); + icg_emit_plain(gen_rtx_PARALLEL(VOIDmode, + gen_rtvec(5, + gen_rtx_SET(VOIDmode, rcx, gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_SET(VOIDmode, rdi, gen_rtx_PLUS(DImode, gen_rtx_ASHIFT(DImode, rcx, three), rdi)), + gen_rtx_SET(VOIDmode, gen_rtx_MEM(BLKmode, rdi), gen_rtx_CONST_INT(DImode, 0)), + gen_rtx_USE(VOIDmode, rax), /* must be 1st use */ + gen_rtx_USE(VOIDmode, rcx) /* must be 2nd use */ + ) + )); + icg_emit_plain(gen_rtx_SET(VOIDmode, dst_rdi, rdi)); + } + ; +""") diff --git a/iburg/briggs/icg-graph.c b/iburg/briggs/icg-graph.c new file mode 100644 index 00000000000..7b609fac270 --- /dev/null +++ b/iburg/briggs/icg-graph.c @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "sparseset.h" +#include "tree-pass.h" +#include "hard-reg-set.h" +#include "flags.h" + +#include "icg.h" + +#define forall(i, s) EXECUTE_IF_SET_IN_SPARSESET(s, i) + +#define add_copy_edges(dst, src, live) add_copy_interferences(add_edges, dst, src, live) + + +/* + * An exercise for the future is to eliminate + * adjacency vectors for the machine registers, + * saving plenty of space. + * + * This does all the work of building the interference graph + * and coalescing. Initially, we fill in the bit matrix and + * accumulate the total degree for each live range. Then we + * iterate. At the beginning of each iteration, we allocate + * adjacency vectors, then fill them in. Then we attempt to + * coalesce copies. When no more coalesces are possible, + * the iteration terminates and the bit matrix is freed. + * The adjacenct vectors are preserved for use during coloring. + * + * When coalesces succeed, we must update the bit matrix and + * the degrees of the various live ranges, being careful so + * that when we next allocate adjacency vectors, they will be + * of the correct length. + * + * We keep track of coalesces via a union-find tree. + * + */ + +static +char *bit_matrix = 0; + +icg_reg_info *icg_reg_vector = 0; + +static +void allocate_bit_matrix(unsigned regs) +{ + unsigned i; + unsigned size = (regs*regs + 15) >> 4; + bit_matrix = (char *) xcalloc(size, sizeof(char)); + for (i = 0; i < regs; i++) + icg_reg_vector[i].degree = 0; +} + + +static +void clear_graph(unsigned regs) +{ + unsigned size = (regs*regs + 15) >> 4; + memset(bit_matrix, 0, size); +} + + + +static +void allocate_adjacency_vectors(unsigned regs) +{ + unsigned i; + for (i = 0; i < regs; i++) + { + if (icg_reg_vector[i].root == i) + { + unsigned degree = icg_reg_vector[i].degree; + size_t size = sizeof(icg_names) + (degree - 1)*sizeof(unsigned); + icg_names *av = (icg_names *)obstack_alloc(&icg_graph_obstack, size); + av->next = NULL; + av->size = 0; + icg_reg_vector[i].av = av; + } + else + icg_reg_vector[i].av = NULL; + } +} + + +unsigned icg_path_compress(unsigned r) +{ + unsigned root; + root = icg_reg_vector[r].root; + if (root != r) + { + root = icg_path_compress(root); + icg_reg_vector[r].root = root; + } + return root; +} + + +#define find(r) (icg_reg_vector[r].root) + + +static +void compress_all(unsigned regs) { + unsigned r; + for (r = 0; r < regs; r++) + { + unsigned root = icg_reg_vector[r].root; + if (root < r) + icg_reg_vector[r].root = find(root); + } +} + + +static +void add_addr(sparseset live, icg_node *addr) +{ + if (addr->a.base_valid) { + sparseset_set_bit(live, find(addr->a.base)); + } + if (addr->a.scale > 0) { + sparseset_set_bit(live, find(addr->a.index)); + } +} + + + +/* this needs to be fast, hence the twiddly hand optimizations */ + +static +void add_edges_to_bit_matrix(unsigned r, sparseset live) +{ + unsigned x; + icg_reg_info *rv = icg_reg_vector; /* these are all loop invariant, but */ + unsigned rr = r*r; /* will (probably) be missed by compiler. */ + unsigned rd = rv[r].degree; + int rk = rv[r].kind; + char *bm = bit_matrix; + unsigned bogus_lastx = ~0x0 - 1; + unsigned lastx = bogus_lastx; + bool in_run = false; + if (dump_file) fprintf(dump_file, "%3d {", r); + forall(x, live) + { + if (x != r && (rk & rv[x].kind)) + { + unsigned index = (x < r) ? (x + rr/2) : (r + x*x/2); + unsigned bit_index = index & 7; + unsigned byte_index = index >> 3; + unsigned mask = 1 << bit_index; + unsigned byte = bm[byte_index]; + if (!(byte & mask)) + { + bm[byte_index] = byte | mask; + rv[x].degree++; + rd++; + } + if (dump_file) + { + if (!in_run) { + fprintf(dump_file, "%3d", x); + in_run = true; + } else { + if (lastx + 1 != x) { + fprintf(dump_file, "-%3d ", lastx); + fprintf(dump_file, "%3d", x); + in_run = true; + } + } + lastx = x; + } + } + } + rv[r].degree = rd; + if (dump_file) { + if (in_run) { + fprintf(dump_file, "-%3d ", lastx); + } + fprintf(dump_file, " }\n"); + } +} + + +/* same here */ + +static +void add_edges_to_graph(unsigned r, sparseset live) +{ + unsigned x; + icg_reg_info *rv = icg_reg_vector; + unsigned rr = r*r; + unsigned rd = rv[r].av->size; + unsigned *rav = rv[r].av->name; + int rk = rv[r].kind; + char *bm = bit_matrix; + forall(x, live) + { + if (x != r && (rk & rv[x].kind)) + { + unsigned index = x < r ? x + rr/2 : r + x*x/2; + unsigned bit_index = index & 7; + unsigned byte_index = index >> 3; + unsigned mask = 1 << bit_index; + unsigned byte = bm[byte_index]; + if (!(byte & mask)) + { + bm[byte_index] = byte | mask; + rv[x].av->name[rv[x].av->size++] = r; + rav[rd++] = x; + } + } + } + rv[r].av->size = rd; +} + + +/* and here */ + +static +void add_more_edges(unsigned r, icg_names *avs) +{ + unsigned i; + icg_reg_info *rv = icg_reg_vector; + unsigned rr = r*r; + unsigned rd = rv[r].degree; + int rk = rv[r].kind; + char *bm = bit_matrix; + unsigned size = avs->size; + for (i = 0; i < size; i++) + { + unsigned x = icg_path_compress(avs->name[i]); + if (r != x && (rk & rv[x].kind)) + { + unsigned index = x < r ? x + rr/2 : r + x*x/2; + unsigned bit_index = index & 7; + unsigned byte_index = index >> 3; + unsigned mask = 1 << bit_index; + unsigned byte = bm[byte_index]; + if (!(byte & mask)) + { + bit_matrix[byte_index] = byte | mask; + rd++; + } + } + } + rv[r].degree = rd; +} + + + +static +unsigned interfere(unsigned i, unsigned j) +{ + /* assert i < j */ + unsigned index = i + j*j/2; + unsigned bit_index = index & 7; + unsigned byte_index = index >> 3; + unsigned mask = 1 << bit_index; + return bit_matrix[byte_index] & mask; +} + + +static +unsigned attempt_coalesce(unsigned pass, const unsigned original_x, const unsigned original_y) +{ + icg_names *avs; + unsigned father, son; + const unsigned x = icg_path_compress(original_x); + const unsigned y = icg_path_compress(original_y); + if (x == y) + return 0; + if (x < y) + { + father = x; + son = y; + } + else + { + father = y; + son = x; + } + if (pass == 0 && father < FIRST_PSEUDO_REGISTER) + return 0; + if (interfere(father, son)) + return 0; + icg_reg_vector[son].root = father; + avs = icg_reg_vector[son].av; + while (avs) { + icg_names *next = avs->next; + add_more_edges(father, avs); + avs->next = icg_reg_vector[father].av; + icg_reg_vector[father].av = avs; + avs = next; + } + if (dump_file) fprintf(dump_file, "coalesced %3d and %3d\n", father, son); + return 1; +} + + +static +unsigned reduce_coalesce(icg_node *p, NT goalNT, unsigned pass) +{ + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + unsigned i; + unsigned coalesces = 0; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + coalesces += reduce_coalesce(kid[i], nts[i], pass); + switch (rule) + { +#include "icg-coalesce.cases" + } + return coalesces; +} + + +static +unsigned coalesce(unsigned pass) +{ + unsigned coalesces = 0; + basic_block bb; + unsigned r; + + /*** checking to be sure degree and size match at this point + for (r = 0; r < icg_interior_regs; r++) + if (icg_reg_vector[r].root == r) + if (icg_reg_vector[r].degree < icg_reg_vector[r].av->size) + fprintf(stderr, "r = %d, degree %d, size %d\n", r, + icg_reg_vector[r].degree, + icg_reg_vector[r].av->size); + ***/ + + if (dump_file) fprintf(dump_file, "\n" "starting coalesce(%d)\n", pass); + FOR_EACH_BB(bb) + { + rtx insn; + FOR_BB_INSNS(bb, insn) + { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) + coalesces += reduce_coalesce(tree, 1, pass); + } + } + if (dump_file) { + fprintf(dump_file, "\n"); + fprintf(dump_file, "found %3d coalesces\n", coalesces); + } + if (coalesces == 0) + for (r = 0; r < icg_interior_regs; r++) + if (icg_reg_vector[r].root == r) + icg_reg_vector[r].degree = icg_reg_vector[r].av->size; + return coalesces; +} + + + + +static +void handle_call_kills(void (*add_edges)(unsigned, sparseset), sparseset live) +{ + unsigned r; + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + if (TEST_HARD_REG_BIT(regs_invalidated_by_call, r)) + { + sparseset_clear_bit(live, r); + add_edges(r, live); + } +} + + +static +void add_copy_interferences(void (*add_edges)(unsigned, sparseset), + const unsigned original_dst, const unsigned original_src, sparseset live) +{ + unsigned dst = find(original_dst); + unsigned src = find(original_src); + if (src != dst) + { + sparseset_clear_bit(live, dst); + sparseset_clear_bit(live, src); + add_edges(dst, live); + } + sparseset_set_bit(live, src); +} + + +static +sparseset reduce_build(icg_node *p, NT goalNT, + void (*add_edges)(unsigned, sparseset), sparseset live) +{ + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + + icg_burm_kids(p, rule, kid); + switch (rule) { +#include "icg-build.cases" + } + /* + * The visit permutation is only valid for non-chain rules with >= 2 nonterminals + */ + if (nts[0] && nts[1] && p->perm_kids >= 2) { + int i; + for (i = p->perm_kids - 1; i >= 0; i--) { + const int k = p->perm[i]; + live = reduce_build(kid[k], nts[k], add_edges, live); + } + } + else { + int i; + for (i = 0; nts[i]; i++) { + live = reduce_build(kid[i], nts[i], add_edges, live); + } + } + return live; +} + + +static +void init_from_live_out(basic_block bb, sparseset live) +{ + unsigned *live_out = icg_lr_liveout[bb->index]->name; + unsigned n = icg_lr_liveout[bb->index]->size; + unsigned i; + + sparseset_clear(live); + for (i = 0; i < n; i++) + sparseset_set_bit(live, find(live_out[i])); + if (!frame_pointer_needed) + sparseset_clear_bit(live, 6); + + if (dump_file) + { + fprintf(dump_file, "\n" "live-out = { "); + for (i = 0; i < icg_live_ranges; i++) + if (sparseset_bit_p(live, i)) + fprintf(dump_file, "%d ", i); + fprintf(dump_file, "}\n"); + } +} + + +static +void build(const char *what, void (*add_edges)(unsigned, sparseset)) +{ + unsigned r; + basic_block bb; + sparseset live = sparseset_alloc(icg_interior_regs); + compress_all(icg_interior_regs); + + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + icg_reg_vector[r].kind = ~0; + + /* set interferences based on kind */ + for (r = 0; r < 8; r++) /* ax, dx, cx, bx, si, di, bp, sp */ + icg_reg_vector[r].kind &= ~INT_REGISTER; + for (r = 21; r < 29; r++) /* xmm0-xmm7 */ + icg_reg_vector[r].kind &= ~FLOAT_REGISTER; + for (r = 37; r < 45; r++) /* r8-r15 */ + icg_reg_vector[r].kind &= ~INT_REGISTER; + for (r = 45; r < 53; r++) /* xmm8-xmm15 */ + icg_reg_vector[r].kind &= ~FLOAT_REGISTER; + + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + sparseset_set_bit(live, r); + for (r = FIRST_PSEUDO_REGISTER; r < icg_interior_regs; r++) + if (icg_reg_vector[r].root == r) + add_edges(r, live); + + /* make machine regs interfere with each other */ + for (r = 0; r < 8; r++) /* ax, dx, cx, si, di, bp, sp */ + icg_reg_vector[r].kind = INT_REGISTER; + for (r = 21; r < 29; r++) /* xmm0-xmm7 */ + icg_reg_vector[r].kind = FLOAT_REGISTER; + for (r = 37; r < 45; r++) /* r8-r15 */ + icg_reg_vector[r].kind = INT_REGISTER; + for (r = 45; r < 53; r++) /* xmm8-xmm15 */ + icg_reg_vector[r].kind = FLOAT_REGISTER; + + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + add_edges(r, live); + + { + char buf[BUFSIZ]; + snprintf(buf, sizeof(buf), "build %s", what); + icg_debug(buf); + } + FOR_EACH_BB(bb) + { + rtx insn; + init_from_live_out(bb, live); + FOR_BB_INSNS_REVERSE(bb, insn) + { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) + live = reduce_build(tree, 1, add_edges, live); + } + } + sparseset_free(live); +} + +static +int sort_icg_unsigneds(const void *vp0, const void *vp1) +{ + const unsigned *p0 = (const unsigned *)(vp0); + const unsigned *p1 = (const unsigned *)(vp1); + return *p0 - *p1; +} + +/* + * print vector vp to file fp, ending with a new line + */ +void icg_print_runs(FILE *fp, const unsigned *vp, size_t size) +{ + unsigned i; + size_t runlg = 0; + unsigned bogus_lastx = ~0x0 - 1; + unsigned lastx = bogus_lastx; + + /* + * make a copy of the incoming vector so we can sort it + */ + unsigned *p = (unsigned *)icg_alloc(sizeof(vp[0])*size); + for (i = 0; i < size; i++) { + p[i] = vp[i]; + } + qsort(p, size, sizeof(p[0]), sort_icg_unsigneds); + + fprintf(fp, "(%3d)", size); + for (i = 0; i < size; i++) { + const unsigned x = p[i]; + if (runlg == 0) { + fprintf(fp, "%3d", x); + runlg = 1; + } else { + if (lastx + 1 != x) { + if (runlg > 1){ + fprintf(fp, "-%3d ", lastx); + } + fprintf(fp, "%3d", x); + runlg = 1; + } else { + runlg += 1; + } + } + lastx = x; + } + if (runlg > 1) { + fprintf(fp, "-%3d ", lastx); + } + fprintf(fp, "\n"); +} + +static +void print_icg_names(FILE* fp, const icg_names *av) +{ + if (fp == 0) { + return; + } + for (; av; av = av->next) { + icg_print_runs(fp, av->name, av->size); + } +} + + +static +void dump_ig(void) +{ + unsigned r; + fprintf(dump_file, "live ranges\n"); + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) + { + fprintf(dump_file, "%3d", r); + if (icg_reg_vector[r].root == r) + { + icg_names *av = icg_reg_vector[r].av; + fprintf(dump_file, ", degree = %3d, interferes with:\n", + icg_reg_vector[r].degree); + print_icg_names(dump_file, av); + + } + else + { + fprintf(dump_file, " coalesced with %3d\n", icg_reg_vector[r].root); + } + } + + fprintf(dump_file, "interior registers\n"); + for (r = icg_live_ranges; r < icg_interior_regs; r++) + { + fprintf(dump_file, "%3d", r); + if (icg_reg_vector[r].root == r) + { + icg_names *av = icg_reg_vector[r].av; + fprintf(dump_file, ", degree = %3d, interferes with:\n", + icg_reg_vector[r].degree); + print_icg_names(dump_file, av); + } + else + { + fprintf(dump_file, " coalesced with %3d\n", icg_reg_vector[r].root); + } + } +} + + +void icg_graph(unsigned pass) +{ + int icg_graph_pass_number = 0; + void *local_mark = obstack_alloc(&icg_graph_obstack, 0); + allocate_bit_matrix(icg_interior_regs); + if (dump_file) fprintf(dump_file, "\n" "building bit matrix\n"); + build("add_edges_to_bit_matrix", add_edges_to_bit_matrix); + for (icg_graph_pass_number = 0; 1; icg_graph_pass_number += 1) { + obstack_free(&icg_graph_obstack, local_mark); + allocate_adjacency_vectors(icg_interior_regs); + clear_graph(icg_interior_regs); + if (dump_file) fprintf(dump_file, "\n" "building adj vectors\n"); + build("add_edges_to_graph", add_edges_to_graph); + if (dump_file) dump_ig(); + if (!coalesce(pass)) { + break; + } + } + free(bit_matrix); +} diff --git a/iburg/briggs/icg-names.c b/iburg/briggs/icg-names.c new file mode 100644 index 00000000000..2d95f42e824 --- /dev/null +++ b/iburg/briggs/icg-names.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" + +#include "icg.h" + +unsigned icg_interior_regs = 0; +static +void hook_names(void) __attribute__((noinline)); + +static +void hook_names(void) +{ +} + +static +int new_reg(void) { + return icg_interior_regs++; +} + + +static +void reduce_names(icg_node *p, NT goalNT) { + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + p->goalNT = goalNT; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) { + reduce_names(kid[i], nts[i]); + } + if (i >= 2) { + /* + * Do NOT clobber p->perm_kids unless this is really a node with a non trivial cover + * Subsequent icg passes will only consult p->perm_kids if nts[0] && nts[1] + * for doing permutations. + */ + p->perm_kids = i; /* mark number of non-chainrule kids */ + for (i = 0; nts[i]; i++) { + p->perm[i] = i; /* set up initial 1:1 permutation */ + } + } + switch (rule) { +#include "icg-names.cases" + } +} + + +static +void reduce_kinds(icg_node *p, NT goalNT) { + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + p->goalNT = goalNT; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + reduce_kinds(kid[i], nts[i]); + switch (rule) { +#include "icg-kinds.cases" + } +} + + +void icg_find_names(void) +{ + basic_block bb; + unsigned r; + icg_interior_regs = icg_live_ranges; + FOR_EACH_BB(bb) + { + rtx insn; + FOR_BB_INSNS(bb, insn) + { + int id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + reduce_names(tree, burm_goal_NT); + } + } + } + + icg_reg_vector = (icg_reg_info *)obstack_alloc(&icg_graph_obstack, icg_interior_regs*sizeof(icg_reg_info)); + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + icg_reg_vector[r].kind = 0; + for (r = FIRST_PSEUDO_REGISTER; r < icg_interior_regs; r++) + icg_reg_vector[r].kind = ~1; + for (r = 0; r < icg_interior_regs; r++) + icg_reg_vector[r].root = r; + + if (dump_file) + { + fprintf(dump_file, "\n"); + fprintf(dump_file, "first = %4d\n", FIRST_PSEUDO_REGISTER); + fprintf(dump_file, "live ranges = %4d\n", icg_live_ranges); + fprintf(dump_file, "interior = %4d\n", icg_interior_regs); + } + + FOR_EACH_BB(bb) + { + rtx insn; + FOR_BB_INSNS(bb, insn) + { + int id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) + reduce_kinds(tree, 1); + } + } + + for (r = FIRST_PSEUDO_REGISTER; r < icg_interior_regs; r++) { + if (icg_reg_vector[r].kind == ~((unsigned)1)) { + icg_reg_vector[r].root = 0; + } + } +} diff --git a/iburg/briggs/icg-reassociate.c b/iburg/briggs/icg-reassociate.c new file mode 100644 index 00000000000..58f2a9ea4da --- /dev/null +++ b/iburg/briggs/icg-reassociate.c @@ -0,0 +1,618 @@ +/* Perform re-association according to extended Sethi-Ullmann + numbering for every real INSN, for GNU compiler. + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include "obstack.h" +#include "icg-opcode.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "df.h" +#include "icg.h" + + +#define REASSOC_DEBUG false +#define ASSOC_OP_PLUS(OP) ((OP >= PLUS_DI) && (OP <= PLUS_SF)) +#define ASSOC_OP_MULT(OP) ((OP >= MULT_DI) && (OP <= MULT_SF)) +#define ASSOC_OP(OP) (ASSOC_OP_PLUS(OP) || ASSOC_OP_MULT(OP)) +#define ICG_REG_REG(OP) ((OP >= REG_DI) && (OP<=REG_SF)) +#define ICG_REG_REGX(OP) ((OP >= REGX_DI) && (OP<=REGX_SF)) +#define ICG_REG(OP) ((OP>=REG_DI) && (OP<=REGX_SF)) + + +/* Code to reassociate expressions in a tree based on the Extended + * Sethi-Ullman numbering. A node in the expression tree is associative + * if it is a part of an associative expression (+,*). A node in the + * expression tree is said to be the root of an associative tree if + * it is associative and starts a new associative expression. + */ + +/* This data structure stores the associative information for a + * node in the expression tree. + */ + +typedef struct _icg_su_reassoc +{ + /* This is the id of a icg_node which is its dfs number + * in the original expression tree + */ + unsigned dfs_number; + + /* Which rtl expr does this node belong to ? */ + icg_node *which_expr; + + /* Who was its original parent ? */ + icg_node *orig_parent; + unsigned orig_parent_dfs; + + /* Who is its associative parent, if any ? */ + icg_node*assoc_parent; + unsigned assoc_parent_dfs; + + /* + * Pointers to all its associative operators, + * defined only for roots of the assoc tree. This + * is used while rewiring the expressions. + */ + unsigned int *expr_children; + unsigned int *orig_expr_children; + unsigned int num_expr_children; + + /* + * Pointers to all its associative children, + * only for root of the assoc tree. Used to determine + * the new order of evaluation of expressions. + */ + unsigned int *assoc_children; + unsigned int *orig_assoc_children; + /* Integer to point to number of associative children. */ + unsigned num_assoc_children; + + /* Is it associative ? - Yes, if it belongs to an associative tree. */ + bool is_associative; + + /* Is it the associative root ? - Yes, if it starts an associative tree. */ + bool is_associative_root; + + /* This flag is set if a new associative order is formed. */ + bool association_changed; + + /* SU-pair values for this node */ + unsigned su_extra; + unsigned su_freed; +}icg_su_reassoc; + +static long long num_icg_expr=0; +static icg_su_reassoc *su_reassoc; + +static int +dump_icg_construct(void) +{ + unsigned i=1; + if(!dump_file) + return 0; + fprintf(dump_file, "\n" "Dumping icg_construct\n"); + fprintf(dump_file, "num_icg_expr=%lld\n", num_icg_expr); + for(i=1;i<num_icg_expr+1;i++) + { + fprintf(dump_file, "%u : %u,%u,%u,%d\n", i, su_reassoc[i].dfs_number, + su_reassoc[i].orig_parent_dfs, su_reassoc[i].assoc_parent_dfs, + su_reassoc[i].which_expr->op); + if(su_reassoc[i].is_associative_root) + { + unsigned int j; + fprintf(dump_file, "Root : "); + for(j=0;j<su_reassoc[i].num_assoc_children;j++) + { + unsigned k = su_reassoc[i].assoc_children[j]; + fprintf(dump_file, "(%u,%u,%u,%d) ", su_reassoc[k].dfs_number, + su_reassoc[k].orig_parent_dfs, su_reassoc[k].assoc_parent_dfs, + su_reassoc[k].which_expr->op); + + } + fprintf(dump_file, "\n"); + fprintf(dump_file, "assoc_children : ["); + for(j=0;j<su_reassoc[i].num_assoc_children;j++) + { + fprintf(dump_file, "(%u,%u) ", su_reassoc[i].assoc_children[j], + su_reassoc[i].orig_assoc_children[j]); + } + fprintf(dump_file, " ]\n"); + } + } + fprintf(dump_file, "\n" "End of Dumping icg_construct\n"); + return 0; +} + +/* This function counts the number of nodes in a expression tree. + */ +static long long +count_occurrences_of_icg_expr(icg_node *node) +{ + long long count=1; + if(node->left) { + count += count_occurrences_of_icg_expr(node->left); + } + if(node->right) { + count += count_occurrences_of_icg_expr(node->right); + } + return count; +} + +/* Rewiring of the expressions based on reassociation is done here. + */ +static bool +su_reconstruct_expr_tree(icg_su_reassoc *assoc_root) +{ + unsigned i, j; + unsigned *assoc_children = assoc_root->assoc_children; + unsigned num_assoc_children = assoc_root->num_assoc_children; + + unsigned *expr_children = assoc_root->expr_children; + unsigned num_expr_children = assoc_root->num_expr_children; + icg_node *expr_src = 0; + + if ((num_expr_children + 1)!= (num_assoc_children-1)) { + fprintf(dump_file, "\n" "Inconsistency between expr and children. ABORT!\n"); + exit(0); + } + + /* Rewire the operators and operands */ + expr_src=assoc_root->which_expr; + expr_src->right = + su_reassoc[assoc_children[num_assoc_children-1]].which_expr; + /* Rewire the operators first */ + for(i=0;i<num_expr_children;i++) { + icg_node *expr_dest=su_reassoc[expr_children[i]].which_expr; + expr_src->left=expr_dest; + expr_src=expr_dest; + } + /* Wire the operands now */ + expr_src->left=su_reassoc[assoc_children[0]].which_expr; + for(i=1, j=num_expr_children-1;i<=num_assoc_children-2;i++, j--) { + expr_src=su_reassoc[expr_children[j]].which_expr; + expr_src->right=su_reassoc[assoc_children[i]].which_expr; + } + return true; +} + +/* The new order of expressions based on (extra,freed) tuple is + * determined here. + */ +static bool +su_reassociate_expressions(icg_su_reassoc *assoc_root) +{ + unsigned i=0, j=0; + unsigned *assoc_children = assoc_root->assoc_children; + unsigned num_assoc_children = assoc_root->num_assoc_children; + if(num_assoc_children <= 2) return false; + /* Sort O(n^2) on extra in ascending order resolving ties through + * freed in descending + */ + for(i = 0;i < (num_assoc_children - 1); i++) { + icg_su_reassoc *ptr1 = &su_reassoc[assoc_children[i]]; + for(j = i + 1;j < num_assoc_children;j++) { + icg_su_reassoc *ptr2 = &su_reassoc[assoc_children[j]]; + if((ptr1->su_extra > ptr2->su_extra) || + ((ptr1->su_extra == ptr2->su_extra) && + (ptr1->su_freed < ptr2->su_freed))) { + unsigned tmp = assoc_children[i]; + assoc_children[i] = assoc_children[j]; + assoc_children[j]=tmp; + ptr1=ptr2; + } + } + } + /* Now, do placement, refer to wiki */ + for(i=(num_assoc_children -1) ;i>=1;i--) { + for(j=0;j<i;j++) { + icg_su_reassoc *ptr=&su_reassoc[assoc_children[j]]; + if(ptr->su_freed > 0) break; + } + if(j==i) { + unsigned tmp=assoc_children[i]; + assoc_children[i]=assoc_children[0]; + assoc_children[0]=tmp; + break; + } + } + su_reconstruct_expr_tree(assoc_root); + return true; +} + +static unsigned +for_each_icg_assoc_construct(icg_node *icg_expr, unsigned parent_dfs_number) +{ + /* Structures to hold su_pairs of children*/ + struct _su_pair_ + { + unsigned su_extra; + unsigned su_freed; + } su_pair_kids[2]; + struct _su_pair_ *left_val, *right_val; + unsigned cost_left, cost_right; + unsigned num_kids=0, child_dfs=0; + + static unsigned dfs_number=0; + unsigned this_dfs_number; + icg_su_reassoc *this_ptr=NULL; + + gcc_assert(icg_expr!=NULL); + + /* parent_dfs_number == 0 implies it is the root of the expression + * tree. + */ + if(parent_dfs_number==0) + { + dfs_number=0; + parent_dfs_number=1; + } + + dfs_number++; + this_dfs_number=dfs_number; + + /* + * The id of a node is its dfs number in the original tree, id may not + * match the dfs number if reassociation happens + */ + this_ptr=&su_reassoc[this_dfs_number]; + icg_expr->id=this_dfs_number; + + this_ptr->which_expr=icg_expr; + this_ptr->orig_parent= + su_reassoc[parent_dfs_number].which_expr; + this_ptr->orig_parent_dfs=parent_dfs_number; + this_ptr->dfs_number=this_dfs_number; + this_ptr->assoc_children=this_ptr->expr_children=NULL; + this_ptr->orig_assoc_children=this_ptr->orig_expr_children=NULL; + this_ptr->num_expr_children=this_ptr->num_assoc_children=0; + this_ptr->su_extra=this_ptr->su_freed=0; + + /* Normally, I am my own associative parent & I dont belong + * to any associative tree + */ + this_ptr->assoc_parent=icg_expr; + this_ptr->assoc_parent_dfs=this_dfs_number; + this_ptr->is_associative=false; + this_ptr->is_associative_root=false; + + /* Find associative children and roots of associative trees */ + if(ASSOC_OP(icg_expr->op)) { + this_ptr->is_associative=true; + if(this_dfs_number == parent_dfs_number) { + /* This is the root of the expression tree */ + this_ptr->is_associative_root=true; + } + else { + /* If the opcode of this node does not match the opcode of its + * parent it is an associative root. + */ + if(icg_expr->op!=this_ptr->orig_parent->op) + this_ptr->is_associative_root=true; + } + } + + /* Update associative parents which are roots of the associative + * tree + */ + if((this_dfs_number != parent_dfs_number) && + su_reassoc[parent_dfs_number].is_associative) { + if(su_reassoc[parent_dfs_number].is_associative_root) { + this_ptr->assoc_parent=this_ptr->orig_parent; + this_ptr->assoc_parent_dfs=parent_dfs_number; + } + else { + this_ptr->assoc_parent=su_reassoc[parent_dfs_number].assoc_parent; + this_ptr->assoc_parent_dfs=su_reassoc[parent_dfs_number].assoc_parent_dfs; + } + } + + /* Populate the expr_children (addresses of operators) of the + * associative root node. These will be later used when rewiring + * the operands. + */ + if(this_ptr->is_associative && !this_ptr->is_associative_root) { + /* Add this as an expr child.*/ + unsigned int assoc_parent_dfs=this_ptr->assoc_parent_dfs; + unsigned int *expr_children= + su_reassoc[assoc_parent_dfs].expr_children; + unsigned int *orig_expr_children= + su_reassoc[assoc_parent_dfs].orig_expr_children; + unsigned int *num_expr_children = NULL; + if(expr_children==NULL) { + expr_children=(unsigned *)icg_calloc((num_icg_expr+1) * + sizeof(unsigned)); + orig_expr_children=(unsigned *)icg_calloc((num_icg_expr+1) * + sizeof(unsigned)); + su_reassoc[assoc_parent_dfs].expr_children=expr_children; + su_reassoc[assoc_parent_dfs].orig_expr_children=orig_expr_children; + } + num_expr_children = &su_reassoc[assoc_parent_dfs].num_expr_children; + expr_children[*num_expr_children]=this_dfs_number; + orig_expr_children[*num_expr_children]=this_dfs_number; + (*num_expr_children)++; + } + + /* Populate the assoc_children of the associative_root parent node + * if necessary + */ + if(su_reassoc[parent_dfs_number].is_associative && + (!this_ptr->is_associative || this_ptr->is_associative_root)) { + unsigned int *num_assoc_children=NULL; + /* Add yourself as an assoc child to your associative parent */ + unsigned int assoc_parent_dfs=this_ptr->assoc_parent_dfs; + unsigned int *assoc_children= + su_reassoc[assoc_parent_dfs].assoc_children; + unsigned int *orig_assoc_children= + su_reassoc[assoc_parent_dfs].orig_assoc_children; + if(assoc_children==NULL) { + assoc_children=(unsigned *)icg_calloc((num_icg_expr+1) * + sizeof(unsigned)); + orig_assoc_children=(unsigned *)icg_calloc((num_icg_expr+1) * + sizeof(unsigned)); + su_reassoc[assoc_parent_dfs].assoc_children=assoc_children; + su_reassoc[assoc_parent_dfs].orig_assoc_children=orig_assoc_children; + } + num_assoc_children= &su_reassoc[assoc_parent_dfs].num_assoc_children; + assoc_children[*num_assoc_children]=this_dfs_number; + orig_assoc_children[*num_assoc_children]=this_dfs_number; + (*num_assoc_children)++; + } + + /* Recurse on the left and right children */ + if(icg_expr->left) { + child_dfs=for_each_icg_assoc_construct(icg_expr->left, this_dfs_number); + su_pair_kids[0].su_extra=su_reassoc[child_dfs].su_extra; + su_pair_kids[0].su_freed=su_reassoc[child_dfs].su_freed; + num_kids++; + } + if(icg_expr->right){ + child_dfs=for_each_icg_assoc_construct(icg_expr->right, this_dfs_number); + su_pair_kids[1].su_extra=su_reassoc[child_dfs].su_extra; + su_pair_kids[1].su_freed=su_reassoc[child_dfs].su_freed; + num_kids++; + } + if(num_kids == 0) { /* This is a leaf */ + /* If this is a register that need not be preserved + * then set free to be 1. + */ + if(ICG_REG_REGX(icg_expr->op)) { + this_ptr->su_freed = 1; + } + else if(this_dfs_number == (parent_dfs_number + 1)) { + /* This is a left child of its parent */ + this_ptr->su_extra = 1; + } + } + else if(num_kids == 1) { + /* Simply propogate it upward after adjusting r-node*/ + left_val=&su_pair_kids[0]; + /* Adjust r-node to be (1, 0) */ + if(left_val->su_extra==0 && left_val->su_freed==0) + left_val->su_extra=1; + this_ptr->su_extra=left_val->su_extra; + this_ptr->su_freed=left_val->su_freed; + } + else if(num_kids == 2) { + /* Use Preston's algorithm in the wiki */ + left_val=&su_pair_kids[0]; + right_val=&su_pair_kids[1]; + /* Adjust r-node to be (1, 0) */ + if(left_val->su_extra==0 && left_val->su_freed==0) + left_val->su_extra=1; + cost_left = + (left_val->su_extra + left_val->su_freed) >right_val->su_extra ? + left_val->su_extra : + (right_val->su_extra -left_val->su_freed + 1); + cost_right = + (right_val->su_extra + right_val->su_freed) > left_val->su_extra ? + right_val->su_extra : + (left_val->su_extra -right_val->su_freed + 1); + this_ptr->su_extra = (cost_left <= cost_right)?cost_left : cost_right; + this_ptr->su_freed = left_val->su_freed + right_val->su_freed; + } + if(this_ptr->is_associative_root) { + this_ptr->association_changed = + su_reassociate_expressions(this_ptr); + } + return this_dfs_number; +} + +static int icg_assoc_tree_construct(icg_node *curr_node) +{ + if(dump_file && REASSOC_DEBUG) { + fprintf(dump_file,"\n" "Before ReAssociation ---> \n"); + print_icg_tree (dump_file, curr_node, "\n" "icg_expr :"); + } + num_icg_expr=count_occurrences_of_icg_expr(curr_node); + su_reassoc=(icg_su_reassoc *)(icg_calloc) + ((num_icg_expr+1)*sizeof(icg_su_reassoc)); + for_each_icg_assoc_construct(curr_node, 0); + if(dump_file && REASSOC_DEBUG) + dump_icg_construct(); + return 0; +} + +static void print_dot(FILE *dotfile, rtx curr_insn); + +void icg_reassociate(void) +{ + basic_block bb; + rtx curr_insn; + static int callnum=0; + char dotfile_name[100]; + FILE *dotfile; + + /* To turn on icg_reassociate do "touch reassociate" */ + char *do_reassociate = getenv("ICG_REASSOC"); + if(do_reassociate) { + if(strcmp(do_reassociate,"true") !=0 ) { + return; + } + } + else { + return; + } + + if(dump_file) + fprintf(dump_file,"Turning on reassociation \n"); + if(REASSOC_DEBUG) + fprintf(stderr,"Turning on reassociation \n"); + + sprintf(dotfile_name,"icg_assoc_%d.dot",callnum); + + dotfile=fopen(dotfile_name, "w"); + callnum++; + if(dump_file && REASSOC_DEBUG) + fprintf(dump_file, "\n\n" "ReAssociation Starts\n\n"); + + FOR_EACH_BB(bb) + { + FOR_BB_INSNS(bb, curr_insn) + { + if(!INSN_P(curr_insn)) + continue; + if (!icg_insn2dirty[INSN_UID(curr_insn)]) + continue; + + if(dump_file && REASSOC_DEBUG) { + fprintf(dump_file, "\n" "****************Source file, line : %s, %d\n", + insn_file(curr_insn), insn_line(curr_insn)); + print_inline_rtx(dump_file, PATTERN(curr_insn), 2); + } + icg_assoc_tree_construct(icg_insn2tree[INSN_UID(curr_insn)]); + if(dump_file && REASSOC_DEBUG) { + fprintf(dump_file, "\n" "After Reassociation ---> \n"); + print_icg_tree (dump_file, icg_insn2tree[INSN_UID(curr_insn)] , "\n" "icg_expr :"); + fprintf(dump_file, "\n"); + print_dot(dotfile, curr_insn); + } + } + } + if(dump_file && REASSOC_DEBUG) { + fprintf(dump_file, "\n\n" "ReAssociation Completed\n\n"); + } + fclose(dotfile); +} + +/* Dot dumper for the associative tree */ +static int +for_each_dot_icg (FILE *dotfile, icg_node *curr_node, int parent, int isleft) +{ + /* Is 100 characters enough ?? */ + char node_string[100]; + icg_su_reassoc *this_ptr=NULL; + + if (curr_node == NULL) + return 0; + this_ptr=&su_reassoc[curr_node->id]; + if (ASSOC_OP_PLUS(curr_node->op)) + snprintf(node_string, sizeof(node_string), "PLUS"); + else if (ASSOC_OP_MULT(curr_node->op)) + snprintf(node_string, sizeof(node_string), "MULT"); + else if (ICG_REG_REG(curr_node->op)) + snprintf(node_string, sizeof(node_string), "REG : %d ", curr_node->r); + else if (ICG_REG_REGX(curr_node->op)) + snprintf(node_string, sizeof(node_string), "REGX : %d ", curr_node->rx); + else + snprintf(node_string, sizeof(node_string), "%s", get_icg_opcode_name(curr_node->op)); + + if (this_ptr->is_associative_root) { + const size_t lg = strlen(node_string); + snprintf(node_string+lg, sizeof(node_string)-lg, "(E)"); + } + + { + const size_t lg = strlen(node_string); + snprintf(node_string+lg, sizeof(node_string)-lg, " (%d,%d)(%d) [%d]", + this_ptr->su_extra, this_ptr->su_freed, + this_ptr->num_assoc_children, curr_node->id); + } + + if (this_ptr->is_associative && !this_ptr->is_associative_root) { + fprintf(dotfile, "n%d [label=\"%s\", shape=box];\n", + curr_node->id, node_string); + } + else if (this_ptr->is_associative_root && this_ptr->association_changed) { + fprintf(dotfile, "n%d [label=\"%s\", shape=invtriangle];\n", + curr_node->id, node_string); + } else { + fprintf(dotfile, "n%d [label=\"%s\"];\n", curr_node->id, node_string); + } + if (isleft < 2) { + if (isleft) { + fprintf(dotfile, "n%d -- n%d [style=bold, label=\"left\"];\n", + parent, curr_node->id); + } else { + fprintf(dotfile, "n%d -- n%d [style=bold, label=\"right\"];\n", + parent, curr_node->id); + } + } + if (curr_node->left) { + for_each_dot_icg(dotfile, curr_node->left, curr_node->id, 1); + } + if (curr_node->right) { + for_each_dot_icg(dotfile, curr_node->right, curr_node->id, 0); + } + + if (this_ptr->is_associative_root) { + unsigned int i=0; + unsigned int *expr_children=this_ptr->expr_children; + unsigned int num_expr_children=this_ptr->num_expr_children; + for(i=0;i < num_expr_children; i++) { + unsigned child_id=expr_children[i]; + fprintf(dotfile, "n%d -- n%d [stlye=dotted, color=green, label=\"%d\"];\n", + curr_node->id, child_id, i); + } + } + if (this_ptr->is_associative_root) { + unsigned int i=0; + unsigned int *assoc_children=this_ptr->assoc_children; + unsigned int *orig_assoc_children=this_ptr->orig_assoc_children; + unsigned int num_assoc_children=this_ptr->num_assoc_children; + for(i=0;i < num_assoc_children; i++) { + unsigned child_id=assoc_children[i]; + unsigned orig_child_id=orig_assoc_children[i]; + fprintf(dotfile, "n%d -- n%d [stlye=dotted, color=red, label=\"%d\"];\n", + curr_node->id, child_id, i); + if (child_id !=orig_child_id) { + fprintf(dotfile, "n%d -- n%d [stlye=dotted, color=blue, label=\"%d\"];\n", + curr_node->id, orig_child_id, i); + } + } + } + + return 0; +} + +static void print_dot(FILE *dotfile, rtx curr_insn) +{ + icg_node *curr_node = NULL; + fprintf(dotfile, "\n" "graph graph_%d {\n", INSN_UID(curr_insn)); + curr_node=icg_insn2tree[INSN_UID(curr_insn)]; + for_each_dot_icg(dotfile, curr_node, 0, 2); + fprintf(dotfile, "}\n"); +} diff --git a/iburg/briggs/icg-remat.c b/iburg/briggs/icg-remat.c new file mode 100644 index 00000000000..7f3b50a6b97 --- /dev/null +++ b/iburg/briggs/icg-remat.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "sparseset.h" +#include "tree-pass.h" +#include "flags.h" +#include "tm_p.h" + +#include "icg.h" +#include "icg-opcode.h" + + + +#define find(r) (icg_reg_vector[r].root) + +#define RHS_REMAT (1 << 0) +#define LHS_REG (1 << 1) + +static +unsigned reduce_remat(icg_node *p, NT goalNT) +{ + unsigned flags = 0; + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) { + flags |= reduce_remat(kid[i], nts[i]); + } + + switch (rule) { +#include "icg-remat.cases" + } + return flags; +} + + + +void icg_remat(void) +{ + basic_block bb; + + if (dump_file) { + fprintf(dump_file, "\n"); + fprintf(dump_file, "remat: started {\n"); + fprintf(dump_file, "remat: looking for opportunities\n"); + fprintf(dump_file, "\n"); + } + + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS_REVERSE(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + unsigned flags = reduce_remat(tree, burm_goal_NT); + if (dump_file && + (flags & (LHS_REG|RHS_REMAT)) == (LHS_REG|RHS_REMAT)) + fprintf(dump_file, " found remat possibility\n"); + } + } + } + + if (dump_file) { + fprintf(dump_file, "remat: finished}\n"); + } +} diff --git a/iburg/briggs/icg-rewrite.c b/iburg/briggs/icg-rewrite.c new file mode 100644 index 00000000000..c990f59d73b --- /dev/null +++ b/iburg/briggs/icg-rewrite.c @@ -0,0 +1,284 @@ +/* Rewrite the ICG trees as a result of constant folding + and memory update discovery + + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include "obstack.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "icg.h" +#include "icg-opcode.h" +#include "insn-constants.h" + +static +bool icg_shallow_equal(const icg_node *p, const icg_node *q) +{ + if (p == q) { + return true; + } + if (p && q) { + if (1 + && (p->op == q->op) + && (p->val == q->val) + && (p->r == q->r) + && (p->rx == q->rx) + ) { + return true; + } + } + return false; +} + +static +bool icg_deep_equal(const icg_node *p, const icg_node *q) +{ + bool eq = true; + if (p == q) { + return eq; + } + eq &= icg_shallow_equal(p, q); + if (!eq) { + return false; + } + if (p->left && q->left) { + eq &= icg_deep_equal(p->left, q->left); + } + if (!eq) { + return false; + } + if (p->right && q->right) { + eq &= icg_deep_equal(p->right, q->right); + } + return eq; +} +/* + * Rewrite P to extract a subtree deeply matching PATTERN. + * Return by reference through *RVAL the matched subtree, if any. + */ +static +icg_node *icg_update_finder1(icg_opcodes op, bool comm, + icg_node *p, const icg_node *pattern, icg_node **rval) +{ + if (p == 0) { + return p; + } + if (p->op == op) { + if (p->left && icg_deep_equal(p->left, pattern)) { + if (rval) { + *rval = p->left; /* matched portion */ + } + return p->right; /* unmatched portion */ + } + if (comm && p->right && icg_deep_equal(p->right, pattern)) { + if (rval) { + *rval = p->right; /* matched portion */ + } + return p->left; /* unmatched portion */ + } + if (p->left) { + p->left = icg_update_finder1(op, comm, p->left, pattern, rval); + } + if (p->right) { + p->right = icg_update_finder1(op, comm, p->right, pattern, rval); + } + } + return p; +} + +typedef struct _comm_op_info { + icg_opcodes mem; + icg_opcodes op; + icg_opcodes mem_op; + bool comm; +} comm_op_info; + +static const comm_op_info optable[] = { + {MEM_DI, AND_DI, MEM_AND_DI, true}, + {MEM_HI, AND_HI, MEM_AND_HI, true}, + {MEM_QI, AND_QI, MEM_AND_QI, true}, + {MEM_SI, AND_SI, MEM_AND_SI, true}, + + {MEM_DI, ASHIFTRT_DI, MEM_ASHIFTRT_DI, false}, + {MEM_HI, ASHIFTRT_HI, MEM_ASHIFTRT_HI, false}, + {MEM_QI, ASHIFTRT_QI, MEM_ASHIFTRT_QI, false}, + {MEM_SI, ASHIFTRT_SI, MEM_ASHIFTRT_SI, false}, + + {MEM_DI, ASHIFT_DI, MEM_ASHIFT_DI, false}, + {MEM_HI, ASHIFT_HI, MEM_ASHIFT_HI, false}, + {MEM_QI, ASHIFT_QI, MEM_ASHIFT_QI, false}, + {MEM_SI, ASHIFT_SI, MEM_ASHIFT_SI, false}, + + {MEM_DI, IOR_DI, MEM_IOR_DI, true}, + {MEM_HI, IOR_HI, MEM_IOR_HI, true}, + {MEM_QI, IOR_QI, MEM_IOR_QI, true}, + {MEM_SI, IOR_SI, MEM_IOR_SI, true}, + + {MEM_SI, LSHIFTRT_SI, MEM_LSHIFTRT_SI, false}, + {MEM_DI, LSHIFTRT_DI, MEM_LSHIFTRT_DI, false}, + {MEM_HI, LSHIFTRT_HI, MEM_LSHIFTRT_HI, false}, + {MEM_QI, LSHIFTRT_QI, MEM_LSHIFTRT_QI, false}, + + {MEM_DI, MINUS_DI, MEM_MINUS_DI, false}, + {MEM_HI, MINUS_HI, MEM_MINUS_HI, false}, + {MEM_QI, MINUS_QI, MEM_MINUS_QI, false}, + {MEM_SI, MINUS_SI, MEM_MINUS_SI, false}, + + {MEM_DI, NEG_DI, MEM_NEG_DI, false}, + {MEM_HI, NEG_HI, MEM_NEG_HI, false}, + {MEM_QI, NEG_QI, MEM_NEG_QI, false}, + {MEM_SI, NEG_SI, MEM_NEG_SI, false}, + + {MEM_DI, NOT_DI, MEM_NOT_DI, false}, + {MEM_HI, NOT_HI, MEM_NOT_HI, false}, + {MEM_QI, NOT_QI, MEM_NOT_QI, false}, + {MEM_SI, NOT_SI, MEM_NOT_SI, false}, + + {MEM_DI, PLUS_DI, MEM_PLUS_DI, true}, + {MEM_HI, PLUS_HI, MEM_PLUS_HI, true}, + {MEM_QI, PLUS_QI, MEM_PLUS_QI, true}, + {MEM_SI, PLUS_SI, MEM_PLUS_SI, true}, + + {MEM_DI, ROTATERT_DI, MEM_ROTATERT_DI, false}, + {MEM_HI, ROTATERT_HI, MEM_ROTATERT_HI, false}, + {MEM_QI, ROTATERT_QI, MEM_ROTATERT_QI, false}, + {MEM_SI, ROTATERT_SI, MEM_ROTATERT_SI, false}, + + {MEM_DI, ROTATE_DI, MEM_ROTATE_DI, false}, + {MEM_HI, ROTATE_HI, MEM_ROTATE_HI, false}, + {MEM_QI, ROTATE_QI, MEM_ROTATE_QI, false}, + {MEM_SI, ROTATE_SI, MEM_ROTATE_SI, false}, + + {MEM_DI, XOR_DI, MEM_XOR_DI, true}, + {MEM_HI, XOR_HI, MEM_XOR_HI, true}, + {MEM_QI, XOR_QI, MEM_XOR_QI, true}, + {MEM_SI, XOR_SI, MEM_XOR_SI, true}, +}; + +static +icg_node *icg_update_finder(icg_node *p) +{ + if (p->op == SET_ALL) { + size_t i; + if (0 + || p->left->op == MEM_DI + || p->left->op == MEM_SI + || p->left->op == MEM_HI + || p->left->op == MEM_QI + ) { + for (i = 0; i < sizeof(optable)/sizeof(optable[0]); i++) { + if (p->left->op == optable[i].mem) { + const icg_opcodes op = optable[i].op; + if (p->right->op == op) { + icg_node *rval = 0; + p->right = icg_update_finder1(op, optable[i].comm, + p->right, p->left, &rval); + if (rval) { + icg_node *n = (icg_node *)icg_calloc(sizeof(icg_node)); + if (dump_file) { + fprintf(dump_file, "%16s ==> %16s update found\n", + icg_burm_opname[op], + icg_burm_opname[optable[i].mem_op]); + } + n->op = optable[i].mem_op; + n->insn = p->insn; + n->rtl = p->rtl; + n->left = p->left; + n->right = p->right; /* rewritten from icg_update_finder1 */ + return n; + } + } + } + } + } + } + return p; +} + +static +icg_node *icg_constant_folder(icg_node *p, bool *isconstp) +{ + bool l_isconst = false; + bool r_isconst = false; + if (isconstp) { + *isconstp = false; + } + if (p == 0) { + return p; + } + if (p->left) { + icg_constant_folder(p->left, &l_isconst); + } + if (p->right) { + icg_constant_folder(p->right, &r_isconst); + } + if (p->left && l_isconst && r_isconst) { + if (isconstp) { + *isconstp = true; + } + print_icg_tree(stdout, p, "constant"); + } + return p; +} + +icg_node *icg_tree_rewrite (icg_node *p) +{ + if (0) { + return p; + } else { + if (0) { + /* TODO: nyi */ + bool is_const = false; + return icg_constant_folder(p, &is_const); + } else { + return icg_update_finder(p); + } + } +} + + + +void icg_find_updates(void) { + basic_block bb; + + if (dump_file) + fprintf(dump_file, "\nstarted finding updates\n"); + + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS(bb, insn) { + unsigned id = INSN_UID(insn); + if (icg_insn2dirty[id]) { + icg_node *tree = icg_insn2tree[id]; + if (tree) + icg_insn2tree[id] = icg_tree_rewrite(tree); + } + } + } + + + if (dump_file) + fprintf(dump_file, "finished finding updates\n\n"); +} diff --git a/iburg/briggs/icg-select.c b/iburg/briggs/icg-select.c new file mode 100644 index 00000000000..fb984a96ef1 --- /dev/null +++ b/iburg/briggs/icg-select.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ + +/* Select instructions. + Zips through all instructions in all basic blocks + and invokes burm_label on each. +*/ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "tree-pass.h" +#include "function.h" +#include "basic-block.h" + +#include "icg.h" +#include "icg-opcode.h" + + +static void +print_icg_tree_1 (FILE *fp, icg_node *tree, int indent) +{ + int i; + if (fp == 0) fp = stdout; + for (i = 0; i < indent; i++) + fprintf (fp, " "); + icg_print_opcode (fp, tree, indent, 1); + if (tree->left) + print_icg_tree_1 (fp, tree->left, indent + 4); + if (tree->right) + print_icg_tree_1 (fp, tree->right, indent + 4); +} + + +static +void print_icg_tree_states (FILE *fp, icg_node *tree) +{ + if (fp == 0) fp = stdout; + print_icg_tree_1 (fp, tree, 0); +} + + +void icg_select(void) +{ + basic_block bb; + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS(bb, insn) { + int id = INSN_UID(insn); + if (icg_insn2dirty[id]) { + icg_node *tree = icg_insn2tree[id]; + if (tree) { + const icg_state_type state = icg_burm_label(tree); + if (dump_file) { + if (state == 0) { + fprintf(dump_file, + "\n" "select: Can not match this icg tree: dump1 (\n"); + print_icg_tree(dump_file, tree, "no match: "); + fprintf(dump_file, "end of dump1 )\n"); + + fprintf(dump_file, + "\n" "select: Can not match this rtx tree: dump2 (\n"); + print_inline_rtx(dump_file, tree->rtl, 0); + fprintf(dump_file, "\n" "end of dump2 )\n"); + + fprintf(dump_file, "\n\n"); + + flag_icg_trace |= (1<<0); /* print cover info */ + print_icg_tree_states(dump_file, tree); + fflush(dump_file); + flag_icg_trace &= ~(1<<0); /* do not print cover info */ + } + print_icg_tree_states(dump_file, tree); + fflush(dump_file); + } + if (state == 0) { + icg_nyi("BURG blocks: can not parse expr tree"); + } + } + } + } + } +} diff --git a/iburg/briggs/icg-spill.c b/iburg/briggs/icg-spill.c new file mode 100644 index 00000000000..cfb61be0651 --- /dev/null +++ b/iburg/briggs/icg-spill.c @@ -0,0 +1,682 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "sparseset.h" +#include "tree-pass.h" +#include "flags.h" +#include "tm_p.h" +#include "output.h" + +#include "icg.h" +#include "icg-opcode.h" + + +/* + * The structure of the stack frame differs so significantly depending on whether + * or not a frame pointer is used that I'm going to talk about the two cases + * completely seperately. The code will also deal with the two cases quite seperately. + * + * First though, I'll talk a bit about terminology. + * In the RTL as it arrives on our doorstep, gcc refers to a FRAMEP and an ARGP + * (frame pointer and argument pointer). Offsets from the frame pointer are used + * to refer to variables in the stack frame and offsets from the argument pointer + * are used to refer to incoming argumnets stored in the stack frame. Note that + * the first 6 arguments are usually passed in registers and the rest are stored in + * memory. + * + * One of the jobs of the register allocator is to rewrite references to FRAMEP and ARGP + * as references to either the base pointer (if we are using a frame pointer) or to the + * stack pointer (if we are not using a frame pointer). Normally, our code is compiled + * with the flag -fno-omit-frame-pointer which causes the compiler to use a frame pointer + * all the time. This is actually a bit slower, but is apparently useful for some of + * tools. + * + * There's an optimization possible for leaf routines. + * Since the calling convention specifies that the 128 bytes + * immediately below the SP are a "red zone" that may be used + * as a scratch area, we can point the stack pointer up to 128 + * bytes higher in the stack frame. The advantage is that offsets + * frame the SP will be slightly smaller as will the stack adjustment, + * perhaps saving a bit of encoding space. Luckily, there's a phase + * that runs downstream that will perform the necessary adjustments. + * We need only set the flag current_function_is_leaf (when we're certain + * the function is a leaf!). Currently, we do this as part of icg-build-tree. + * + * The stack pointer is always kept aligned to a 16-byte boundary, + * so sometimes we'll see the frame be 8 bytes larger than otherwise necessary. + * + * This has all proved pretty tedious to get correct; + * hence the relative extensive documentation. + * + * + * + * Here's a picture of the stack frame, with a frame pointer + * + * | ... | + * | high addresses | + * +-------------------+ + * | | + * | args | + * 16(%rbp) | | 0(ARGP) + * +-------------------+ + * 8(%rbp) | return | + * +-------------------+ + * 0(%rbp) | old BP | 0(FRAMEP) + * +-------------------+ + * | | + * | callee-saves | + * | registers | + * | | + * +-------------------+ + * | | + * | fix-sized | + * | variables | + * | | + * +-------------------+ + * | | + * | spills | + * | | + * +-------------------+ + * | | + * | dynamically-sized | + * | variables | + * 0(%rsp) | | + * +-------------------+ + * | low addresses | + * | ... | + * + * + * The frame pointer will be required if the size of variables is not known + * at compile time (e.g., if there's a call to alloca). It'll also be + * required if the routine is compiled using -fno-omit-frame-pointer. + * We don't actually to figure it out; the variable frame_pointer_needed + * (set in icg.c) gives us the answer. + * + * If the frame pointer is used, then everything will be referenced via the + * base pointer. The stack pointer is used only to support things like alloca() + * and ever deeper calls. + + * The interesting problem is in converting references to the ARGP and FRAMEP + * (names used in the RTL entering the allocator) to either RBP or RSP (actual + * machine registers used after the allocator). + * + * If we're using the frame pointer, then we need to convert all references to + * ARGP into references to RBP, including an adjustment of offsets. Similarly, + * references to FRAMEP will be changed into references to RBP. Note that + * adjusting the offsets to the FRAMEP will depend on the number of callee-saves + * registers. The same is true with spilled values. + * + * In my experiments, it appears that gcc (downstream of the allocator) inserts + * code to save and restore the callee-saves registers, though I must deal with + * the space requirements for them; that is, I must correctly adjust offsets + * from the RBP or RSP to reach across the space required for the callee-saves + * registers. Care is required here, since the number of callee-saves registers + * may change (up or down) from pass to pass of the allocator. + * + * Generally, my approach is to keep track of the total adjustments I've applied + * in the passes so far, then compute the new adjustment required. In this fashion, + * we can avoid any last second scramble to handle offsets greater than 2 GBytes + * (which require an additional register); it's just handled naturally as part + * of the allocators iterative structure. + * + * + * + * + * + * + * + * + * + * Here's a picture of the stack frame, when the frame pointer is omitted. + * + * | ... | + * | high addresses | + * +-------------------+ + * | | + * | args | + * | | 0(ARGP) + * +-------------------+ + * | return | 0(FRAMEP) + * +-------------------+ + * | | + * | callee-saves | + * | registers | + * | | + * +-------------------+ + * | | + * | fix-sized | + * | variables | + * | | + * +-------------------+ + * | | + * | spills | + * 0(%rsp) | | + * +-------------------+ + * | low addresses | + * | ... | + * + * + * If the frame pointer is omitted, then all variables, spills, and args + * will be addressed by an offset from the stack pointer. + * + * The interesting problem is in converting references to the ARGP and FRAMEP + * (names used in the RTL entering the allocator) to either RBP or RSP (actual + * machine registers used after the allocator). + * + * If we're using the base pointer, then we need to convert all references to + * ARGP into references to RBP, including an adjustment of offsets. Similarly, + * references to FRAMEP will be changed into references to RBP. Note that + * adjusting the offsets to the FRAMEP will depend on the number of callee-saves + * registers. + * + * If we're not using the base pointer (and we'd prefer not to, since avoiding it + * will save space, time, and a register), more adjustments are required. + * Both the ARGP and FRAMEP are rewritten to refer to the RSP. Offsets will + * need to be adjusted and the adjustment will depend on the number of callee-saves + * registers and the number of spills. Since instruction selection can depend on + * the size of offsets, we'll need to redo instruction selection whenever an offset + * changes (though only for the local tree). + * + * In my experiments, it appears that gcc (downstream of the allocator) inserts + * code to save and restore the callee-saves registers, though I must deal with + * the space requirements for them; that is, I must correctly adjust offsets + * from the RSP to reach across the space required for the callee-saves + * registers. Care is required here, since the number of callee-saves registers + * may change (up or down) from pass to pass of the allocator. Similarly, the + * amount of space required by the spilled values will tend to increase from + * pass to pass. + * + * Generally, my approach is to keep track of the total adjustments I've applied + * in the passes so far, then compute the new adjustment required. In this fashion, + * we can avoid any last second scramble to handle offsets greater than 2 GBytes + * (which require an additional register); it's just handled naturally as part + * of the allocators iterative structure. + * + */ + + +long long int accumulated_fp_adjustment = 0; +long long int accumulated_argp_adjustment = 0; + +long long int current_fp_adjustment = 0; +long long int current_argp_adjustment = 0; + + +icg_opcodes icg_op_of_constant(long long int offset) { + if (offset == -1) return CONST_N1; + else if (offset == 0) return CONST_0; + else if (offset == 1) return CONST_P1; + else if (offset == 2) return CONST_P2; + else if (offset == 3) return CONST_P3; + else if (offset == 4) return CONST_P4; + else if (offset == 8) return CONST_P8; + else if (offset == 15) return CONST_P15; + else if (offset == 16) return CONST_P16; + else if (offset == 24) return CONST_P24; + else if (offset == 31) return CONST_P31; + else if (offset == 32) return CONST_P32; + else if (offset == 48) return CONST_P48; + else if (offset == 56) return CONST_P56; + else if (offset == 63) return CONST_P63; + else if (offset == 255) return CONST_P255; + + else if (offset > 0x7FFFFFFFLL) return CONST64P; + else if (offset > 0x3FFFFFFFLL) return CONST32P; + else if (offset > 0x1FFFFFFFLL) return CONST31P; + else if (offset > 0xFFFFFFFLL) return CONST30P; + else if (offset > 0x7FFF) return CONST29P; + else if (offset > 0x3FFF) return CONST16P; + else if (offset > 0x1FFF) return CONST15P; + else if (offset > 0xFFF) return CONST14P; + else if (offset > 0x7FF) return CONST13P; + else if (offset > 0x7F) return CONST12P; + else if (offset > 0x3F) return CONST8P; + else if (offset > 0x1F) return CONST7P; + else if (offset > 0xF) return CONST6P; + else if (offset > 0x7) return CONST5P; + else if (offset > 0) return CONST4P; + + else if (offset < -0x80000000LL) return CONST64N; + else if (offset < -0x40000000LL) return CONST32N; + else if (offset < -0x20000000LL) return CONST31N; + else if (offset < -0x10000000LL) return CONST30N; + else if (offset < -0x8000) return CONST29N; + else if (offset < -0x4000) return CONST16N; + else if (offset < -0x2000) return CONST15N; + else if (offset < -0x1000) return CONST14N; + else if (offset < -0x800) return CONST13N; + else if (offset < -0x80) return CONST12N; + else if (offset < -0x40) return CONST8N; + else if (offset < -0x20) return CONST7N; + else if (offset < -0x10) return CONST6N; + else if (offset < -0x8) return CONST5N; + else return CONST4N; +} + + +static +icg_node *kind_of_constant(long long int offset) +{ + icg_node *node = (icg_node *) icg_calloc(sizeof(icg_node)); + node->val = offset; + node->a.string = NULL; + node->op = icg_op_of_constant(offset); + return node; +} + + +/* + * The function make_spill_code is to be called from + * within the spill { ... } arm of the grammar files. + * + * Return true if spill code was made + */ +static +bool make_spill_code(unsigned r, icg_node *p) +{ + if (icg_reg_vector[r].color < 0) { + int new_op; + icg_node *plus = (icg_node *) icg_calloc(sizeof(icg_node)); + icg_node *left = (icg_node *) icg_calloc(sizeof(icg_node)); + icg_node *right = kind_of_constant(icg_reg_vector[r].offset + accumulated_fp_adjustment); + + if (dump_file) { + fprintf(dump_file, "spilling: make_spill_code r=%3d root=%3d, offset=%lld\n", + r, icg_reg_vector[r].root, icg_reg_vector[r].offset); + } + + switch (p->op) { + case REG_DI: case REGX_DI: new_op = MEM_DI; break; + case REG_SI: case REGX_SI: new_op = MEM_SI; break; + case REG_HI: case REGX_HI: new_op = MEM_HI; break; + case REG_QI: case REGX_QI: new_op = MEM_QI; break; + case REG_DF: case REGX_DF: new_op = MEM_DF; break; + case REG_SF: case REGX_SF: new_op = MEM_SF; break; + default: + fprintf(stdout, "make_spill_code: unexpected op\n"); + abort(); + } + + left->op = REG_DI; + left->r = left->rx = REG_FP; + plus->op = PLUS_DI; + plus->left = left; + plus->right = right; + if (dump_file) { + fprintf(dump_file, + "spilling: smashing p->op from %d/%s to %d/%s (l=%s:%d r=%s:%lld)\n", + p->op, get_icg_opcode_name(p->op), + new_op, get_icg_opcode_name(new_op), + get_icg_opcode_name(left->op), + REG_FP, + get_icg_opcode_name(right->op), + icg_reg_vector[r].offset + accumulated_fp_adjustment); + } + p->op = new_op; + p->left = plus; + return true; + } + else + return false; +} + + +#define find(r) (icg_reg_vector[r].root) + + +static +bool reduce_spill(icg_node *p, NT goalNT) +{ + bool dirty = false; + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + dirty |= reduce_spill(kid[i], nts[i]); + switch (rule) { +#include "icg-spill.cases" + } + return dirty; +} + + +static +long long int extract_offset(const_rtx mem_rtx) +{ + const enum rtx_code mem_opcode = GET_CODE(mem_rtx); + if (mem_opcode == MEM) { + const_rtx plus_rtx = XEXP(mem_rtx, 0); + const enum rtx_code plus_opcode = GET_CODE(plus_rtx); + if (plus_opcode == PLUS) { + const_rtx left_rtx = XEXP(plus_rtx, 0); + const enum rtx_code left_opcode = GET_CODE(left_rtx); + if (left_opcode == CONST_INT) + return INTVAL(left_rtx); + else { + const_rtx right_rtx = XEXP(plus_rtx, 1); + const enum rtx_code right_opcode = GET_CODE(right_rtx); + if (right_opcode == CONST_INT) + return INTVAL(right_rtx); + } + } + } + fflush(stdout); + fprintf(stderr, "extract_offset: poorly formated spill code\n"); + abort(); +} + + +/* + * Overwrite the register tree node with (PLUS_DI tree adjustment) + */ + +static +bool replace_with_sum(icg_node *tree, long long int adjustment) { + if (adjustment) { + icg_node *c = kind_of_constant(adjustment); + icg_node *r = (icg_node *) icg_calloc(sizeof(icg_node)); + memcpy(r, tree, sizeof(icg_node)); + tree->op = PLUS_DI; + tree->left = r; + tree->right = c; + return true; + } + return false; +} + + +/* + * return true if the sum rooted by tree contains a + * reference to reg + */ + +static +bool sum_contains_reg(icg_node *tree, unsigned reg) { + if (tree) { + if ((tree->op == REG_DI && tree->r == reg) || + (tree->op == REGX_DI && tree->rx == reg)) + return true; + else if (tree->op == PLUS_DI) + return sum_contains_reg(tree->left, reg) || + sum_contains_reg(tree->right, reg); + } + return false; +} + + +/* + * return true if the sum rooted by tree contains a + * constant + */ + +static +bool sum_contains_const(icg_node *tree) { + if (tree) { + if (tree->op >= CONST_0 && tree->op <= CONST64N) + return true; + else if (tree->op == PLUS_DI) + return sum_contains_const(tree->left) || + sum_contains_const(tree->right); + } + return false; +} + + +/* + * Walk over the sum rooted by tree, + * looking for a constant. It's guaranteed to be there. + * When found, add adjustment to it. + */ + +static +bool adjust_const(icg_node *tree, long long int adjustment) { + if (tree) { + if (tree->op >= CONST_0 && tree->op <= CONST64N) { + tree->val += adjustment; + tree->op = icg_op_of_constant(tree->val); + return true; + } + else if (tree->op == PLUS_DI) + return adjust_const(tree->left, adjustment) || + adjust_const(tree->right, adjustment); + } + return false; +} + + +static +bool adjust_register(icg_node *tree, unsigned reg, long long int adjustment); + +static +void adjust_children_of_sum(icg_node *tree, unsigned reg, long long int adjustment) { + if (tree) { + if (tree->op == PLUS_DI) { + adjust_children_of_sum(tree->left, reg, adjustment); + adjust_children_of_sum(tree->right, reg, adjustment); + } + else if (tree->op != REG_DI) + (void) adjust_register(tree, reg, adjustment); + } +} + + +/* + * Update all existing FP and ARGP references based on icg_current_adjustment. + * Return true if any updates. + */ + +static +bool adjust_register(icg_node *tree, unsigned reg, long long int adjustment) { + if (tree) { + if ((tree->op == REG_DI && tree->r == reg) || + (tree->op == REGX_DI && tree->rx == reg)) + return replace_with_sum(tree, adjustment); + else if (tree->op == PLUS_DI && + sum_contains_reg(tree, reg) && + sum_contains_const(tree)) { + (void) adjust_const(tree, adjustment); + adjust_children_of_sum(tree, reg, adjustment); + return true; + } + else /* please don't change the '|' below into '||' */ + return adjust_register(tree->left, reg, adjustment) | + adjust_register(tree->right, reg, adjustment); + } + return false; +} + + +long long int register_save_space; + +long long int size_variables; +int size_callee_saves; +int size_spills; + +bool icg_spill(unsigned pass) +{ + unsigned r; + basic_block bb; + long long int temp; + bool all_done = true; + + current_function_is_leaf = 0; /* TODO: someday explore making this work again */ + + if (dump_file) { + fprintf(dump_file, "\n"); + fprintf(dump_file, "spilling: started {\n"); + if (frame_pointer_needed) + fprintf(dump_file, "frame pointer needed\n"); + else + fprintf(dump_file, "frame pointer not needed\n"); + } + + if (pass == 0) { + accumulated_fp_adjustment = 0; + accumulated_argp_adjustment = 0; + } + + /* find size of area for callee_saves register (may wobble up and down from pass to pass) */ + { + bool used[FIRST_PSEUDO_REGISTER]; + size_callee_saves = 0; + for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) + used[r] = false; + for (r = FIRST_PSEUDO_REGISTER; r < icg_interior_regs; r++) + if (icg_reg_vector[r].root == r && + icg_reg_vector[r].color >= 0) + used[icg_reg_vector[r].color] = true; + if (used[41]) + size_callee_saves += 8; + if (used[42]) + size_callee_saves += 8; + if (used[43]) + size_callee_saves += 8; + if (used[44]) + size_callee_saves += 8; + if (used[REG_RBX]) + size_callee_saves += 8; + if (used[REG_RBP]) + size_callee_saves += 8; + size_variables = get_frame_size(); + if (dump_file) + fprintf(dump_file, "callee saves = %d, vars = %lld, outgoing args = %d\n", + size_callee_saves, size_variables, crtl->outgoing_args_size); + } + + + if (frame_pointer_needed) { + if (dump_file) { + fprintf(dump_file, "spilling: assigning spill offsets\n"); + fprintf(dump_file, "\n"); + } + + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) { + if (icg_reg_vector[r].root == r && icg_reg_vector[r].color < 0) { + const_rtx x; + all_done = false; + if (icg_reg_vector[r].kind == INT_REGISTER) + x = assign_stack_local(DImode, 8, 8); + else + x = assign_stack_local(V2DFmode, 16, 16); + if (dump_file) { + fprintf(dump_file, "register %d\n", r); + print_inline_rtx(dump_file, x, 0); + fprintf(dump_file, "\n\n"); + } + icg_reg_vector[r].offset = extract_offset(x) - size_callee_saves; + } + } + + if (pass == 0) { + INITIAL_ELIMINATION_OFFSET(FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, current_fp_adjustment); + INITIAL_ELIMINATION_OFFSET(ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, current_argp_adjustment); + current_fp_adjustment -= accumulated_fp_adjustment; + current_argp_adjustment -= accumulated_argp_adjustment; + INITIAL_ELIMINATION_OFFSET(FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, accumulated_fp_adjustment); + INITIAL_ELIMINATION_OFFSET(ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, accumulated_argp_adjustment); + + /* update all existing FP and ARGP references based on current_adjustment */ + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS_REVERSE(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + icg_insn2dirty[id] = adjust_register(tree, REG_FP, current_fp_adjustment - size_callee_saves); + icg_insn2dirty[id] |= adjust_register(tree, REG_ARGP, current_argp_adjustment); + } + } + } + } + + /* insert spill code based on accumulated_fp_adjustment */ + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS_REVERSE(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + icg_insn2dirty[id] |= reduce_spill(tree, burm_goal_NT); + } + } + } + } + + + + + + /* deal with case when no frame pointer is required */ + + else { + if (dump_file) { + fprintf(dump_file, "spilling: assigning spill offsets\n"); + fprintf(dump_file, "\n"); + } + + for (r = FIRST_PSEUDO_REGISTER; r < icg_live_ranges; r++) { + if (icg_reg_vector[r].root == r && icg_reg_vector[r].color < 0) { + const_rtx x; + if (icg_reg_vector[r].kind == INT_REGISTER) + x = assign_stack_local(DImode, 8, 8); + else + x = assign_stack_local(V2DFmode, 16, 16); + if (dump_file) { + fprintf(dump_file, "register %d\n", r); + print_inline_rtx(dump_file, x, 0); + fprintf(dump_file, "\n\n"); + } + icg_reg_vector[r].offset = extract_offset(x); + } + } + + /* I did a lot of experimentation to fine this formula for current_argp_adjustment. Hope it's right! */ + INITIAL_ELIMINATION_OFFSET(ARG_POINTER_REGNUM, STACK_POINTER_REGNUM, current_argp_adjustment); + current_argp_adjustment += (size_callee_saves >> 4) << 4; + temp = current_argp_adjustment; + current_argp_adjustment -= accumulated_argp_adjustment; + accumulated_argp_adjustment = temp; + + + INITIAL_ELIMINATION_OFFSET(FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM, current_fp_adjustment); + current_fp_adjustment -= accumulated_fp_adjustment; + INITIAL_ELIMINATION_OFFSET(FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM, accumulated_fp_adjustment); + + if (dump_file) { + fprintf(dump_file, "adjusting fp offsets by %lld\n", current_fp_adjustment); + fprintf(dump_file, "adjusting argp offsets by %lld\n", current_argp_adjustment); + } + + FOR_EACH_BB(bb) { + rtx insn; + FOR_BB_INSNS(bb, insn) { + unsigned id = INSN_UID(insn); + icg_node *tree = icg_insn2tree[id]; + if (tree) { + bool adjusted_fp = current_fp_adjustment == 0 ? false : adjust_register(tree, REG_FP, current_fp_adjustment); + bool adjusted_argp = current_argp_adjustment == 0 ? false : adjust_register(tree, REG_ARGP, current_argp_adjustment); + bool spilled = reduce_spill(tree, burm_goal_NT); + icg_insn2dirty[id] = adjusted_fp || adjusted_argp || spilled; + if (icg_insn2dirty[id]) + all_done = false; + } + } + } + } + + if (dump_file) + fprintf(dump_file, "spilling: finished}\n"); + return all_done; +} diff --git a/iburg/briggs/icg-ssa.c b/iburg/briggs/icg-ssa.c new file mode 100644 index 00000000000..1e92984dbe8 --- /dev/null +++ b/iburg/briggs/icg-ssa.c @@ -0,0 +1,811 @@ +/* Construct SSA for ICG. + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "df.h" +#include "vecprim.h" +#include "vec.h" +#include "tree-flow.h" +#include "domwalk.h" +#include "icg.h" + + +/* Adds a phi node for register REG to the list of phi nodes for basic + block BB. */ + +static void +add_phi_node (basic_block bb, int reg) +{ + icg_phi_node *phi; + int npreds; + + npreds = EDGE_COUNT (bb->preds); + gcc_assert (npreds >= 2); + phi = (icg_phi_node *)icg_calloc (sizeof (icg_phi_node) + npreds * sizeof (int)); + phi->reg = reg; + phi->next = icg_bb2phi[bb->index]; + icg_bb2phi[bb->index] = phi; +} + +/* Returns true iff REG is live into basic block BB. */ + +static bool +register_live_in_p (int reg, basic_block bb) +{ + return REGNO_REG_SET_P (DF_LIVE_IN (bb), reg); +} + +/* State for walking the dominator tree when renaming. */ + +struct walk_state +{ + /* Next available SSA name. */ + int next_name; + /* Mapping from register to current SSA name. */ + int *curr_name; + /* Stack of renames. */ + VEC (int, heap) *st; +}; + +/* Called each time a new def is encountered. + 1) reserves a unique SSA name for the def + 2) Save (register, old name) pair on to stack + 3) Set current name of register to new value + Returns the SSA name for the def. */ + +static int +register_new_def (int reg, struct walk_state *gdata) +{ + int new_name = gdata->next_name++; + + VEC_reserve (int, heap, gdata->st, 2); + VEC_quick_push (int, gdata->st, gdata->curr_name[reg]); + VEC_quick_push (int, gdata->st, reg); + + gdata->curr_name[reg] = new_name; + + return new_name; +} + +/* Callback function for renaming uses, called for each icg_node + register use by for_each_icg_tree_use. */ + +static int +rename_uses (icg_node *pn, void *data) +{ + int reg = REGNO (pn->rtl); + if (reg >= FIRST_PSEUDO_REGISTER) + { + struct walk_state *gdata = (struct walk_state *)data; + int new_name = gdata->curr_name[reg]; + /* Assert will fail if use has no definition. */ + if (dump_file) fflush(dump_file); + gcc_assert (new_name != 0); + if (dump_file) + fprintf (dump_file, " use of register %3d in insn %3d renamed to %3d\n", + reg, INSN_UID (pn->insn), new_name); + pn->ssa_name = new_name; + } + else + pn->ssa_name = reg; + return 0; +} + +/* Callback function for registering and renaming defs, called for + each icg_node register use by for_each_icg_tree_def. */ + +static int +register_defs (icg_node *pn, void *data) +{ + int reg = REGNO (pn->rtl); + if (reg >= FIRST_PSEUDO_REGISTER) + { + struct walk_state *gdata = (struct walk_state *)data; + int new_name = register_new_def (reg, gdata); + if (dump_file) + fprintf (dump_file, " def of register %3d in insn %3d renamed to %3d\n", + reg, INSN_UID (pn->insn), new_name); + pn->ssa_name = new_name; + } + else + pn->ssa_name = reg; + return 0; +} + +/* Called during the dominator walk when a new block is entered: + 1) mark location on name stack for restore when leaving block + 2) register the defs of each phi node. + 3) iterate through trees amd rename uses and defs */ + +static void +rename_enter_block (struct dom_walk_data *walk_data, basic_block bb) +{ + struct walk_state *gdata = (struct walk_state *)walk_data->global_data; + icg_phi_node *pn; + icg_node *inode; + + if (dump_file) + fprintf (dump_file, " Entering BB %2d\n", bb->index); + + /* Save marker indicating new block. Stack will be rolled back to + this point when leaving block. */ + VEC_safe_push (int, heap, gdata->st, -1); + + FOR_BB_ICG_PHI_NODES (bb, pn) + { + pn->def = register_new_def (pn->reg, gdata); + if (dump_file) + fprintf (dump_file, " def in phi node for register %3d named %3d\n", + pn->reg, pn->def); + } + + FOR_BB_ICG_TREES(bb, inode) + { + for_each_icg_tree_use (inode, rename_uses, gdata); + for_each_icg_tree_def (inode, register_defs, gdata); + } +} + +/* Returns the index in the predecessor vector of BB for the + predecessor PRED. */ + +static int +get_pred_index (basic_block bb, basic_block pred) +{ + edge e; + edge_iterator ei; + int n = 0; + FOR_EACH_EDGE (e, ei, bb->preds) + { + if (e->src == pred) + return n; + n++; + } + gcc_assert (0); + return 0; +} + +/* Called immediate before traversing children during dominator walk. + Iterate successors of BB and fill in respective phi node arguments + with current name of register. */ + +static void +rename_phi_arguments (struct dom_walk_data *walk_data, basic_block bb) +{ + struct walk_state *gdata = (struct walk_state *)walk_data->global_data; + edge e; + edge_iterator ei; + icg_phi_node *pn; + + FOR_EACH_EDGE (e, ei, bb->succs) + { + int idx = get_pred_index (e->dest, bb); + FOR_BB_ICG_PHI_NODES (e->dest, pn) + { + pn->uses[idx] = gdata->curr_name[pn->reg]; + if (dump_file) + fprintf (dump_file, " arg %3d of phi for reg %3d in BB %3d set to %3d\n", + idx, pn->reg, e->dest->index, gdata->curr_name[pn->reg]); + } + } +} + +/* Called when backing out of a basic block during the dominator tree walk. + 1) builds SSA variable live-out vector for the basic block + 2) Restore names to state prior to entering block by popping changes + from stack. */ + +static void +rename_leave_block (struct dom_walk_data *walk_data, + basic_block bb ATTRIBUTE_UNUSED) +{ + unsigned int i; + int n; + bitmap_iterator bi; + icg_names *p; + bitmap liveout = DF_LIVE_OUT(bb); + struct walk_state *gdata = (struct walk_state *)walk_data->global_data; + + /* Build SSA name live out vector. */ + p = (icg_names *)icg_calloc (sizeof (icg_names) + + sizeof (int) * (bitmap_count_bits (liveout) - 1)); + p->size = bitmap_count_bits (liveout); + n=0; + EXECUTE_IF_SET_IN_BITMAP (liveout, 0, i, bi) + if (i < FIRST_PSEUDO_REGISTER) + p->name[n++] = i; + else + p->name[n++] = gdata->curr_name[i]; + icg_ssa_liveout[bb->index] = p; + + /* Restore stack to state upon entering BB by popping until -1 + marker is found. */ + while (1) + { + int reg, name; + + gcc_assert (VEC_length (int, gdata->st) > 0); + reg = VEC_pop (int, gdata->st); + if (reg == -1) + break; + gcc_assert (VEC_length (int, gdata->st) > 0); + name = VEC_pop (int, gdata->st); + gdata->curr_name[reg] = name; + } +} + +/* Walks the dominator tree and renames uses and defs. Also constructs + SSA live out vectors for each basic block. */ + +static int +rename_registers (void) +{ + struct walk_state gdata; + struct dom_walk_data walk_data; + + gdata.next_name = FIRST_PSEUDO_REGISTER; + gdata.curr_name = XCNEWVEC (int, max_reg_num()); + gdata.st = VEC_alloc (int, heap, 10); + + if (dump_file) + fprintf (dump_file, "Walking dominance tree and renaming registers:\n"); + memset (&walk_data, 0, sizeof (walk_data)); + walk_data.dom_direction = CDI_DOMINATORS; + walk_data.global_data = &gdata; + + walk_data.before_dom_children_before_stmts = rename_enter_block; + walk_data.before_dom_children_after_stmts = rename_phi_arguments; + walk_data.after_dom_children_after_stmts = rename_leave_block; + + init_walk_dominator_tree (&walk_data); + walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); + fini_walk_dominator_tree (&walk_data); + + VEC_free (int, heap, gdata.st); + free (gdata.curr_name); + + return gdata.next_name; +} + +/* Helper struct and callback function for computing the set of basic + blocks in which a register is defined. */ + +struct reg_defs_struct +{ + basic_block bb; + bitmap *reg_defs; +}; + +static int +set_def_bit (icg_node *pn, void *data) +{ + struct reg_defs_struct *p = (struct reg_defs_struct *)data; + int reg = REGNO (pn->rtl); + if (reg >= FIRST_PSEUDO_REGISTER) + bitmap_set_bit (p->reg_defs[reg], p->bb->index); + return 0; +} + +/* Fills in the allocated array of bitmaps REG_DEFS. Array is indexed + by rtl register name and indicates in which basic blocks the + register is defined. */ + +static void +compute_def_bitmaps (bitmap *reg_defs) +{ + basic_block bb; + icg_node *pn; + struct reg_defs_struct st; + + st.reg_defs = reg_defs; + FOR_EACH_BB (bb) + { + st.bb = bb; + FOR_BB_ICG_TREES (bb, pn) + for_each_icg_tree_def (pn, set_def_bit, &st); + } +} + +/* Computes the iterated dominance frontier in IDF of the set of basic blocks + indicated by the bitmap DEF_BLOCKs using the dominance frontiers + in DFRONT. (Taken from tree-into-ssa.c) */ + +static void +set_idf_bits (bitmap idf, bitmap def_blocks, bitmap *dfront) +{ + bitmap_iterator bi; + unsigned bb_index, i; + VEC(int,heap) *work_stack; + + work_stack = VEC_alloc (int, heap, n_basic_blocks); + + /* Seed the work list with all the blocks in DEF_BLOCKS. We use + VEC_quick_push here for speed. This is safe because we know that + the number of definition blocks is no greater than the number of + basic blocks, which is the initial capacity of WORK_STACK. */ + EXECUTE_IF_SET_IN_BITMAP (def_blocks, 0, bb_index, bi) + VEC_quick_push (int, work_stack, bb_index); + + /* Pop a block off the worklist, add every block that appears in + the original block's DF that we have not already processed to + the worklist. Iterate until the worklist is empty. Blocks + which are added to the worklist are potential sites for + PHI nodes. */ + while (VEC_length (int, work_stack) > 0) + { + bb_index = VEC_pop (int, work_stack); + EXECUTE_IF_AND_COMPL_IN_BITMAP (dfront[bb_index], idf, 0, i, bi) + { + /* Use a safe push because if there is a definition of REG + in every basic block, then WORK_STACK may eventually have + more than N_BASIC_BLOCK entries. */ + VEC_safe_push (int, heap, work_stack, i); + bitmap_set_bit (idf, i); + } + } + + VEC_free (int, heap, work_stack); +} + +/* Constructs lists of phi nodes for every basic block using iterated + dominance frontiers. */ + +static void +place_phi_nodes (void) +{ + int reg; + bitmap_iterator bi; + basic_block bb; + unsigned i; + bitmap *reg_defs; + bitmap *dfront; + bitmap idf; + + if (dump_file) + fprintf (dump_file, "Placing phi nodes:\n"); + + /* Initialize array of reg def bitmaps. */ + reg_defs = XNEWVEC (bitmap, max_reg_num()); + for (reg = 0; reg < max_reg_num(); reg++) + reg_defs [reg] = BITMAP_ALLOC (NULL); + compute_def_bitmaps (reg_defs); + + /* Compute dominance frontier bitmap. */ + dfront = XNEWVEC (bitmap, last_basic_block); + FOR_EACH_BB (bb) + dfront[bb->index] = BITMAP_ALLOC (NULL); + calculate_dominance_info (CDI_DOMINATORS); + compute_dominance_frontiers (dfront); + + idf = BITMAP_ALLOC (NULL); + for (reg = FIRST_PSEUDO_REGISTER; reg < max_reg_num(); reg++) + { + bitmap_clear (idf); + set_idf_bits (idf, reg_defs[reg], dfront); + + EXECUTE_IF_SET_IN_BITMAP(idf, 0, i, bi) + if (register_live_in_p (reg, BASIC_BLOCK (i))) + { + add_phi_node (BASIC_BLOCK (i), reg); + if (dump_file) + fprintf (dump_file, "phi node for register %3d placed in BB %3d\n", + reg, i); + } + } + BITMAP_FREE (idf); + + FOR_EACH_BB (bb) + BITMAP_FREE (dfront[bb->index]); + free (dfront); + + for (reg = 0; reg < max_reg_num(); reg++) + BITMAP_FREE (reg_defs [reg]); + free (reg_defs); +} + +/* Constructs SSA form: + 1) Renames registers in icg tree. New names placed in field + ssa_name. + 2) Constructs phi node data structure icg_bb2phi, an array of lists + of phi_node's. + + Sets icg_ssa_regs to the highest SSA name number + 1. */ + +void +icg_build_ssa (void) +{ + df_live_add_problem (); + df_scan_alloc (NULL); + df_scan_blocks (); + + df_live_add_problem (); + df_live_set_all_dirty (); + df_analyze (); + + if (dump_file) + { + fprintf (dump_file, "\n*** icg_build_ssa ***\n\n"); + fprintf (dump_file, "RTL defs and uses:\n"); + dump_icg_rtl (dump_file); + } + + icg_ssa_liveout = (icg_names**) icg_calloc (last_basic_block * sizeof (icg_names *)); + icg_bb2phi = (icg_phi_node **)icg_calloc (last_basic_block * sizeof (icg_phi_node *)); + + place_phi_nodes (); + + icg_ssa_regs = rename_registers (); + + if (dump_file) + { + fprintf (dump_file, "SSA defs and uses:\n"); + dump_icg_ssa (dump_file); + } +} + + +/* Data structure and functions for union-find used for merging SSA + variables which share PHI nodes. */ + +struct live_range { + struct live_range *root; + int rank; + unsigned int ssa_name; + unsigned int lr_name; +}; + +static struct live_range * +range_find (struct live_range *lr) +{ + if (lr->root == lr) + return lr; + else + { + lr->root = range_find (lr->root); + return lr->root; + } +} + +static void +range_union (struct live_range *x, struct live_range *y) +{ + x = range_find(x); + y = range_find(y); + if (x != y) + { + if (x->rank > y->rank) + y->root = x; + else if (x->rank < y->rank) + x->root = y; + else + { + y->root = x; + x->rank++; + } + } +} + +static int +name_live_range (icg_node *pn, void *data) +{ + struct live_range *ranges = (struct live_range *)data; + struct live_range *plr = range_find (&ranges[pn->ssa_name]); + pn->live_range = plr->lr_name; + pn->r = pn->rx = pn->live_range; + return 0; +} + +/* Finds and names live ranges. Unique name is placed in live_range + field within the icg tree. Names of live ranges of real registers + are the same as the REGNO of the register. Live ranges of symbolic + registers are numbered consecutively from FIRST_PSEUDO_REGISTER. + + Sets icg_live_ranges to the maximum live range name + 1. */ + +void +icg_build_live_ranges (void) +{ + basic_block bb; + struct live_range *ranges; + unsigned i; + icg_phi_node *pn; + + if (dump_file) + fprintf (dump_file, "\n*** icg_build_live_ranges ***\n\n"); + + icg_live_ranges = FIRST_PSEUDO_REGISTER; + icg_ssa_to_lr = (unsigned int *)icg_calloc (icg_ssa_regs * sizeof (int)); + icg_lr_liveout = (icg_names **)icg_calloc (last_basic_block * sizeof (icg_names *)); + + ranges = XNEWVEC (struct live_range, icg_ssa_regs); + for (i = 0; i < icg_ssa_regs; i++) + { + ranges[i].root = &ranges[i]; + ranges[i].rank = 0; + ranges[i].ssa_name = i; + ranges[i].lr_name = 0; + } + + /* Union together the live range of each arg of a phi node + into the live range of the def. */ + FOR_EACH_BB (bb) + FOR_BB_ICG_PHI_NODES (bb, pn) + for (i = 0; i < EDGE_COUNT (bb->preds); i++) + range_union (&ranges[pn->def], &ranges[pn->uses[i]]); + + /* Name each live range a unique name. Also create ssa name to live + range map. */ + for (i = 0; i < icg_ssa_regs; i++) + { + struct live_range *lr = range_find (&ranges[i]); + if (i < FIRST_PSEUDO_REGISTER) + { + gcc_assert (lr->ssa_name == i); + lr->lr_name = i; + } + else + { + gcc_assert (lr->ssa_name >= FIRST_PSEUDO_REGISTER); + if (lr->lr_name == 0) + lr->lr_name = icg_live_ranges++; + } + icg_ssa_to_lr[i] = lr->lr_name; + } + + /* Fill in live_range field for each instance of live range + variable. */ + FOR_EACH_BB (bb) + { + icg_node *inode; + icg_names *p, *pssa; + bool *chk; + + FOR_BB_ICG_TREES(bb, inode) + { + for_each_icg_tree_def (inode, name_live_range, ranges); + for_each_icg_tree_use (inode, name_live_range, ranges); + } + + pssa = icg_ssa_liveout[bb->index]; + p = (icg_names *)icg_calloc (sizeof (icg_names) + sizeof (int) * (pssa->size - 1)); + p->size = pssa->size; + for (i = 0; i < pssa->size; i++) + { + unsigned lr = icg_ssa_to_lr[pssa->name[i]]; + p->name[i] = lr; + } + icg_lr_liveout[bb->index] = p; + + /* For verification, check that no live ranges appear twice. + There should be a one-to-one mapping from SSA names to + _unique_ live ranges for the SSA names which are live out of + each basic block. I know, the check is not terribly + efficient. */ + chk = XCNEWVEC (bool, icg_ssa_regs); + for (i = 0; i < p->size; i++) + { + gcc_assert (!chk[p->name[i]]); + chk[p->name[i]] = true; + } + free (chk); + } + + free (ranges); + + if (dump_file) + { + fprintf (dump_file, "Live range defs and uses:\n"); + dump_icg_live_ranges (dump_file); + } +} + + +/* Helper functions for dumping register names. To avoid confusion, + RTL names are prefixed with 'R', SSA names with 'S', and live + ranges with 'L'. */ + +typedef enum { + ICG_RTL_NAME, + ICG_SSA_NAME, + ICG_LR_NAME +} icg_name_type; + +static void +dump_reg (FILE *fp, bool space, icg_name_type t, int name) +{ + if (fp == 0) fp = stdout; + if (space) + fprintf (fp, " "); + if (name < FIRST_PSEUDO_REGISTER) + fprintf (fp, "%s", reg_names[name]); + else + { + if (t == ICG_RTL_NAME) + fprintf (fp, "R%d", name); + else if (t == ICG_SSA_NAME) + fprintf (fp, "S%d", name); + else if (t== ICG_LR_NAME) + fprintf (fp, "L%d", name); + } +} + +static int +dump_rtl_name (icg_node *pn, void *data) +{ + FILE *fp = (FILE *)data; + dump_reg (fp, true, ICG_RTL_NAME, REGNO (pn->rtl)); + return 0; +} + +static int +dump_ssa_name (icg_node *pn, void *data) +{ + FILE *fp = (FILE *)data; + dump_reg (fp, true, ICG_SSA_NAME, pn->ssa_name); + return 0; +} + +static int +dump_live_range_name (icg_node *pn, void *data) +{ + FILE *fp = (FILE *)data; + dump_reg (fp, true, ICG_LR_NAME, pn->live_range); + return 0; +} + +/* Dumps the trees in each basic block in the following form: + + ( defs ...) <= ( uses ... ) + + Also dumps live out for each BB. Parameterized for dumping + RTL/SSA/live ranges. */ + +static void +dump_def_uses (FILE *fp, bool ssa, bool lr) +{ + basic_block bb; + icg_phi_node *phi; + unsigned int i; + edge e; + edge_iterator ei; + icg_node *inode; + + if (fp == 0) fp = stdout; + df_live_add_problem (); + df_live_set_all_dirty (); + df_analyze (); + + FOR_EACH_BB (bb) + { + fprintf (fp, " BB %d ( preds =", bb->index); + FOR_EACH_EDGE (e, ei, bb->preds) + fprintf (fp, " %d", e->src->index); + fprintf (fp, " ; succs ="); + FOR_EACH_EDGE (e, ei, bb->succs) + fprintf (fp, " %d", e->dest->index); + fprintf (fp, " )\n"); + + if (ssa) + FOR_BB_ICG_PHI_NODES (bb, phi) + { + fprintf (fp, " PHI "); + dump_reg (fp, false, ICG_RTL_NAME, phi->reg); + fprintf (fp, " ( "); + dump_reg (fp, false, ICG_SSA_NAME, phi->def); + fprintf (fp, " ) <= ("); + for (i = 0; i < EDGE_COUNT (bb->preds); i++) + dump_reg (fp, true, ICG_SSA_NAME, phi->uses[i]); + fprintf (fp, " )\n"); + } + + FOR_BB_ICG_TREES (bb, inode) + { + int i, pos; + int (*dump_f)(icg_node *, void *); + + if (ssa) + dump_f = dump_ssa_name; + else if (lr) + dump_f = dump_live_range_name; + else + dump_f = dump_rtl_name; + + fprintf (fp, " insn %3d (", INSN_UID (inode->insn)); + pos = ftell (fp); + for_each_icg_tree_def (inode, dump_f, fp); + /* Make sure line position is advanced by at least 8 so each + '<=' lines up for clarity. This should give room for two + defs without causing misalignment problems. */ + for (i = ftell (fp); i < pos + 4; i = ftell (fp)) + fprintf (fp, " "); + fprintf (fp, " ) <= ("); + for_each_icg_tree_use (inode, dump_f, fp); + fprintf (fp, " )\n"); + } + + fprintf (fp, " live out ("); + if (ssa) + for (i = 0; i < icg_ssa_liveout[bb->index]->size; i++) + dump_reg (fp, true, ICG_SSA_NAME, icg_ssa_liveout[bb->index]->name[i]); + else if (lr) + for (i = 0; i < icg_lr_liveout[bb->index]->size; i++) + dump_reg (fp, true, ICG_LR_NAME, icg_lr_liveout[bb->index]->name[i]); + else + { + bitmap_iterator bi; + EXECUTE_IF_SET_IN_BITMAP (DF_LIVE_OUT(bb), 0, i, bi) + dump_reg (fp, true, ICG_RTL_NAME, i); + } + fprintf (fp, " )\n"); + } +} + + +/* Dumps the defs and uses of the original RTL registers. */ + +void dump_icg_rtl (FILE *fp) +{ + dump_def_uses (fp, false, false); +} + +/* Dumps the defs and uses of every operation and phi nodes to FP. */ + +void dump_icg_ssa (FILE *fp) +{ + dump_def_uses (fp, true, false); +} + +/* Dumps the defs and uses of live ranges. */ + +void dump_icg_live_ranges (FILE *fp) +{ + unsigned lr, ssa; + + if (fp == 0) fp = stdout; + /* Dump list of SSA names composing each (non-empty) live range. + Inefficient way of doing it. */ + fprintf (fp, " SSA names in live ranges:\n"); + for (lr = FIRST_PSEUDO_REGISTER; lr < icg_live_ranges; lr++) + { + bool first = true; + for (ssa = FIRST_PSEUDO_REGISTER; ssa < icg_ssa_regs; ssa++) + if (icg_ssa_to_lr[ssa] == lr) + { + if (first) + { + fprintf (fp, " "); + dump_reg (fp, false, ICG_LR_NAME, lr); + fprintf (fp, " = ("); + first = false; + } + dump_reg (fp, true, ICG_SSA_NAME, ssa); + } + if (!first) + fprintf (fp, " )\n"); + } + dump_def_uses (fp, false, true); +} diff --git a/iburg/briggs/icg-supairs.c b/iburg/briggs/icg-supairs.c new file mode 100644 index 00000000000..ec5f3d9c257 --- /dev/null +++ b/iburg/briggs/icg-supairs.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2008 Google Inc. All rights reserved. + * + * $Header: $ + */ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" + +#include "icg.h" + +/* + * TODO: the perm vector is only defined for subject nodes that are matched + * by the root of a pattern tree, where the pattern tree has >= 2 non-terminals. + * This lets us avoid overwriting legitimate permutations with the 0:0 permutation + * induced by chain rules. + */ + +static +void suOrder2(icg_node *p, icg_node *x, icg_node *y, + icg_node **kid, int kids) { + int i, j; + int cost0, cost1; + icg_node *left; + icg_node *right; + + p->perm_kids = 2; + j = 0; + for (i = 0; i < kids; i++) + if (kid[i] == x || + kid[i] == y) + p->perm[j++] = i; + + /* j should equal 2 */ + if (j != 2) + fprintf(stderr, "\n" "j != 2\n"); + + + left = kid[p->perm[0]]; + right = kid[p->perm[1]]; + cost0 = left->extra + left->freed > right->extra ? + left->extra : right->extra - left->freed + 1; + cost1 = right->extra + right->freed > left->extra ? + right->extra : left->extra - right->freed + 1; + if (cost0 > cost1) { + p->extra = cost1; + i = p->perm[0]; + p->perm[0] = p->perm[1]; + p->perm[1] = i; + } + else + p->extra = cost0; + p->freed = x->freed + y->freed; +} + + +/* see Knuth, Volume 4, Section 7.2.1.2, Algorithm L */ + +static +int next_perm(short *a, int n) { + int j, k, l, t; + + j = n - 1; + while (a[j] >= a[j + 1]) + j--; + if (j == 0) return 0; + + l = n; + while (a[j] >= a[l]) + l--; + t = a[j]; a[j] = a[l]; a[l] = t; + + k = j + 1; + l = n; + while (k < l) { + t = a[k]; a[k] = a[l]; a[l] = t; + k++; + l--; + } + return 1; +} + + +/* Is this correct? Check closely. */ + +static +int cost_of_visit(icg_node *p, int n, icg_node **kid) { + int i; + short *perm = p->perm; + int cost = 0; + int spare = 0; + for (i = 0; i < n; i++) { + int freed = kid[perm[i]]->freed; + int extra = kid[perm[i]]->extra; + if (spare < extra) { + cost += extra - spare; + spare = freed + extra - 1; + } + else + spare += freed - 1; + } + return cost; +} + + + +/* This is pretty gross. Can I find a better approach? */ + +static +void suOrder3(icg_node *p, + icg_node *x, icg_node *y, icg_node *z, + icg_node **kid, int kids) { + int i, j; + int best_index, best_cost; + int cost[MAX_KIDS]; + + p->perm_kids = 3; + j = 0; + for (i = 0; i < kids; i++) + if (kid[i] == x || + kid[i] == y || + kid[i] == z) + p->perm[j++] = i; + + /* j should equal 3 */ + if (j != 3) + fprintf(stderr, "\n" "j != 3\n"); + + i = 0; + do { + cost[i++] = cost_of_visit(p, 3, kid); + } while (next_perm(p->perm, 3)); + best_cost = cost[0]; + best_index = 0; + for (j = 1; j < i; j++) + if (cost[j] < best_cost) { + best_cost = cost[j]; + best_index = j; + } + i = p->perm[0]; + p->perm[0] = p->perm[2]; + p->perm[2] = i; + for (i = 0; i < best_index; i++) + (void) next_perm(p->perm, 3); + p->extra = best_cost; + p->freed = x->freed + y->freed + z->freed; +} + + +static +void reduce_supairs(icg_node *p, NT goalNT) { + icg_node *kid[MAX_KIDS]; + const RuleNumber rule = icg_burm_rule(p->state_label, goalNT); + const NT *nts = icg_burm_nts[rule]; + int i, kids; + + icg_burm_kids(p, rule, kid); + for (i = 0; nts[i]; i++) + reduce_supairs(kid[i], nts[i]); + kids = i; + switch (rule) { +#include "icg-supairs.cases" + } +} + + + +void icg_supairs(void) +{ + basic_block bb; + (void)suOrder3; /* this function is not currently used; shut up gcc */ + FOR_EACH_BB(bb) + { + rtx insn; + FOR_BB_INSNS(bb, insn) + { + int id = INSN_UID(insn); + if (icg_insn2dirty[id]) + { + icg_node *tree = icg_insn2tree[id]; + if (tree) { + reduce_supairs(tree, burm_goal_NT); + } + } + } + } +} diff --git a/iburg/briggs/icg-tools/iburg/LICENSE b/iburg/briggs/icg-tools/iburg/LICENSE new file mode 100644 index 00000000000..b21f90758a3 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 1993,1994,1995,1996 David R. Hanson. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +<http://www.opensource.org/licenses/mit-license.php> diff --git a/iburg/briggs/icg-tools/iburg/LOG b/iburg/briggs/icg-tools/iburg/LOG new file mode 100644 index 00000000000..3556af7cc0a --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/LOG @@ -0,0 +1,39 @@ +Tue Aug 12 10:03:34 PDT 1997 + +makefile: +Customized for use under NT. + +gram.y: +Fixed diagnostic formatting, handled cases when \n doesn't terminate +the input buffer; protected against versions of fgets that touch +buffer at EOF. + +sample4.brg: +Changed state value from int to long for 64-bit machines. + + +Tue May 7 14:20:11 PDT 1996 + +The distribution now includes the RCS files. +Specific changes are as follows; thanks to Francisco Arzu +(farzu@uvg.edu.gt) for these suggestions. + +gram.y: +Changed TERM to TERMINAL for bison. +Moved definition of yylineno for bison. +Changed hard-coded 32767 to maxcost, and checked +only costs against maxcost. +Replaced 0s in calls with NULL. + +iburg.1: +Document STATE_TYPE, -maxcost=ddd, and use of SHRT_MAX. + +iburg.c: +Implemented STATE_TYPE, default int. +Changed 32767 to maxcost, which is SHRT_MAX, SHRT_MAX/2 +(when sizeof(int)==sizeof(short)), or maxcost. Included limits.h. + + +Thu May 12 11:33:48 EDT 1994 + +initial release. diff --git a/iburg/briggs/icg-tools/iburg/README b/iburg/briggs/icg-tools/iburg/README new file mode 100644 index 00000000000..b9d4cb15df1 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/README @@ -0,0 +1,58 @@ +iburg -- A Code Generator Generator + +iburg is a code-generator generator that uses dynamic programming at +compile time. It's described in + +C. W. Fraser, D. R. Hanson and T. A. Proebsting, +Engineering a simple, efficient code generator generator, +ACM Letters on Prog. Languages and Systems 1, 3 (Sep. 1992), 213-226. +http://storage.webhop.net/documents/iburg.pdf + +iburg is written in and generates ANSI C and thus must be compiled +with an ANSI C compiler and preprocessor, e.g., gcc or lcc. To compile +iburg, type "make". There should be no warnings or errors (except +perhaps in the system-dependent YACC skeleton). If you need to +customize the makefile, edit custom.mk, which is included in makefile. +The default custom.mk is empty. + +sample.brg is from the paper in burg.ps, sample4.brg is from the paper +in iburg.ps, and sample5.brg is an example from a compilers course. +"make test" runs iburg on sample[45].brg and executes the resulting +programs. The output should be something like: + +% make test +./iburg -I sample4.brg sample4.c; cc -o test4 sample4.c; ./test4 +sample4.c +i = c + 4; +stmt: ASGNI(disp,reg) + disp: ADDRLP + reg: disp + disp: ADDI(reg,con) + reg: CVCI(INDIRC(disp)) + disp: ADDRLP + con: CNSTI +./iburg -I sample5.brg sample5.c; cc -o test5 sample5.c; ./test5 +sample5.c +stm: MOVE(MEM(loc),reg) + loc: NAME + reg: PLUS(MEM(loc),reg) + loc: PLUS(NAME,reg) + reg: MEM(loc) + loc: NAME + reg: con + con: CONST +% + +To install iburg, copy it and its man page to the appropriate local +directories, e.g., on UNIX: + +% cp iburg /usr/local +% cp iburg.1 /usr/local/man/man1 + +"make clobber" removes the executables and all derived files except +gram.c; "make clean" removes just object, core, and sample*.c files. + +Mail bug reports along with the shortest input that exposes them to +drh@drhanson.net. + +$Id: README 71 2006-12-11 01:22:25Z drhanson $ diff --git a/iburg/briggs/icg-tools/iburg/custom.mk b/iburg/briggs/icg-tools/iburg/custom.mk new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/custom.mk diff --git a/iburg/briggs/icg-tools/iburg/gram.y b/iburg/briggs/icg-tools/iburg/gram.y new file mode 100644 index 00000000000..56734e79233 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/gram.y @@ -0,0 +1,174 @@ +%{ +#include <string.h> +#include <stdio.h> +#include <limits.h> +#include "iburg.h" +static char rcsid[] = "$Id: gram.y 71 2006-12-11 01:22:25Z drhanson $"; +static int yylineno = 0; +%} +%union { + int n; + char *string; + Tree tree; +} +%term TERMINAL +%term START +%term PPERCENT + +%token <string> ID +%token <n> INT +%type <string> lhs +%type <tree> tree +%type <n> cost +%% +spec : decls PPERCENT rules { yylineno = 0; } + | decls { yylineno = 0; } + ; + +decls : /* lambda */ + | decls decl + ; + +decl : TERMINAL blist '\n' + | START lhs '\n' { + if (nonterm($2)->number != 1) + yyerror("redeclaration of the start symbol\n"); + } + | '\n' + | error '\n' { yyerrok; } + ; + +blist : /* lambda */ + | blist ID '=' INT { term($2, $4); } + ; + +rules : /* lambda */ + | rules lhs ':' tree '=' INT cost ';' '\n' { rule($2, $4, $6, $7); } + | rules '\n' + | rules error '\n' { yyerrok; } + ; + +lhs : ID { nonterm($$ = $1); } + ; + +tree : ID { $$ = tree($1, NULL, NULL); } + | ID '(' tree ')' { $$ = tree($1, $3, NULL); } + | ID '(' tree ',' tree ')' { $$ = tree($1, $3, $5); } + ; + +cost : /* lambda */ { $$ = 0; } + | '(' INT ')' { if ($2 > maxcost) { + yyerror("%d exceeds maximum cost of %d\n", $2, maxcost); + $$ = maxcost; + } else + $$ = $2; } + ; +%% +#include <stdarg.h> +#include <ctype.h> + +int errcnt = 0; +FILE *infp = NULL; +FILE *outfp = NULL; +static char buf[BUFSIZ], *bp = buf; +static int ppercent = 0; + +static int get(void) { + if (*bp == 0) { + bp = buf; + *bp = 0; + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; + while (buf[0] == '%' && buf[1] == '{' && (buf[2] == '\n' || buf[2] == '\r')) { + for (;;) { + if (fgets(buf, sizeof buf, infp) == NULL) { + yywarn("unterminated %{...%}\n"); + return EOF; + } + yylineno++; + if (strcmp(buf, "%}\n") == 0 || strcmp(buf, "%}\r\n") == 0) + break; + fputs(buf, outfp); + } + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; + } + } + return *bp++; +} + +void yyerror(char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + if (yylineno > 0) + fprintf(stderr, "line %d: ", yylineno); + vfprintf(stderr, fmt, ap); + if (fmt[strlen(fmt)-1] != '\n') + fprintf(stderr, "\n"); + errcnt++; +} + +int yylex(void) { + int c; + + while ((c = get()) != EOF) { + switch (c) { + case ' ': case '\f': case '\t': case '\r': + continue; + case '\n': + case '(': case ')': case ',': + case ';': case '=': case ':': + return c; + } + if (c == '%' && *bp == '%') { + bp++; + return ppercent++ ? 0 : PPERCENT; + } else if (c == '%' && strncmp(bp, "term", 4) == 0 + && isspace(bp[4])) { + bp += 4; + return TERMINAL; + } else if (c == '%' && strncmp(bp, "start", 5) == 0 + && isspace(bp[5])) { + bp += 5; + return START; + } else if (isdigit(c)) { + int n = 0; + do { + int d = c - '0'; + if (n > (INT_MAX - d)/10) + yyerror("integer greater than %d\n", INT_MAX); + else + n = 10*n + d; + c = get(); + } while (c != EOF && isdigit(c)); + bp--; + yylval.n = n; + return INT; + } else if (isalpha(c)) { + char *p = bp - 1; + while (isalpha(*bp) || isdigit(*bp) || *bp == '_') + bp++; + yylval.string = alloc(bp - p + 1); + strncpy(yylval.string, p, bp - p); + yylval.string[bp - p] = 0; + return ID; + } else if (isprint(c)) + yyerror("invalid character `%c'\n", c); + else + yyerror("invalid character `\\%03o'\n", (unsigned char)c); + } + return 0; +} + +void yywarn(char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + if (yylineno > 0) + fprintf(stderr, "line %d: ", yylineno); + fprintf(stderr, "warning: "); + vfprintf(stderr, fmt, ap); +} diff --git a/iburg/briggs/icg-tools/iburg/iburg.1 b/iburg/briggs/icg-tools/iburg/iburg.1 new file mode 100644 index 00000000000..e1c17b72915 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/iburg.1 @@ -0,0 +1,285 @@ +.TH IBURG 1 "local \- 1/26/93" +.\" $Id: iburg.1 71 2006-12-11 01:22:25Z drhanson $ +.SH NAME +iburg \- code generator generator +.SH SYNOPSIS +.B iburg +[ +.I option +]... +[ [ +.I input +] +.I output +] +.br +.SH DESCRIPTION +.PP +.I iburg +reads BURG specification from +.I input +and writes a pattern-matching code generator to +.IR output . +If +.I input +is `\-' or is omitted, +.I iburg +reads the standard input; +If +.I output +is `\-' or is omitted, +.I iburg +writes to the standard output. +.PP +.I iburg +accepts BURG specifications that conform to the following EBNF grammar. +Terminals are enclosed in single quotes, all other symbols are nonterminals, +{X} denotes zero or more instances of X, and [X] denotes an optional X. +.PP +.nf +.RS +.ft CW +spec: { dcl } `%%' { rule } [ `%%' ] + +dcl: `%start' nonterm + `%term' { identifier `=' integer } + +rule: nonterm `:' tree `=' integer [ cost ] `;' + +cost: `(' integer ')' + +tree: term `(' tree `,' tree `)' + term `(' tree `)' + term + nonterm +.RE +.fi +.PP +Specifications are structurally similar to +.IR yacc 's. +Text between +`\f(CW%{\fP' +and +`\f(CW%}\fP' +is called the configuration section; there may be several such segments. +All are concatenated and copied verbatim into the head of the generated +parser, which is called burm. +Text after the second +`\f(CW%%\fP', +if any, is also copied verbatim into +.IR burm , +at the end. +.PP +Specifications consist of declarations, a +`\f(CW%%\fP' +separator, and rules. +Input is line-oriented; each declaration and rule must appear on a separate line, +and declarations must begin in column 1. +Declarations declare terminals \(em the operators in subject +trees \(em and associate a unique, positive external symbol +number with each one. +Non-terminals are declared by their presence +on the left side of rules. The +\f(CW%start\fP +declaration optionally declares a non-terminal as the start symbol. +In the grammar above, +\f(CWterm\fP +and +\f(CWnonterm\fP +denote identifiers that are terminals and non-terminals, respectively. +.PP +Rules define tree patterns in a fully parenthesized prefix +form. Every non-terminal denotes a tree. +Each operator has a fixed +arity, which is inferred from the rules in which it is used. +A chain rule is a rule whose pattern is another non-terminal. +If no start symbol is declared, the non-terminal defined by the first rule is used. +.PP +Each rule has a unique, positive external rule number, which +comes after the pattern and is preceded by a +`\f(CW=\fP'. +External rule numbers are used to report the +matching rule to a user-supplied semantic action routine. +Rules end with an optional non-negative, integer cost; omitted costs +default to zero. +.PP +The display below shows a fragment of a BURG specification. +This example uses upper-case for terminals and lower-case for non-terminals. +.PP +.nf +.ft CW +%{ +enum { ADDI=309, ADDRLP=295, ASGNI=53, + CNSTI=21, CVCI=85, I0I=661, INDIRC=67 }; + +typedef struct tree { + int op; + struct tree *kids[2]; + int val; + struct { int state; } x; +} *NODEPTR_TYPE, *Tree; +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define PANIC printf +#define STATE_LABEL(p) ((p)->x.state) + +int OP_LABEL(NODEPTR_TYPE p) { + switch (p->op) { + case CNSTI: if (p->val == 0) return 661 /* I0I */; + default: return p->op; + } +} +%} +%term ADDI=309 ADDRLP=295 ASGNI=53 +%term CNSTI=21 CVCI=85 I0I=661 INDIRC=67 +%% +stmt: ASGNI(disp,reg) = 4 (1); +stmt: reg = 5; +reg: ADDI(reg,rc) = 6 (1); +reg: CVCI(INDIRC(disp)) = 7 (1); +reg: I0I = 8; +reg: disp = 9 (1); +disp: ADDI(reg,con) = 10; +disp: ADDRLP = 11; +rc: con = 12; +rc: reg = 13; +con: CNSTI = 14; +con: I0I = 15; +%% +.fi +.PP +The configuration section configures +\f(CWburm\fP +for the trees being parsed and the client's environment. +As shown, this section must define +\f(CWNODEPTR_TYPE\fP +to be a visible typedef symbol for a pointer to a +node in the subject tree. +\f(CWburm\fP +invokes +\f(CWOP_LABEL(p)\fP, +\f(CWLEFT\_CHILD(p)\fP, and +\f(CWRIGHT\_CHILD(p)\fP +to read the operator and children from the node pointed to by \f(CWp\fP. +It invokes +\f(CWPANIC\fP +when it detects an error. +If the configuration section defines these operations as macros, they are implemented in-line; +otherwise, they must be implemented as functions. +.PP +By default, +\f(CWburm\fP +computes and stores a single integral state in each node of the subject tree. +The configuration section must define a macro +\f(CWSTATE_LABEL(p)\fP +to access the state field of the node pointed to +by \f(CWp\fP. It must be large enough to hold a pointer, and +a macro is required because it is used as an lvalue. +The configuration section may define the macro +\f(CWSTATE_TYPE\fP +to specify a different type for state values; if +\f(CWSTATE_TYPE\fP +is not defined, int is used. +.PP +The configuration section may also define +\f(CWALLOC(n)\fP +for allocating +\f(CWn\fP +bytes. +If +\f(CWALLOC\fP +is not defined, +.IR malloc (3) +is used. +.SH OPTIONS +.TP +.BI \-p \ prefix +.br +.ns +.TP +.BI \-p prefix +Use +.I prefix +as the disambiquating prefix for exported names and visible fields. +The default is `\f(CWburm\fP'. +.TP +.BI \-maxcost= ddd +Use the integral value +.I ddd +as the maximum cost. +The default is \f(CWSHRT_MAX\fR +when ints are bigger than shorts, and +\f(CWSHRT_MAX\fP/2 when ints and shorts are the same size. +.TP +.B \-I +Emit code for the following data values and functions. +.sp +.nf +.ft CW + char burm_arity[]; + char *burm_opname[]; + char *burm_ntname[]; + char *burm_string[]; + short burm_cost[][4]; + int burm_op_label(NODEPTR_TYPE p); + NODEPTR_TYPE burm_child(NODEPTR_TYPE p, int index); + STATE_TYPE burm_state_label(NODEPTR_TYPE p); +.sp +.fi +.ft R +\f(CWburm_arity\fP and +\f(CWburm_opname\fP +are indexed by external symbol numbers and gives their arities. +\f(CWburm_ntname\fP +is indexed by a non-terminal number and gives its string name. +\f(CWburm_string\fP +and +\f(CWburm_cost\fP +are indexed by an external rule number and give the string +representation and cost of each rule. +The functions encapsulate the similarly named macros. +.TP +.B \-T +Arrange for +.sp +.nf +.ft CW + void burm_trace(NODEPTR_TYPE p, int eruleno, + int cost, int bestcost); +.sp +.fi +.ft R +to be called at each successful match. +\f(CWp\fP +identifies the node and +\f(CWeruleno\fP +identifies the matching rule; +\f(CWeruleno\fP +is an index into \f(CWburm_string\fP. +\f(CWcost\fP +is the cost of the match and +\f(CWbestcost\fP +is the cost of the best previous match. The current match +wins only if +\f(CWcost\fP +is less than \f(CWbestcost\fP. +SHRT_MAX represents the infinite cost of no previous match. +\f(CWburm_trace\fP must be declared in the configuration section. +.SH "SEE ALSO" +C. W. Fraser, R. R. Henry and T. A. Proebsting, +`BURG \(em Fast optimal instruction selection and tree parsing,' +.I +SIGPLAN Notices +.BR 27 , +4 (Apr. 1992), 68-76. +.PP +C. W. Fraser, D. R. Hanson and T. A. Proebsting, +`Engineering a simple, efficient code generator generator,' +.I +ACM Letters on Programming Languages and Systems +.BR 1 , +3 (Sep. 1992), 213-226. +.br +.SH BUGS +Mail bug reports along with the shortest input +that exposes them to drh@drhanson.net. diff --git a/iburg/briggs/icg-tools/iburg/iburg.c b/iburg/briggs/icg-tools/iburg/iburg.c new file mode 100644 index 00000000000..e749381d61d --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/iburg.c @@ -0,0 +1,759 @@ +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <limits.h> +#include "iburg.h" + +static char rcsid[] = "$Id: iburg.c 71 2006-12-11 01:22:25Z drhanson $"; + +float maxcost = (1./0.); + +static char *prefix = "burm"; +static int Iflag = 0, Tflag = 0; +static int ntnumber = 0; +static Nonterm start = 0; +static Term terms; +static Nonterm nts; +static Rule rules; +static int nrules; + +static char *stringf(char *fmt, ...); +static void print(char *fmt, ...); +static void ckreach(Nonterm p); +static void emitclosure(Nonterm nts); +static void emitcost(Tree t, char *v); +static void emitdefs(Nonterm nts, int ntnumber); +static void emitfuncs(void); +static void emitheader(void); +static void emitkids(Rule rules, int nrules); +static void emitlabel(Nonterm start); +static void emitleaf(Term p, int ntnumber); +static void emitnts(Rule rules, int nrules); +static void emitrecord(char *pre, Rule r, float cost); +static void emitrule(Nonterm nts); +static void emitstate(Term terms, Nonterm start, int ntnumber); +static void emitstring(Rule rules); +static void emitstruct(Nonterm nts, int ntnumber); +static void emitterms(Term terms); +static void emittest(Tree t, char *v, char *suffix); + +int main(int argc, char *argv[]) { + int c, i; + Nonterm p; + + for (i = 1; i < argc; i++) + if (strcmp(argv[i], "-I") == 0) + Iflag = 1; + else if (strcmp(argv[i], "-T") == 0) + Tflag = 1; + else if (strncmp(argv[i], "-maxcost=", 9) == 0 && isdigit(argv[i][9])) + maxcost = atoi(argv[i] + 9); + else if (strncmp(argv[i], "-p", 2) == 0 && argv[i][2]) + prefix = &argv[i][2]; + else if (strncmp(argv[i], "-p", 2) == 0 && i + 1 < argc) + prefix = argv[++i]; + else if (*argv[i] == '-' && argv[i][1]) { + yyerror("usage: %s [-T | -I | -p prefix | -maxcost=ddd ]... [ [ input ] output]\n", + argv[0]); + exit(1); + } else if (infp == NULL) { + if (strcmp(argv[i], "-") == 0) + infp = stdin; + else if ((infp = fopen(argv[i], "r")) == NULL) { + yyerror("%s: can't read `%s'\n", argv[0], argv[i]); + exit(1); + } + } else if (outfp == NULL) { + if (strcmp(argv[i], "-") == 0) + outfp = stdout; + if ((outfp = fopen(argv[i], "w")) == NULL) { + yyerror("%s: can't write `%s'\n", argv[0], argv[i]); + exit(1); + } + } + if (infp == NULL) + infp = stdin; + if (outfp == NULL) + outfp = stdout; + yyparse(); + if (start) + ckreach(start); + for (p = nts; p; p = p->link) + if (!p->reached) + yyerror("can't reach non-terminal `%s'\n", p->name); + emitheader(); + emitdefs(nts, ntnumber); + emitstruct(nts, ntnumber); + emitnts(rules, nrules); + emitterms(terms); + if (Iflag) + emitstring(rules); + emitrule(nts); + emitclosure(nts); + if (start) + emitstate(terms, start, ntnumber); + print("#ifdef STATE_LABEL\n"); + if (start) + emitlabel(start); + emitkids(rules, nrules); + emitfuncs(); + print("#endif\n"); + if (!feof(infp)) + while ((c = getc(infp)) != EOF) + putc(c, outfp); + return errcnt > 0; +} + +/* alloc - allocate nbytes or issue fatal error */ +void *alloc(int nbytes) { + void *p = calloc(1, nbytes); + + if (p == NULL) { + yyerror("out of memory\n"); + exit(1); + } + return p; +} + +/* stringf - format and save a string */ +static char *stringf(char *fmt, ...) { + va_list ap; + char *s, buf[512]; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + return strcpy(alloc(strlen(buf) + 1), buf); +} + +struct entry { + union { + char *name; + struct term t; + struct nonterm nt; + } sym; + struct entry *link; +} *table[211]; +#define HASHSIZE (sizeof table/sizeof table[0]) + +/* hash - return hash number for str */ +static unsigned hash(char *str) { + unsigned h = 0; + + while (*str) + h = (h<<1) + *str++; + return h; +} + +/* lookup - lookup symbol name */ +static void *lookup(char *name) { + struct entry *p = table[hash(name)%HASHSIZE]; + + for ( ; p; p = p->link) + if (strcmp(name, p->sym.name) == 0) + return &p->sym; + return 0; +} + +/* install - install symbol name */ +static void *install(char *name) { + struct entry *p = alloc(sizeof *p); + int i = hash(name)%HASHSIZE; + + p->sym.name = name; + p->link = table[i]; + table[i] = p; + return &p->sym; +} + +/* nonterm - create a new terminal id, if necessary */ +Nonterm nonterm(char *id) { + Nonterm p = lookup(id), *q = &nts; + + if (p && p->kind == NONTERM) + return p; + if (p && p->kind == TERM) + yyerror("`%s' is a terminal\n", id); + p = install(id); + p->kind = NONTERM; + p->number = ++ntnumber; + if (p->number == 1) + start = p; + while (*q && (*q)->number < p->number) + q = &(*q)->link; + assert(*q == 0 || (*q)->number != p->number); + p->link = *q; + *q = p; + return p; +} + +/* term - create a new terminal id with external symbol number esn */ +Term term(char *id, int esn) { + Term p = lookup(id), *q = &terms; + + if (p) + yyerror("redefinition of terminal `%s'\n", id); + else + p = install(id); + p->kind = TERM; + p->esn = esn; + p->arity = -1; + while (*q && (*q)->esn < p->esn) + q = &(*q)->link; + if (*q && (*q)->esn == p->esn) + yyerror("duplicate external symbol number `%s=%d'\n", + p->name, p->esn); + p->link = *q; + *q = p; + return p; +} + +/* tree - create & initialize a tree node with the given fields */ +Tree tree(char *id, Tree left, Tree right) { + Tree t = alloc(sizeof *t); + Term p = lookup(id); + int arity = 0; + + if (left && right) + arity = 2; + else if (left) + arity = 1; + if (p == NULL && arity > 0) { + yyerror("undefined terminal `%s'\n", id); + p = term(id, -1); + } else if (p == NULL && arity == 0) + p = (Term)nonterm(id); + else if (p && p->kind == NONTERM && arity > 0) { + yyerror("`%s' is a non-terminal\n", id); + p = term(id, -1); + } + if (p->kind == TERM && p->arity == -1) + p->arity = arity; + if (p->kind == TERM && arity != p->arity) + yyerror("inconsistent arity for terminal `%s'\n", id); + t->op = p; + t->nterms = p->kind == TERM; + if (t->left = left) + t->nterms += left->nterms; + if (t->right = right) + t->nterms += right->nterms; + return t; +} + +/* rule - create & initialize a rule with the given fields */ +Rule rule(char *id, Tree pattern, int ern, float cost) { + Rule r = alloc(sizeof *r), *q; + Term p = pattern->op; + + nrules++; + r->lhs = nonterm(id); + r->packed = ++r->lhs->lhscount; + for (q = &r->lhs->rules; *q; q = &(*q)->decode) + ; + *q = r; + r->pattern = pattern; + r->ern = ern; + r->cost = cost; + if (p->kind == TERM) { + r->next = p->rules; + p->rules = r; + } else if (pattern->left == NULL && pattern->right == NULL) { + Nonterm p = pattern->op; + r->chain = p->chain; + p->chain = r; + } + for (q = &rules; *q && (*q)->ern < r->ern; q = &(*q)->link) + ; + if (*q && (*q)->ern == r->ern) + yyerror("duplicate external rule number `%d'\n", r->ern); + r->link = *q; + *q = r; + return r; +} + +/* print - formatted output */ +static void print(char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + for ( ; *fmt; fmt++) + if (*fmt == '%') + switch (*++fmt) { + case 'd': fprintf(outfp, "%d", va_arg(ap, int)); break; + case 'f': fprintf(outfp, "%g", va_arg(ap, double)); break; + case 's': fputs(va_arg(ap, char *), outfp); break; + case 'P': fprintf(outfp, "%s_", prefix); break; + case 'T': { + Tree t = va_arg(ap, Tree); + print("%S", t->op); + if (t->left && t->right) + print("(%T,%T)", t->left, t->right); + else if (t->left) + print("(%T)", t->left); + break; + } + case 'R': { + Rule r = va_arg(ap, Rule); + print("%S: %T", r->lhs, r->pattern); + break; + } + case 'S': fputs(va_arg(ap, Term)->name, outfp); break; + case '1': case '2': case '3': case '4': case '5': { + int n = *fmt - '0'; + while (n-- > 0) + putc('\t', outfp); + break; + } + default: putc(*fmt, outfp); break; + } + else + putc(*fmt, outfp); + va_end(ap); +} + +/* reach - mark all non-terminals in tree t as reachable */ +static void reach(Tree t) { + Nonterm p = t->op; + + if (p->kind == NONTERM) + if (!p->reached) + ckreach(p); + if (t->left) + reach(t->left); + if (t->right) + reach(t->right); +} + +/* ckreach - mark all non-terminals reachable from p */ +static void ckreach(Nonterm p) { + Rule r; + + p->reached = 1; + for (r = p->rules; r; r = r->decode) + reach(r->pattern); +} + +/* emitcase - emit one case in function state */ +static void emitcase(Term p, int ntnumber) { + Rule r; + + print("%1case %d: /* %S */\n", p->esn, p); + switch (p->arity) { + case 0: case -1: + if (!Tflag) { + emitleaf(p, ntnumber); + return; + } + break; + case 1: print("%2assert(l);\n"); break; + case 2: print("%2assert(l && r);\n"); break; + default: assert(0); + } + for (r = p->rules; r; r = r->next) { + switch (p->arity) { + case 0: case -1: + print("%2{%1/* %R */\n%3c = ", r); + break; + case 1: + if (r->pattern->nterms > 1) { + print("%2if (%1/* %R */\n", r); + emittest(r->pattern->left, "l", " "); + print("%2) {\n%3c = "); + } else + print("%2{%1/* %R */\n%3c = ", r); + emitcost(r->pattern->left, "l"); + break; + case 2: + if (r->pattern->nterms > 1) { + print("%2if (%1/* %R */\n", r); + emittest(r->pattern->left, "l", + r->pattern->right->nterms ? " && " : " "); + emittest(r->pattern->right, "r", " "); + print("%2) {\n%3c = "); + } else + print("%2{%1/* %R */\n%3c = ", r); + emitcost(r->pattern->left, "l"); + emitcost(r->pattern->right, "r"); + break; + default: assert(0); + } + print("%f;\n", r->cost); + emitrecord("\t\t\t", r, 0); + print("%2}\n"); + } + print("%2break;\n"); +} + +/* emitclosure - emit the closure functions */ +static void emitclosure(Nonterm nts) { + Nonterm p; + + for (p = nts; p; p = p->link) + if (p->chain) + print("static void %Pclosure_%S(struct %Pstate *, float);\n", p); + print("\n"); + for (p = nts; p; p = p->link) + if (p->chain) { + Rule r; + print("static void %Pclosure_%S(struct %Pstate *p, float c) {\n", p); + print("\t(void)%Pclosure_%S;\n", p); + for (r = p->chain; r; r = r->chain) + emitrecord("\t", r, r->cost); + print("}\n\n"); + } +} + +/* emitcost - emit cost computation for tree t */ +static void emitcost(Tree t, char *v) { + Nonterm p = t->op; + + if (p->kind == TERM) { + if (t->left) + emitcost(t->left, stringf("%s->left", v)); + if (t->right) + emitcost(t->right, stringf("%s->right", v)); + } else + print("%s->cost[%P%S_NT] + ", v, p); +} + +/* emitdefs - emit non-terminal defines and data structures */ +static void emitdefs(Nonterm nts, int ntnumber) { + Nonterm p; + + char *sep = " "; + print("enum %P_NT {\n"); + for (p = nts; p; p = p->link) { + print("%s%P%S_NT= %d\n", sep, p, p->number); + sep = ","; + } + print("%s%Pmax_nt = %d\n\n", sep, ntnumber); + print("};\n"); + if (Iflag) { + print("const char *const %Pntname[] = {\n%10,\n"); + for (p = nts; p; p = p->link) + print("%1\"%S\",\n", p); + print("%10\n};\n\n"); + } +} + +/* emitfuncs - emit functions to access node fields */ +static void emitfuncs(void) { + print("int %Pop_label(NODEPTR_TYPE p) {\n" +"%1%Passert(p, PANIC(\"NULL tree in %Pop_label\\n\"));\n" +"%1return OP_LABEL(p);\n}\n\n"); + print("STATE_TYPE %Pstate_label(NODEPTR_TYPE p) {\n" +"%1%Passert(p, PANIC(\"NULL tree in %Pstate_label\\n\"));\n" +"%1return STATE_LABEL(p);\n}\n\n"); + print("NODEPTR_TYPE %Pchild(NODEPTR_TYPE p, int index) {\n" +"%1%Passert(p, PANIC(\"NULL tree in %Pchild\\n\"));\n" +"%1switch (index) {\n%1case 0:%1return LEFT_CHILD(p);\n" +"%1case 1:%1return RIGHT_CHILD(p);\n%1}\n" +"%1%Passert(0, PANIC(\"Bad index %%d in %Pchild\\n\", index));\n%1return 0;\n}\n\n"); +} + +/* emitheader - emit initial definitions */ +static void emitheader(void) { + print("#include <limits.h>\n#include <stdlib.h>\n"); + print("#ifndef STATE_TYPE\n#define STATE_TYPE int\n#endif\n"); + print("#ifndef ALLOC\n#define ALLOC(n) malloc(n)\n#endif\n" +"#ifndef %Passert\n#define %Passert(x,y) if (!(x)) { y; abort(); }\n#endif\n\n"); + if (Tflag) + print("static NODEPTR_TYPE %Pnp;\n\n"); + printf("#define inf (1./0.)\n\n"); +} + +/* computekids - compute paths to kids in tree t */ +static char *computekids(Tree t, char *v, char *bp, int *ip) { + Term p = t->op; + + if (p->kind == NONTERM) { + sprintf(bp, "\t\tkids[%d] = %s;\n", (*ip)++, v); + bp += strlen(bp); + } else if (p->arity > 0) { + bp = computekids(t->left, stringf("LEFT_CHILD(%s)", v), bp, ip); + if (p->arity == 2) + bp = computekids(t->right, stringf("RIGHT_CHILD(%s)", v), bp, ip); + } + return bp; +} + +/* emitkids - emit burm_kids */ +static void emitkids(Rule rules, int nrules) { + int i; + Rule r, *rc = alloc((nrules + 1)*sizeof *rc); + char **str = alloc((nrules + 1)*sizeof *str); + + for (i = 0, r = rules; r; r = r->link) { + int j = 0; + char buf[1024], *bp = buf; + *computekids(r->pattern, "p", bp, &j) = 0; + for (j = 0; str[j] && strcmp(str[j], buf); j++) + ; + if (str[j] == NULL) + str[j] = strcpy(alloc(strlen(buf) + 1), buf); + r->kids = rc[j]; + rc[j] = r; + } + print("NODEPTR_TYPE *%Pkids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]) {\n" +"%1%Passert(p, PANIC(\"NULL tree in %Pkids\\n\"));\n" +"%1%Passert(kids, PANIC(\"NULL kids in %Pkids\\n\"));\n" +"%1switch (eruleno) {\n"); + for (i = 0; r = rc[i]; i++) { + for ( ; r; r = r->kids) + print("%1case %d: /* %R */\n", r->ern, r); + print("%s%2break;\n", str[i]); + } + print("%1default:\n%2%Passert(0, PANIC(\"Bad external rule number %%d in %Pkids\\n\", eruleno));\n%1}\n%1return kids;\n}\n\n"); +} + +/* emitlabel - emit the labelling functions */ +static void emitlabel(Nonterm start) { + print("static void %Plabel1(NODEPTR_TYPE p) {\n" +"%1%Passert(p, PANIC(\"NULL tree in %Plabel\\n\"));\n" +"%1switch (%Parity[OP_LABEL(p)]) {\n" +"%1case 0:\n"); + if (Tflag) + print("%2%Pnp = p;\n"); + print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p), 0, 0);\n%2break;\n" +"%1case 1:\n%2%Plabel1(LEFT_CHILD(p));\n"); + if (Tflag) + print("%2%Pnp = p;\n"); + print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p),\n" +"%3STATE_LABEL(LEFT_CHILD(p)), 0);\n%2break;\n" +"%1case 2:\n%2%Plabel1(LEFT_CHILD(p));\n%2%Plabel1(RIGHT_CHILD(p));\n"); + if (Tflag) + print("%2%Pnp = p;\n"); + print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p),\n" +"%3STATE_LABEL(LEFT_CHILD(p)),\n%3STATE_LABEL(RIGHT_CHILD(p)));\n%2break;\n" +"%1}\n}\n\n"); + print( +"STATE_TYPE %Plabel(NODEPTR_TYPE p) {\n%1%Plabel1(p);\n" +"%1return ((struct %Pstate *)STATE_LABEL(p))->rule.%P%S ? STATE_LABEL(p) : 0;\n" +"}\n\n", start); +} + +/* closure - fill in cost & rule with results of chain rules w/p as rhs */ +static void closure(float cost[], Rule rule[], Nonterm p, float c) { + Rule r; + + for (r = p->chain; r; r = r->chain) + if (c + r->cost < cost[r->lhs->number]) { + cost[r->lhs->number] = c + r->cost; + rule[r->lhs->number] = r; + closure(cost, rule, r->lhs, c + r->cost); + } +} + +/* emitleaf - emit state code for a leaf */ +static void emitleaf(Term p, int ntnumber) { + int i; + Rule r; + static float *cost; + static Rule *rule; + + if (cost == NULL) { + cost = alloc((ntnumber + 1)*sizeof *cost); + rule = alloc((ntnumber + 1)*sizeof *rule); + } + for (i = 0; i <= ntnumber; i++) { + cost[i] = maxcost; + rule[i] = NULL; + } + for (r = p->rules; r; r = r->next) + if (r->pattern->left == NULL && r->pattern->right == NULL) { + cost[r->lhs->number] = r->cost; + rule[r->lhs->number] = r; + closure(cost, rule, r->lhs, r->cost); + } + print("%2{\n%3static struct %Pstate z = { %d, 0, 0,\n%4{%10,\n", p->esn); + for (i = 1; i <= ntnumber; i++) + if (cost[i] < maxcost) + print("%5%f,%1/* %R */\n", cost[i], rule[i]); + else + print("%5%f,\n", cost[i]); + print("%4},{\n"); + for (i = 1; i <= ntnumber; i++) + if (rule[i]) + print("%5%d,%1/* %R */\n", rule[i]->packed, rule[i]); + else + print("%50,\n"); + print("%4}\n%3};\n%3return (STATE_TYPE)&z;\n%2}\n"); +} + +/* computents - fill in bp with burm_nts vector for tree t */ +static char *computents(Tree t, char *bp) { + if (t) { + Nonterm p = t->op; + if (p->kind == NONTERM) { + sprintf(bp, "%s_%s_NT, ", prefix, p->name); + bp += strlen(bp); + } else + bp = computents(t->right, computents(t->left, bp)); + } + return bp; +} + +/* emitnts - emit burm_nts ragged array */ +static void emitnts(Rule rules, int nrules) { + Rule r; + int i, j, *nts = alloc(nrules*sizeof *nts); + char **str = alloc(nrules*sizeof *str); + + for (i = 0, r = rules; r; r = r->link) { + char buf[1024]; + *computents(r->pattern, buf) = 0; + for (j = 0; str[j] && strcmp(str[j], buf); j++) + ; + if (str[j] == NULL) { + print("static short const %Pnts_%d[] = { %s0 };\n", j, buf); + str[j] = strcpy(alloc(strlen(buf) + 1), buf); + } + nts[i++] = j; + } + print("\nconst short *const %Pnts[] = {\n"); + for (i = j = 0, r = rules; r; r = r->link) { + for ( ; j < r->ern; j++) + print("%10,%1/* %d */\n", j); + print("%1%Pnts_%d,%1/* %d */\n", nts[i++], j++); + } + print("};\n\n"); +} + +/* emitrecord - emit code that tests for a winning match of rule r */ +static void emitrecord(char *pre, Rule r, float cost) { + print("%sif (", pre); + if (Tflag) + print("%Ptrace(%Pnp, %d, c + %f, p->cost[%P%S_NT]), ", + r->ern, cost, r->lhs); + print("c + %f < p->cost[%P%S_NT]) {\n" +"%s%1p->cost[%P%S_NT] = c + %f;\n%s%1p->rule.%P%S = %d;\n", + cost, r->lhs, pre, r->lhs, cost, pre, r->lhs, + r->packed); + if (r->lhs->chain) + print("%s%1%Pclosure_%S(p, c + %f);\n", pre, r->lhs, cost); + print("%s}\n", pre); +} + +/* emitrule - emit decoding vectors and burm_rule */ +static void emitrule(Nonterm nts) { + Nonterm p; + + for (p = nts; p; p = p->link) { + Rule r; + print("static short const %Pdecode_%S[] = {\n%10,\n", p); + for (r = p->rules; r; r = r->decode) + print("%1%d,\n", r->ern); + print("};\n\n"); + } + + print("float %Pget_cost(const STATE_TYPE state, short goalnt) {\n" +"%1%Passert(goalnt >= 1 && goalnt <= %d, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n" +"%1if (!state)\n%2return inf;\n", ntnumber); + print("return ((struct %Pstate *)state)->cost[goalnt];\n", p); + print("}\n"); + + print("int %Prule(const STATE_TYPE state, short goalnt) {\n" +"%1%Passert(goalnt >= 1 && goalnt <= %d, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n" +"%1if (!state)\n%2return 0;\n%1switch (goalnt) {\n", ntnumber); + for (p = nts; p; p = p->link) + print("%1case %P%S_NT:" +"%1return %Pdecode_%S[((struct %Pstate *)state)->rule.%P%S];\n", p, p, p); + print("%1default:\n%2%Passert(0, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n%1}\n%1return 0;\n}\n\n"); +} + +/* emitstate - emit state function */ +static void emitstate(Term terms, Nonterm start, int ntnumber) { + int i; + Term p; + + print("STATE_TYPE %Pstate(int op, STATE_TYPE left, STATE_TYPE right) {\n%1float c;\n" +"%1struct %Pstate *p, *l = (struct %Pstate *)left,\n" +"%2*r = (struct %Pstate *)right;\n\n%1assert(sizeof (STATE_TYPE) >= sizeof (void *));\n%1"); + if (!Tflag) + print("if (%Parity[op] > 0) "); + print("{\n%2p = (struct %Pstate *)ALLOC(sizeof *p);\n" +"%2%Passert(p, PANIC(\"ALLOC returned NULL in %Pstate\\n\"));\n" +"%2p->op = op;\n%2p->left = l;\n%2p->right = r;\n%2p->rule.%P%S = 0;\n", start); + for (i = 1; i <= ntnumber; i++) + print("%2p->cost[%d] =\n", i); + print("%3%f;\n%1}\n%1switch (op) {\n", maxcost); + for (p = terms; p; p = p->link) + emitcase(p, ntnumber); + print("%1default:\n" +"%2%Passert(0, PANIC(\"Bad operator %%d in %Pstate\\n\", op));\n%1}\n" +"%1return (STATE_TYPE)p;\n}\n\n"); +} + +/* emitstring - emit array of rules and costs */ +static void emitstring(Rule rules) { + Rule r; + int k; + + print("float const %Pcost[][4] = {\n"); + for (k = 0, r = rules; r; r = r->link) { + for ( ; k < r->ern; k++) + print("%1{ 0 },%1/* %d */\n", k); + print("%1{ %f },%1/* %d = %R */\n", r->cost, k++, r); + } + print("};\n\nconst char *const %Pstring [] = {\n"); + for (k = 0, r = rules; r; r = r->link) { + for ( ; k < r->ern; k++) + print("%1/* %d */%10,\n", k); + print("%1/* %d */%1\"%R\",\n", k++, r); + } + print("};\n\n"); +} + +/* emitstruct - emit the definition of the state structure */ +static void emitstruct(Nonterm nts, int ntnumber) { + print("struct %Pstate {\n%1int op;\n%1struct %Pstate *left, *right;\n" +"%1float cost[%d];\n%1struct {\n", ntnumber + 1); + for ( ; nts; nts = nts->link) { + int n = 1, m = nts->lhscount; + while (m >>= 1) + n++; + print("%2unsigned %P%S:%d;\n", nts, n); + } + print("%1} rule;\n};\n\n"); +} + +/* emitterms - emit terminal data structures */ +static void emitterms(Term terms) { + Term p; + int k; + + print("char const %Parity[] = {\n"); + for (k = 0, p = terms; p; p = p->link) { + for ( ; k < p->esn; k++) + print("%10,%1/* %d */\n", k); + print("%1%d,%1/* %d=%S */\n", p->arity < 0 ? 0 : p->arity, k++, p); + } + print("};\n\n"); + if (Iflag) { + print("const char *const %Popname[] = {\n"); + for (k = 0, p = terms; p; p = p->link) { + for ( ; k < p->esn; k++) + print("%1/* %d */%10,\n", k); + print("%1/* %d */%1\"%S\",\n", k++, p); + } + print("};\n\n"); + } +} + +/* emittest - emit clause for testing a match */ +static void emittest(Tree t, char *v, char *suffix) { + Term p = t->op; + + if (p->kind == TERM) { + print("%3%s->op == %d%s/* %S */\n", v, p->esn, + t->nterms > 1 ? " && " : suffix, p); + if (t->left) + emittest(t->left, stringf("%s->left", v), + t->right && t->right->nterms ? " && " : suffix); + if (t->right) + emittest(t->right, stringf("%s->right", v), suffix); + } +} diff --git a/iburg/briggs/icg-tools/iburg/iburg.h b/iburg/briggs/icg-tools/iburg/iburg.h new file mode 100644 index 00000000000..e801d6a1ae5 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/iburg.h @@ -0,0 +1,65 @@ +#ifndef BURG_INCLUDED +#define BURG_INCLUDED + +/* $Id: iburg.h 71 2006-12-11 01:22:25Z drhanson $ */ +/* iburg.c: */ +extern void *alloc(int nbytes); + +typedef enum { TERM=1, NONTERM } Kind; +typedef struct rule *Rule; +typedef struct term *Term; +struct term { /* terminals: */ + char *name; /* terminal name */ + Kind kind; /* TERM */ + int esn; /* external symbol number */ + int arity; /* operator arity */ + Term link; /* next terminal in esn order */ + Rule rules; /* rules whose pattern starts with term */ +}; + +typedef struct nonterm *Nonterm; +struct nonterm { /* non-terminals: */ + char *name; /* non-terminal name */ + Kind kind; /* NONTERM */ + int number; /* identifying number */ + int lhscount; /* # times nt appears in a rule lhs */ + int reached; /* 1 iff reached from start non-terminal */ + Rule rules; /* rules w/non-terminal on lhs */ + Rule chain; /* chain rules w/non-terminal on rhs */ + Nonterm link; /* next terminal in number order */ +}; +extern Nonterm nonterm(char *id); +extern Term term(char *id, int esn); + +typedef struct tree *Tree; +struct tree { /* tree patterns: */ + void *op; /* a terminal or non-terminal */ + Tree left, right; /* operands */ + int nterms; /* number of terminal nodes in this tree */ +}; +extern Tree tree(char *op, Tree left, Tree right); + +struct rule { /* rules: */ + Nonterm lhs; /* lefthand side non-terminal */ + Tree pattern; /* rule pattern */ + int ern; /* external rule number */ + int packed; /* packed external rule number */ + float cost; /* associated cost */ + Rule link; /* next rule in ern order */ + Rule next; /* next rule with same pattern root */ + Rule chain; /* next chain rule with same rhs */ + Rule decode; /* next rule with same lhs */ + Rule kids; /* next rule with same burm_kids pattern */ +}; +extern Rule rule(char *id, Tree pattern, int ern, float cost); +extern float maxcost; /* maximum cost */ + +/* gram.y: */ +void yyerror(char *fmt, ...); +int yyparse(void); +void yywarn(char *fmt, ...); +extern int errcnt; +extern FILE *infp; +extern FILE *outfp; + +#endif diff --git a/iburg/briggs/icg-tools/iburg/index.html b/iburg/briggs/icg-tools/iburg/index.html new file mode 100644 index 00000000000..8b030d0a94c --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/index.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> + +<head> +<link HREF="http://drh.home.dyndns.org/" REV="made" TITLE="David R. Hanson"> +<title>iburg, A Tree Parser Generator</title> +</head> + +<body> + +<h1>iburg, A Tree Parser Generator</h1> + +<p><code>iburg</code> is a program that generates fast tree parsers for cost-augmented +tree grammars. <code>iburg</code> is useful for writing code generators and for teaching +computer science compiler courses. A variant of <code>iburg</code> is used in the code +generators for <a HREF="/software/lcc/"><code>lcc</code></a>, a retargetable compiler for +ANSI C. <code>iburg</code> is described in</p> + +<blockquote> + <p><a HREF="http://cwfraser.webhop.net/">C. W. Fraser</a>, <a + HREF="http:///drh.home.dyndns.org/">D. R. Hanson</a>, and <a + HREF="http://proebsting.webhop.net/">T. A. Proebsting</a>,<br> + Engineering a Simple, Efficient Code Generator Generator,<br> + <cite>ACM Letters on Programming Languages and Systems</cite> <strong>1</strong>, 3 + (Sep. 1992), 213-226. <a href="http://storage.webhop.net/documents/iburg.pdf">PDF</a> (157KB).</p> +</blockquote> + <p>The source code is available from the subversion repository at <a +HREF="http://code.google.com/p/iburg/source">http://code.google.com/p/iburg/source</a>; +the <code><a HREF="http://iburg.googlecode.com/svn/trunk/README">README</a></code> file elaborates. +The <code><a HREF="http://iburg.googlecode.com/svn/trunk/LOG">LOG</a></code> file describes recent changes. +You can also <a HREF="http://iburg.googlecode.com/svn/">browse the source code</a>.</p> + <hr> + +<address>$Id: index.html 73 2007-01-23 04:03:00Z drhanson $</address> +</body> diff --git a/iburg/briggs/icg-tools/iburg/makefile b/iburg/briggs/icg-tools/iburg/makefile new file mode 100644 index 00000000000..11b82ed9b91 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/makefile @@ -0,0 +1,23 @@ +# $Id: makefile 71 2006-12-11 01:22:25Z drhanson $ +O=.o +E= +CFLAGS= +LDFLAGS= +YFLAGS= +OBJS=iburg$O gram$O +CUSTOM=custom.mk +include $(CUSTOM) + +iburg$E: $(OBJS); $(CC) -o $@ $(LDFLAGS) $(OBJS) + +$(OBJS): iburg.h + +test: iburg$E sample4.brg sample5.brg + ./iburg$E -I sample4.brg sample4.c; $(CC) -o test4$E sample4.c; ./test4$E + ./iburg$E -I sample5.brg sample5.c; $(CC) -o test5$E sample5.c; ./test5$E + +clean:: + rm -f *$O core sample*.c a.out test4$E test5$E + +clobber:: clean + rm -f y.tab.c gram.tab.c iburg$E diff --git a/iburg/briggs/icg-tools/iburg/sample4.brg b/iburg/briggs/icg-tools/iburg/sample4.brg new file mode 100644 index 00000000000..0b5c6116afa --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/sample4.brg @@ -0,0 +1,109 @@ +%{ +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +enum { + ADDI=309, ADDRLP=295, ASGNI=53, + CNSTI=21, CVCI=85, I0I=661, INDIRC=67 +}; + +#define STATE_TYPE long +typedef struct tree { + int op; + struct tree *kids[2]; + int val; + struct { STATE_TYPE state; } x; +} *NODEPTR_TYPE, *Tree; +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define PANIC printf +#define STATE_LABEL(p) ((p)->x.state) + +int OP_LABEL(NODEPTR_TYPE p) { + switch (p->op) { + case CNSTI: if (p->val == 0) return 661 /* I0I */; + default: return p->op; + } +} + +static void burm_trace(NODEPTR_TYPE, int, int, int); +%} +%term ADDI=309 ADDRLP=295 ASGNI=53 +%term CNSTI=21 CVCI=85 I0I=661 INDIRC=67 +%% +stmt: ASGNI(disp,reg) = 4 (1); +stmt: reg = 5; +reg: ADDI(reg,rc) = 6 (1); +reg: CVCI(INDIRC(disp)) = 7 (1); +reg: I0I = 8; +reg: disp = 9 (1); +disp: ADDI(reg,con) = 10; +disp: ADDRLP = 11; +rc: con = 12; +rc: reg = 13; +con: CNSTI = 14; +con: I0I = 15; +%% + +static int trace; + +/* burm_trace - print trace message for matching p; decrement trace */ +static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) { + if (trace < 0) + fprintf(stderr, "0x%p matched %s = %d with cost %d vs. %d\n", p, + burm_string[eruleno], eruleno, cost, bestcost); + else if (trace > 0 && cost < bestcost) { + --trace; + fprintf(stderr, "0x%p matched %s = %d with cost %d\n", p, + burm_string[eruleno], eruleno, cost); + } +} + +/* dumpCover - print the matched cover for p */ +static void dumpCover(Tree p, int goalnt, int indent) { + int eruleno = burm_rule(p->x.state, goalnt); + short *nts = burm_nts[eruleno]; + Tree kids[10]; + int i; + + for (i = 0; i < indent; i++) + fprintf(stderr, " "); + fprintf(stderr, "%s\n", burm_string[eruleno]); + burm_kids(p, eruleno, kids); + for (i = 0; nts[i]; i++) + dumpCover(kids[i], nts[i], indent + 1); +} + +static void gen(NODEPTR_TYPE p) { + if (burm_label(p) == 0) + fprintf(stderr, "no cover\n"); + else + dumpCover(p, 1, 0); +} + +static Tree tree(int op, Tree l, Tree r) { + Tree t = malloc(sizeof *t); + + t->op = op; + t->kids[0] = l; t->kids[1] = r; + t->val = 0; + t->x.state = 0; + return t; +} + +main(void) { + Tree t; + + if (getenv("Trace")) + trace = atoi(getenv("Trace")); + printf("i = c + 4;\n"); + t = tree(ASGNI, + tree(ADDRLP, 0, 0), + tree(ADDI, + tree(CVCI, tree(INDIRC, tree(ADDRLP, 0, 0), 0), 0), + (t = tree(CNSTI, 0, 0), t->val = 4, t) + ) + ); + gen(t); + return 0; +} diff --git a/iburg/briggs/icg-tools/iburg/sample5.brg b/iburg/briggs/icg-tools/iburg/sample5.brg new file mode 100644 index 00000000000..a830d03c953 --- /dev/null +++ b/iburg/briggs/icg-tools/iburg/sample5.brg @@ -0,0 +1,85 @@ +%{ +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> + +#define TRACE + +enum { MOVE=1, MEM=2, PLUS=3, NAME=4, CONST=6 }; + +#define STATE_TYPE void* +typedef struct tree { + int op; + struct tree *kids[2]; + STATE_TYPE state_label; +} *NODEPTR_TYPE; +#define OP_LABEL(p) ((p)->op) +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define STATE_LABEL(p) ((p)->state_label) +#define PANIC printf + +static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) { +#ifdef TRACE + extern char *burm_string[]; + + fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p, + burm_string[eruleno], cost, bestcost); +#endif +} +%} +%term MOVE=1 MEM=2 PLUS=3 NAME=4 CONST=6 +%% +stm: MOVE(MEM(loc),reg) = 1 (4); + +reg: PLUS(con,reg) = 2 (3); +reg: PLUS(reg,reg) = 3 (2); +reg: PLUS(MEM(loc),reg) = 4 (4); +reg: MEM(loc) = 5 (4); +reg: con = 6 (2); + +loc: reg = 7; +loc: NAME = 8; +loc: PLUS(NAME,reg) = 9; + +con: CONST = 10; +%% +static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) { +#ifdef TRACE + int eruleno = burm_rule(STATE_LABEL(p), goalnt); + short *nts = burm_nts[eruleno]; + NODEPTR_TYPE kids[10]; + int i; + + for (i = 0; i < indent; i++) + fprintf(stderr, " "); + fprintf(stderr, "%s\n", burm_string[eruleno]); + burm_kids(p, eruleno, kids); + for (i = 0; nts[i]; i++) + dumpCover(kids[i], nts[i], indent + 1); +#endif +} + +static NODEPTR_TYPE tree(int op, NODEPTR_TYPE l, NODEPTR_TYPE r) { + NODEPTR_TYPE p = malloc(sizeof *p); + + assert(p); + p->op = op; + p->kids[0] = l; p->kids[1] = r; + return p; +} + +main(void) { + NODEPTR_TYPE p; + + p = tree(MOVE, + tree(MEM, tree(NAME, 0, 0), 0), + tree(PLUS, + tree(MEM, tree(PLUS, + tree(NAME, 0, 0), + tree(MEM, tree(NAME, 0, 0), 0)), 0), + tree(CONST, 0, 0) ) ); + burm_label(p); + dumpCover(p, 1, 0); + return 0; +} diff --git a/iburg/briggs/icg-tools/plug/Notes b/iburg/briggs/icg-tools/plug/Notes new file mode 100644 index 00000000000..9eeb6411917 --- /dev/null +++ b/iburg/briggs/icg-tools/plug/Notes @@ -0,0 +1,86 @@ +plug - a burg (or iburg) preprocessor + +experimental, so I can gain some experience + + +A machine description looks like + +[prologue] +%% +decls +rules +[%% + epilogue] + + +where the prologue and epilogue are simply lines of C code. +Typically, the prologue contains declarations and the epilogue +will consist of C routines. + + +decls = { decl ";" } + +decl = "start" nonterm-id + | "nonterm" nonterm-id { "," nonterm-id } + | "term" term-equate { "," term-equate } + | "reduce" reduce-equate { "," reduce-equate } + +term-equate = term-id "=" number + +reduce-equate = reduce-id "=" path + +rules = { rule | include } + +include = "include" path ";" + +rule = specs [ reductions ] ";" + +specs = spec { "," spec } + +spec = nonterm-id ":" pattern cost + +pattern = nonterm-id + | term-id [ "(" patterns ")" ] + +patterns = pattern [ "," pattern ] + | pattern { "|" pattern } + +cost = [ "[" number "," number "]" ] + +reductions = reduction { "," reduction } + +reduction = reduce-id "{" code "}" + + where code is C code with balanced curly braces + + +id = alpha { alphanum | '_' } + +path = '"' { char } '"' + +number = digit { digit } + + + +comments are started by "--" and extend to EOL + + + +5 keywords: reduce, term, nonterm, start, include + +other tokens + + ; , = : ( ) [ ] { } | + path id number + done + + +Make sure term numbers (in the term-equates) are unique. +Make sure file names (in reduce-equates) are unique +Make sure each use of a particular term-id has the same +number of children. + +Maybe make the cost model fancier, allowing function calls + + +-o filename to redirect output diff --git a/iburg/briggs/icg-tools/plug/plug.c b/iburg/briggs/icg-tools/plug/plug.c new file mode 100644 index 00000000000..c630e6a39a2 --- /dev/null +++ b/iburg/briggs/icg-tools/plug/plug.c @@ -0,0 +1,1541 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +enum tokens { + COLON_token = (1 << 0) + ,COMMA_token = (1 << 1) + ,LPAREN_token = (1 << 2) + ,RPAREN_token = (1 << 3) + ,LBRACK_token = (1 << 4) + ,RBRACK_token = (1 << 5) + ,LBRACE_token = (1 << 6) + ,RBRACE_token = (1 << 7) + ,INT_token = (1 << 8) + ,ID_token = (1 << 9) + ,DONE_token = (1 << 10) + ,SEMI_token = (1 << 11) + ,PATH_token = (1 << 12) + ,EQUAL_token = (1 << 13) + ,REDUCE_token = (1 << 14) + ,TERM_token = (1 << 15) + ,NONTERM_token = (1 << 16) + ,START_token = (1 << 17) + ,INCLUDE_token = (1 << 18) + ,BAR_token = (1 << 19) + ,AT_token = (1 << 20) + ,TERM_ALIGN_token = (1 << 21) + ,TERM_INCR_token = (1 << 22) + /* + * If you add here, be sure to extend tok2str + */ + ,unused_0 = (1 << 23) + ,unused_1 = (1 << 24) + ,unused_2 = (1 << 25) + ,unused_3 = (1 << 26) + ,unused_4 = (1 << 27) + ,unused_5 = (1 << 28) + ,unused_6 = (1 << 29) + ,unused_7 = (1 << 30) + ,unused_8 = (1 << 31) +}; + + +#define HASH_SIZE 2047 + +typedef struct hash_node { + struct hash_node *next; + const char *id; + int keyword; + int kind; /* reduce, term, nonterm */ + FILE *file; /* for file-name */ + int kids; /* for term */ + struct hash_node *path; /* for reduce */ +} Hash_Node; + + +void label_file(FILE *fp) +{ + const char *start_comment = "/*"; + const char *end_comment = "*/"; + if (fp == 0) return; + fprintf(fp, "%s %s\n", start_comment, end_comment); + fprintf(fp, "%s THIS FILE IS AUTOMATICALLY PRODUCED BY plug %s\n", start_comment, end_comment); + fprintf(fp, "%s DO NOT EDIT %s\n", start_comment, end_comment); + fprintf(fp, "%s %s\n", start_comment, end_comment); +} + + +FILE *f = 0; +FILE *bf = 0; +FILE *opfile = 0; +FILE *opnfile = 0; +FILE *rulefile = 0; +FILE *infofile = 0; + +int first_opcode; + +const char *file_name; /* file name of grammar source file */ +const char *base_name; /* file name only part of file_name */ +const char *dir_name; /* directory name part of file_name */ + + +FILE *open_and_update_names(const char *fn) { + FILE *f; + char *ndn; + if (fn[0]=='/') { + ndn = strdup(fn); + } else { + int fnl = strlen(fn); + int dnl = strlen(dir_name); + ndn = (char *) malloc((fnl + dnl + 2)*sizeof(char)); + strcpy(ndn, dir_name); + strcat(ndn, "/"); + strcat(ndn, fn); + } + file_name = (char *) canonicalize_file_name(ndn); + free(ndn); ndn = 0; + if (file_name) { + f = fopen(file_name, "r"); + if (f) { + dir_name = strdup(file_name); + ndn = rindex(dir_name, '/'); + if (ndn) + *ndn = 0; + else + fprintf(stderr, "\n" "oops, rindex return NULL\n"); + + base_name = rindex(file_name, '/'); + if (!base_name) + base_name = file_name; + else + base_name += 1; /* move one right to the '/' */ + return f; + } else { + perror(file_name); + } + } else { + base_name = "<stdin>"; + } + return 0; +} + +int line_number = -1; /* input file line number; first line is synthetic */ +int last_was_nl = 1; /* last character was a new line */ +int start_new_file = 1; /* */ + +int token; +int number; +int case_number = 0; +Hash_Node *id; + +Hash_Node *start_node = 0; + +Hash_Node *hash_table[HASH_SIZE] = { 0 }; + + +unsigned hash(const char *s) { + unsigned v = *s++; + while (*s) + v = 3*v + *s++; + return v; +} + + +Hash_Node *find(const char *s) { + unsigned h = hash(s) % 2047; + Hash_Node *p = hash_table[h]; + while (p) { + if (strcmp(s, p->id) == 0) + return p; + p = p->next; + } + p = (Hash_Node *) malloc(sizeof(Hash_Node)); + p->next = hash_table[h]; + hash_table[h] = p; + p->id = strdup(s); + p->keyword = 0; + p->kind = 0; + p->file = 0; + p->kids = 0; + p->path = 0; + return p; +} + + +void init_keywords(void) { + id = find("start"); id->keyword = 1; id->kind = START_token; + id = find("term"); id->keyword = 1; id->kind = TERM_token; + id = find("nonterm"); id->keyword = 1; id->kind = NONTERM_token; + id = find("reduce"); id->keyword = 1; id->kind = REDUCE_token; + id = find("include"); id->keyword = 1; id->kind = INCLUDE_token; + id = find("term_align"); id->keyword = 1; id->kind = TERM_ALIGN_token; + id = find("term_incr"); id->keyword = 1; id->kind = TERM_INCR_token; +} + +void get_token(void) { + char c = start_new_file ? '\n' : fgetc(f); + start_new_file = 0; + while (isspace(c)) { + last_was_nl = (c == '\n'); + if (last_was_nl) { + line_number++; + } + c = fgetc(f); + } + if (last_was_nl) { + if (c == '#') { /* consume #line directive */ + char buf[BUFSIZ]; + char *cp = buf; + while (c != '\n') { + *cp++ = c; *cp = 0; + c = fgetc(f); + } + last_was_nl = 1; + { + char *start_fname = 0; + int new_line_number = 0; + char *cp = buf; + char termch; + if (*cp == '#') { + cp += 1; + } + while (isspace(*cp)) { + cp += 1; + } + if (strncmp(cp, "line", 4) == 0) { + cp += 4; + while (isspace(*cp)) { + cp += 1; + } + } + new_line_number = strtol(cp, &cp, 0); + while (isspace(*cp)) { + cp += 1; + } + if (*cp == '"') { + termch = '"'; + cp += 1; + } else { + termch = 0; + } + start_fname = cp; + while (*cp != termch) { + cp += 1; + } + *cp = 0; /* smash end of file name */ + base_name = strdup(start_fname); + line_number = new_line_number; + if (0) { + printf("fname=%s lineno=%d\n", file_name, line_number); + } + + get_token(); + return; + } + } + } + last_was_nl = 0; + if (c == EOF) + token = DONE_token; + else if (c == ':') + token = COLON_token; + else if (c == ',') + token = COMMA_token; + else if (c == ';') + token = SEMI_token; + else if (c == '=') + token = EQUAL_token; + else if (c == '(') + token = LPAREN_token; + else if (c == ')') + token = RPAREN_token; + else if (c == '[') + token = LBRACK_token; + else if (c == ']') + token = RBRACK_token; + else if (c == '{') + token = LBRACE_token; + else if (c == '}') + token = RBRACE_token; + else if (c == '|') + token = BAR_token; + else if (c == '@') + token = AT_token; + else if (c == '/') { /* allow C++ style comments */ + c = fgetc(f); + if (c == '/') { + do { + c = fgetc(f); + } while (c != '\n'); + line_number++; + last_was_nl = 1; + get_token(); + } + else { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, unexpected character '/'>\n", line_number); + exit(1); + } + } + else if (c == '-') { /* allow Ada style comments */ + c = fgetc(f); + if (c == '-') { + do { + c = fgetc(f); + } while (c != '\n'); + line_number++; + last_was_nl = 1; + get_token(); + } + else { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, unexpected character '-'\n", line_number); + exit(1); + } + } + else if (c == '%') { + c = fgetc(f); + if (c == '%') { + token = DONE_token; + } + } + else if (isalpha(c)) { + char s[100]; + int i = 0; + do { + s[i++] = c; + c = fgetc(f); + } while (isalnum(c) || c == '_'); + s[i] = 0; + ungetc(c, f); + id = find(s); + if (id->keyword) + token = id->kind; + else + token = ID_token; + } + else if (isdigit(c)) { + number = c - '0'; + c = fgetc(f); + while (isdigit(c)) { + number = 10*number + c - '0'; + c = fgetc(f); + } + ungetc(c, f); + token = INT_token; + } + else if (c == '"') { + char s[100]; + int i = 0; + c = fgetc(f); + while (c != '"') { + s[i++] = c; + c = fgetc(f); + } + s[i] = 0; + id = find(s); + token = PATH_token; + } + else { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, unexpected character '", line_number); + if (isgraph(c)) + fprintf(stderr, "%c'\n", c); + else + fprintf(stderr, "0x%02x'\n", c); + exit(1); + } + if (0) { + printf("line_number=%4d token=0x%08x\n", line_number, token); + } +} + + +const char *tok2str(int t) { + if (t == COLON_token) + return ":"; + if (t == SEMI_token) + return ";"; + if (t == EQUAL_token) + return "="; + if (t == COMMA_token) + return ","; + if (t == LPAREN_token) + return "("; + if (t == RPAREN_token) + return ")"; + if (t == LBRACK_token) + return "["; + if (t == RBRACK_token) + return "]"; + if (t == LBRACE_token) + return "{"; + if (t == RBRACE_token) + return "}"; + if (t == INT_token) + return "INT"; + if (t == ID_token) + return "ID"; + if (t == PATH_token) + return "PATH"; + if (t == REDUCE_token) + return "REDUCE"; + if (t == TERM_token) + return "TERM"; + if (t == NONTERM_token) + return "NONTERM"; + if (t == START_token) + return "START"; + if (t == DONE_token) + return "%%"; + if (t == INCLUDE_token) + return "INCLUDE"; + if (t == TERM_ALIGN_token) + return "term_align"; + if (t == TERM_INCR_token) + return "term_incr"; + else { + fprintf(stderr, "\n" + "internal plug error: can not map token number 0x%08x\n", t); + exit(1); + } + return 0; +} + + +void check(int set) { + if (!(token & set)) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, unexpected token <%s>\n", + line_number, tok2str(token)); + exit(1); + } +} + + +void expect(int expected) { + if (token != expected) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, expected <%s>, got <%s>\n", + line_number, tok2str(expected), tok2str(token)); + exit(1); + } +} + + + +typedef struct pattern { + Hash_Node *id; + struct pattern *kid[9]; + int llink[10]; + int rlink[9]; + int a[10]; + int kids; + int permute; // 0 ==> no permute; 1 ==> permute; 2 ==> swap + int leaf; +} Pattern; + +typedef struct locus { + const char *file_name; + int line_number; +} Locus; + +/* + * a reduction is a named piece of C code containing a semantic action + * we keep track of the source locus so we can produce #line directives + * so that error messages from compiling the semantic action will + * be meaningful with respect to the grammar files + */ +typedef struct reduction { + struct reduction *next; + FILE *file; + const char *code; /* the C++ code with the semantic action */ + Locus locus; +} Reduction; + +/* + * a Spec corresponds to a production(rule) in the tree grammar + * we also have a file name and line number pair so that + * at tree match time (reduction time) we can cross reference to the grammar + */ +typedef struct spec { + struct spec *next; + const char *id; + int cost; + Pattern *pattern; + int case_number; /* aka iburg/burm rule number */ + Locus locus; /* file locus information */ +} Spec; + + +int global_leaf; + +Pattern *parse_pattern(int set) { + Pattern *p = (Pattern *) calloc(1, sizeof(Pattern)); + expect(ID_token); + p->id = id; + if (id->kind == NONTERM_token) { + get_token(); + p->leaf = global_leaf++; + } + else if (id->kind == TERM_token) { + Hash_Node *termid = id; + int kids = 0; + get_token(); + check(LPAREN_token|set); + if (token == LPAREN_token) { + get_token(); + p->kid[kids] = parse_pattern(COMMA_token|RPAREN_token|BAR_token|AT_token); + kids++; + check(COMMA_token|RPAREN_token|BAR_token|AT_token); + if (token == COMMA_token) { + p->permute = 0; + get_token(); + p->kid[kids++] = parse_pattern(COMMA_token|RPAREN_token); + } + else if (token == BAR_token) { + p->permute = 1; + do { + get_token(); + p->kid[kids++] = parse_pattern(BAR_token|RPAREN_token); + check(BAR_token|RPAREN_token); + } while (token == BAR_token); + } + else if (token == AT_token) { + p->permute = 2; + get_token(); + p->kid[kids++] = parse_pattern(AT_token|RPAREN_token); + } + expect(RPAREN_token); + get_token(); + } + p->kids = kids; + if (p->permute == 1) + kids = 2; + if (termid->kids == -1) + termid->kids = kids; + else if (termid->kids != kids) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, + "line %d, terminal <%s> used inconsistently\n", + line_number, termid->id); + exit(1); + } + } + else { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, + "line %d, <%s> should have been declared as either a terminal or a non-terminal\n", + line_number, id->id); + exit(1); + } + return p; +} + + +int parse_cost(int set) { + int cost = 0; + check(set|LBRACK_token); + if (token == LBRACK_token) { + get_token(); + expect(INT_token); + cost =number << 11; + get_token(); + expect(COMMA_token); + get_token(); + expect(INT_token); + cost += number; + get_token(); + expect(RBRACK_token); + get_token(); + } + return cost; +} + + +Spec *parse_spec(void) { + Spec *s = (Spec *) malloc(sizeof(Spec)); + s->next = NULL; + if (id->kind != NONTERM_token) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, + "line %d, <%s> should have been declared as a non-terminal\n", + line_number, id->id); + exit(1); + } + s->id = id->id; + get_token(); + expect(COLON_token); + get_token(); + global_leaf = 0; + s->pattern = parse_pattern(LBRACK_token|ID_token|SEMI_token|COMMA_token); + if (global_leaf > 9) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, too many leaves in pattern\n", + line_number); + exit(1); + } + s->locus.line_number = line_number; + s->locus.file_name = strdup(base_name ? base_name : "<stdin>"); + s->cost = parse_cost(ID_token|SEMI_token|COMMA_token); + return s; + +} + + +Spec *parse_specs(void) { + Spec *specs = parse_spec(); + check(COMMA_token|SEMI_token|ID_token); + while (token == COMMA_token) { + Spec *nspec; + get_token(); + nspec = parse_spec(); + nspec->next = specs; + specs = nspec; + check(COMMA_token|SEMI_token|ID_token); + } + return specs; +} + + +int current; +int limit; +char *buffer; + +void saveC(char c) { + if (current == limit) { + limit *= 2; + buffer = (char *) realloc(buffer, limit*sizeof(char)); + } + buffer[current++] = c; +} + + +void save_code(void) { + int c = fgetc(f); + while (c != '}') { + switch (c) { + case EOF: + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, unexpected EOF\n", + line_number); + exit(1); + case '{': + saveC(c); + save_code(); + saveC('}'); + break; + case '"': + saveC(c); + c = fgetc(f); + while (c != '"') { + if (c == '\\') { + saveC(c); + c = fgetc(f); + } + else if (c == '\n') { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, bad string constant\n", line_number); + exit(1); + } + saveC(c); + c = fgetc(f); + } + saveC(c); + break; + case '\'': + saveC(c); + c = fgetc(f); + if (c == '\\') { + saveC(c); + c = fgetc(f); + } + saveC(c); + c = fgetc(f); + if (c == '\'') + saveC(c); + else { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, bad character constant\n", line_number); + exit(1); + } + break; + case '/': + c = fgetc(f); + if (c == '/') { + char line[1000]; + const char *p = line; + fgets(line, 1000, f); + saveC('/'); + saveC('/'); + while (*p) + saveC(*p++); + } + else { + saveC('/'); + ungetc(c, f); + } + break; + case '\n': + line_number++; + default: + saveC(c); + break; + } + c = fgetc(f); + } +} + + +Reduction *parse_reduction(void) { + Reduction *r = (Reduction *) malloc(sizeof(Reduction)); + r->next = NULL; + /* + * add one to current line_number because the directive #line + * is put on next line in generated file + */ + r->locus.line_number = line_number + 1; + r->locus.file_name = strdup(base_name ? base_name : "<stdin>"); + + expect(ID_token); + if (id->kind != REDUCE_token) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, + "line %d, <%s> wasn't declared as a reduction\n", + line_number, id->id); + exit(1); + } + r->file = id->path->file; + get_token(); + expect(LBRACE_token); + current = 0; + limit = 10; + buffer = (char *) malloc(limit*sizeof(char)); + save_code(); + saveC(0); + r->code = buffer; + get_token(); + return r; +} + +Reduction *parse_reductions(void) { + Reduction *r = NULL; + check(ID_token|SEMI_token); + if (token == ID_token) { + r = parse_reduction(); + check(COMMA_token|SEMI_token); + while (token == COMMA_token) { + Reduction *rr; + get_token(); + rr = parse_reduction(); + rr->next = r; + r = rr; + check(COMMA_token|SEMI_token); + } + } + expect(SEMI_token); + get_token(); + return r; +} + +void free_pattern(Pattern *p) { + int i; + for (i = 0; i < p->kids; i++) { + free_pattern(p->kid[i]); + } + free(p); p = 0; +} + + +void free_spec(Spec *spec) { + free_pattern(spec->pattern); + free(spec); spec = 0; +} + +void free_reduction(Reduction *reduction) { + free((char *)reduction->code); reduction->code = 0; + free(reduction); reduction = 0; +} + + +int perm_vector[9]; + +void dump_reduction(Reduction *r) { + FILE *f = r->file; + const char *p = r->code; + fprintf(f, "case %d: {\n", case_number); + fprintf(f, "#line %d \"%s\"", + r->locus.line_number, + r->locus.file_name /* this is really the base_name, not the full path */ + ); + while (*p) { + char c = *p++; + switch (c) { + case '"': + fputc(c, f); + c = *p++; + while (c != '"') { + if (c == '\\') { + fputc(c, f); + c = *p++; + } + fputc(c, f); + c = *p++; + } + fputc(c, f); + break; + case '\'': + fputc(c, f); + c = *p++; + if (c == '\\') { + fputc(c, f); + c = *p++; + } + fputc(c, f); + c = *p++; + fputc(c, f); + break; + case '/': + c = *p++; + if (c == '/') { + fputc('/', f); + fputc('/', f); + while (*p != '\n') + fputc(*p++, f); + } + else { + fputc('/', f); + p--; + } + break; + case '$': + c = *p++; + if (c == '$') + fputc('p', f); + else + fprintf(f, "kid[%d]", perm_vector[c - '1']); + break; + default: + fputc(c, f); + break; + } + } + fprintf(f, "}\n break;\n"); +} + + +void dump_reductions(Reduction *r) { + while (r) { + dump_reduction(r); + r = r->next; + } +} + + + + +/* see Knuth, Volume 4, Section 7.2.1.2, Algorithm L */ + +int next_perm(int n, int *a) { + int j, k, l, t; + + j = n - 1; + while (a[j] >= a[j + 1]) + j--; + if (j == 0) return 0; + + l = n; + while (a[j] >= a[l]) + l--; + t = a[j]; a[j] = a[l]; a[l] = t; + + k = j + 1; + l = n; + while (k < l) { + t = a[k]; a[k] = a[l]; a[l] = t; + k++; + l--; + } + return 1; +} + + + +/* see Knuth, Volume 4, Section 7.2.1.6, Algorithm B */ + +int next_tree(int *l, int *r, int ops) { + int y, k; + int j = 1; + while (l[j] == 0) { + r[j] = 0; + l[j] = j + 1; + j++; + } + if (j > ops) return 0; + + y = l[j]; + k = 0; + while (r[y] > 0) { + k = y; + y = r[y]; + } + + if (k > 0) + r[k] = 0; + else + l[j] = 0; + r[y] = r[j]; + r[j] = y; + return 1; +} + + +void init_pattern(Pattern *p) { + int i; + int kids = p->kids; + if (p->permute == 0) { + for (i = 0; i < kids; i++) + init_pattern(p->kid[i]); + } + else if (p->permute == 1) { + int ops = kids - 1; + for (i = 1; i < ops; i++) { + p->llink[i] = i + 1; + p->rlink[i] = 0; + } + p->llink[ops] = 0; + p->rlink[ops] = 0; + p->llink[kids] = 1; + for (i = 0; i <= p->kids; i++) + p->a[i] = i - 1; + for (i = 0; i < kids; i++) + init_pattern(p->kid[i]); + } + else if (p->permute == 2) { + init_pattern(p->kid[1]); + init_pattern(p->kid[0]); + } + else { + fprintf(stderr, "\n" "poorly structured pattern (init_pattern)\n"); + exit(1); + } +} + + + +int next_pattern(Pattern *p) { + int kids = p->kids; + if (kids == 0) + return 0; + else if (kids == 1) + return next_pattern(p->kid[0]); + else if (kids == 2 && p->permute == 0) { + if (next_pattern(p->kid[0])) + return 1; + if (next_pattern(p->kid[1])) { + init_pattern(p->kid[0]); + return 1; + } + return 0; + } + else if (kids == 2 && p->permute == 2) { + if (next_pattern(p->kid[1])) + return 1; + if (next_pattern(p->kid[0])) { + init_pattern(p->kid[1]); + return 1; + } + return 0; + } + else if (kids >= 2 && p->permute == 1) { + int i, j; + for (i = 0; i < kids; i++) { + if (next_pattern(p->kid[i])) + break; + } + if (i < kids) { + for (j = 0; j < i; j++) + init_pattern(p->kid[j]); + return 1; + } + if (next_perm(kids, p->a)) { + for (j = 0; j < kids; j++) + init_pattern(p->kid[j]); + return 1; + } + if (next_tree(p->llink, p->rlink, kids - 1)) { + for (j = 0; j < kids; j++) + init_pattern(p->kid[j]); + for (i = 0; i <= p->kids; i++) + p->a[i] = i - 1; + return 1; + } + return 0; + } + else { + fprintf(stderr, "\n" "poorly structured pattern (next_pattern)\n"); + exit(1); + } +} + + +void dump_pattern(Pattern *p); + +int dump_tree(Pattern *p, int root, int leaf) { + if (root == 0) { + dump_pattern(p->kid[p->a[leaf]]); + return leaf + 1; + } + else { + fprintf(bf, "%s(", p->id->id); + leaf = dump_tree(p, p->llink[root], leaf); + fputc(',', bf); + leaf = dump_tree(p, p->rlink[root], leaf); + fputc(')', bf); + return leaf; + } +} + + +int global_position; + +void dump_pattern(Pattern *p) { + int kids = p->kids; + if (kids == 0) { + if (p->id->kind == NONTERM_token) + perm_vector[p->leaf] = global_position++; + fputs(p->id->id, bf); + } + else if (kids == 1) { + fprintf(bf, "%s(", p->id->id); + dump_pattern(p->kid[0]); + fputc(')', bf); + } + else if (kids == 2 && p->permute == 0) { + fprintf(bf, "%s(", p->id->id); + dump_pattern(p->kid[0]); + fputc(',', bf); + dump_pattern(p->kid[1]); + fputc(')', bf); + } + else if (kids == 2 && p->permute == 2) { + fprintf(bf, "%s(", p->id->id); + dump_pattern(p->kid[1]); + fputc(',', bf); + dump_pattern(p->kid[0]); + fputc(')', bf); + } + else if (kids >= 2 && p->permute == 1) + (void) dump_tree(p, 1, 1); + else { + fprintf(stderr, "\n" "poorly structured pattern (dump_pattern)\n"); + exit(1); + } +} + +void dump_pattern_info(const Spec *s) { + fprintf(rulefile, "{\"%s\", %4d}, \t/* %4d */\n", + s->locus.file_name, s->locus.line_number, + case_number); +} + +void emit_rule(Spec *s, Reduction *r) { + case_number++; + s->case_number = case_number; + fprintf(bf, "%s : ", s->id); + global_position = 0; + dump_pattern(s->pattern); + dump_pattern_info(s); + fprintf(bf, " = %d (%d);\n", case_number, s->cost); + dump_reductions(r); +} + +void parse_rule(void) { + Spec *specs = parse_specs(); + Reduction *reductions = parse_reductions(); + while (specs) { + Spec *spec = specs; + specs = specs->next; + init_pattern(spec->pattern); + do { + emit_rule(spec, reductions); + } while (next_pattern(spec->pattern)); + free_spec(spec); + } + while (reductions) { + Reduction *reduction = reductions; + reductions = reductions->next; + free_reduction(reduction); + } +} + +void parse_rules(void); + +void parse_include(void) { + FILE *saved_file; + int saved_line_number; + Hash_Node *path_id; + const char *saved_file_name; + const char *saved_dir_name; + const char *saved_base_name; + + get_token(); + expect(PATH_token); + path_id = id; + get_token(); + expect(SEMI_token); + saved_file = f; + saved_dir_name = dir_name; + saved_file_name = file_name; + saved_base_name = base_name; + f = open_and_update_names(path_id->id); + if (f == 0) { + if (saved_file_name) + fprintf(stderr, "%s, ", saved_file_name); + fprintf(stderr, "line %d, couldn't open include file <%s>\n", + line_number, path_id->id); + exit(1); + } + saved_line_number= line_number; + line_number = 0; + start_new_file = 1; + get_token(); + parse_rules(); + expect(DONE_token); + fclose(f); f = 0; + free((char *)file_name); file_name = 0; + free((char *)dir_name); dir_name = 0; + f = saved_file; + line_number = saved_line_number; + base_name = saved_base_name; + file_name = saved_file_name; + dir_name = saved_dir_name; + get_token(); +} + + +void parse_rules(void) { + check(ID_token|INCLUDE_token|DONE_token); + while (token == ID_token || token == INCLUDE_token) { + if (token == ID_token) + parse_rule(); + else if (token == INCLUDE_token) + parse_include(); + else { + fprintf(stderr, "plug: inconsistent parser for parse_rules\n"); + exit(1); + } + check(ID_token|INCLUDE_token|DONE_token); + } +} + + +typedef struct int_node { + struct int_node *next; + int val; +} Int_Node; + + +Int_Node *terminals[HASH_SIZE] = { 0 }; + + +/* + * Register the terminal number n in the terminals table. + * Return 1 if the terminal number n exists in the terminals table. + * Return 0 if this is a new entry. + */ +int register_terminal(int n) { + unsigned nn = (unsigned) n; + unsigned h = nn % HASH_SIZE; + Int_Node *p = terminals[h]; + while (p) { + if (p->val == n) + return 1; + p = p->next; + } + p = (Int_Node *) malloc(sizeof(Int_Node)); + p->val = n; + p->next = terminals[h]; + terminals[h] = p; + return 0; +} + + +int next_term_id = 0; +void parse_term_equate(void) { + int this_term_id = -1; + if (token == TERM_INCR_token) { + get_token(); + expect(LPAREN_token); + get_token(); + expect(INT_token); + next_term_id += number; + get_token(); + expect(RPAREN_token); + get_token(); + } else if (token == TERM_ALIGN_token) { + get_token(); + expect(LPAREN_token); + get_token(); + expect(INT_token); + next_term_id = ((next_term_id+(number-1))/number)*number; + get_token(); + expect(RPAREN_token); + get_token(); + } else { + expect(ID_token); + if (id->kind) { + if (file_name) { + fprintf(stderr, "%s, ", file_name); + } + fprintf(stderr, "line %d, %s already declared\n", line_number, id->id); + exit(1); + } + id->kind = TERM_token; + id->kids = -1; + fprintf(bf, " %s=", id->id); + if (first_opcode) { + fprintf(opfile, "\n %s=", id->id); + first_opcode = 0; + } else { + fprintf(opfile, ",\n %s=", id->id); + } + get_token(); + if (token == EQUAL_token) { + expect(EQUAL_token); + get_token(); + expect(INT_token); + this_term_id = number; + get_token(); + } else { + this_term_id = next_term_id++; + } + if (register_terminal(this_term_id)) { + if (file_name) { + fprintf(stderr, "%s, ", file_name); + } + fprintf(stderr, "line %d, terminal %d already appears\n", + line_number, this_term_id); + exit(1); + } + fprintf(bf, "%d", this_term_id); + fprintf(opfile, "%d", this_term_id); + fprintf(opnfile, " { %d, \"%s\" },\n", this_term_id, id->id ); + } +} + + +void parse_reduce_equate(void) { + Hash_Node *reduce_id; + expect(ID_token); + if (id->kind) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, %s already declared\n", line_number, id->id); + exit(1); + } + id->kind = REDUCE_token; + reduce_id = id; + get_token(); + expect(EQUAL_token); + get_token(); + expect(PATH_token); + if (id->file) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, file <%s>already opened\n", line_number, id->id); + exit(1); + } + id->file = fopen(id->id, "w"); + if (id->file == 0) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, couldn't open file <%s>\n", line_number, id->id); + exit(1); + } + label_file(id->file); + reduce_id->path = id; + get_token(); +} + + +void parse_decls(void) { + opnfile = fopen("icg-opcode-names.c", "w"); + if (opnfile == 0) { + perror("icg-opcode-names.c"); + exit(1); + } + label_file(opnfile); + + opfile = fopen("icg-opcode.h", "w"); + if (opfile == 0) { + perror("icg-opcode.h"); + exit(1); + } + fprintf(opfile, "#ifndef _icg_opcode_h\n"); + fprintf(opfile, "#define _icg_opcode_h\n"); + label_file(opfile); + + fprintf(opnfile, "#include \"icg-opcode.h\"\n" + "#include <stdio.h>\n" + "static const struct opnames_t {\n" + " const icg_opcodes op;\n" + " const char *str;\n" + "} opnames [] = {\n"); + + fprintf(opfile, "typedef enum {"); + + line_number = 0; + start_new_file = 1; + first_opcode = 1; + get_token(); + check(START_token|NONTERM_token|TERM_token|REDUCE_token|ID_token|DONE_token|INCLUDE_token); + while (token & (START_token|NONTERM_token|TERM_token|REDUCE_token)) { + if (token == START_token) { + if (start_node != 0) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, goal nonterminal already declared\n", line_number); + exit(1); + } + get_token(); + expect(ID_token); + start_node = id; + get_token(); + } + else if (token == NONTERM_token) { + get_token(); + expect(ID_token); + if (id->kind) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, %s already declared\n", line_number, id->id); + exit(1); + } + id->kind = NONTERM_token; + get_token(); + check(COMMA_token|SEMI_token); + while (token == COMMA_token) { + get_token(); + expect(ID_token); + if (id->kind) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, %s already declared\n", line_number, id->id); + exit(1); + } + id->kind = NONTERM_token; + get_token(); + check(COMMA_token|SEMI_token); + } + } + else if (token == TERM_token) { + fprintf(bf, "%%term"); + get_token(); + parse_term_equate(); + check(COMMA_token|SEMI_token); + while (token == COMMA_token) { + get_token(); + parse_term_equate(); + check(COMMA_token|SEMI_token); + } + fprintf(bf, "\n"); + } + else { /* token == REDUCE_token */ + get_token(); + parse_reduce_equate(); + check(COMMA_token|SEMI_token); + while (token == COMMA_token) { + get_token(); + parse_reduce_equate(); + check(COMMA_token|SEMI_token); + } + } + expect(SEMI_token); + get_token(); + check(START_token|NONTERM_token|TERM_token|REDUCE_token|ID_token|DONE_token|INCLUDE_token); + } + if (start_node == 0) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, "line %d, missing declaration for goal nonterminal\n", line_number); + exit(1); + } + else if (start_node->kind != NONTERM_token) { + if (file_name) + fprintf(stderr, "%s, ", file_name); + fprintf(stderr, + "line %d, goal symbol <%s> should be declared as nonterminal\n", + line_number, start_node->id); + exit(1); + } + fprintf(bf, "\n" "%%start %s\n\n%%%%\n\n", start_node->id); + + fprintf(opfile, "\n" "} icg_opcodes;\n\n"); + fprintf(opfile, "const char *get_icg_opcode_name( icg_opcodes op );\n"); + fprintf(opfile, "#endif /*_icg_opcode_h*/\n"); + + fclose(opfile); opfile = 0; + + fprintf(opnfile, " { 0, 0 } };\n\n"); + fprintf(opnfile, + "const char *get_icg_opcode_name( icg_opcodes op ) {\n" + " static char buffer[128];\n" + " int i = 0;\n" + " for (;;) {\n" + " if (opnames[i].op == 0) {\n" + " snprintf(buffer, sizeof(buffer), \"error: opcode %%d not found\", op);\n" + " return buffer;\n" + " }\n" + " if (opnames[i].op == op) {\n" + " return opnames[i].str;\n" + " }\n" + " ++i;\n" + " }\n" + "}\n" + ); + + fclose(opnfile); opnfile = 0; +} + + + + +#define BIG_LINE 1000 + +void prologue(void) { + char line[BIG_LINE]; + fprintf(bf, "%%{\n"); + line_number = 1; + while (fgets(line, BIG_LINE, f)) { + line_number++; + if (line[0] == '%' && line[1] == '%') + break; + fputs(line, bf); + } + fprintf(bf, "%%}\n\n"); +} + + +void epilogue(void) { + char line[BIG_LINE]; + fputs("\n" "%%\n", bf); + while (fgets(line, BIG_LINE, f)) + fputs(line, bf); +} + + +int main(int argc, char *argv[]) { + int arg = 1; + bf = stdout; + f = stdin; + dir_name = (char *) get_current_dir_name(); + file_name = 0; + while (arg < argc) { + if (argv[arg][0] == '-') { + if (strcmp(argv[arg], "-o") == 0) { + if (bf == stdout) { + arg++; + if (arg < argc) { + bf = fopen(argv[arg], "w"); + if (!bf) { + perror(argv[arg]); + fprintf(stderr, "couldn't open %s\n", argv[arg]); + exit(1); + } + label_file(bf); + } + else { + fprintf(stderr, "expected a pathname after -o\n"); + exit(1); + } + } + else { + fprintf(stderr, "expected no more than one -o flag\n"); + exit(1); + } + } + else { + fprintf(stderr, "unexpected command-line option: %s\n", argv[arg]); + exit(1); + } + } + else if (f == stdin) { + f = open_and_update_names(argv[arg]); + if (!f) { + fprintf(stderr, "couldn't open %s\n", argv[arg]); + exit(1); + } + } + else { + fprintf(stderr, "expected no more than one filename as input\n"); + exit(1); + } + arg++; + } + + infofile = fopen("icg-ruleinfo.h", "w"); + if (infofile == 0) { + perror("icg-ruleinfo.h"); + exit(1); + } + label_file(infofile); + fprintf(infofile, "#if !defined(_icg_ruleinfo_h)\n"); + fprintf(infofile, "#define _icg_ruleinfo_h\n"); + + rulefile = fopen("icg-rulemaps.c", "w"); + if (rulefile == 0) { + perror("icg-rulemaps.h"); + exit(1); + } + label_file(rulefile); + fprintf(rulefile, "#include \"icg-ruleinfo.h\"\n"); + fprintf(rulefile, "typedef struct {\n"); + fprintf(rulefile, " const char *filename;\n"); + fprintf(rulefile, " int line_number;\n"); + fprintf(rulefile, "} icg_locus;\n"); + fprintf(rulefile, "icg_locus const icg_rule_to_locus[PLUG_NRULES] = {\n"); + fprintf(rulefile, "{\"?\",0},\n"); /* rule 0 is not used */ + + init_keywords(); + prologue(); + parse_decls(); + parse_rules(); + epilogue(); + + fprintf(rulefile, "};\n"); + fclose(rulefile); rulefile = 0; + + fprintf(infofile, "\n"); + fprintf(infofile, "#define PLUG_NRULES %4d\n", case_number+1); + fprintf(infofile, "\n"); + fprintf(infofile, "extern const char *const icg_burm_opname[];\n"); + fprintf(infofile, "extern char const icg_burm_arity[];\n"); + fprintf(infofile, "extern const char *const icg_burm_ntname[];\n"); + fprintf(infofile, "extern const short *const icg_burm_nts[PLUG_NRULES];\n"); + fprintf(infofile, "extern float const icg_burm_cost[PLUG_NRULES][4];\n"); + fprintf(infofile, "extern const char *const icg_burm_string[PLUG_NRULES];\n"); + fprintf(infofile, "\n"); + fprintf(infofile, "#endif\n"); + fclose(infofile); infofile = 0; + + return 0; /* assume success */ +} diff --git a/iburg/briggs/icg-x86.txt b/iburg/briggs/icg-x86.txt new file mode 100644 index 00000000000..ccadad9bfd4 --- /dev/null +++ b/iburg/briggs/icg-x86.txt @@ -0,0 +1,65 @@ +# +# Copyright © 2008 Google Inc. All rights reserved. +# +# $Header: $ +# +This table combines the gcc register number (1st col) +with the register name (2nd column) +with the register usage from table 3.4 in the ABI. +(The table was produced semi-auutomatically by joining data from +several places, and so may not be 100% accurate). +# + + 0 ax temporary register; with variable arguments passes information about the number of SSE registers used; 1st return register + 1 dx used to pass 3rd argument to functions; 2nd return register + 2 cx used to pass 4th integer argument to functions + 3 bx callee-saved register; optionally used as base pointer + 4 si used to pass 2nd argument to functions + 5 di used to pass 1st argument to functions + 6 bp HARD_FRAME_POINTER_REGNUM; callee-saved reg; optionally used as fp + 7 sp STACK_POINTER_REGNUM; stack pointer + 8 st0 temporary register; used to return long double arguments + 9 st1 temporary register; used to return long double arguments + 10 st2 temporary register + 11 st3 temporary register + 12 st4 temporary register + 13 st5 temporary register + 14 st6 temporary register + 15 st7 temporary register + 16 argp ARG_POINTER_REGNUM; used to address arguments before ICG + 17 flags no usage known + 18 fpsr no usage known + 19 fpcr no usage known + 20 frame FRAME_POINTER_REGNUM; used to address local variables before ICG + 21 xmm0 used to pass and return floating point arguments + 22 xmm1 used to pass and return floating point arguments + 23 xmm2 used to pass floating point arguments + 24 xmm3 used to pass floating point arguments + 25 xmm4 used to pass floating point arguments + 26 xmm5 used to pass floating point arguments + 27 xmm6 used to pass floating point arguments + 28 xmm7 used to pass floating point arguments + 29 mmx0 temporary register + 30 mmx1 temporary register + 31 mmx2 temporary register + 32 mmx3 temporary register + 33 mmx4 temporary register + 34 mmx5 temporary register + 35 mmx6 temporary register + 36 mmx7 temporary register + 37 r8 used to pass 5th argument to functions + 38 r9 used to pass 6th argument to functions + 39 r10 temporary register, used for passing a function's static chain pointer + 40 r11 temporary register + 41 r12 callee-saved register + 42 r13 callee-saved register + 43 r14 callee-saved register + 44 r15 callee-saved register + 45 xmm8 temporary register + 46 xmm9 temporary register + 47 xmm10 temporary register + 48 xmm11 temporary register + 49 xmm12 temporary register + 50 xmm13 temporary register + 51 xmm14 temporary register + 52 xmm15 temporary register diff --git a/iburg/briggs/icg.c b/iburg/briggs/icg.c new file mode 100644 index 00000000000..533c4e08d1f --- /dev/null +++ b/iburg/briggs/icg.c @@ -0,0 +1,524 @@ +/* Allocate registers within a basic block, for GNU compiler. + Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "flags.h" +#include "tm_p.h" +#include "function.h" +#include "basic-block.h" +#include "tree-pass.h" +#include "df.h" +#include "icg.h" +#include "icg-opcode.h" +#include "icg-ruleinfo.h" +#include "langhooks.h" + +struct obstack icg_obstack; +struct obstack icg_graph_obstack; + +icg_phi_node **icg_bb2phi; +unsigned icg_ssa_regs; +unsigned icg_live_ranges; +unsigned int *icg_ssa_to_lr; +icg_names **icg_ssa_liveout; +icg_names **icg_lr_liveout; + + +void icg_print_opcode (FILE *fp, icg_node *node, int indent, bool indent_p) +{ + if (fp == 0) fp = stdout; + if (node == NULL) { + fprintf (fp, "NULL\n"); + } else { + if (node->op == SYMBOL_REF_DI) { + fprintf (fp, "%s:%s", get_icg_opcode_name(node->op), node->a.string); + } else if (icg_reg_p (node)) { + const int reg = (icg_dead_reg_p (node) ? node->rx : node->r); + if (reg < FIRST_PSEUDO_REGISTER) { + fprintf (fp, "%s:%d[%s]", get_icg_opcode_name(node->op), + reg, reg_names[reg]); + } else { + fprintf (fp, "%s:%d", get_icg_opcode_name(node->op), reg); + } + } else if (icg_const_p (node)) { + fprintf (fp, "%s:%lld", get_icg_opcode_name(node->op), node->val); + } else { + fprintf (fp, "%s", get_icg_opcode_name(node->op)); + } + if (node->state_label) { + fprintf (fp, " <iburg handle %p>", node->state_label); + /* + * the state_label is really an opaque pointer + * to an opaque iburg specific data structure icg_burm_state, + * which is declared and defined in the icg-burg.c file from burg + * TODO + */ + } else { + fprintf (fp, " *** unmatched"); + } + fprintf(fp, " {node %p}", (void *)node); + if (flag_icg_trace & (1<<0)) { + icg_diagnose_match_candidates(fp, node->state_label, node, + indent, indent_p); + } + fprintf (fp, "\n"); + } +} + +#define inf (1.0/0.0) +void icg_diagnose_match_candidates(FILE *dump_file, + const icg_state_type state, icg_node *p, + int indent, bool indent_p) +{ + int NT; + char spaces[BUFSIZ]; + int i; + const char *sep = "\n"; + if (indent && indent_p) { + for (i = 0; i < indent + 4 && i < BUFSIZ-1; i++) { + spaces[i] = ' '; + } + spaces[i] = 0; + } + (void)state; + /* + * TODO: 77 is the number of NTs at one point in the development of the + * x86 grammar. This needs to come from some burg definition file. + */ + for (NT = 1; NT <= 77; NT++) { + /* + * icg_burm_rule can't necessarily be called with any NT, + * as we valgrind shows that we may use uninitialized variables + * internal to burg. + */ + const RuleNumber ruleno = icg_burm_rule(p->state_label, NT); + const float cost = icg_burm_get_cost(p->state_label, NT); + if (ruleno > 0 && cost != inf) { + if (indent && indent_p) { + fprintf(dump_file, "%s%s%6g:%5d: %s", + sep, spaces, + cost, ruleno, icg_burm_string[ruleno]); + } else { + fprintf(dump_file, " %6g:%5d:%s", + cost, ruleno, icg_burm_ntname[NT]); + } + } + } +} + +void * +icg_alloc (size_t size) +{ + return obstack_alloc (&icg_obstack, size); +} + +void * +icg_calloc (size_t size) +{ + void *p = obstack_alloc (&icg_obstack, size); + memset (p, 0, size); + return p; +} + +bool icg_reg_p (icg_node *pn) +{ + return (pn->op >= REG_DI && pn->op <= REGX_SF); +} + +bool icg_dead_reg_p (icg_node *pn) +{ + return (pn->op >= REGX_DI && pn->op <= REGX_SF); +} + +bool icg_const_p (icg_node *pn) +{ + return (pn->op >= CONST_0 && pn->op <= CONST64N); +} + +icg_node * +first_bb_icg_tree (basic_block bb) +{ + rtx insn; + FOR_BB_INSNS (bb, insn) { + if (INSN_P (insn) + && icg_insn2tree[INSN_UID (insn)]) { + return icg_insn2tree[INSN_UID (insn)]; + } + } + return 0; +} + + +icg_node * +next_bb_icg_tree (basic_block bb, icg_node* pn) +{ + rtx insn; + for (insn = NEXT_INSN (pn->insn); + insn && insn != NEXT_INSN (BB_END (bb)); + insn = NEXT_INSN (insn)) { + if (INSN_P (insn) + && icg_insn2tree[INSN_UID (insn)]) { + return icg_insn2tree[INSN_UID (insn)]; + } + } + return 0; +} + +/* Helper functions for for_reach_icg_tree_(def|use). */ + +static bool +icg_subreg_p (icg_node *pn) +{ + return (pn->op >= SUBREG_DI && pn->op <= SUBREG_QI); +} + +static int +mode_width (enum machine_mode mode) +{ + switch (mode) + { + case (QImode): + return 1; + case (HImode): + return 2; + case (SImode): + return 4; + case (DImode): + return 8; + default: + gcc_assert(0); + return 0; + } +} + +static int +for_each_icg_tree_1 (icg_node *pn, bool use, + int (*f)(icg_node *, void *), void *data) +{ + int ret = 0; + if (pn == NULL) + ret = 0; + else if (icg_reg_p (pn) && use) + ret = (*f)(pn, data); + else + { + /* Handle sets of REGs and SUBREGs. */ + if (pn->op == SET_ALL + && (icg_reg_p (pn->left) + || icg_subreg_p (pn->left))) + { + if (icg_reg_p (pn->left) && !use) + ret = (*f)(pn->left, data); + else if (icg_subreg_p (pn->left)) + { + gcc_assert (pn->left->left + && icg_reg_p (pn->left->left)); + /* If width of subreg is less than width of reg, then + this SET is an update (ie, both a use and def), + otherwise it is just a def. */ + if (mode_width (pn->left->mode) + < mode_width (pn->left->left->mode)) + ret = (*f)(pn->left->left, data); + else if (!use) + ret = (*f)(pn->left->left, data); + } + } + else if (pn->op == DEF_ALL) + { + if (!use) + { + gcc_assert (pn->left && icg_reg_p (pn->left)); + ret = (*f)(pn->left, data); + } + } + else + ret = for_each_icg_tree_1 (pn->left, use, f, data); + if (!ret) + ret = for_each_icg_tree_1 (pn->right, use, f, data); + } + return ret; +} + +/* Calls F on each icg_node in the icg tree PN which is a register + def. DATA is a used as a parameter to F. If F returns a nonzero + value at any time, the tree search stops and the value is returned + by the function. */ + +int +for_each_icg_tree_def (icg_node *pn, int (*f)(icg_node *, void *), void *data) +{ + return for_each_icg_tree_1 (pn, false, f, data); +} + +/* Like for_each_icg_tree_def, but F is called only on register + uses. */ + +int +for_each_icg_tree_use (icg_node *pn, int (*f)(icg_node *, void *), void *data) +{ + return for_each_icg_tree_1 (pn, true, f, data); +} + + +/* Prints icg_node NODE to FP in a compact representation, all on one + line. */ + +void +print_inline_icg_tree (FILE *fp, icg_node *node) +{ + if (fp == 0) fp = stdout; + fprintf (fp, "("); + icg_print_opcode (fp, node, 0, 0); + if (node->left) + { + fprintf (fp, " "); + print_inline_icg_tree (fp, node->left); + } + if (node->right) + { + fprintf (fp, " "); + print_inline_icg_tree (fp, node->right); + } + fprintf (fp, ")"); +} + + +/* Helper function for print_icg_node. */ + +static void +print_icg_tree_1 (FILE *fp, icg_node *tree, int indent, bool indent_p) +{ + int i; + if (fp == 0) fp = stdout; + if (indent_p) { + for (i = 0; i < indent; i++) { + fprintf (fp, " "); + } + } + icg_print_opcode (fp, tree, indent, indent_p); + if (tree->left) + print_icg_tree_1 (fp, tree->left, indent + 4, true); + if (tree->right) + print_icg_tree_1 (fp, tree->right, indent + 4, true); +} + +/* Prints icg_node TREE to FP in a multi-line pretty-printed indented + format. Output is prefixed on the same line by string specified by + FMT and ARGS in fprintf format, eg: + print_icg_tree (fp, n, "insn %d: ", id) */ + +void +print_icg_tree (FILE *fp, icg_node *tree, const char *fmt, ...) +{ + int len; + va_list arglist; + char str[BUFSIZ]; + va_start (arglist, fmt); + if (fp == 0) fp = stdout; + if (fmt == 0) fmt = ""; + vsnprintf (str, BUFSIZ, fmt, arglist); + len = strlen (str); + fprintf (fp, "%s", str); + print_icg_tree_1 (fp, tree, len, false); +} + +/* Dump all of the icg trees of the current function to FP. */ + +void +dump_icg_function (FILE *fp) +{ + basic_block bb; + if (fp == 0) fp = stdout; + FOR_EACH_BB (bb) { + dump_icg_bb (fp, bb); + } +} + +/* Dump all of the icg trees of basic block BB to FP. */ + +void +dump_icg_bb (FILE *fp, basic_block bb) +{ + icg_node *pn; + if (fp == 0) fp = stdout; + FOR_BB_ICG_TREES (bb, pn) { + print_icg_tree (fp, pn, "insn %d: ", INSN_UID (pn->insn)); + } +} + + +/* Dump the icg_tree TREE to stderr, for use in a debugger. */ + +void +debug_icg (icg_node *tree) +{ + char str[1] = ""; /* avoid gcc warning about zero length string. */ + print_icg_tree (stderr, tree, str); +} + +#include <stdarg.h> +extern void icg_nyi_handler(const char *filename, int lineno, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (dump_file) { + fflush(dump_file); + } + fprintf(stderr, "%s:%d: icg not yet implemented: ", filename, lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + abort(); + /*NOTREACHED*/ + exit(1); + /*NOTREACHED*/ +} + + +/* Pass implementing new code generator (combined instruction + selection and graph-coloring register allocator) */ + +static unsigned +rest_of_handle_icg (void) +{ + void *firstobj; + void *graph_mark; + unsigned pass = 0; + + df_note_add_problem (); + df_scan_alloc (NULL); + df_scan_blocks (); + df_analyze (); + + gcc_obstack_init (&icg_graph_obstack); + graph_mark = obstack_alloc(&icg_graph_obstack, 0); + gcc_obstack_init (&icg_obstack); + firstobj = icg_alloc (0); + + /* + * Results accumulate in the vector icg_insn2tree and icg_insn2dirty + */ + icg_create_side_tree (); + if (dump_file) + { + fprintf (dump_file, "*** Initial ICG tree:\n"); + dump_icg_function (dump_file); + } + + icg_build_ssa (); + icg_build_live_ranges (); + + /* copied from reload1.c's computation of frame_pointer_needed */ + frame_pointer_needed = !flag_omit_frame_pointer + || (cfun->calls_alloca && EXIT_IGNORE_STACK) + || crtl->accesses_prior_frames + || FRAME_POINTER_REQUIRED; + + icg_find_updates(); + icg_forward_prop(); + + for (pass = 0; 1; pass++) { + bool all_done; + icg_reassociate(); + icg_select(); + icg_find_names(); + /* icg_supairs(); */ /* As of 18Aug2008 not tested */ + icg_graph(pass); + icg_remat(); + icg_costs(pass); + icg_color(); + all_done = icg_spill(pass); + if (pass > 0 && all_done) { + /* If spill code is required, we must do another pass. + * But we always do at least two passes, whether or not there is spill code. + * + * Why? On pass 0, I don't allow machine registers to be coalesced with + * symbolic registers, since such coalesces will often create very long + * live ranges that cannot be spilled. Therefore, we make an initial + * pass reducing register pressure to a reasonable level (inserting some spill code), + * then make at least one more pass, inserting final touchups. + * + * In addition, we must run icg_spill() at least once so that references + * from ARGP are correctly adjusted. + */ + break; + } + obstack_free (&icg_graph_obstack, graph_mark); + icg_find_updates(); + } + + icg_final(); + + if (dump_file) { + icg_debug("final"); + } + + icg_emit(); + + /* + * icg_final and icg_debug refer to icg_reg_vector, + * so we can't free up icg_graph_obstack until we are all done + */ + obstack_free (&icg_graph_obstack, graph_mark); + obstack_free (&icg_obstack, firstobj); + + reload_completed = true; + df_finish_pass (true); + if (optimize > 1) + df_live_add_problem (); + df_scan_alloc (NULL); + df_scan_blocks (); + + if (optimize) + df_analyze (); + + return 0; +} + + + +static bool +gate_icg (void) +{ + return flag_icg; +} + + +struct rtl_opt_pass pass_icg = +{ + { + RTL_PASS, + "icg", /* name */ + gate_icg, /* gate */ + rest_of_handle_icg, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + } +}; diff --git a/iburg/briggs/icg.h b/iburg/briggs/icg.h new file mode 100644 index 00000000000..e97f2fd49a4 --- /dev/null +++ b/iburg/briggs/icg.h @@ -0,0 +1,274 @@ +/* Integrated code generator (ICG), combined instruction selector and + register allocator. Copyright (C) 2008 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 +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_ICG_H +#define GCC_ICG_H + +#include "obstack.h" + +/* icg_state_type is an opaque type that points to a burg private data struct */ +typedef void *icg_state_type; + + +#define MAX_KIDS 10 /* maximum number of NT children in pattern */ + +#include "icg-opcode.h" + +enum { + burm_goal_NT=1 /* stmt */ +}; +typedef short NT; /* type must agree with burm */ +typedef int RuleNumber; /* type must agree with burm */ + +typedef struct _amode { + unsigned char base_valid; /* 1 if base valid; 0 if base invalid */ + unsigned char base_rip; /* 1 if base is really %rip */ + unsigned base; /* base register, iff valid */ + int scale; /* scale value (1,2,4,8) */ + unsigned index; /* if scale > 0, then associated index reg */ + int disp; /* displacement value */ + const char *string; /* symbol name */ +} amode; + +typedef struct _icg_node { + icg_opcodes op; + + struct _icg_node *left; /* left child */ + struct _icg_node *right; /* right child */ + icg_state_type state_label; /* from burg */ + NT goalNT; /* goal non terminal for best match */ + + rtx rtl; /* rtx of operation */ + rtx insn; /* rtx of containing insn */ + + unsigned ssa_name; /* real register REGNO or SSA name if symbolic */ + unsigned live_range; /* real register REGNO or live range name if symbolic */ + + unsigned r; /* register that may NOT be reused */ + unsigned rx; /* register that might be reused */ + + bool spilled; /* indicates that an lhs register has been spilled (replace with a mem reference) */ + + amode a; /* matched addressing mode */ + + long long int val; /* value of constant */ + + enum rtx_code code; /* used to indicate type of condition: LE, LTU, ... */ + enum machine_mode cc_code; /* one of: CCmode CCFPU CCFPmode */ + + unsigned extra; + unsigned freed; + + /* + * perm controls the visit order to the children. + */ + short perm[MAX_KIDS]; /* visit order */ + /* + * perm_kids is the number of kids iff this node is covered by the root of a pattern + * that has >=2 non terminals. The primary purpose of this is to avoid + * setting up a permutation for a chain rule that clobbers the permutation + * for a rule where the permutation really matters. + */ + int perm_kids; /* access control on perm: either 0 or >= 2 */ + + unsigned id; /* instruction id (?) */ + + /* + * mode reflects whatever the opcode said: ADD_DI would be DImode and so on. + */ + enum machine_mode mode; + +} icg_node; + +typedef icg_node *icg_nodes; + +extern bool *icg_insn2dirty; +extern icg_node **icg_insn2tree; +extern int *icg_insn2goalNT; + +#define FOR_BB_ICG_TREES(BB, PT) \ + for ((PT) = first_bb_icg_tree (BB); (PT); (PT) = next_bb_icg_tree (BB, PT)) + +int for_each_icg_tree_def (icg_node*, int (*)(icg_node *, void *), void*); +int for_each_icg_tree_use (icg_node*, int (*)(icg_node *, void *), void*); +icg_node *first_bb_icg_tree (basic_block); +icg_node *next_bb_icg_tree (basic_block, icg_node*); +icg_node *icg_tree_rewrite (icg_node*); + +/* List of SSA phi nodes associated with a particular basic block, + computed in icg-ssa.c */ +typedef struct _icg_phi_node { + struct _icg_phi_node *next; + /* regno of register in original RTL */ + unsigned reg; + unsigned def; + /* Dynamically-sized array. Size of USES is number of predecessors + of basic block. */ + unsigned uses[1]; +} icg_phi_node; + +/* List of phi nodes for each BB, indexed by basic block index. */ +extern icg_phi_node **icg_bb2phi; + +typedef struct _icg_names { + struct _icg_names *next; + unsigned size; + unsigned name[1]; +} icg_names; + + +typedef struct { + unsigned root; /* for union-find structure */ + unsigned degree; /* number of neighbors in the interference graph */ + float cost; /* spill cost, possibly infinite */ + float loads; /* weighted number of loads */ + float stores; /* weighted number of stores */ + float copies; /* weighted number of copies */ + float points; /* weighted number of points */ + int color; /* assigned during coloring, -1 indicates spilled */ + unsigned kind; /* bit vector to indicated kind of register */ + unsigned stack; /* used to implement stack during coloring */ + long long int offset; /* if spilled, location in stack frame */ + icg_names *av; /* adjacency vectors */ + bool leaf; /* used during spill-cost calculation */ +} icg_reg_info; + +#define INT_REGISTER (1 << 0) +#define FLOAT_REGISTER (1 << 1) + +extern icg_reg_info *icg_reg_vector; +extern unsigned icg_ssa_regs; +extern unsigned icg_live_ranges; +extern unsigned icg_interior_regs; + +/* Mapping from SSA name to live range name. */ +extern unsigned int *icg_ssa_to_lr; +/* SSA variables live out of each basic block. Indexed by basic block index. */ +extern icg_names **icg_ssa_liveout; +/* Live ranges live out of each basic block. Indexed by basic block index. */ +extern icg_names **icg_lr_liveout; + + +extern struct obstack icg_obstack; +extern struct obstack icg_graph_obstack; + +#define FOR_BB_ICG_PHI_NODES(BB, PHI) \ + for ((PHI) = icg_bb2phi[(BB)->index]; (PHI); (PHI) = (PHI)->next) + +/* In icg.c. */ +extern void *icg_alloc (size_t size); +extern void *icg_calloc (size_t size); +extern bool icg_reg_p (icg_node*); +extern bool icg_dead_reg_p (icg_node*); +extern bool icg_const_p (icg_node*); +extern void print_inline_icg_tree (FILE*, icg_node*); +extern void print_icg_tree (FILE*, icg_node*, const char*, ...) + __attribute__((format(printf, 3, 4))); +extern void dump_icg_function (FILE*); +extern void dump_icg_bb (FILE*, basic_block); +extern void debug_icg (icg_node*); + +/* In icg-emit.c */ +extern void icg_print_rulecount (FILE *dump_file, int dump_code); +extern void icg_dump_rulecount (void); +extern void icg_read_rulecount (FILE *read_file); + +/* In icg-build-tree.c */ +extern unsigned icg_create_side_tree(void); +typedef enum _icg_analyze_asm_key { + ICG_ASM_PHASE_FILTER, + ICG_ASM_PHASE_BUILD, + ICG_ASM_PHASE_DEBUG +} icg_analyze_asm_key; +extern int icg_analyze_asm(rtx expr, icg_analyze_asm_key how); + +/* In icg-ssa.c */ +extern void icg_build_ssa (void); +extern void icg_build_live_ranges (void); +extern void dump_icg_rtl (FILE *fp); +extern void dump_icg_ssa (FILE *fp); +extern void dump_icg_live_ranges (FILE *fp); + +/* In icg-burg.c (generated by iburg) */ +extern icg_state_type icg_burm_label(icg_nodes p); +extern RuleNumber icg_burm_rule(icg_state_type state, NT goalNT); +extern float icg_burm_get_cost(icg_state_type state, NT goalNT); +extern const NT *const icg_burm_nts[]; +extern icg_nodes *icg_burm_kids(icg_nodes p, RuleNumber eruleno, icg_nodes kids[]); + +/* In icg-debug.c */ +extern void icg_trace_rule(FILE *dump_file, const icg_node *p, + int depth, NT goalNT); + +/* In icg-burg.c (generated by iburg -I) */ +extern const char *const icg_burm_ntname[]; +extern const char *const icg_burm_opname[]; +extern const char *const icg_burm_string[]; +extern char const icg_burm_arity[]; + +/* + * These are enumerations in gcc's i386 register space + */ +enum _gcc_i386_registers_t { + REG_RAX=0, /* temporary register */ + REG_RBX=3, /* callee-saved */ + REG_RCX=2, /* 4th argument to functions */ + REG_RDX=1, /* 3rd argument to functions */ + REG_RSI=4, /* 2nd argument to functions */ + REG_RDI=5, /* 1st argument to functions */ + REG_RBP=6, /* HARD_FRAME_POINTER_REGNUM */ + REG_RSP=7, /* STACK_POINTER_REGNUM */ + REG_ARGP=16, /* argument pointer */ + REG_CC=17, /* condition code/flags */ + REG_CCFPU=19, /* floating condition code/flags */ + REG_FP=20 /* frame pointer */ +}; + + +extern unsigned icg_path_compress(unsigned); + +/* In icg-reassociate.c */ +extern void icg_reassociate(void); +extern void icg_forward_prop(void); +extern void icg_select(void); +extern void icg_find_names(void); +extern void icg_supairs(void); +extern void icg_graph(unsigned pass); +extern void icg_costs(unsigned pass); +extern void icg_color(void); +extern void icg_remat(void); +extern bool icg_spill(unsigned pass); +extern void icg_find_updates(void); +extern void icg_final(void); +extern void icg_emit(void); +extern void icg_debug(const char *whence); +extern icg_opcodes icg_op_of_constant(long long int offset); + +extern void icg_print_opcode(FILE *fp, icg_node *node, + int indent, bool indent_p); +extern void icg_print_runs(FILE *fp, const unsigned *p, size_t size); +void icg_diagnose_match_candidates(FILE *dump_file, + const icg_state_type state, icg_node *node, + int indent, bool indent_p); + +#define icg_nyi(fmt, ...) icg_nyi_handler(__FILE__, __LINE__, fmt, ## __VA_ARGS__) +extern void icg_nyi_handler(const char *filename, int lineno, + const char *fmt, ...) __attribute__((format (printf, 3, 4))); + +#endif /* GCC_ICG_H */ |