diff options
Diffstat (limited to 'gcc/config/rs6000')
65 files changed, 0 insertions, 30224 deletions
diff --git a/gcc/config/rs6000/aix31.h b/gcc/config/rs6000/aix31.h deleted file mode 100755 index 46bd03c..0000000 --- a/gcc/config/rs6000/aix31.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 running AIX version 3.1. - Copyright (C) 1993,1997 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "rs6000/rs6000.h" - -/* AIX 3.2 defined _AIX32, but older versions do not. */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D_IBMR2 -D_AIX -Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" - -/* AIX 3.1 uses bit 15 in CROR as the magic nop. */ -#undef RS6000_CALL_GLUE -#define RS6000_CALL_GLUE "cror 15,15,15" - -/* AIX 3.1 does not prepend underscores to itrunc, uitrunc, or mcount. */ -#undef RS6000_ITRUNC -#define RS6000_ITRUNC "itrunc" -#undef RS6000_UITRUNC -#define RS6000_UITRUNC "uitrunc" -#undef RS6000_MCOUNT -#define RS6000_MCOUNT ".mcount" - diff --git a/gcc/config/rs6000/aix3newas.h b/gcc/config/rs6000/aix3newas.h deleted file mode 100755 index 9659794..0000000 --- a/gcc/config/rs6000/aix3newas.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX version 3.x with the fixed assembler. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, - -#include "rs6000/rs6000.h" - -/* Tell the assembler to assume that all undefined names are external. */ - -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu)" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mpwr" - -/* Define the options for the binder: Start text at 512, align all segments - to 512 bytes, and warn if there is text relocation. - - The -bhalt:4 option supposedly changes the level at which ld will abort, - but it also suppresses warnings about multiply defined symbols and is - used by the AIX cc command. So we use it here. - - -bnodelcsect undoes a poor choice of default relating to multiply-defined - csects. See AIX documentation for more information about this. - - -bM:SRE tells the linker that the output file is Shared REusable. Note - that to actually build a shared library you will also need to specify an - export list with the -Wl,-bE option. - - If -mcpu=common, export the architecture dependent multiply/divide routines - as per README.RS6000. */ - -#undef LINK_SPEC -#ifndef CROSS_COMPILE -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso -bI:/lib/syscalls.exp} \ - %{mcpu=common: milli.exp%s} \ - %{!shared:%{g*:-bexport:/usr/lib/libg.exp}} %{shared:-bM:SRE}" -#else -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso} \ - %{mcpu=common: milli.exp%s} \ - %{shared:-bM:SRE}" -#endif - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} diff --git a/gcc/config/rs6000/aix41.h b/gcc/config/rs6000/aix41.h deleted file mode 100755 index b35fe93..0000000 --- a/gcc/config/rs6000/aix41.h +++ /dev/null @@ -1,169 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX version 4.1. - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@npac.syr.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, \ - {"threads", 0}, \ - {"pe", 0}, - -#include "rs6000/rs6000.h" - -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu)" - -/* Common ASM definitions used by ASM_SPEC amonst the various targets - for handling -mcpu=xxx switches. */ -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -mpwr}} \ - %{mpower2: -mpwr2} \ - %{mpowerpc*: -mppc} \ - %{!mpower*: %{!mpowerpc*: %(asm_default)}}} \ -%{mcpu=common: -mcom} \ -%{mcpu=power: -mpwr} \ -%{mcpu=power2: -mpwr2} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rios: -mpwr} \ -%{mcpu=rios1: -mpwr} \ -%{mcpu=rios2: -mpwr2} \ -%{mcpu=rsc: -mpwr} \ -%{mcpu=rsc1: -mpwr} \ -%{mcpu=403: -mppc} \ -%{mcpu=505: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=620: -mppc} \ -%{mcpu=821: -mppc} \ -%{mcpu=860: -mppc}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mcom" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 \ --D_LONG_LONG -Asystem(unix) -Asystem(aix)" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ - %{mpe: -I/usr/lpp/ppe.poe/include}\ - %{mthreads: -D_THREAD_SAFE}\ - %(cpp_cpu)" - -/* Common CPP definitions used by CPP_SPEC among the various targets - for handling -mcpu=xxx switches. */ -#undef CPP_CPU_SPEC -#define CPP_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -D_ARCH_PWR}} \ - %{mpower2: -D_ARCH_PWR2} \ - %{mpowerpc*: -D_ARCH_PPC} \ - %{!mpower*: %{!mpowerpc*: %(cpp_default)}}} \ -%{mcpu=common: -D_ARCH_COM} \ -%{mcpu=power: -D_ARCH_PWR} \ -%{mcpu=power2: -D_ARCH_PWR2} \ -%{mcpu=powerpc: -D_ARCH_PPC} \ -%{mcpu=rios: -D_ARCH_PWR} \ -%{mcpu=rios1: -D_ARCH_PWR} \ -%{mcpu=rios2: -D_ARCH_PWR2} \ -%{mcpu=rsc: -D_ARCH_PWR} \ -%{mcpu=rsc1: -D_ARCH_PWR} \ -%{mcpu=403: -D_ARCH_PPC} \ -%{mcpu=505: -D_ARCH_PPC} \ -%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \ -%{mcpu=602: -D_ARCH_PPC} \ -%{mcpu=603: -D_ARCH_PPC} \ -%{mcpu=603e: -D_ARCH_PPC} \ -%{mcpu=604: -D_ARCH_PPC} \ -%{mcpu=620: -D_ARCH_PPC} \ -%{mcpu=821: -D_ARCH_PPC} \ -%{mcpu=860: -D_ARCH_PPC}" - -#undef CPP_DEFAULT_SPEC -#define CPP_DEFAULT_SPEC "-D_ARCH_COM" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_NEW_MNEMONICS - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC601 - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mcpu=common" } - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ - %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}}\ - %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{mthreads: -L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a}\ - %{!mthreads: -lc}" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{!shared: %{g*: %(link_libg) }}\ - %{shared:-bM:SRE %{!e:-bnoentry}}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\ - %{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\ - %{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\ - %{!mpe:\ - %{mthreads:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!mthreads:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" - diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h deleted file mode 100755 index 124fc17..0000000 --- a/gcc/config/rs6000/aix43.h +++ /dev/null @@ -1,199 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX version 4.3. - Copyright (C) 1998 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@mhpcc.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"aix64", MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC}, \ - {"aix32", - (MASK_64BIT | MASK_POWERPC64)}, \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, \ - {"threads", 0}, \ - {"pe", 0}, - -/* Sometimes certain combinations of command options do not make sense - on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control. */ - -#define NON_POWERPC_MASKS (MASK_POWER | MASK_POWER2 | MASK_STRING) -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && (target_flags & NON_POWERPC_MASKS)) \ - { \ - target_flags &= ~NON_POWERPC_MASKS; \ - error ("-maix64 and POWER architecture are incompatible."); \ - } \ -} while (0); - -#include "rs6000/rs6000.h" - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)" - -/* Common ASM definitions used by ASM_SPEC amonst the various targets - for handling -mcpu=xxx switches. */ -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC \ -"%{!mcpu*: %{!maix64: \ - %{mpower: %{!mpower2: -mpwr}} \ - %{mpower2: -mpwr2} \ - %{mpowerpc*: %{!mpowerpc64: -mppc}} \ - %{mpowerpc64: -mppc64} \ - %{!mpower*: %{!mpowerpc*: %(asm_default)}}}} \ -%{mcpu=common: -mcom} \ -%{mcpu=power: -mpwr} \ -%{mcpu=power2: -mpwr2} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rios: -mpwr} \ -%{mcpu=rios1: -mpwr} \ -%{mcpu=rios2: -mpwr2} \ -%{mcpu=rsc: -mpwr} \ -%{mcpu=rsc1: -mpwr} \ -%{mcpu=403: -mppc} \ -%{mcpu=505: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=620: -mppc} \ -%{mcpu=821: -mppc} \ -%{mcpu=860: -mppc}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mcom" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 \ --D_LONG_LONG -Asystem(unix) -Asystem(aix)" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ - %{maix64: -D__64BIT__ -D_ARCH_PPC}\ - %{mpe: -I/usr/lpp/ppe.poe/include}\ - %{mthreads: -D_THREAD_SAFE}\ - %(cpp_cpu)" - -/* Common CPP definitions used by CPP_SPEC among the various targets - for handling -mcpu=xxx switches. */ -#undef CPP_CPU_SPEC -#define CPP_CPU_SPEC \ -"%{!mcpu*: %{!maix64: \ - %{mpower: %{!mpower2: -D_ARCH_PWR}} \ - %{mpower2: -D_ARCH_PWR2} \ - %{mpowerpc*: -D_ARCH_PPC} \ - %{!mpower*: %{!mpowerpc*: %(cpp_default)}}}} \ -%{mcpu=common: -D_ARCH_COM} \ -%{mcpu=power: -D_ARCH_PWR} \ -%{mcpu=power2: -D_ARCH_PWR2} \ -%{mcpu=powerpc: -D_ARCH_PPC} \ -%{mcpu=rios: -D_ARCH_PWR} \ -%{mcpu=rios1: -D_ARCH_PWR} \ -%{mcpu=rios2: -D_ARCH_PWR2} \ -%{mcpu=rsc: -D_ARCH_PWR} \ -%{mcpu=rsc1: -D_ARCH_PWR} \ -%{mcpu=403: -D_ARCH_PPC} \ -%{mcpu=505: -D_ARCH_PPC} \ -%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \ -%{mcpu=602: -D_ARCH_PPC} \ -%{mcpu=603: -D_ARCH_PPC} \ -%{mcpu=603e: -D_ARCH_PPC} \ -%{mcpu=604: -D_ARCH_PPC} \ -%{mcpu=620: -D_ARCH_PPC} \ -%{mcpu=821: -D_ARCH_PPC} \ -%{mcpu=860: -D_ARCH_PPC}" - -#undef CPP_DEFAULT_SPEC -#define CPP_DEFAULT_SPEC "-D_ARCH_COM" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_NEW_MNEMONICS - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC604 - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mcpu=common" } - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ - %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}}\ - %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{mthreads: -L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a}\ - %{!mthreads: -lc}" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{!shared: %{g*: %(link_libg) }}\ - %{shared:-bM:SRE %{!e:-bnoentry}} %{maix64:-b64}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\ - %{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\ - %{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\ - %{!mpe:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{mthreads:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!mthreads:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}" - -/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - diff --git a/gcc/config/rs6000/beos.h b/gcc/config/rs6000/beos.h deleted file mode 100755 index 851601f..0000000 --- a/gcc/config/rs6000/beos.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Definitions of target machine for GNU compiler, for BeOS. - Copyright (C) 1997 Free Software Foundation, Inc. - Contributed by Fred Fish (fnf@cygnus.com), based on aix41.h - from David Edelsohn (edelsohn@npac.syr.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, \ - {"threads", 0}, \ - {"pe", 0}, - -#include "rs6000/rs6000.h" - -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu)" - -#undef CPP_PREDEFINES -/* __POWERPC__ must be defined for some header files */ -#define CPP_PREDEFINES "-D__BEOS__ -D__POWERPC__ -Asystem(beos) -Acpu(powerpc) -Amachine(powerpc)" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_cpu)" - -#undef CPP_DEFAULT_SPEC -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -/* This is the easiest way to disable use of gcc's builtin alloca, - which in the current BeOS release (DR9) is a problem because of the - relatively low default stack size of 256K with no way to expand it. - So anything we compile for the BeOS target should not use the - builtin alloca. This also has the unwanted side effect of - disabling all builtin functions though. */ - -#undef CC1_SPEC -#define CC1_SPEC "%{!fbuiltin: -fno-builtin}" -#undef CC1PLUS_SPEC -#define CC1PLUS_SPEC "%{!fbuiltin: -fno-builtin}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC603 - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mcpu=powerpc" } - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} - -/* These empty definitions get rid of the attempt to link in crt0.o - and any libraries like libc.a. - On BeOS the ld executable is actually a linker front end that first runs - the GNU linker with the -r option to generate a relocatable XCOFF output - file, and then runs Metrowork's linker (mwld) to generate a fully linked - executable. */ - -#undef LIB_SPEC -#define LIB_SPEC "" - -#undef LINK_SPEC -#define LINK_SPEC "" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "" - -/* Text to write out after a CALL that may be replaced by glue code by - the loader. */ - -#undef RS6000_CALL_GLUE -#define RS6000_CALL_GLUE "cror 15,15,15" - -/* Struct alignments are done on 4 byte boundaries for all types. */ -#undef BIGGEST_FIELD_ALIGNMENT -#define BIGGEST_FIELD_ALIGNMENT 32 diff --git a/gcc/config/rs6000/cygwin.h b/gcc/config/rs6000/cygwin.h deleted file mode 100755 index 0ed448b..0000000 --- a/gcc/config/rs6000/cygwin.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Operating system specific defines to be used when targeting GCC for - hosting on Windows NT 3.x, using the Cygnus API - - This is different to the winnt.h file, since that is used - to build GCC for use with a windows style library and tool - set, winnt.h uses the Microsoft tools to do that. - - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Ugly hack */ -#include "rs6000/win-nt.h" - - -#ifdef CPP_PREDEFINES -#undef CPP_PREDEFINES -#endif - -#define CPP_PREDEFINES "-D_WIN32 -DWINNT -D__CYGWIN__ -D__CYGWIN32__ -DPOSIX \ - -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)" - -#undef CPP_SPEC -#define CPP_SPEC "-remap %{posix: -D_POSIX_SOURCE} %(cpp_cpu)" - -/* We have to dynamic link to get to the system DLLs. All of libc, libm and - the Unix stuff is in cygwin.dll. The import library is called - 'libcygwin.a'. For Windows applications, include more libraries, but - always include kernel32. We'd like to specific subsystem windows to - ld, but that doesn't work just yet. */ - -#undef LIB_SPEC -#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32" - -#undef LINK_SPEC -#define LINK_SPEC "%{v:-V}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "crti%O%s crt0%O%s" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtn%O%s" - -#define PTRDIFF_TYPE "int" -#define WCHAR_UNSIGNED 1 -#define WCHAR_TYPE_SIZE 16 -#define WCHAR_TYPE "short unsigned int" - -#define DBX_DEBUGGING_INFO -#undef SDB_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/gcc/config/rs6000/eabi-ci.asm b/gcc/config/rs6000/eabi-ci.asm deleted file mode 100755 index da3914c..0000000 --- a/gcc/config/rs6000/eabi-ci.asm +++ /dev/null @@ -1,131 +0,0 @@ -# crti.s for eabi - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled starting points for the .got* and other -# special sections. It is linked in first before other modules. - - .file "crti.s" - .ident "GNU C crti.s" - -#include <ppc-asm.h> - - .section ".got","aw" - .globl __GOT_START__ - .type __GOT_START__,@object -__GOT_START__: - - .section ".got1","aw" - .globl __GOT1_START__ - .type __GOT1_START__,@object -__GOT1_START__: - - .section ".got2","aw" - .globl __GOT2_START__ - .type __GOT2_START__,@object -__GOT2_START__: - - .section ".fixup","aw" - .globl __FIXUP_START__ - .type __FIXUP_START__,@object -__FIXUP_START__: - - .section ".ctors","aw" - .globl __CTOR_LIST__ - .type __CTOR_LIST__,@object -__CTOR_LIST__: - -# CYGNUS LOCAL vmakarov - .globl ___CTOR_LIST__ # add support for -fleading-underscore - .type ___CTOR_LIST__,@object -___CTOR_LIST__: -# END CYGNUS LOCAL - - .section ".dtors","aw" - .globl __DTOR_LIST__ - .type __DTOR_LIST__,@object -__DTOR_LIST__: - -# CYGNUS LOCAL vmakarov - .globl ___DTOR_LIST__ - .type ___DTOR_LIST__,@object -___DTOR_LIST__: -# END CYGNUS LOCAL - - .section ".sdata","aw" - .globl __SDATA_START__ - .type __SDATA_START__,@object - .weak _SDA_BASE_ - .type _SDA_BASE_,@object -__SDATA_START__: -_SDA_BASE_: - - .section ".sbss","aw",@nobits - .globl __SBSS_START__ - .type __SBSS_START__,@object -__SBSS_START__: - - .section ".sdata2","a" - .weak _SDA2_BASE_ - .type _SDA2_BASE_,@object - .globl __SDATA2_START__ - .type __SDATA2_START__,@object -__SDATA2_START__: -_SDA2_BASE_: - - .section ".sbss2","a" - .globl __SBSS2_START__ - .type __SBSS2_START__,@object -__SBSS2_START__: - - .section ".gcc_except_table","aw" - .globl __EXCEPT_START__ - .type __EXCEPT_START__,@object -__EXCEPT_START__: - -# Head of __init function used for static constructors in Solaris - .section ".init","ax" - .align 2 -FUNC_START(__init) - stwu 1,-8(1) - mflr 0 - stw 0,12(1) - -# Head of __fini function used for static destructors in Solaris - .section ".fini","ax" - .align 2 -FUNC_START(__fini) - stwu 1,-8(1) - mflr 0 - stw 0,12(1) diff --git a/gcc/config/rs6000/eabi-cn.asm b/gcc/config/rs6000/eabi-cn.asm deleted file mode 100755 index 9456762..0000000 --- a/gcc/config/rs6000/eabi-cn.asm +++ /dev/null @@ -1,121 +0,0 @@ -# crtn.s for eabi - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled ending points for the .got* and other -# special sections. It is linked in last after other modules. - - .file "crtn.s" - .ident "GNU C crtn.s" - - .section ".got","aw" - .globl __GOT_END__ - .type __GOT_END__,@object -__GOT_END__: - - .section ".got1","aw" - .globl __GOT1_END__ - .type __GOT1_END__,@object -__GOT1_END__: - - .section ".got2","aw" - .globl __GOT2_END__ - .type __GOT2_END__,@object -__GOT2_END__: - - .section ".fixup","aw" - .globl __FIXUP_END__ - .type __FIXUP_END__,@object -__FIXUP_END__: - - .section ".ctors","aw" - .globl __CTOR_END__ - .type __CTOR_END__,@object -__CTOR_END__: - -# CYGNUS LOCAL vmakarov - .globl ___CTOR_END__ # add support for -fleading-underscore - .type ___CTOR_END__,@object -___CTOR_END__: -# END CYGNUS LOCAL - - .section ".dtors","aw" - .globl __DTOR_END__ - .type __DTOR_END__,@object -__DTOR_END__: - -# CYGNUS LOCAL vmakarov - .globl ___DTOR_END__ - .type ___DTOR_END__,@object -___DTOR_END__: -# END CYGNUS LOCAL - - .section ".sdata","aw" - .globl __SDATA_END__ - .type __SDATA_END__,@object -__SDATA_END__: - - .section ".sbss","aw",@nobits - .globl __SBSS_END__ - .type __SBSS_END__,@object -__SBSS_END__: - - .section ".sdata2","a" - .globl __SDATA2_END__ - .type __SDATA2_END__,@object -__SDATA2_END__: - - .section ".sbss2","a" - .globl __SBSS2_END__ - .type __SBSS2_END__,@object -__SBSS2_END__: - - .section ".gcc_except_table","aw" - .globl __EXCEPT_END__ - .type __EXCEPT_END__,@object -__EXCEPT_END__: - -# Tail of __init used for static constructors in Solaris - .section ".init","ax" - lwz 0,12(1) - mtlr 0 - addi 1,1,8 - blr - -# Tail of __fini used for static destructors in Solaris - .section ".fini","ax" - lwz 0,12(1) - mtlr 0 - addi 1,1,8 - blr diff --git a/gcc/config/rs6000/eabi-ctors.c b/gcc/config/rs6000/eabi-ctors.c deleted file mode 100755 index ebc23de..0000000 --- a/gcc/config/rs6000/eabi-ctors.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Stripped down support to run global constructors and destructors on - embedded PowerPC systems. - - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - - -/* Declare a pointer to void function type. */ - -typedef void (*func_ptr) (void); - -/* Declare the set of symbols use as begin and end markers for the lists - of global object constructors and global object destructors. */ - -extern func_ptr __CTOR_LIST__[]; -extern func_ptr __CTOR_END__ []; -extern func_ptr __DTOR_LIST__[]; -extern func_ptr __DTOR_END__ []; - -extern void __do_global_ctors (void); -extern void __do_global_dtors (void); - -extern void __init (), __fini (); - -/* The Solaris linker seems to incorrectly relocate PC relative relocations - to a different section (ie, calls to __init, __fini), so avoid it by - using a function pointer. */ -static void (*init_ptr) (void) = __init; -static void (*fini_ptr) (void) = __fini; - -void (*__atexit)(func_ptr); - -/* Call all global constructors */ -void -__do_global_ctors (void) -{ - func_ptr *ptr = &__CTOR_LIST__[0]; - func_ptr *end = &__CTOR_END__[0]; - - if (__atexit) - __atexit (__do_global_dtors); - - /* Call the constructors collected in the .ctors section. */ - for ( ; ptr != end; ptr++) - if (*ptr) - (*ptr)(); - - /* Call the initialization function in the .init section. */ - (*init_ptr) (); -} - -/* Call all global destructors */ -void -__do_global_dtors (void) -{ - func_ptr *ptr = &__DTOR_END__[0] - 1; - func_ptr *start = &__DTOR_LIST__[0]; - - /* Call the termination function in the .fini section. */ - (*fini_ptr) (); - - /* Call the destructors collected in the .dtors section. Run - the destructors in reverse order. */ - for ( ; ptr >= start; ptr--) - if (*ptr) - (*ptr)(); -} - diff --git a/gcc/config/rs6000/eabi.asm b/gcc/config/rs6000/eabi.asm deleted file mode 100755 index 803105f..0000000 --- a/gcc/config/rs6000/eabi.asm +++ /dev/null @@ -1,575 +0,0 @@ -/* - * special support for eabi - * - * Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. - * Written By Michael Meissner - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * In addition to the permissions in the GNU General Public License, the - * Free Software Foundation gives you unlimited permission to link the - * compiled version of this file with other programs, and to distribute - * those programs without any restriction coming from the use of this - * file. (The General Public License restrictions do apply in other - * respects; for example, they cover modification of the file, and - * distribution when not linked into another program.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * As a special exception, if you link this library with files - * compiled with GCC to produce an executable, this does not cause - * the resulting executable to be covered by the GNU General Public License. - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - */ - -/* Do any initializations needed for the eabi environment */ - - .file "eabi.asm" - .section ".text" - #include "ppc-asm.h" - - .section ".got2","aw" - .align 2 -.LCTOC1 = . /* +32768 */ - -/* Table of addresses */ -.Ltable = .-.LCTOC1 - .long .LCTOC1 /* address we are really at */ - -.Lsda = .-.LCTOC1 - .long _SDA_BASE_ /* address of the first small data area */ - -.Lsdas = .-.LCTOC1 - .long __SDATA_START__ /* start of .sdata/.sbss section */ - -.Lsdae = .-.LCTOC1 - .long __SBSS_END__ /* end of .sdata/.sbss section */ - -.Lsda2 = .-.LCTOC1 - .long _SDA2_BASE_ /* address of the second small data area */ - -.Lsda2s = .-.LCTOC1 - .long __SDATA2_START__ /* start of .sdata2/.sbss2 section */ - -.Lsda2e = .-.LCTOC1 - .long __SBSS2_END__ /* end of .sdata2/.sbss2 section */ - -#ifdef _RELOCATABLE -.Lgots = .-.LCTOC1 - .long __GOT_START__ /* Global offset table start */ - -.Lgotm1 = .-.LCTOC1 - .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */ - -.Lgotm2 = .-.LCTOC1 - .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */ - -.Lgote = .-.LCTOC1 - .long __GOT_END__ /* Global offset table end */ - -.Lgot2s = .-.LCTOC1 - .long __GOT2_START__ /* -mrelocatable GOT pointers start */ - -.Lgot2e = .-.LCTOC1 - .long __GOT2_END__ /* -mrelocatable GOT pointers end */ - -.Lfixups = .-.LCTOC1 - .long __FIXUP_START__ /* start of .fixup section */ - -.Lfixupe = .-.LCTOC1 - .long __FIXUP_END__ /* end of .fixup section */ - -.Lctors = .-.LCTOC1 - .long __CTOR_LIST__ /* start of .ctor section */ - -.Lctore = .-.LCTOC1 - .long __CTOR_END__ /* end of .ctor section */ - -.Ldtors = .-.LCTOC1 - .long __DTOR_LIST__ /* start of .dtor section */ - -.Ldtore = .-.LCTOC1 - .long __DTOR_END__ /* end of .dtor section */ - -.Lexcepts = .-.LCTOC1 - .long __EXCEPT_START__ /* start of .gcc_except_table section */ - -.Lexcepte = .-.LCTOC1 - .long __EXCEPT_END__ /* end of .gcc_except_table section */ - -.Linit = .-.LCTOC1 - .long .Linit_p /* address of variable to say we've been called */ - - .text - .align 2 -.Lptr: - .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */ -#endif - - .data - .align 2 -.Linit_p: - .long 0 - - .text - -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ -FUNC_START(__eabi) -/* CYGNUS LOCAL vmakarov */ -#endif - /* Don't use FUNC_NAME here, this name doesn't depend on - -fleading-underscore. */ - .globl __eabi - .type __eabi@function -__eabi: -/* END CYGNUS LOCAL */ - -/* Eliminate -mrelocatable code if not -mrelocatable, so that this file can - be assembled with other assemblers than GAS, such as the Solaris PowerPC - assembler. */ - -#ifndef _RELOCATABLE - addis 10,0,.Linit_p@ha /* init flag */ - addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */ - lwz 9,.Linit_p@l(10) /* init flag */ - addi 11,11,.LCTOC1@l - cmplwi 2,9,0 /* init flag != 0? */ - bnelr 2 /* return now, if we've been called already */ - stw 1,.Linit_p@l(10) /* store a non-zero value in the done flag */ - -#else /* -mrelocatable */ - mflr 0 - bl .Laddr /* get current address */ -.Laddr: - mflr 12 /* real address of .Laddr */ - lwz 11,(.Lptr-.Laddr)(12) /* linker generated address of .LCTOC1 */ - add 11,11,12 /* correct to real pointer */ - lwz 12,.Ltable(11) /* get linker's idea of where .Laddr is */ - lwz 10,.Linit(11) /* address of init flag */ - subf. 12,12,11 /* calculate difference */ - lwzx 9,10,12 /* done flag */ - cmplwi 2,9,0 /* init flag != 0? */ - mtlr 0 /* restore in case branch was taken */ - bnelr 2 /* return now, if we've been called already */ - stwx 1,10,12 /* store a non-zero value in the done flag */ - beq+ 0,.Lsdata /* skip if we don't need to relocate */ - -/* We need to relocate the .got2 pointers. */ - - lwz 3,.Lgot2s(11) /* GOT2 pointers start */ - lwz 4,.Lgot2e(11) /* GOT2 pointers end */ - add 3,12,3 /* adjust pointers */ - add 4,12,4 - bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */ - -/* Fixup the .ctor section for static constructors */ - - lwz 3,.Lctors(11) /* constructors pointers start */ - lwz 4,.Lctore(11) /* constructors pointers end */ - bl FUNC_NAME(__eabi_convert) /* convert constructors */ - -/* Fixup the .dtor section for static destructors */ - - lwz 3,.Ldtors(11) /* destructors pointers start */ - lwz 4,.Ldtore(11) /* destructors pointers end */ - bl FUNC_NAME(__eabi_convert) /* convert destructors */ - -/* Fixup the .gcc_except_table section for G++ exceptions */ - - lwz 3,.Lexcepts(11) /* exception table pointers start */ - lwz 4,.Lexcepte(11) /* exception table pointers end */ - bl FUNC_NAME(__eabi_convert) /* convert exceptions */ - -/* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */ - - lwz 3,.Lgots(11) /* GOT table pointers start */ - lwz 4,.Lgotm1(11) /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */ - bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ - -/* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */ - - lwz 3,.Lgotm2(11) /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */ - lwz 4,.Lgote(11) /* GOT table pointers end */ - bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ - -/* Fixup any user initialized pointers now (the compiler drops pointers to */ -/* each of the relocs that it does in the .fixup section). */ - -.Lfix: - lwz 3,.Lfixups(11) /* fixup pointers start */ - lwz 4,.Lfixupe(11) /* fixup pointers end */ - bl FUNC_NAME(__eabi_uconvert) /* convert user initialized pointers */ - -.Lsdata: - mtlr 0 /* restore link register */ -#endif /* _RELOCATABLE */ - -/* Only load up register 13 if there is a .sdata and/or .sbss section */ - lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */ - lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */ - cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ - beq- 1,.Lsda2l /* skip loading r13 */ - - lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */ - -/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */ - -.Lsda2l: - lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */ - lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */ - cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ - beq+ 1,.Ldone /* skip loading r2 */ - - lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */ - -/* Done adjusting pointers, return by way of doing the C++ global constructors. */ - -.Ldone: - b FUNC_NAME(__do_global_ctors) /* do any C++ global constructors (which returns to caller) */ -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ -FUNC_END(__eabi) -/* CYGNUS LOCAL vmakarov */ -#endif -.L.end: - .size __eabi,.L.end-__eabi -/* END CYGNUS LOCAL */ - -/* Special subroutine to convert a bunch of pointers directly. - r0 has original link register - r3 has low pointer to convert - r4 has high pointer to convert - r5 .. r10 are scratch registers - r11 has the address of .LCTOC1 in it. - r12 has the value to add to each pointer - r13 .. r31 are unchanged */ - -FUNC_START(__eabi_convert) - cmplw 1,3,4 /* any pointers to convert? */ - subf 5,3,4 /* calculate number of words to convert */ - bclr 4,4 /* return if no pointers */ - - srawi 5,5,2 - addi 3,3,-4 /* start-4 for use with lwzu */ - mtctr 5 - -.Lcvt: - lwzu 6,4(3) /* pointer to convert */ - cmpi 0,6,0 - beq- .Lcvt2 /* if pointer is null, don't convert */ - - add 6,6,12 /* convert pointer */ - stw 6,0(3) -.Lcvt2: - bdnz+ .Lcvt - blr - -FUNC_END(__eabi_convert) - -/* Special subroutine to convert the pointers the user has initialized. The - compiler has placed the address of the initialized pointer into the .fixup - section. - - r0 has original link register - r3 has low pointer to convert - r4 has high pointer to convert - r5 .. r10 are scratch registers - r11 has the address of .LCTOC1 in it. - r12 has the value to add to each pointer - r13 .. r31 are unchanged */ - -FUNC_START(__eabi_uconvert) - cmplw 1,3,4 /* any pointers to convert? */ - subf 5,3,4 /* calculate number of words to convert */ - bclr 4,4 /* return if no pointers */ - - srawi 5,5,2 - addi 3,3,-4 /* start-4 for use with lwzu */ - mtctr 5 - -.Lucvt: - lwzu 6,4(3) /* next pointer to pointer to convert */ - add 6,6,12 /* adjust pointer */ - lwz 7,0(6) /* get the pointer it points to */ - stw 6,0(3) /* store adjusted pointer */ - add 7,7,12 /* adjust */ - stw 7,0(6) - bdnz+ .Lucvt - blr - -FUNC_END(__eabi_uconvert) - -/* Routines for saving floating point registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the floating point save area. */ - -FUNC_START(_savefpr_14) stfd 14,-144(11) /* save fp registers */ -FUNC_START(_savefpr_15) stfd 15,-136(11) -FUNC_START(_savefpr_16) stfd 16,-128(11) -FUNC_START(_savefpr_17) stfd 17,-120(11) -FUNC_START(_savefpr_18) stfd 18,-112(11) -FUNC_START(_savefpr_19) stfd 19,-104(11) -FUNC_START(_savefpr_20) stfd 20,-96(11) -FUNC_START(_savefpr_21) stfd 21,-88(11) -FUNC_START(_savefpr_22) stfd 22,-80(11) -FUNC_START(_savefpr_23) stfd 23,-72(11) -FUNC_START(_savefpr_24) stfd 24,-64(11) -FUNC_START(_savefpr_25) stfd 25,-56(11) -FUNC_START(_savefpr_26) stfd 26,-48(11) -FUNC_START(_savefpr_27) stfd 27,-40(11) -FUNC_START(_savefpr_28) stfd 28,-32(11) -FUNC_START(_savefpr_29) stfd 29,-24(11) -FUNC_START(_savefpr_30) stfd 30,-16(11) -FUNC_START(_savefpr_31) stfd 31,-8(11) - blr -FUNC_END(_savefpr_31) -FUNC_END(_savefpr_30) -FUNC_END(_savefpr_29) -FUNC_END(_savefpr_28) -FUNC_END(_savefpr_27) -FUNC_END(_savefpr_26) -FUNC_END(_savefpr_25) -FUNC_END(_savefpr_24) -FUNC_END(_savefpr_23) -FUNC_END(_savefpr_22) -FUNC_END(_savefpr_21) -FUNC_END(_savefpr_20) -FUNC_END(_savefpr_19) -FUNC_END(_savefpr_18) -FUNC_END(_savefpr_17) -FUNC_END(_savefpr_16) -FUNC_END(_savefpr_15) -FUNC_END(_savefpr_14) - -/* Routines for saving integer registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the integer save area. */ - -FUNC_START(_savegpr_14) stw 14,-72(11) /* save gp registers */ -FUNC_START(_savegpr_15) stw 15,-68(11) -FUNC_START(_savegpr_16) stw 16,-64(11) -FUNC_START(_savegpr_17) stw 17,-60(11) -FUNC_START(_savegpr_18) stw 18,-56(11) -FUNC_START(_savegpr_19) stw 19,-52(11) -FUNC_START(_savegpr_20) stw 20,-48(11) -FUNC_START(_savegpr_21) stw 21,-44(11) -FUNC_START(_savegpr_22) stw 22,-40(11) -FUNC_START(_savegpr_23) stw 23,-36(11) -FUNC_START(_savegpr_24) stw 24,-32(11) -FUNC_START(_savegpr_25) stw 25,-28(11) -FUNC_START(_savegpr_26) stw 26,-24(11) -FUNC_START(_savegpr_27) stw 27,-20(11) -FUNC_START(_savegpr_28) stw 28,-16(11) -FUNC_START(_savegpr_29) stw 29,-12(11) -FUNC_START(_savegpr_30) stw 30,-8(11) -FUNC_START(_savegpr_31) stw 31,-4(11) - blr -FUNC_END(_savegpr_31) -FUNC_END(_savegpr_30) -FUNC_END(_savegpr_29) -FUNC_END(_savegpr_28) -FUNC_END(_savegpr_27) -FUNC_END(_savegpr_26) -FUNC_END(_savegpr_25) -FUNC_END(_savegpr_24) -FUNC_END(_savegpr_23) -FUNC_END(_savegpr_22) -FUNC_END(_savegpr_21) -FUNC_END(_savegpr_20) -FUNC_END(_savegpr_19) -FUNC_END(_savegpr_18) -FUNC_END(_savegpr_17) -FUNC_END(_savegpr_16) -FUNC_END(_savegpr_15) -FUNC_END(_savegpr_14) - -/* Routines for restoring floating point registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the floating point save area. */ - -FUNC_START(_restfpr_14) lfd 14,-144(11) /* restore fp registers */ -FUNC_START(_restfpr_15) lfd 15,-136(11) -FUNC_START(_restfpr_16) lfd 16,-128(11) -FUNC_START(_restfpr_17) lfd 17,-120(11) -FUNC_START(_restfpr_18) lfd 18,-112(11) -FUNC_START(_restfpr_19) lfd 19,-104(11) -FUNC_START(_restfpr_20) lfd 20,-96(11) -FUNC_START(_restfpr_21) lfd 21,-88(11) -FUNC_START(_restfpr_22) lfd 22,-80(11) -FUNC_START(_restfpr_23) lfd 23,-72(11) -FUNC_START(_restfpr_24) lfd 24,-64(11) -FUNC_START(_restfpr_25) lfd 25,-56(11) -FUNC_START(_restfpr_26) lfd 26,-48(11) -FUNC_START(_restfpr_27) lfd 27,-40(11) -FUNC_START(_restfpr_28) lfd 28,-32(11) -FUNC_START(_restfpr_29) lfd 29,-24(11) -FUNC_START(_restfpr_30) lfd 30,-16(11) -FUNC_START(_restfpr_31) lfd 31,-8(11) - blr -FUNC_END(_restfpr_31) -FUNC_END(_restfpr_30) -FUNC_END(_restfpr_29) -FUNC_END(_restfpr_28) -FUNC_END(_restfpr_27) -FUNC_END(_restfpr_26) -FUNC_END(_restfpr_25) -FUNC_END(_restfpr_24) -FUNC_END(_restfpr_23) -FUNC_END(_restfpr_22) -FUNC_END(_restfpr_21) -FUNC_END(_restfpr_20) -FUNC_END(_restfpr_19) -FUNC_END(_restfpr_18) -FUNC_END(_restfpr_17) -FUNC_END(_restfpr_16) -FUNC_END(_restfpr_15) -FUNC_END(_restfpr_14) - -/* Routines for restoring integer registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the integer restore area. */ - -FUNC_START(_restgpr_14) lwz 14,-72(11) /* restore gp registers */ -FUNC_START(_restgpr_15) lwz 15,-68(11) -FUNC_START(_restgpr_16) lwz 16,-64(11) -FUNC_START(_restgpr_17) lwz 17,-60(11) -FUNC_START(_restgpr_18) lwz 18,-56(11) -FUNC_START(_restgpr_19) lwz 19,-52(11) -FUNC_START(_restgpr_20) lwz 20,-48(11) -FUNC_START(_restgpr_21) lwz 21,-44(11) -FUNC_START(_restgpr_22) lwz 22,-40(11) -FUNC_START(_restgpr_23) lwz 23,-36(11) -FUNC_START(_restgpr_24) lwz 24,-32(11) -FUNC_START(_restgpr_25) lwz 25,-28(11) -FUNC_START(_restgpr_26) lwz 26,-24(11) -FUNC_START(_restgpr_27) lwz 27,-20(11) -FUNC_START(_restgpr_28) lwz 28,-16(11) -FUNC_START(_restgpr_29) lwz 29,-12(11) -FUNC_START(_restgpr_30) lwz 30,-8(11) -FUNC_START(_restgpr_31) lwz 31,-4(11) - blr -FUNC_END(_restgpr_31) -FUNC_END(_restgpr_30) -FUNC_END(_restgpr_29) -FUNC_END(_restgpr_28) -FUNC_END(_restgpr_27) -FUNC_END(_restgpr_26) -FUNC_END(_restgpr_25) -FUNC_END(_restgpr_24) -FUNC_END(_restgpr_23) -FUNC_END(_restgpr_22) -FUNC_END(_restgpr_21) -FUNC_END(_restgpr_20) -FUNC_END(_restgpr_19) -FUNC_END(_restgpr_18) -FUNC_END(_restgpr_17) -FUNC_END(_restgpr_16) -FUNC_END(_restgpr_15) -FUNC_END(_restgpr_14) - -/* Routines for restoring floating point registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the floating point save area. */ -/* In addition to restoring the fp registers, it will return to the caller's */ -/* caller */ - -FUNC_START(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */ -FUNC_START(_restfpr_15_x) lfd 15,-136(11) -FUNC_START(_restfpr_16_x) lfd 16,-128(11) -FUNC_START(_restfpr_17_x) lfd 17,-120(11) -FUNC_START(_restfpr_18_x) lfd 18,-112(11) -FUNC_START(_restfpr_19_x) lfd 19,-104(11) -FUNC_START(_restfpr_20_x) lfd 20,-96(11) -FUNC_START(_restfpr_21_x) lfd 21,-88(11) -FUNC_START(_restfpr_22_x) lfd 22,-80(11) -FUNC_START(_restfpr_23_x) lfd 23,-72(11) -FUNC_START(_restfpr_24_x) lfd 24,-64(11) -FUNC_START(_restfpr_25_x) lfd 25,-56(11) -FUNC_START(_restfpr_26_x) lfd 26,-48(11) -FUNC_START(_restfpr_27_x) lfd 27,-40(11) -FUNC_START(_restfpr_28_x) lfd 28,-32(11) -FUNC_START(_restfpr_29_x) lfd 29,-24(11) -FUNC_START(_restfpr_30_x) lfd 30,-16(11) -FUNC_START(_restfpr_31_x) lwz 0,4(11) - lfd 31,-8(11) - mtlr 0 - mr 1,11 - blr -FUNC_END(_restfpr_31_x) -FUNC_END(_restfpr_30_x) -FUNC_END(_restfpr_29_x) -FUNC_END(_restfpr_28_x) -FUNC_END(_restfpr_27_x) -FUNC_END(_restfpr_26_x) -FUNC_END(_restfpr_25_x) -FUNC_END(_restfpr_24_x) -FUNC_END(_restfpr_23_x) -FUNC_END(_restfpr_22_x) -FUNC_END(_restfpr_21_x) -FUNC_END(_restfpr_20_x) -FUNC_END(_restfpr_19_x) -FUNC_END(_restfpr_18_x) -FUNC_END(_restfpr_17_x) -FUNC_END(_restfpr_16_x) -FUNC_END(_restfpr_15_x) -FUNC_END(_restfpr_14_x) - -/* Routines for restoring integer registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the integer restore area. */ - -FUNC_START(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */ -FUNC_START(_restgpr_15_x) lwz 15,-68(11) -FUNC_START(_restgpr_16_x) lwz 16,-64(11) -FUNC_START(_restgpr_17_x) lwz 17,-60(11) -FUNC_START(_restgpr_18_x) lwz 18,-56(11) -FUNC_START(_restgpr_19_x) lwz 19,-52(11) -FUNC_START(_restgpr_20_x) lwz 20,-48(11) -FUNC_START(_restgpr_21_x) lwz 21,-44(11) -FUNC_START(_restgpr_22_x) lwz 22,-40(11) -FUNC_START(_restgpr_23_x) lwz 23,-36(11) -FUNC_START(_restgpr_24_x) lwz 24,-32(11) -FUNC_START(_restgpr_25_x) lwz 25,-28(11) -FUNC_START(_restgpr_26_x) lwz 26,-24(11) -FUNC_START(_restgpr_27_x) lwz 27,-20(11) -FUNC_START(_restgpr_28_x) lwz 28,-16(11) -FUNC_START(_restgpr_29_x) lwz 29,-12(11) -FUNC_START(_restgpr_30_x) lwz 30,-8(11) -FUNC_START(_restgpr_31_x) lwz 0,4(11) - lwz 31,-4(11) - mtlr 0 - mr 1,11 - blr -FUNC_END(_restgpr_31_x) -FUNC_END(_restgpr_30_x) -FUNC_END(_restgpr_29_x) -FUNC_END(_restgpr_28_x) -FUNC_END(_restgpr_27_x) -FUNC_END(_restgpr_26_x) -FUNC_END(_restgpr_25_x) -FUNC_END(_restgpr_24_x) -FUNC_END(_restgpr_23_x) -FUNC_END(_restgpr_22_x) -FUNC_END(_restgpr_21_x) -FUNC_END(_restgpr_20_x) -FUNC_END(_restgpr_19_x) -FUNC_END(_restgpr_18_x) -FUNC_END(_restgpr_17_x) -FUNC_END(_restgpr_16_x) -FUNC_END(_restgpr_15_x) -FUNC_END(_restgpr_14_x) diff --git a/gcc/config/rs6000/eabi.h b/gcc/config/rs6000/eabi.h deleted file mode 100755 index 1c225ea..0000000 --- a/gcc/config/rs6000/eabi.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Core target definitions for GNU compiler - for IBM RS/6000 PowerPC targeted to embedded ELF systems. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/sysv4.h" - -/* Add -meabi to target flags */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI) - -/* Invoke an initializer function to set up the GOT */ -#define NAME__MAIN "__eabi" - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)"); - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC -D__embedded__ -Asystem(embedded) -Acpu(powerpc) -Amachine(powerpc)" - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" } diff --git a/gcc/config/rs6000/eabiaix.h b/gcc/config/rs6000/eabiaix.h deleted file mode 100755 index 5cfd890..0000000 --- a/gcc/config/rs6000/eabiaix.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Embedded ELF system support, using old AIX based calling sequence. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/eabi.h" - -/* Default ABI to use */ -#undef RS6000_ABI_NAME -#define RS6000_ABI_NAME "aix" - -#undef CPP_SYSV_DEFAULT_SPEC -#define CPP_SYSV_DEFAULT_SPEC "-D_CALL_AIX" - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mcall-aix" } diff --git a/gcc/config/rs6000/eabile.h b/gcc/config/rs6000/eabile.h deleted file mode 100755 index 97e2b7c..0000000 --- a/gcc/config/rs6000/eabile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Core target definitions for GNU compiler for PowerPC targeted to - little endian embedded ELF systems. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/eabi.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN | MASK_EABI) - -#undef CPP_ENDIAN_DEFAULT_SPEC -#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_little)" - -#undef CC1_ENDIAN_DEFAULT_SPEC -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)" - -#undef LINK_TARGET_SPEC -#define LINK_TARGET_SPEC "\ -%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-linux: -oformat elf32-powerpc}}}}}" - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" } diff --git a/gcc/config/rs6000/eabilesim.h b/gcc/config/rs6000/eabilesim.h deleted file mode 100755 index 7ced05c..0000000 --- a/gcc/config/rs6000/eabilesim.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Support for GCC on simulated PowerPC systems targeted to embedded ELF - systems. - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/eabile.h" - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)"); - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)" - -/* Make the simulator the default */ -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_sim)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_sim)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_sim)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_sim)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_start_sim)" diff --git a/gcc/config/rs6000/eabisim.h b/gcc/config/rs6000/eabisim.h deleted file mode 100755 index 0fc590b..0000000 --- a/gcc/config/rs6000/eabisim.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Support for GCC on simulated PowerPC systems targeted to embedded ELF - systems. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/eabi.h" - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)"); - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)" - -/* Make the simulator the default */ -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_sim)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_sim)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_sim)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_sim)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_sim)" diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h deleted file mode 100755 index cdc4dc0..0000000 --- a/gcc/config/rs6000/linux.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 running AIX version 3.1. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/sysv4.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC -D__ELF__ -Dunix -Dlinux -Dpowerpc -Asystem(unix) -Asystem(linux) -Acpu(powerpc) -Amachine(powerpc)" - -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" - -#undef LINK_SPEC -#define LINK_SPEC "-m elf32ppc %{G*} %{shared:-shared} \ - %{!shared: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ - %{static:-static}}" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_linux)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)"); - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mcall-linux" } - -#undef DEFAULT_VTABLE_THUNKS -#ifndef USE_GNULIBC_1 -#define DEFAULT_VTABLE_THUNKS 1 -#endif - -#undef JUMP_TABLES_IN_TEXT_SECTION -#define JUMP_TABLES_IN_TEXT_SECTION 0 diff --git a/gcc/config/rs6000/lynx.h b/gcc/config/rs6000/lynx.h deleted file mode 100755 index e2fe633..0000000 --- a/gcc/config/rs6000/lynx.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Definitions for Rs6000 running LynxOS. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include <lynx.h> - -/* Definitions we want to override with those from rs6000.h: */ -#undef LIB_SPEC -#undef PTRDIFF_TYPE -#undef WCHAR_TYPE -#undef WCHAR_TYPE_SIZE -#undef ASM_FILE_START -#undef EXTRA_SECTIONS -#undef READONLY_DATA_SECTION -#undef EXTRA_SECTION_FUNCTIONS -#undef SELECT_RTX_SECTION -#undef SELECT_SECTION -#undef USER_LABEL_PREFIX -#undef ASM_OUTPUT_LABELREF -#undef ASM_OUTPUT_INTERNAL_LABEL -#undef ASM_GENERATE_INTERNAL_LABEL -#undef ASM_OUTPUT_COMMON -#undef ASM_OUTPUT_LOCAL -#undef ASM_OUTPUT_CONSTRUCTOR -#undef ASM_OUTPUT_DESTRUCTOR -#undef CTORS_SECTION_FUNCTION -#undef DTORS_SECTION_FUNCTION - -#undef SDB_DEBUGGING_INFO -#undef DBX_DEBUGGING_INFO -#undef PREFERRED_DEBUGGING_TYPE - -#undef FUNCTION_PROFILER - -#include <rs6000/rs6000.h> - -/* LynxOS has signed chars, regardless of what most R/S 6000 systems do */ -#undef DEFAULT_SIGNED_CHAR -#define DEFAULT_SIGNED_CHAR 1 - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Acpu(rs6000) -Amachine(rs6000) -Asystem(lynx) -Asystem(unix) -DLynx -D_IBMR2 -Dunix -Drs6000 -Dlynx -DLYNX" - -#undef LINK_SPEC -#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}" - -#undef LIB_SPEC -#define LIB_SPEC "%{mthreads:-L/lib/thread/} \ - %{msystem-v:-lc_v -lm.v} \ - %{!msystem-v:%{mposix:-lc_p} -lc -lm}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{p:%{mthreads:thread/pinit.o%s}%{!mthreads:pinit.o%s}}%{!p:%{msystem-v:vinit.o%s -e_start}%{!msystem-v:%{mthreads:thread/init.o%s}%{!mthreads:init.o%s}}}" - -#undef ENDFILE_SPEC - -/* This can become more refined as we have more powerpc options. */ -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu)" - -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"threads", MASK_THREADS}, \ - {"posix", MASK_POSIX}, \ - {"system-v", MASK_SYSTEM_V}, - -#undef SUBTARGET_OVERRIDE_OPTIONS -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_SYSTEM_V && profile_flag) \ - warning ("-msystem-v and -p are incompatible"); \ - if (TARGET_SYSTEM_V && TARGET_THREADS) \ - warning ("-msystem-v and -mthreads are incompatible"); \ -} while (0) - -/* For collect2 */ -#define OBJECT_FORMAT_NONE -#undef OBJECT_FORMAT_COFF -#undef OBJECT_FORMAT_ROSE -#undef MD_EXEC_PREFIX -#undef REAL_LD_FILE_NAME -#undef REAL_NM_FILE_NAME -#undef REAL_STRIP_FILE_NAME - -/* LynxOS doesn't have mcount. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(file, profile_label_no) diff --git a/gcc/config/rs6000/mach.h b/gcc/config/rs6000/mach.h deleted file mode 100755 index bb4e8b4..0000000 --- a/gcc/config/rs6000/mach.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 running MACH. - Copyright (C) 1992 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_AIX 0 - -#include "rs6000/rs6000.h" - -/* We don't define AIX under MACH; instead we define `unix'. */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Drios -D_IBMR2 -Dunix -Asystem(unix) -Asystem(mach) -Acpu(rs6000) -Amachine(rs6000)" - -/* Define different binder options for MACH. */ -#undef LINK_SPEC -#define LINK_SPEC \ - "-T0x10000000 -D0x20000000 -K %{!nostdlib:%{!r*:%{!e*:-e __start}}} \ - -bnoso -berrmsg -btextro -bhalt:4 -bnodelcsect" - -/* MACH doesn't have atexit. */ -#undef HAVE_ATEXIT - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 diff --git a/gcc/config/rs6000/milli.exp b/gcc/config/rs6000/milli.exp deleted file mode 100755 index ea3a2b7..0000000 --- a/gcc/config/rs6000/milli.exp +++ /dev/null @@ -1,7 +0,0 @@ -#! -__mulh 0x3100 -__mull 0x3180 -__divss 0x3200 -__divus 0x3280 -__quoss 0x3300 -__quous 0x3380 diff --git a/gcc/config/rs6000/netware.h b/gcc/config/rs6000/netware.h deleted file mode 100755 index 61133b9..0000000 --- a/gcc/config/rs6000/netware.h +++ /dev/null @@ -1,284 +0,0 @@ -/* Core target definitions for GNU compiler - for IBM RS/6000 PowerPC running NetWare - Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_AIX 0 - -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#define ASM_DEFAULT_SPEC "-mppc" - -#include "rs6000/rs6000.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC601 - -/* Don't generate XCOFF debugging information. */ - -#undef XCOFF_DEBUGGING_INFO - -/* Don't use the COFF object file format. */ - -#undef OBJECT_FORMAT_COFF - -/* The XCOFF support uses weird symbol suffixes, which we don't want - for ELF. */ - -#undef STRIP_NAME_ENCODING - -/* Don't bother to output .extern pseudo-ops. They are not needed by - ELF assemblers. */ - -#undef ASM_OUTPUT_EXTERNAL - -/* Undefine some things which are defined by the generic svr4.h. */ - -#undef ASM_FILE_END -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#undef READONLY_DATA_SECTION -#undef SELECT_SECTION -#undef ASM_DECLARE_FUNCTION_NAME - -/* Use the regular svr4 definitions. */ - -#include "svr4.h" -#include "netware.h" - -/* Create a function descriptor when we declare a function name. This - is a mixture of the ASM_DECLARE_FUNCTION_NAME macros in rs6000.h - and svr4.h. The unmodified function name is used to name the - descriptor. The function name with an initial `.' is used to name - the code. */ - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - if (TREE_PUBLIC (DECL)) \ - { \ - fprintf (FILE, "\t.globl ."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - data_section (); \ - ASM_OUTPUT_ALIGN (FILE, 2); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - fprintf (FILE, "\t.long ."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ", __GOT0, 0\n"); \ - text_section (); \ - fprintf (FILE, "."); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - } while (0) - -/* We need to override the .size output in order to put a `.' before - the function name. */ - -#undef ASM_DECLARE_FUNCTION_SIZE -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-."); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) - -/* Use ELF style section commands. */ - -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP "\t.section\t\".text\"" - -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP "\t.section\t\".data\"" - -/* Besides the usual ELF sections, we need a toc section. */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION \ - TOC_SECTION_FUNCTION - -#define TOC_SECTION_FUNCTION \ -void \ -toc_section () \ -{ \ - if (TARGET_MINIMAL_TOC) \ - { \ - static int toc_initialized = 0; \ - \ - if (! toc_initialized) \ - { \ - fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \ - fprintf (asm_out_file, ".LCTOC0:\n"); \ - fprintf (asm_out_file, "\t.tc .LCTOC1\n"); \ - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ - fprintf (asm_out_file, ".LCTOC1:\n"); \ - toc_initialized = 1; \ - } \ - } \ - \ - if (in_section != in_toc) \ - { \ - fprintf (asm_out_file, "%s\n", \ - (TARGET_MINIMAL_TOC \ - ? MINIMAL_TOC_SECTION_ASM_OP \ - : TOC_SECTION_ASM_OP)); \ - in_section = in_toc; \ - } \ -} - -#define TOC_SECTION_ASM_OP "\t.section\t.got,\"aw\"" -#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t.got1,\"aw\"" - -/* Use the TOC section for TOC entries. */ - -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE, X) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ - toc_section (); \ - else \ - const_section (); \ -} - -/* How to renumber registers for dbx and gdb. */ - -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) - -/* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL. */ - -#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, ".%s", PREFIX) - -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu) \ -{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}" -/* This is the end of what might become sysv4.h. */ - -/* Enable output of DBX (stabs) debugging information when asked for it. */ - -#define DBX_DEBUGGING_INFO - -/* Prefer DBX (stabs) debugging information over the native (DWARF) format. */ - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -/* Line numbers are relative to the current function. */ - -#undef ASM_OUTPUT_SOURCE_LINE -#define ASM_OUTPUT_SOURCE_LINE(file, line) \ - { static int sym_lineno = 1; \ - fprintf (file, ".stabn 68,0,%d,.LM%d-.%s\n.LM%d:\n",\ - line, sym_lineno, \ - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0), \ - sym_lineno); \ - sym_lineno += 1; } - -/* But, to make this work, we have to output the stabs for the function - name *first*... */ - -#define DBX_FUNCTION_FIRST - -/* We need to output LBRAC and RBRAC lines specially to include the - dot in from of the text symbol for a function. */ - -#define DBX_OUTPUT_LBRAC(FILE, BUF) \ -do \ - { \ - fprintf (FILE, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC); \ - assemble_name (FILE, BUF); \ - fprintf (FILE, "-."); \ - assemble_name (asmfile, \ - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \ - fprintf (asmfile, "\n"); \ - } \ -while (0) - -#define DBX_OUTPUT_RBRAC(FILE, BUF) \ -do \ - { \ - fprintf (FILE, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC); \ - assemble_name (FILE, BUF); \ - fprintf (FILE, "-."); \ - assemble_name (asmfile, \ - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \ - fprintf (asmfile, "\n"); \ - } \ -while (0) - -/* We are using function descriptors, so the value of a function - symbol is in the .data section. However, we want the stabs entry - for that function to point at the actual function code in the .text - section, which we get by prefixing the symbol with a dot. */ - -#define DBX_FINISH_SYMBOL(sym) \ -do { \ - int line = 0; \ - if (use_gnu_debug_info_extensions && sym != 0) \ - line = DECL_SOURCE_LINE (sym); \ - \ - fprintf (asmfile, "\",%d,0,%d,", current_sym_code, line); \ - if (current_sym_addr) \ - { \ - if (TREE_CODE (sym) == FUNCTION_DECL) \ - fprintf (asmfile, "."); \ - output_addr_const (asmfile, current_sym_addr); \ - } \ - else \ - fprintf (asmfile, "%d", current_sym_value); \ - putc ('\n', asmfile); \ -} while (0) - -/* This is the end of what might become sysv4dbx.h. */ - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC Netware)"); - -/* FIXME: These should actually indicate PowerPC, when there is some - standard way of expressing that. */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC D__netware__ -Asystem(netware) -Acpu(powerpc) -Amachine(powerpc)" diff --git a/gcc/config/rs6000/nt-ci.asm b/gcc/config/rs6000/nt-ci.asm deleted file mode 100755 index 67ca956..0000000 --- a/gcc/config/rs6000/nt-ci.asm +++ /dev/null @@ -1,48 +0,0 @@ -# crti.s for Windows NT - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled starting points for the static constructors -# and destructors. It is linked in first before other modules. - - .file "crti.s" - .ident "GNU C crti.s" - - .section .ctors,"w" - .globl __CTOR_LIST__ -__CTOR_LIST__: - - .section .dtors,"w" - .globl __DTOR_LIST__ -__DTOR_LIST__: diff --git a/gcc/config/rs6000/nt-cn.asm b/gcc/config/rs6000/nt-cn.asm deleted file mode 100755 index dd6daf2..0000000 --- a/gcc/config/rs6000/nt-cn.asm +++ /dev/null @@ -1,48 +0,0 @@ -# crtn.s for Windows NT - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled ending points for the static constructors -# and destructors. It is linked in last after other modules. - - .file "crtn.s" - .ident "GNU C crtn.s" - - .section .ctors,"w" - .globl __CTOR_END__ -__CTOR_END__: - - .section .dtors,"w" - .globl __DTOR_END__ -__DTOR_END__: diff --git a/gcc/config/rs6000/ntstack.asm b/gcc/config/rs6000/ntstack.asm deleted file mode 100755 index aa4179e..0000000 --- a/gcc/config/rs6000/ntstack.asm +++ /dev/null @@ -1,42 +0,0 @@ -# Allocate stack for NT, inserting stack probes every 4k pages - - .file "ntstack.asm" - -# Setup MS Structured-Exception-Handling - .pdata - .align 2 - .ualong ..__allocate_stack,__allocate_stack.e,0,0,__allocate_stack.b - -# Switch to the relocation section - .reldata - .globl __allocate_stack - .globl ..__allocate_stack -__allocate_stack: - .ualong ..__allocate_stack,.toc - - .text - .align 2 -..__allocate_stack: - .function ..__allocate_stack -__allocate_stack.b: - addi 3,3,15 # round up to 16 byte alignment - lwz 0,0(1) # old stack link - rlwinm 3,3,0,0,28 - srawi. 4,3,12 # get # of pages to check - neg 3,3 # negate so we can use stwux - bgt- 0,.Lcheck - stwux 0,1,3 # small request, just decrement and return - blr - -.Lcheck: - mtctr 4 # number of pages to check - mr 5,1 # tmp pointer -.Lloop: - lwzu 6,-4096(5) # touch the page - bdnz+ .Lloop # and loop back - - stwux 0,1,3 # update stack pointer - blr - -__allocate_stack.e: -FE_MOT_RESVD..__allocate_stack: diff --git a/gcc/config/rs6000/powerpc.h b/gcc/config/rs6000/powerpc.h deleted file mode 100755 index 9f1ffd6..0000000 --- a/gcc/config/rs6000/powerpc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 PowerPC running AIX version 3.2. - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@npac.syr.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "rs6000/rs6000.h" - -#undef ASM_SPEC -#define ASM_SPEC "-u %(asm_cpu)" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 \ --Asystem(unix) -Asystem(aix) -Acpu(powerpc) -Amachine(powerpc)" - -#undef CPP_DEFAULT_SPEC -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC601 - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c deleted file mode 100755 index 53ef3f1..0000000 --- a/gcc/config/rs6000/rs6000.c +++ /dev/null @@ -1,7156 +0,0 @@ -/* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991, 93-8, 1999 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "insn-attr.h" -#include "flags.h" -#include "recog.h" -#include "expr.h" -#include "obstack.h" -#include "tree.h" -#include "except.h" -#include "function.h" -#include "output.h" -#include "toplev.h" - -#ifndef TARGET_NO_PROTOTYPE -#define TARGET_NO_PROTOTYPE 0 -#endif - -extern char *language_string; -extern int profile_block_flag; - -#define min(A,B) ((A) < (B) ? (A) : (B)) -#define max(A,B) ((A) > (B) ? (A) : (B)) - -/* Target cpu type */ - -enum processor_type rs6000_cpu; -struct rs6000_cpu_select rs6000_select[3] = -{ - /* switch name, tune arch */ - { (char *)0, "--with-cpu=", 1, 1 }, - { (char *)0, "-mcpu=", 1, 1 }, - { (char *)0, "-mtune=", 1, 0 }, -}; - -/* Set to non-zero by "fix" operation to indicate that itrunc and - uitrunc must be defined. */ - -int rs6000_trunc_used; - -/* Set to non-zero once they have been defined. */ - -static int trunc_defined; - -/* Set to non-zero once AIX common-mode calls have been defined. */ -static int common_mode_defined; - -/* Save information from a "cmpxx" operation until the branch or scc is - emitted. */ -rtx rs6000_compare_op0, rs6000_compare_op1; -int rs6000_compare_fp_p; - -/* CYGNUS LOCAL -- vmakarov */ -/* Override for BRANCH_COST */ -char *rs6000_branch_cost_string; -int rs6000_branch_cost = BRANCH_COST_DEFAULT; -/* END CYGNUS LOCAL */ - -#ifdef USING_SVR4_H -/* Label number of label created for -mrelocatable, to call to so we can - get the address of the GOT section */ -int rs6000_pic_labelno; -int rs6000_pic_func_labelno; - -/* Which abi to adhere to */ -char *rs6000_abi_name = RS6000_ABI_NAME; - -/* Semantics of the small data area */ -enum rs6000_sdata_type rs6000_sdata = SDATA_DATA; - -/* Which small data model to use */ -char *rs6000_sdata_name = (char *)0; -#endif - -/* Whether a System V.4 varargs area was created. */ -int rs6000_sysv_varargs_p; - -/* ABI enumeration available for subtarget to use. */ -enum rs6000_abi rs6000_current_abi; - -/* Offset & size for fpmem stack locations used for converting between - float and integral types. */ -int rs6000_fpmem_offset; -int rs6000_fpmem_size; - -/* Debug flags */ -char *rs6000_debug_name; -int rs6000_debug_stack; /* debug stack applications */ -int rs6000_debug_arg; /* debug argument handling */ - -/* Flag to say the TOC is initialized */ -int toc_initialized; - - -/* Default register names. */ -char rs6000_reg_names[][8] = -{ - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "mq", "lr", "ctr","ap", - "0", "1", "2", "3", "4", "5", "6", "7", - "fpmem" -}; - -#ifdef TARGET_REGNAMES -static char alt_reg_names[][8] = -{ - "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", - "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", - "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23", - "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31", - "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", - "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15", - "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23", - "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31", - "mq", "lr", "ctr", "ap", - "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", - "fpmem" -}; -#endif - -#ifndef MASK_STRICT_ALIGN -#define MASK_STRICT_ALIGN 0 -#endif - -/* Override command line options. Mostly we process the processor - type and sometimes adjust other TARGET_ options. */ - -void -rs6000_override_options (default_cpu) - char *default_cpu; -{ - size_t i, j; - struct rs6000_cpu_select *ptr; - - /* Simplify the entries below by making a mask for any POWER - variant and any PowerPC variant. */ - -#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING) -#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \ - | MASK_PPC_GFXOPT | MASK_POWERPC64) -#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT) - - static struct ptt - { - char *name; /* Canonical processor name. */ - enum processor_type processor; /* Processor type enum value. */ - int target_enable; /* Target flags to enable. */ - int target_disable; /* Target flags to disable. */ - } processor_target_table[] - = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_MASKS}, - {"power", PROCESSOR_POWER, - MASK_POWER | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"power2", PROCESSOR_POWER, - MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING, - POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"powerpc", PROCESSOR_POWERPC, - MASK_POWERPC | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"rios", PROCESSOR_RIOS1, - MASK_POWER | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"rios1", PROCESSOR_RIOS1, - MASK_POWER | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"rsc", PROCESSOR_PPC601, - MASK_POWER | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"rsc1", PROCESSOR_PPC601, - MASK_POWER | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"rios2", PROCESSOR_RIOS2, - MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2, - POWERPC_MASKS | MASK_NEW_MNEMONICS}, - {"401", PROCESSOR_PPC403, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"403", PROCESSOR_PPC403, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"505", PROCESSOR_MPCCORE, - MASK_POWERPC | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"601", PROCESSOR_PPC601, - MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING, - MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"602", PROCESSOR_PPC603, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"603", PROCESSOR_PPC603, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"603e", PROCESSOR_PPC603, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"ec603e", PROCESSOR_PPC603, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"604", PROCESSOR_PPC604, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"604e", PROCESSOR_PPC604e, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"620", PROCESSOR_PPC620, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT}, - {"740", PROCESSOR_PPC750, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"750", PROCESSOR_PPC750, - MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, - POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, - {"801", PROCESSOR_MPCCORE, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"821", PROCESSOR_MPCCORE, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"823", PROCESSOR_MPCCORE, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, - {"860", PROCESSOR_MPCCORE, - MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, - POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}}; - - size_t ptt_size = sizeof (processor_target_table) / sizeof (struct ptt); - - int multiple = TARGET_MULTIPLE; /* save current -mmultiple/-mno-multiple status */ - int string = TARGET_STRING; /* save current -mstring/-mno-string status */ - - profile_block_flag = 0; - - /* Identify the processor type */ - rs6000_select[0].string = default_cpu; - rs6000_cpu = PROCESSOR_DEFAULT; - - for (i = 0; i < sizeof (rs6000_select) / sizeof (rs6000_select[0]); i++) - { - ptr = &rs6000_select[i]; - if (ptr->string != (char *)0 && ptr->string[0] != '\0') - { - for (j = 0; j < ptt_size; j++) - if (! strcmp (ptr->string, processor_target_table[j].name)) - { - if (ptr->set_tune_p) - rs6000_cpu = processor_target_table[j].processor; - - if (ptr->set_arch_p) - { - target_flags |= processor_target_table[j].target_enable; - target_flags &= ~processor_target_table[j].target_disable; - } - break; - } - - if (i == ptt_size) - error ("bad value (%s) for %s switch", ptr->string, ptr->name); - } - } - - /* If we are optimizing big endian systems for space, use the - store multiple instructions. */ - if (BYTES_BIG_ENDIAN && optimize_size) - target_flags |= MASK_MULTIPLE; - - /* If -mmultiple or -mno-multiple was explicitly used, don't - override with the processor default */ - if (TARGET_MULTIPLE_SET) - target_flags = (target_flags & ~MASK_MULTIPLE) | multiple; - - /* If -mstring or -mno-string was explicitly used, don't - override with the processor default */ - if (TARGET_STRING_SET) - target_flags = (target_flags & ~MASK_STRING) | string; - - /* Don't allow -mmultiple or -mstring on little endian systems unless the cpu - is a 750, because the hardware doesn't support the instructions used in - little endian mode, and causes an alignment trap. The 750 does not cause - an alignment trap (except when the target is unaligned). */ - - if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750) - { - if (TARGET_MULTIPLE) - { - target_flags &= ~MASK_MULTIPLE; - if (TARGET_MULTIPLE_SET) - warning ("-mmultiple is not supported on little endian systems"); - } - - if (TARGET_STRING) - { - target_flags &= ~MASK_STRING; - if (TARGET_STRING_SET) - warning ("-mstring is not supported on little endian systems"); - } - } - - if (flag_pic && (DEFAULT_ABI == ABI_AIX)) - { - warning ("-f%s ignored for AIX (all code is position independent)", - (flag_pic > 1) ? "PIC" : "pic"); - flag_pic = 0; - } - - /* Set debug flags */ - if (rs6000_debug_name) - { - if (!strcmp (rs6000_debug_name, "all")) - rs6000_debug_stack = rs6000_debug_arg = 1; - else if (!strcmp (rs6000_debug_name, "stack")) - rs6000_debug_stack = 1; - else if (!strcmp (rs6000_debug_name, "arg")) - rs6000_debug_arg = 1; - else - error ("Unknown -mdebug-%s switch", rs6000_debug_name); - } - -#ifdef TARGET_REGNAMES - /* If the user desires alternate register names, copy in the alternate names - now. */ - if (TARGET_REGNAMES) - bcopy ((char *)alt_reg_names, (char *)rs6000_reg_names, sizeof (rs6000_reg_names)); -#endif - - /* CYGNUS LOCAL -- vmakarov */ - /* Override BRANCH_COST if -mbranch-cost= */ - if (rs6000_branch_cost_string) - rs6000_branch_cost = atoi (rs6000_branch_cost_string); - /* END CYGNUS LOCAL */ - -#ifdef SUBTARGET_OVERRIDE_OPTIONS - SUBTARGET_OVERRIDE_OPTIONS; -#endif -} - -void -optimization_options (level, size) - int level; - int size ATTRIBUTE_UNUSED; -{ -#ifdef HAVE_decrement_and_branch_on_count - /* When optimizing, enable use of BCT instruction. */ - if (level >= 1) - flag_branch_on_count_reg = 1; -#endif -} - -/* Do anything needed at the start of the asm file. */ - -void -rs6000_file_start (file, default_cpu) - FILE *file; - char *default_cpu; -{ - size_t i; - char buffer[80]; - char *start = buffer; - struct rs6000_cpu_select *ptr; - - if (flag_verbose_asm) - { - sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START); - rs6000_select[0].string = default_cpu; - - for (i = 0; i < sizeof (rs6000_select) / sizeof (rs6000_select[0]); i++) - { - ptr = &rs6000_select[i]; - if (ptr->string != (char *)0 && ptr->string[0] != '\0') - { - fprintf (file, "%s %s%s", start, ptr->name, ptr->string); - start = ""; - } - } - -#ifdef USING_SVR4_H - switch (rs6000_sdata) - { - case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break; - case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break; - case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break; - case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break; - } - - if (rs6000_sdata && g_switch_value) - { - fprintf (file, "%s -G %d", start, g_switch_value); - start = ""; - } -#endif - - if (*start == '\0') - fputs ("\n", file); - } -} - - -/* Create a CONST_DOUBLE from a string. */ - -struct rtx_def * -rs6000_float_const (string, mode) - char *string; - enum machine_mode mode; -{ - REAL_VALUE_TYPE value = REAL_VALUE_ATOF (string, mode); - return immed_real_const_1 (value, mode); -} - -/* Return non-zero if this function is known to have a null epilogue. */ - -int -direct_return () -{ - if (reload_completed) - { - rs6000_stack_t *info = rs6000_stack_info (); - - if (info->first_gp_reg_save == 32 - && info->first_fp_reg_save == 64 - && !info->lr_save_p - && !info->cr_save_p - && !info->push_p) - return 1; - } - - return 0; -} - -/* Returns 1 always. */ - -int -any_operand (op, mode) - register rtx op ATTRIBUTE_UNUSED; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return 1; -} - -/* Returns 1 if op is the count register */ -int -count_register_operand(op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - if (GET_CODE (op) != REG) - return 0; - - if (REGNO (op) == COUNT_REGISTER_REGNUM) - return 1; - - if (REGNO (op) > FIRST_PSEUDO_REGISTER) - return 1; - - return 0; -} - -/* Returns 1 if op is memory location for float/int conversions that masquerades - as a register. */ -int -fpmem_operand(op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - if (GET_CODE (op) != REG) - return 0; - - if (FPMEM_REGNO_P (REGNO (op))) - return 1; - -#if 0 - if (REGNO (op) > FIRST_PSEUDO_REGISTER) - return 1; -#endif - - return 0; -} - -/* Return 1 if OP is a constant that can fit in a D field. */ - -int -short_cint_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return ((GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000) - || GET_CODE (op) == CONSTANT_P_RTX); -} - -/* Similar for a unsigned D field. */ - -int -u_short_cint_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return ((GET_CODE (op) == CONST_INT - && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0) - || GET_CODE (op) == CONSTANT_P_RTX); -} - -/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */ - -int -non_short_cint_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000); -} - -/* Returns 1 if OP is a register that is not special (i.e., not MQ, - ctr, or lr). */ - -int -gpc_reg_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) - && (GET_CODE (op) != REG - || (REGNO (op) >= 67 && !FPMEM_REGNO_P (REGNO (op))) - || REGNO (op) < 64)); -} - -/* Returns 1 if OP is either a pseudo-register or a register denoting a - CR field. */ - -int -cc_reg_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) - && (GET_CODE (op) != REG - || REGNO (op) >= FIRST_PSEUDO_REGISTER - || CR_REGNO_P (REGNO (op)))); -} - -/* Returns 1 if OP is either a pseudo-register or a register denoting a - CR field that isn't CR0. */ - -int -cc_reg_not_cr0_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) - && (GET_CODE (op) != REG - || REGNO (op) >= FIRST_PSEUDO_REGISTER - || CR_REGNO_NOT_CR0_P (REGNO (op)))); -} - -/* Returns 1 if OP is either a constant integer valid for a D-field or a - non-special register. If a register, it must be in the proper mode unless - MODE is VOIDmode. */ - -int -reg_or_short_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return short_cint_operand (op, mode) || gpc_reg_operand (op, mode); -} - -/* Similar, except check if the negation of the constant would be valid for - a D-field. */ - -int -reg_or_neg_short_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P'); - - return gpc_reg_operand (op, mode); -} - -/* Return 1 if the operand is either a register or an integer whose high-order - 16 bits are zero. */ - -int -reg_or_u_short_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode); -} - -/* Return 1 is the operand is either a non-special register or ANY - constant integer. */ - -int -reg_or_cint_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == CONST_INT - || GET_CODE (op) == CONSTANT_P_RTX - || gpc_reg_operand (op, mode)); -} - -/* Return 1 if the operand is an operand that can be loaded via the GOT */ - -int -got_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == SYMBOL_REF - || GET_CODE (op) == CONST - || GET_CODE (op) == LABEL_REF); -} - -/* Return 1 if the operand is a simple references that can be loaded via - the GOT (labels involving addition aren't allowed). */ - -int -got_no_const_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF); -} - -/* Return the number of instructions it takes to form a constant in an - integer register. */ - -static int -num_insns_constant_wide (value) - HOST_WIDE_INT value; -{ - /* signed constant loadable with {cal|addi} */ - if (((unsigned HOST_WIDE_INT)value + 0x8000) < 0x10000) - return 1; - -#if HOST_BITS_PER_WIDE_INT == 32 - /* constant loadable with {cau|addis} */ - else if ((value & 0xffff) == 0) - return 1; - -#else - /* constant loadable with {cau|addis} */ - else if ((value & 0xffff) == 0 && (value & ~0xffffffff) == 0) - return 1; - - else if (TARGET_64BIT) - { - HOST_WIDE_INT low = value & 0xffffffff; - HOST_WIDE_INT high = value >> 32; - - if (high == 0 && (low & 0x80000000) == 0) - return 2; - - else if (high == 0xffffffff && (low & 0x80000000) != 0) - return 2; - - else if (!low) - return num_insns_constant_wide (high) + 1; - - else - return (num_insns_constant_wide (high) - + num_insns_constant_wide (low) + 1); - } -#endif - - else - return 2; -} - -int -num_insns_constant (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - return num_insns_constant_wide (INTVAL (op)); - - else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode) - { - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - return num_insns_constant_wide ((HOST_WIDE_INT)l); - } - - else if (GET_CODE (op) == CONST_DOUBLE) - { - HOST_WIDE_INT low; - HOST_WIDE_INT high; - long l[2]; - REAL_VALUE_TYPE rv; - int endian = (WORDS_BIG_ENDIAN == 0); - - if (mode == VOIDmode || mode == DImode) - { - high = CONST_DOUBLE_HIGH (op); - low = CONST_DOUBLE_LOW (op); - } - else - { - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_DOUBLE (rv, l); - high = l[endian]; - low = l[1 - endian]; - } - - if (TARGET_32BIT) - return (num_insns_constant_wide (low) - + num_insns_constant_wide (high)); - - else - { - if (high == 0 && (low & 0x80000000) == 0) - return num_insns_constant_wide (low); - - else if (((high & 0xffffffff) == 0xffffffff) - && ((low & 0x80000000) != 0)) - return num_insns_constant_wide (low); - - else if (mask64_operand (op, mode)) - return 2; - - else if (low == 0) - return num_insns_constant_wide (high) + 1; - - else - return (num_insns_constant_wide (high) - + num_insns_constant_wide (low) + 1); - } - } - - else - abort (); -} - -/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a register - with one instruction per word. We only do this if we can safely read - CONST_DOUBLE_{LOW,HIGH}. */ - -int -easy_fp_constant (op, mode) - register rtx op; - register enum machine_mode mode; -{ - if (GET_CODE (op) != CONST_DOUBLE - || GET_MODE (op) != mode - || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode)) - return 0; - - /* Consider all constants with -msoft-float to be easy */ - if (TARGET_SOFT_FLOAT && mode != DImode) - return 1; - - /* If we are using V.4 style PIC, consider all constants to be hard */ - if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - return 0; - -#ifdef TARGET_RELOCATABLE - /* Similarly if we are using -mrelocatable, consider all constants to be hard */ - if (TARGET_RELOCATABLE) - return 0; -#endif - - if (mode == DFmode) - { - long k[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - - return (num_insns_constant_wide ((HOST_WIDE_INT)k[0]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT)k[1]) == 1); - } - - else if (mode == SFmode) - { - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - - return num_insns_constant_wide (l) == 1; - } - - else if (mode == DImode) - return ((TARGET_64BIT - && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0) - || (num_insns_constant (op, DImode) <= 2)); - - else - abort (); -} - -/* Return 1 if the operand is in volatile memory. Note that during the - RTL generation phase, memory_operand does not return TRUE for - volatile memory references. So this function allows us to - recognize volatile references where its safe. */ - -int -volatile_mem_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) != MEM) - return 0; - - if (!MEM_VOLATILE_P (op)) - return 0; - - if (mode != GET_MODE (op)) - return 0; - - if (reload_completed) - return memory_operand (op, mode); - - if (reload_in_progress) - return strict_memory_address_p (mode, XEXP (op, 0)); - - return memory_address_p (mode, XEXP (op, 0)); -} - -/* Return 1 if the operand is an offsettable memory address. */ - -int -offsettable_addr_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return offsettable_address_p (reload_completed | reload_in_progress, - mode, op); -} - -/* Return 1 if the operand is either an easy FP constant (see above) or - memory. */ - -int -mem_or_easy_const_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return memory_operand (op, mode) || easy_fp_constant (op, mode); -} - -/* Return 1 if the operand is either a non-special register or an item - that can be used as the operand of an SI add insn. */ - -int -add_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (reg_or_short_operand (op, mode) - || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0)); -} - -/* Return 1 if OP is a constant but not a valid add_operand. */ - -int -non_add_cint_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000 - && (INTVAL (op) & 0xffff) != 0); -} - -/* Return 1 if the operand is a non-special register or a constant that - can be used as the operand of an OR or XOR insn on the RS/6000. */ - -int -logical_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (gpc_reg_operand (op, mode) - || (GET_CODE (op) == CONST_INT - && ((INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0 - || (INTVAL (op) & 0xffff) == 0)) - || GET_CODE (op) == CONSTANT_P_RTX); -} - -/* Return 1 if C is a constant that is not a logical operand (as - above). */ - -int -non_logical_cint_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0 - && (INTVAL (op) & 0xffff) != 0); -} - -/* Return 1 if C is a constant that can be encoded in a mask on the - RS/6000. It is if there are no more than two 1->0 or 0->1 transitions. - Reject all ones and all zeros, since these should have been optimized - away and confuse the making of MB and ME. */ - -int -mask_constant (c) - register HOST_WIDE_INT c; -{ - int i; - int last_bit_value; - int transitions = 0; - - if (c == 0 || c == ~0) - return 0; - - last_bit_value = c & 1; - - for (i = 1; i < 32; i++) - if (((c >>= 1) & 1) != last_bit_value) - last_bit_value ^= 1, transitions++; - - return transitions <= 2; -} - -/* Return 1 if the operand is a constant that is a mask on the RS/6000. */ - -int -mask_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op)); -} - -/* Return 1 if the operand is a constant that is a PowerPC64 mask. - It is if there are no more than one 1->0 or 0->1 transitions. - Reject all ones and all zeros, since these should have been optimized - away and confuse the making of MB and ME. */ - -int -mask64_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - { - HOST_WIDE_INT c = INTVAL (op); - int i; - int last_bit_value; - int transitions = 0; - - if (c == 0 || c == ~0) - return 0; - - last_bit_value = c & 1; - - for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++) - if (((c >>= 1) & 1) != last_bit_value) - last_bit_value ^= 1, transitions++; - -#if HOST_BITS_PER_WIDE_INT == 32 - /* Consider CONST_INT sign-extended. */ - transitions += (last_bit_value != 1); -#endif - - return transitions <= 1; - } - else if (GET_CODE (op) == CONST_DOUBLE - && (mode == VOIDmode || mode == DImode)) - { - HOST_WIDE_INT low = CONST_DOUBLE_LOW (op); -#if HOST_BITS_PER_WIDE_INT == 32 - HOST_WIDE_INT high = CONST_DOUBLE_HIGH (op); -#endif - int i; - int last_bit_value; - int transitions = 0; - - if ((low == 0 -#if HOST_BITS_PER_WIDE_INT == 32 - && high == 0 -#endif - ) - || (low == ~0 -#if HOST_BITS_PER_WIDE_INT == 32 - && high == ~0 -#endif - )) - return 0; - - last_bit_value = low & 1; - - for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++) - if (((low >>= 1) & 1) != last_bit_value) - last_bit_value ^= 1, transitions++; - -#if HOST_BITS_PER_WIDE_INT == 32 - if ((high & 1) != last_bit_value) - last_bit_value ^= 1, transitions++; - - for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++) - if (((high >>= 1) & 1) != last_bit_value) - last_bit_value ^= 1, transitions++; -#endif - - return transitions <= 1; - } - else - return 0; -} - -/* Return 1 if the operand is either a non-special register or a constant - that can be used as the operand of a PowerPC64 logical AND insn. */ - -int -and64_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (logical_operand (op, mode) - || mask64_operand (op, mode)); -} - -/* Return 1 if the operand is either a non-special register or a - constant that can be used as the operand of an RS/6000 logical AND insn. */ - -int -and_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (logical_operand (op, mode) - || mask_operand (op, mode)); -} - -/* Return 1 if the operand is a general register or memory operand. */ - -int -reg_or_mem_operand (op, mode) - register rtx op; - register enum machine_mode mode; -{ - return (gpc_reg_operand (op, mode) - || memory_operand (op, mode) - || volatile_mem_operand (op, mode)); -} - -/* Return 1 if the operand is a general register or memory operand without - pre-inc or pre_dec which produces invalid form of PowerPC lwa - instruction. */ - -int -lwa_operand (op, mode) - register rtx op; - register enum machine_mode mode; -{ - rtx inner = op; - - if (reload_completed && GET_CODE (inner) == SUBREG) - inner = SUBREG_REG (inner); - - return gpc_reg_operand (inner, mode) - || (memory_operand (inner, mode) - && GET_CODE (XEXP (inner, 0)) != PRE_INC - && GET_CODE (XEXP (inner, 0)) != PRE_DEC); -} - -/* Return 1 if the operand, used inside a MEM, is a valid first argument - to CALL. This is a SYMBOL_REF or a pseudo-register, which will be - forced to lr. */ - -int -call_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (mode != VOIDmode && GET_MODE (op) != mode) - return 0; - - return (GET_CODE (op) == SYMBOL_REF - || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER)); -} - - -/* Return 1 if the operand is a SYMBOL_REF for a function known to be in - this file. */ - -int -current_file_function_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == SYMBOL_REF - && (SYMBOL_REF_FLAG (op) - || op == XEXP (DECL_RTL (current_function_decl), 0))); -} - - -/* Return 1 if this operand is a valid input for a move insn. */ - -int -input_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - /* Memory is always valid. */ - if (memory_operand (op, mode)) - return 1; - - /* For floating-point, easy constants are valid. */ - if (GET_MODE_CLASS (mode) == MODE_FLOAT - && CONSTANT_P (op) - && easy_fp_constant (op, mode)) - return 1; - - /* Allow any integer constant. */ - if (GET_MODE_CLASS (mode) == MODE_INT - && (GET_CODE (op) == CONST_INT - || GET_CODE (op) == CONSTANT_P_RTX - || GET_CODE (op) == CONST_DOUBLE)) - return 1; - - /* For floating-point or multi-word mode, the only remaining valid type - is a register. */ - if (GET_MODE_CLASS (mode) == MODE_FLOAT - || GET_MODE_SIZE (mode) > UNITS_PER_WORD) - return register_operand (op, mode); - - /* The only cases left are integral modes one word or smaller (we - do not get called for MODE_CC values). These can be in any - register. */ - if (register_operand (op, mode)) - return 1; - - /* A SYMBOL_REF referring to the TOC is valid. */ - if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op)) - return 1; - - /* Windows NT allows SYMBOL_REFs and LABEL_REFs against the TOC - directly in the instruction stream */ - if (DEFAULT_ABI == ABI_NT - && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)) - return 1; - - /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region - to be valid. */ - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) - && small_data_operand (op, Pmode)) - return 1; - - return 0; -} - -/* Return 1 for an operand in small memory on V.4/eabi */ - -int -small_data_operand (op, mode) - rtx op ATTRIBUTE_UNUSED; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ -#if TARGET_ELF - rtx sym_ref, const_part; - - if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA) - return 0; - - if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - return 0; - - if (GET_CODE (op) == SYMBOL_REF) - sym_ref = op; - - else if (GET_CODE (op) != CONST - || GET_CODE (XEXP (op, 0)) != PLUS - || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF - || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT) - return 0; - - else - { - rtx sum = XEXP (op, 0); - HOST_WIDE_INT summand; - - /* We have to be careful here, because it is the referenced address - that must be 32k from _SDA_BASE_, not just the symbol. */ - summand = INTVAL (XEXP (sum, 1)); - if (summand < 0 || summand > g_switch_value) - return 0; - - sym_ref = XEXP (sum, 0); - } - - if (*XSTR (sym_ref, 0) != '@') - return 0; - - return 1; - -#else - return 0; -#endif -} - - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. - - For incoming args we set the number of arguments in the prototype large - so we never return a PARALLEL. */ - -void -init_cumulative_args (cum, fntype, libname, incoming) - CUMULATIVE_ARGS *cum; - tree fntype; - rtx libname ATTRIBUTE_UNUSED; - int incoming; -{ - static CUMULATIVE_ARGS zero_cumulative; - enum rs6000_abi abi = DEFAULT_ABI; - - *cum = zero_cumulative; - cum->words = 0; - cum->fregno = FP_ARG_MIN_REG; - cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); - cum->call_cookie = CALL_NORMAL; - - if (incoming) - { - cum->nargs_prototype = 1000; /* don't return a PARALLEL */ - if (abi == ABI_V4 || abi == ABI_SOLARIS) - cum->varargs_offset = RS6000_VARARGS_OFFSET; - } - - else if (cum->prototype) - cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1 - + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode - || RETURN_IN_MEMORY (TREE_TYPE (fntype)))); - - else - cum->nargs_prototype = 0; - - cum->orig_nargs = cum->nargs_prototype; - - /* Check for DLL import functions */ - if (abi == ABI_NT - && fntype - && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype))) - cum->call_cookie = CALL_NT_DLLIMPORT; - - /* Also check for longcall's */ - else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))) - cum->call_cookie = CALL_LONG; - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "\ninit_cumulative_args:"); - if (fntype) - { - tree ret_type = TREE_TYPE (fntype); - fprintf (stderr, " ret code = %s,", - tree_code_name[ (int)TREE_CODE (ret_type) ]); - } - - if ((abi == ABI_V4 || abi == ABI_SOLARIS) && incoming) - fprintf (stderr, " varargs = %d, ", cum->varargs_offset); - - if (cum->call_cookie & CALL_NT_DLLIMPORT) - fprintf (stderr, " dllimport,"); - - if (cum->call_cookie & CALL_LONG) - fprintf (stderr, " longcall,"); - - fprintf (stderr, " proto = %d, nargs = %d\n", - cum->prototype, cum->nargs_prototype); - } -} - -/* If defined, a C expression which determines whether, and in which - direction, to pad out an argument with extra space. The value - should be of type `enum direction': either `upward' to pad above - the argument, `downward' to pad below, or `none' to inhibit - padding. - - For the AIX ABI structs are always stored left shifted in their - argument slot. */ - -int -function_arg_padding (mode, type) - enum machine_mode mode; - tree type; -{ - if (type != 0 && AGGREGATE_TYPE_P (type)) - return (int)upward; - - /* This is the default definition. */ - return (! BYTES_BIG_ENDIAN - ? (int)upward - : ((mode == BLKmode - ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT)) - : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY) - ? (int)downward : (int)upward)); -} - -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. - - Windows NT wants anything >= 8 bytes to be double word aligned. - - V.4 wants long longs to be double word aligned. */ - -int -function_arg_boundary (mode, type) - enum machine_mode mode; - tree type; -{ - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && mode == DImode) - return 64; - - if (DEFAULT_ABI != ABI_NT || TARGET_64BIT) - return PARM_BOUNDARY; - - if (mode != BLKmode) - return (GET_MODE_SIZE (mode)) >= 8 ? 64 : 32; - - return (int_size_in_bytes (type) >= 8) ? 64 : 32; -} - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -void -function_arg_advance (cum, mode, type, named) - CUMULATIVE_ARGS *cum; - enum machine_mode mode; - tree type; - int named; -{ - int align = (TARGET_32BIT && (cum->words & 1) != 0 - && function_arg_boundary (mode, type) == 64) ? 1 : 0; - cum->words += align; - cum->nargs_prototype--; - - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - { - /* Long longs must not be split between registers and stack */ - if ((GET_MODE_CLASS (mode) != MODE_FLOAT || TARGET_SOFT_FLOAT) - && type && !AGGREGATE_TYPE_P (type) - && cum->words < GP_ARG_NUM_REG - && cum->words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG) - { - cum->words = GP_ARG_NUM_REG; - } - - /* Aggregates get passed as pointers */ - if (type && AGGREGATE_TYPE_P (type)) - cum->words++; - - /* Floats go in registers, & don't occupy space in the GP registers - like they do for AIX unless software floating point. */ - else if (GET_MODE_CLASS (mode) == MODE_FLOAT - && TARGET_HARD_FLOAT - && cum->fregno <= FP_ARG_V4_MAX_REG) - cum->fregno++; - - else - cum->words += RS6000_ARG_SIZE (mode, type, 1); - } - else - if (named) - { - cum->words += RS6000_ARG_SIZE (mode, type, named); - if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT) - cum->fregno++; - } - - if (TARGET_DEBUG_ARG) - fprintf (stderr, - "function_adv: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n", - cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align); -} - -/* Determine where to put an argument to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). - - On RS/6000 the first eight words of non-FP are normally in registers - and the rest are pushed. Under AIX, the first 13 FP args are in registers. - Under V.4, the first 8 FP args are in registers. - - If this is floating-point and no prototype is specified, we use - both an FP and integer register (or possibly FP reg and stack). Library - functions (when TYPE is zero) always have the proper types for args, - so we can pass the FP value just in one register. emit_library_function - doesn't support PARALLEL anyway. */ - -struct rtx_def * -function_arg (cum, mode, type, named) - CUMULATIVE_ARGS *cum; - enum machine_mode mode; - tree type; - int named; -{ - int align = (TARGET_32BIT && (cum->words & 1) != 0 - && function_arg_boundary (mode, type) == 64) ? 1 : 0; - int align_words = cum->words + align; - - if (TARGET_DEBUG_ARG) - fprintf (stderr, - "function_arg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n", - cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align); - - /* Return a marker to indicate whether CR1 needs to set or clear the bit that V.4 - uses to say fp args were passed in registers. Assume that we don't need the - marker for software floating point, or compiler generated library calls. */ - if (mode == VOIDmode) - { - enum rs6000_abi abi = DEFAULT_ABI; - - if ((abi == ABI_V4 || abi == ABI_SOLARIS) - && TARGET_HARD_FLOAT - && cum->nargs_prototype < 0 - && type && (cum->prototype || TARGET_NO_PROTOTYPE)) - { - return GEN_INT (cum->call_cookie - | ((cum->fregno == FP_ARG_MIN_REG) - ? CALL_V4_SET_FP_ARGS - : CALL_V4_CLEAR_FP_ARGS)); - } - - return GEN_INT (cum->call_cookie); - } - - if (!named) - { - if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - return NULL_RTX; - } - - if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - return NULL_RTX; - - if (USE_FP_FOR_ARG_P (*cum, mode, type)) - { - if (DEFAULT_ABI == ABI_V4 /* V.4 never passes FP values in GP registers */ - || DEFAULT_ABI == ABI_SOLARIS - || ! type - || ((cum->nargs_prototype > 0) - /* IBM AIX extended its linkage convention definition always to - require FP args after register save area hole on the stack. */ - && (DEFAULT_ABI != ABI_AIX - || ! TARGET_XL_CALL - || (align_words < GP_ARG_NUM_REG)))) - return gen_rtx_REG (mode, cum->fregno); - - return gen_rtx_PARALLEL (mode, - gen_rtvec - (2, - gen_rtx_EXPR_LIST (VOIDmode, - ((align_words >= GP_ARG_NUM_REG) - ? NULL_RTX - : (align_words - + RS6000_ARG_SIZE (mode, type, named) - > GP_ARG_NUM_REG - /* If this is partially on the stack, then - we only include the portion actually - in registers here. */ - ? gen_rtx_REG (SImode, - GP_ARG_MIN_REG + align_words) - : gen_rtx_REG (mode, - GP_ARG_MIN_REG + align_words))), - const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, cum->fregno), - const0_rtx))); - } - - /* Long longs won't be split between register and stack; - FP arguments get passed on the stack if they didn't get a register. */ - else if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && - (align_words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG - || (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT))) - { - return NULL_RTX; - } - - else if (align_words < GP_ARG_NUM_REG) - return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); - - return NULL_RTX; -} - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -int -function_arg_partial_nregs (cum, mode, type, named) - CUMULATIVE_ARGS *cum; - enum machine_mode mode; - tree type; - int named; -{ - if (! named) - return 0; - - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - return 0; - - if (USE_FP_FOR_ARG_P (*cum, mode, type)) - { - if (cum->nargs_prototype >= 0) - return 0; - } - - if (cum->words < GP_ARG_NUM_REG - && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type, named))) - { - int ret = GP_ARG_NUM_REG - cum->words; - if (ret && TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_partial_nregs: %d\n", ret); - - return ret; - } - - return 0; -} - -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. - - Under V.4, structures and unions are passed by reference. */ - -int -function_arg_pass_by_reference (cum, mode, type, named) - CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED; - enum machine_mode mode ATTRIBUTE_UNUSED; - tree type; - int named ATTRIBUTE_UNUSED; -{ - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && type && AGGREGATE_TYPE_P (type)) - { - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: aggregate\n"); - - return 1; - } - - return 0; -} - - -/* Perform any needed actions needed for a function that is receiving a - variable number of arguments. - - CUM is as above. - - MODE and TYPE are the mode and type of the current parameter. - - PRETEND_SIZE is a variable that should be set to the amount of stack - that must be pushed by the prolog to pretend that our caller pushed - it. - - Normally, this macro will push all remaining incoming registers on the - stack and set PRETEND_SIZE to the length of the registers pushed. */ - -void -setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) - CUMULATIVE_ARGS *cum; - enum machine_mode mode; - tree type; - int *pretend_size; - int no_rtl; - -{ - rtx save_area = virtual_incoming_args_rtx; - int reg_size = TARGET_32BIT ? 4 : 8; - - if (TARGET_DEBUG_ARG) - fprintf (stderr, - "setup_vararg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n", - cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl); - - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - { - rs6000_sysv_varargs_p = 1; - if (! no_rtl) - save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET); - } - else - rs6000_sysv_varargs_p = 0; - - if (cum->words < 8) - { - int first_reg_offset = cum->words; - - if (MUST_PASS_IN_STACK (mode, type)) - first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type, 1); - - if (first_reg_offset > GP_ARG_NUM_REG) - first_reg_offset = GP_ARG_NUM_REG; - - if (!no_rtl && first_reg_offset != GP_ARG_NUM_REG) - move_block_from_reg - (GP_ARG_MIN_REG + first_reg_offset, - gen_rtx_MEM (BLKmode, - plus_constant (save_area, first_reg_offset * reg_size)), - GP_ARG_NUM_REG - first_reg_offset, - (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD); - - *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD; - } - - /* Save FP registers if needed. */ - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && TARGET_HARD_FLOAT && !no_rtl) - { - int fregno = cum->fregno; - int num_fp_reg = FP_ARG_V4_MAX_REG + 1 - fregno; - - if (num_fp_reg >= 0) - { - rtx cr1 = gen_rtx_REG (CCmode, 69); - rtx lab = gen_label_rtx (); - int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8); - - emit_jump_insn (gen_rtx_SET (VOIDmode, - pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, - gen_rtx_NE (VOIDmode, cr1, const0_rtx), - gen_rtx_LABEL_REF (VOIDmode, lab), - pc_rtx))); - - while ( num_fp_reg-- >= 0) - { - emit_move_insn (gen_rtx_MEM (DFmode, plus_constant (save_area, off)), - gen_rtx_REG (DFmode, fregno++)); - off += 8; - } - - emit_label (lab); - } - } -} - -/* If defined, is a C expression that produces the machine-specific - code for a call to `__builtin_saveregs'. This code will be moved - to the very beginning of the function, before any parameter access - are made. The return value of this function should be an RTX that - contains the value to use as the return of `__builtin_saveregs'. - - The argument ARGS is a `tree_list' containing the arguments that - were passed to `__builtin_saveregs'. - - If this macro is not defined, the compiler will output an ordinary - call to the library function `__builtin_saveregs'. - - On the Power/PowerPC return the address of the area on the stack - used to hold arguments. Under AIX, this includes the 8 word register - save area. Under V.4 this does not. */ - -struct rtx_def * -expand_builtin_saveregs (args) - tree args ATTRIBUTE_UNUSED; -{ - return virtual_incoming_args_rtx; -} - - -/* Generate a memory reference for expand_block_move, copying volatile, - and other bits from an original memory reference. */ - -static rtx -expand_block_move_mem (mode, addr, orig_mem) - enum machine_mode mode; - rtx addr; - rtx orig_mem; -{ - rtx mem = gen_rtx_MEM (mode, addr); - - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (orig_mem); - MEM_COPY_ATTRIBUTES (mem, orig_mem); -#ifdef MEM_UNALIGNED_P - MEM_UNALIGNED_P (mem) = MEM_UNALIGNED_P (orig_mem); -#endif - return mem; -} - -/* Expand a block move operation, and return 1 if successful. Return 0 - if we should let the compiler generate normal code. - - operands[0] is the destination - operands[1] is the source - operands[2] is the length - operands[3] is the alignment */ - -#define MAX_MOVE_REG 4 - -int -expand_block_move (operands) - rtx operands[]; -{ - rtx orig_dest = operands[0]; - rtx orig_src = operands[1]; - rtx bytes_rtx = operands[2]; - rtx align_rtx = operands[3]; - int constp = (GET_CODE (bytes_rtx) == CONST_INT); - int align = XINT (align_rtx, 0); - int bytes; - int offset; - int num_reg; - int i; - rtx src_reg; - rtx dest_reg; - rtx src_addr; - rtx dest_addr; - rtx tmp_reg; - rtx stores[MAX_MOVE_REG]; - int move_bytes; - - /* If this is not a fixed size move, just call memcpy */ - if (!constp) - return 0; - - /* Anything to move? */ - bytes = INTVAL (bytes_rtx); - if (bytes <= 0) - return 1; - - /* Don't support real large moves. If string instructions are not used, - then don't generate more than 8 loads. */ - if (TARGET_STRING) - { - if (bytes > 4*8) - return 0; - } - else if (!STRICT_ALIGNMENT) - { - if (bytes > 4*8) - return 0; - } - else if (bytes > 8*align) - return 0; - - /* Move the address into scratch registers. */ - dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0)); - src_reg = copy_addr_to_reg (XEXP (orig_src, 0)); - - if (TARGET_STRING) /* string instructions are available */ - { - for ( ; bytes > 0; bytes -= move_bytes) - { - if (bytes > 24 /* move up to 32 bytes at a time */ - && !fixed_regs[5] - && !fixed_regs[6] - && !fixed_regs[7] - && !fixed_regs[8] - && !fixed_regs[9] - && !fixed_regs[10] - && !fixed_regs[11] - && !fixed_regs[12]) - { - move_bytes = (bytes > 32) ? 32 : bytes; - emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), - expand_block_move_mem (BLKmode, src_reg, orig_src), - GEN_INT ((move_bytes == 32) ? 0 : move_bytes), - align_rtx)); - } - else if (bytes > 16 /* move up to 24 bytes at a time */ - && !fixed_regs[7] - && !fixed_regs[8] - && !fixed_regs[9] - && !fixed_regs[10] - && !fixed_regs[11] - && !fixed_regs[12]) - { - move_bytes = (bytes > 24) ? 24 : bytes; - emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), - expand_block_move_mem (BLKmode, src_reg, orig_src), - GEN_INT (move_bytes), - align_rtx)); - } - else if (bytes > 8 /* move up to 16 bytes at a time */ - && !fixed_regs[9] - && !fixed_regs[10] - && !fixed_regs[11] - && !fixed_regs[12]) - { - move_bytes = (bytes > 16) ? 16 : bytes; - emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), - expand_block_move_mem (BLKmode, src_reg, orig_src), - GEN_INT (move_bytes), - align_rtx)); - } - else if (bytes > 4 && !TARGET_64BIT) - { /* move up to 8 bytes at a time */ - move_bytes = (bytes > 8) ? 8 : bytes; - emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), - expand_block_move_mem (BLKmode, src_reg, orig_src), - GEN_INT (move_bytes), - align_rtx)); - } - else if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) - { /* move 4 bytes */ - move_bytes = 4; - tmp_reg = gen_reg_rtx (SImode); - emit_move_insn (tmp_reg, expand_block_move_mem (SImode, src_reg, orig_src)); - emit_move_insn (expand_block_move_mem (SImode, dest_reg, orig_dest), tmp_reg); - } - else if (bytes == 2 && (align >= 2 || !STRICT_ALIGNMENT)) - { /* move 2 bytes */ - move_bytes = 2; - tmp_reg = gen_reg_rtx (HImode); - emit_move_insn (tmp_reg, expand_block_move_mem (HImode, src_reg, orig_src)); - emit_move_insn (expand_block_move_mem (HImode, dest_reg, orig_dest), tmp_reg); - } - else if (bytes == 1) /* move 1 byte */ - { - move_bytes = 1; - tmp_reg = gen_reg_rtx (QImode); - emit_move_insn (tmp_reg, expand_block_move_mem (QImode, src_reg, orig_src)); - emit_move_insn (expand_block_move_mem (QImode, dest_reg, orig_dest), tmp_reg); - } - else - { /* move up to 4 bytes at a time */ - move_bytes = (bytes > 4) ? 4 : bytes; - emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), - expand_block_move_mem (BLKmode, src_reg, orig_src), - GEN_INT (move_bytes), - align_rtx)); - } - - if (bytes > move_bytes) - { - emit_insn (gen_addsi3 (src_reg, src_reg, GEN_INT (move_bytes))); - emit_insn (gen_addsi3 (dest_reg, dest_reg, GEN_INT (move_bytes))); - } - } - } - - else /* string instructions not available */ - { - num_reg = offset = 0; - for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes)) - { - /* Calculate the correct offset for src/dest */ - if (offset == 0) - { - src_addr = src_reg; - dest_addr = dest_reg; - } - else - { - src_addr = gen_rtx_PLUS (Pmode, src_reg, GEN_INT (offset)); - dest_addr = gen_rtx_PLUS (Pmode, dest_reg, GEN_INT (offset)); - } - - /* Generate the appropriate load and store, saving the stores for later */ - if (bytes >= 8 && TARGET_64BIT && (align >= 8 || !STRICT_ALIGNMENT)) - { - move_bytes = 8; - tmp_reg = gen_reg_rtx (DImode); - emit_insn (gen_movdi (tmp_reg, expand_block_move_mem (DImode, src_addr, orig_src))); - stores[ num_reg++ ] = gen_movdi (expand_block_move_mem (DImode, dest_addr, orig_dest), tmp_reg); - } - else if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) - { - move_bytes = 4; - tmp_reg = gen_reg_rtx (SImode); - emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (SImode, src_addr, orig_src))); - stores[ num_reg++ ] = gen_movsi (expand_block_move_mem (SImode, dest_addr, orig_dest), tmp_reg); - } - else if (bytes >= 2 && (align >= 2 || !STRICT_ALIGNMENT)) - { - move_bytes = 2; - tmp_reg = gen_reg_rtx (HImode); - emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (HImode, src_addr, orig_src))); - stores[ num_reg++ ] = gen_movhi (expand_block_move_mem (HImode, dest_addr, orig_dest), tmp_reg); - } - else - { - move_bytes = 1; - tmp_reg = gen_reg_rtx (QImode); - emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (QImode, src_addr, orig_src))); - stores[ num_reg++ ] = gen_movqi (expand_block_move_mem (QImode, dest_addr, orig_dest), tmp_reg); - } - - if (num_reg >= MAX_MOVE_REG) - { - for (i = 0; i < num_reg; i++) - emit_insn (stores[i]); - num_reg = 0; - } - } - - for (i = 0; i < num_reg; i++) - emit_insn (stores[i]); - } - - return 1; -} - - -/* Return 1 if OP is a load multiple operation. It is known to be a - PARALLEL and the first section will be tested. */ - -int -load_multiple_operation (op, mode) - rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - int count = XVECLEN (op, 0); - int dest_regno; - rtx src_addr; - int i; - - /* Perform a quick check so we don't blow up below. */ - if (count <= 1 - || GET_CODE (XVECEXP (op, 0, 0)) != SET - || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) - return 0; - - dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); - src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); - - for (i = 1; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i); - - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != SImode - || REGNO (SET_DEST (elt)) != dest_regno + i - || GET_CODE (SET_SRC (elt)) != MEM - || GET_MODE (SET_SRC (elt)) != SImode - || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS - || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) - || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT - || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) - return 0; - } - - return 1; -} - -/* Similar, but tests for store multiple. Here, the second vector element - is a CLOBBER. It will be tested later. */ - -int -store_multiple_operation (op, mode) - rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - int count = XVECLEN (op, 0) - 1; - int src_regno; - rtx dest_addr; - int i; - - /* Perform a quick check so we don't blow up below. */ - if (count <= 1 - || GET_CODE (XVECEXP (op, 0, 0)) != SET - || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) - return 0; - - src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); - dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); - - for (i = 1; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i + 1); - - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != SImode - || REGNO (SET_SRC (elt)) != src_regno + i - || GET_CODE (SET_DEST (elt)) != MEM - || GET_MODE (SET_DEST (elt)) != SImode - || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS - || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) - || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT - || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) - return 0; - } - - return 1; -} - -/* Return 1 if OP is a comparison operation that is valid for a branch insn. - We only check the opcode against the mode of the CC value here. */ - -int -branch_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - enum rtx_code code = GET_CODE (op); - enum machine_mode cc_mode; - - if (GET_RTX_CLASS (code) != '<') - return 0; - - cc_mode = GET_MODE (XEXP (op, 0)); - if (GET_MODE_CLASS (cc_mode) != MODE_CC) - return 0; - - if ((code == GT || code == LT || code == GE || code == LE) - && cc_mode == CCUNSmode) - return 0; - - if ((code == GTU || code == LTU || code == GEU || code == LEU) - && (cc_mode != CCUNSmode)) - return 0; - - return 1; -} - -/* Return 1 if OP is a comparison operation that is valid for an scc insn. - We check the opcode against the mode of the CC value and disallow EQ or - NE comparisons for integers. */ - -int -scc_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (op); - enum machine_mode cc_mode; - - if (GET_MODE (op) != mode && mode != VOIDmode) - return 0; - - if (GET_RTX_CLASS (code) != '<') - return 0; - - cc_mode = GET_MODE (XEXP (op, 0)); - if (GET_MODE_CLASS (cc_mode) != MODE_CC) - return 0; - - if (code == NE && cc_mode != CCFPmode) - return 0; - - if ((code == GT || code == LT || code == GE || code == LE) - && cc_mode == CCUNSmode) - return 0; - - if ((code == GTU || code == LTU || code == GEU || code == LEU) - && (cc_mode != CCUNSmode)) - return 0; - - if (cc_mode == CCEQmode && code != EQ && code != NE) - return 0; - - return 1; -} - -int -trap_comparison_operator (op, mode) - rtx op; - enum machine_mode mode; -{ - if (mode != VOIDmode && mode != GET_MODE (op)) - return 0; - return (GET_RTX_CLASS (GET_CODE (op)) == '<' - || GET_CODE (op) == EQ || GET_CODE (op) == NE); -} - -/* Return 1 if ANDOP is a mask that has no bits on that are not in the - mask required to convert the result of a rotate insn into a shift - left insn of SHIFTOP bits. Both are known to be CONST_INT. */ - -int -includes_lshift_p (shiftop, andop) - register rtx shiftop; - register rtx andop; -{ - int shift_mask = (~0 << INTVAL (shiftop)); - - return (INTVAL (andop) & ~shift_mask) == 0; -} - -/* Similar, but for right shift. */ - -int -includes_rshift_p (shiftop, andop) - register rtx shiftop; - register rtx andop; -{ - unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0; - - shift_mask >>= INTVAL (shiftop); - - return (INTVAL (andop) & ~ shift_mask) == 0; -} - -/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates - for lfq and stfq insns. - - Note reg1 and reg2 *must* be hard registers. To be sure we will - abort if we are passed pseudo registers. */ - -int -registers_ok_for_quad_peep (reg1, reg2) - rtx reg1, reg2; -{ - /* We might have been passed a SUBREG. */ - if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) - return 0; - - return (REGNO (reg1) == REGNO (reg2) - 1); -} - -/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn. addr1 and - addr2 must be in consecutive memory locations (addr2 == addr1 + 8). */ - -int -addrs_ok_for_quad_peep (addr1, addr2) - register rtx addr1; - register rtx addr2; -{ - int reg1; - int offset1; - - /* Extract an offset (if used) from the first addr. */ - if (GET_CODE (addr1) == PLUS) - { - /* If not a REG, return zero. */ - if (GET_CODE (XEXP (addr1, 0)) != REG) - return 0; - else - { - reg1 = REGNO (XEXP (addr1, 0)); - /* The offset must be constant! */ - if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) - return 0; - offset1 = INTVAL (XEXP (addr1, 1)); - } - } - else if (GET_CODE (addr1) != REG) - return 0; - else - { - reg1 = REGNO (addr1); - /* This was a simple (mem (reg)) expression. Offset is 0. */ - offset1 = 0; - } - - /* Make sure the second address is a (mem (plus (reg) (const_int). */ - if (GET_CODE (addr2) != PLUS) - return 0; - - if (GET_CODE (XEXP (addr2, 0)) != REG - || GET_CODE (XEXP (addr2, 1)) != CONST_INT) - return 0; - - if (reg1 != REGNO (XEXP (addr2, 0))) - return 0; - - /* The offset for the second addr must be 8 more than the first addr. */ - if (INTVAL (XEXP (addr2, 1)) != offset1 + 8) - return 0; - - /* All the tests passed. addr1 and addr2 are valid for lfq or stfq - instructions. */ - return 1; -} - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -enum reg_class -secondary_reload_class (class, mode, in) - enum reg_class class; - enum machine_mode mode ATTRIBUTE_UNUSED; - rtx in; -{ - int regno; - - /* We can not copy a symbolic operand directly into anything other than - BASE_REGS for TARGET_ELF. So indicate that a register from BASE_REGS - is needed as an intermediate register. */ - if (TARGET_ELF - && class != BASE_REGS - && (GET_CODE (in) == SYMBOL_REF - || GET_CODE (in) == HIGH - || GET_CODE (in) == LABEL_REF - || GET_CODE (in) == CONST)) - return BASE_REGS; - - if (GET_CODE (in) == REG) - { - regno = REGNO (in); - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno = true_regnum (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - } - } - else if (GET_CODE (in) == SUBREG) - { - regno = true_regnum (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - } - else - regno = -1; - - /* We can place anything into GENERAL_REGS and can put GENERAL_REGS - into anything. */ - if (class == GENERAL_REGS || class == BASE_REGS - || (regno >= 0 && INT_REGNO_P (regno))) - return NO_REGS; - - /* Constants, memory, and FP registers can go into FP registers. */ - if ((regno == -1 || FP_REGNO_P (regno)) - && (class == FLOAT_REGS || class == NON_SPECIAL_REGS)) - return NO_REGS; - - /* We can copy among the CR registers. */ - if ((class == CR_REGS || class == CR0_REGS) - && regno >= 0 && CR_REGNO_P (regno)) - return NO_REGS; - - /* Otherwise, we need GENERAL_REGS. */ - return GENERAL_REGS; -} - -/* Given a comparison operation, return the bit number in CCR to test. We - know this is a valid comparison. - - SCC_P is 1 if this is for an scc. That means that %D will have been - used instead of %C, so the bits will be in different places. - - Return -1 if OP isn't a valid comparison for some reason. */ - -int -ccr_bit (op, scc_p) - register rtx op; - int scc_p; -{ - /* CYGNUS LOCAL -- meissner/branch prediction */ - enum rtx_code code = GET_CODE (op); - enum machine_mode cc_mode; - int cc_regnum; - int base_bit; - rtx reg; - - if (GET_RTX_CLASS (code) != '<') - return -1; - - reg = XEXP (op, 0); - - if (GET_CODE (reg) == EXPECT) - reg = XEXP (reg, 0); - - if (GET_CODE (reg) != REG - || REGNO (reg) < 68 - || REGNO (reg) > 75) - abort (); - - cc_mode = GET_MODE (reg); - cc_regnum = REGNO (reg); - base_bit = 4 * (cc_regnum - 68); - /* END CYGNUS LOCAL -- meissner/branch prediction */ - - /* In CCEQmode cases we have made sure that the result is always in the - third bit of the CR field. */ - - if (cc_mode == CCEQmode) - return base_bit + 3; - - switch (code) - { - case NE: - return scc_p ? base_bit + 3 : base_bit + 2; - case EQ: - return base_bit + 2; - case GT: case GTU: - return base_bit + 1; - case LT: case LTU: - return base_bit; - - case GE: case GEU: - /* If floating-point, we will have done a cror to put the bit in the - unordered position. So test that bit. For integer, this is ! LT - unless this is an scc insn. */ - return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit; - - case LE: case LEU: - return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1; - - default: - abort (); - } -} - -/* Return the GOT register, creating it if needed. */ - -struct rtx_def * -rs6000_got_register (value) - rtx value; -{ - if (!current_function_uses_pic_offset_table || !pic_offset_table_rtx) - { - if (reload_in_progress || reload_completed) - fatal_insn ("internal error -- needed new GOT register during reload phase to load:", value); - - current_function_uses_pic_offset_table = 1; - pic_offset_table_rtx = gen_rtx_REG (Pmode, GOT_TOC_REGNUM); - } - - return pic_offset_table_rtx; -} - - -/* Replace all occurrences of register FROM with an new pseudo register in an insn X. - Store the pseudo register used in REG. - This is only safe during FINALIZE_PIC, since the registers haven't been setup - yet. */ - -static rtx -rs6000_replace_regno (x, from, reg) - rtx x; - int from; - rtx *reg; -{ - register int i, j; - register char *fmt; - - /* Allow this function to make replacements in EXPR_LISTs. */ - if (!x) - return x; - - switch (GET_CODE (x)) - { - case SCRATCH: - case PC: - case CC0: - case CONST_INT: - case CONST_DOUBLE: - case CONST: - case SYMBOL_REF: - case LABEL_REF: - return x; - - case REG: - if (REGNO (x) == from) - { - if (! *reg) - *reg = pic_offset_table_rtx = gen_reg_rtx (Pmode); - - return *reg; - } - - return x; - - default: - break; - } - - fmt = GET_RTX_FORMAT (GET_CODE (x)); - for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - XEXP (x, i) = rs6000_replace_regno (XEXP (x, i), from, reg); - else if (fmt[i] == 'E') - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - XVECEXP (x, i, j) = rs6000_replace_regno (XVECEXP (x, i, j), from, reg); - } - - return x; -} - - -/* By generating position-independent code, when two different - programs (A and B) share a common library (libC.a), the text of - the library can be shared whether or not the library is linked at - the same address for both programs. In some of these - environments, position-independent code requires not only the use - of different addressing modes, but also special code to enable the - use of these addressing modes. - - The `FINALIZE_PIC' macro serves as a hook to emit these special - codes once the function is being compiled into assembly code, but - not before. (It is not done before, because in the case of - compiling an inline function, it would lead to multiple PIC - prologues being included in functions which used inline functions - and were compiled to assembly language.) */ - -void -rs6000_finalize_pic () -{ - /* Loop through all of the insns, replacing the special GOT_TOC_REGNUM - with an appropriate pseudo register. If we find we need GOT/TOC, - add the appropriate init code. */ - if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - { - rtx insn = get_insns (); - rtx reg = NULL_RTX; - rtx first_insn; - rtx last_insn = NULL_RTX; - - if (GET_CODE (insn) == NOTE) - insn = next_nonnote_insn (insn); - - first_insn = insn; - for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn)) - { - if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') - { - PATTERN (insn) = rs6000_replace_regno (PATTERN (insn), - GOT_TOC_REGNUM, - ®); - - if (REG_NOTES (insn)) - REG_NOTES (insn) = rs6000_replace_regno (REG_NOTES (insn), - GOT_TOC_REGNUM, - ®); - } - - if (GET_CODE (insn) != NOTE) - last_insn = insn; - } - - if (reg) - { - rtx init = gen_init_v4_pic (reg); - emit_insn_before (init, first_insn); - if (!optimize && last_insn) - emit_insn_after (gen_rtx_USE (VOIDmode, reg), last_insn); - } - } -} - - -/* Search for any occurrence of the GOT_TOC register marker that should - have been eliminated, but may have crept back in. */ - -void -rs6000_reorg (insn) - rtx insn; -{ - if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - { - rtx got_reg = gen_rtx_REG (Pmode, GOT_TOC_REGNUM); - for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn)) - if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' - && reg_mentioned_p (got_reg, PATTERN (insn))) - fatal_insn ("GOT/TOC register marker not removed:", PATTERN (insn)); - } -} - - -/* Define the structure for the machine field in struct function. */ -struct machine_function -{ - int sysv_varargs_p; - int save_toc_p; - int fpmem_size; - int fpmem_offset; - rtx pic_offset_table_rtx; -}; - -/* Functions to save and restore rs6000_fpmem_size. - These will be called, via pointer variables, - from push_function_context and pop_function_context. */ - -void -rs6000_save_machine_status (p) - struct function *p; -{ - struct machine_function *machine = - (struct machine_function *) xmalloc (sizeof (struct machine_function)); - - p->machine = machine; - machine->sysv_varargs_p = rs6000_sysv_varargs_p; - machine->fpmem_size = rs6000_fpmem_size; - machine->fpmem_offset = rs6000_fpmem_offset; - machine->pic_offset_table_rtx = pic_offset_table_rtx; -} - -void -rs6000_restore_machine_status (p) - struct function *p; -{ - struct machine_function *machine = p->machine; - - rs6000_sysv_varargs_p = machine->sysv_varargs_p; - rs6000_fpmem_size = machine->fpmem_size; - rs6000_fpmem_offset = machine->fpmem_offset; - pic_offset_table_rtx = machine->pic_offset_table_rtx; - - free (machine); - p->machine = (struct machine_function *)0; -} - -/* Do anything needed before RTL is emitted for each function. */ - -void -rs6000_init_expanders () -{ - /* Reset varargs and save TOC indicator */ - rs6000_sysv_varargs_p = 0; - rs6000_fpmem_size = 0; - rs6000_fpmem_offset = 0; - pic_offset_table_rtx = (rtx)0; - - /* Arrange to save and restore machine status around nested functions. */ - save_machine_status = rs6000_save_machine_status; - restore_machine_status = rs6000_restore_machine_status; -} - - -/* Print an operand. Recognize special options, documented below. */ - -#if TARGET_ELF -#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel") -#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13) -#else -#define SMALL_DATA_RELOC "sda21" -#define SMALL_DATA_REG 0 -#endif - -void -print_operand (file, x, code) - FILE *file; - rtx x; - char code; -{ - int i; - /* CYGNUS LOCAL -- meissner/branch prediction */ - int succeed; - /* END CYGNUS LOCAL -- meissner/branch prediction */ - HOST_WIDE_INT val; - - /* These macros test for integers and extract the low-order bits. */ -#define INT_P(X) \ -((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \ - && GET_MODE (X) == VOIDmode) - -#define INT_LOWPART(X) \ - (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X)) - - switch (code) - { - case '.': - /* Write out an instruction after the call which may be replaced - with glue code by the loader. This depends on the AIX version. */ - asm_fprintf (file, RS6000_CALL_GLUE); - return; - - case '*': - /* Write the register number of the TOC register. */ - fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2], file); - return; - - case '$': - /* Write out either a '.' or '$' for the current location, depending - on whether this is Solaris or not. */ - putc ((DEFAULT_ABI == ABI_SOLARIS) ? '.' : '$', file); - return; - - case 'A': - /* If X is a constant integer whose low-order 5 bits are zero, - write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug - in the AIX assembler where "sri" with a zero shift count - write a trash instruction. */ - if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) - putc ('l', file); - else - putc ('r', file); - return; - - case 'b': - /* Low-order 16 bits of constant, unsigned. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%b value"); - - fprintf (file, "%d", INT_LOWPART (x) & 0xffff); - return; - - case 'B': - /* If the low-order bit is zero, write 'r'; otherwise, write 'l' - for 64-bit mask direction. */ - putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file); - return; - - case 'C': - /* This is an optional cror needed for LE or GE floating-point - comparisons. Otherwise write nothing. */ - if ((GET_CODE (x) == LE || GET_CODE (x) == GE) - && GET_MODE (XEXP (x, 0)) == CCFPmode) - { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); - - fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, - base_bit + 2, base_bit + (GET_CODE (x) == GE)); - } - return; - - case 'D': - /* Similar, except that this is for an scc, so we must be able to - encode the test in a single bit that is one. We do the above - for any LE, GE, GEU, or LEU and invert the bit for NE. */ - if (GET_CODE (x) == LE || GET_CODE (x) == GE - || GET_CODE (x) == LEU || GET_CODE (x) == GEU) - { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); - - fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, - base_bit + 2, - base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU)); - } - - else if (GET_CODE (x) == NE) - { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); - - fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3, - base_bit + 2, base_bit + 2); - } - return; - - case 'E': - /* X is a CR register. Print the number of the third bit of the CR */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%E value"); - - fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3); - return; - - case 'f': - /* X is a CR register. Print the shift count needed to move it - to the high-order four bits. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%f value"); - else - fprintf (file, "%d", 4 * (REGNO (x) - 68)); - return; - - case 'F': - /* Similar, but print the count for the rotate in the opposite - direction. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%F value"); - else - fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68)); - return; - - case 'G': - /* X is a constant integer. If it is negative, print "m", - otherwise print "z". This is to make a aze or ame insn. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%G value"); - else if (INTVAL (x) >= 0) - putc ('z', file); - else - putc ('m', file); - return; - - case 'h': - /* If constant, output low-order five bits. Otherwise, - write normally. */ - if (INT_P (x)) - fprintf (file, "%d", INT_LOWPART (x) & 31); - else - print_operand (file, x, 0); - return; - - case 'H': - /* If constant, output low-order six bits. Otherwise, - write normally. */ - if (INT_P (x)) - fprintf (file, "%d", INT_LOWPART (x) & 63); - else - print_operand (file, x, 0); - return; - - case 'I': - /* Print `i' if this is a constant, else nothing. */ - if (INT_P (x)) - putc ('i', file); - return; - - case 'j': - /* Write the bit number in CCR for jump. */ - i = ccr_bit (x, 0); - if (i == -1) - output_operand_lossage ("invalid %%j code"); - else - fprintf (file, "%d", i); - return; - - case 'J': - /* Similar, but add one for shift count in rlinm for scc and pass - scc flag to `ccr_bit'. */ - i = ccr_bit (x, 1); - if (i == -1) - output_operand_lossage ("invalid %%J code"); - else - /* If we want bit 31, write a shift count of zero, not 32. */ - fprintf (file, "%d", i == 31 ? 0 : i + 1); - return; - - case 'k': - /* X must be a constant. Write the 1's complement of the - constant. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%k value"); - - fprintf (file, "%d", ~ INT_LOWPART (x)); - return; - - case 'L': - /* Write second word of DImode or DFmode reference. Works on register - or non-indexed memory only. */ - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x) + 1]); - else if (GET_CODE (x) == MEM) - { - /* Handle possible auto-increment. Since it is pre-increment and - we have already done it, we can just use an offset of word. */ - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (XEXP (XEXP (x, 0), 0), - UNITS_PER_WORD)); - else - output_address (plus_constant (XEXP (x, 0), UNITS_PER_WORD)); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - case 'm': - /* MB value for a mask operand. */ - if (! mask_operand (x, VOIDmode)) - output_operand_lossage ("invalid %%m value"); - - val = INT_LOWPART (x); - - /* If the high bit is set and the low bit is not, the value is zero. - If the high bit is zero, the value is the first 1 bit we find from - the left. */ - if ((val & 0x80000000) && ((val & 1) == 0)) - { - putc ('0', file); - return; - } - else if ((val & 0x80000000) == 0) - { - for (i = 1; i < 32; i++) - if ((val <<= 1) & 0x80000000) - break; - fprintf (file, "%d", i); - return; - } - - /* Otherwise, look for the first 0 bit from the right. The result is its - number plus 1. We know the low-order bit is one. */ - for (i = 0; i < 32; i++) - if (((val >>= 1) & 1) == 0) - break; - - /* If we ended in ...01, i would be 0. The correct value is 31, so - we want 31 - i. */ - fprintf (file, "%d", 31 - i); - return; - - case 'M': - /* ME value for a mask operand. */ - if (! mask_operand (x, VOIDmode)) - output_operand_lossage ("invalid %%M value"); - - val = INT_LOWPART (x); - - /* If the low bit is set and the high bit is not, the value is 31. - If the low bit is zero, the value is the first 1 bit we find from - the right. */ - if ((val & 1) && ((val & 0x80000000) == 0)) - { - fputs ("31", file); - return; - } - else if ((val & 1) == 0) - { - for (i = 0; i < 32; i++) - if ((val >>= 1) & 1) - break; - - /* If we had ....10, i would be 0. The result should be - 30, so we need 30 - i. */ - fprintf (file, "%d", 30 - i); - return; - } - - /* Otherwise, look for the first 0 bit from the left. The result is its - number minus 1. We know the high-order bit is one. */ - for (i = 0; i < 32; i++) - if (((val <<= 1) & 0x80000000) == 0) - break; - - fprintf (file, "%d", i); - return; - - case 'N': - /* Write the number of elements in the vector times 4. */ - if (GET_CODE (x) != PARALLEL) - output_operand_lossage ("invalid %%N value"); - - fprintf (file, "%d", XVECLEN (x, 0) * 4); - return; - - case 'O': - /* Similar, but subtract 1 first. */ - if (GET_CODE (x) != PARALLEL) - output_operand_lossage ("invalid %%O value"); - - fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4); - return; - - case 'p': - /* X is a CONST_INT that is a power of two. Output the logarithm. */ - if (! INT_P (x) - || (i = exact_log2 (INT_LOWPART (x))) < 0) - output_operand_lossage ("invalid %%p value"); - - fprintf (file, "%d", i); - return; - - case 'P': - /* The operand must be an indirect memory reference. The result - is the register number. */ - if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG - || REGNO (XEXP (x, 0)) >= 32) - output_operand_lossage ("invalid %%P value"); - - fprintf (file, "%d", REGNO (XEXP (x, 0))); - return; - - /* CYGNUS LOCAL -- meissner/branch prediction */ - case 'q': - case 'Q': - /* Write -/+ depending on whether a branch is expected to succeed */ - succeed = (code == 'Q'); - if (x != const0_rtx) - succeed = !succeed; - - putc ((succeed) ? '+' : '-', file); - return; - /* END CYGNUS LOCAL -- meissner/branch prediction */ - - case 'R': - /* X is a CR register. Print the mask for `mtcrf'. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%R value"); - else - fprintf (file, "%d", 128 >> (REGNO (x) - 68)); - return; - - case 's': - /* Low 5 bits of 32 - value */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%s value"); - - fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31); - return; - - case 'S': - /* PowerPC64 mask position. All 0's and all 1's are excluded. - CONST_INT 32-bit mask is considered sign-extended so any - transition must occur within the CONST_INT, not on the boundary. */ - if (! mask64_operand (x, VOIDmode)) - output_operand_lossage ("invalid %%S value"); - - val = INT_LOWPART (x); - - if (val & 1) /* Clear Left */ - { - for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++) - if (!((val >>= 1) & 1)) - break; - -#if HOST_BITS_PER_WIDE_INT == 32 - if (GET_CODE (x) == CONST_DOUBLE && i == 32) - { - val = CONST_DOUBLE_HIGH (x); - - if (val == 0) - --i; - else - for (i = 32; i < 64; i++) - if (!((val >>= 1) & 1)) - break; - } -#endif - /* i = index of last set bit from right - mask begins at 63 - i from left */ - if (i > 63) - output_operand_lossage ("%%S computed all 1's mask"); - fprintf (file, "%d", 63 - i); - return; - } - else /* Clear Right */ - { - for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++) - if ((val >>= 1) & 1) - break; - -#if HOST_BITS_PER_WIDE_INT == 32 - if (GET_CODE (x) == CONST_DOUBLE && i == 32) - { - val = CONST_DOUBLE_HIGH (x); - - if (val == (HOST_WIDE_INT) -1) - --i; - else - for (i = 32; i < 64; i++) - if ((val >>= 1) & 1) - break; - } -#endif - /* i = index of last clear bit from right - mask ends at 62 - i from left */ - if (i > 62) - output_operand_lossage ("%%S computed all 0's mask"); - fprintf (file, "%d", 62 - i); - return; - } - - case 't': - /* Write 12 if this jump operation will branch if true, 4 otherwise. - All floating-point operations except NE branch true and integer - EQ, LT, GT, LTU and GTU also branch true. */ - if (GET_RTX_CLASS (GET_CODE (x)) != '<') - output_operand_lossage ("invalid %%t value"); - - else if ((GET_MODE (XEXP (x, 0)) == CCFPmode - && GET_CODE (x) != NE) - || GET_CODE (x) == EQ - || GET_CODE (x) == LT || GET_CODE (x) == GT - || GET_CODE (x) == LTU || GET_CODE (x) == GTU) - fputs ("12", file); - else - putc ('4', file); - return; - - case 'T': - /* Opposite of 't': write 4 if this jump operation will branch if true, - 12 otherwise. */ - if (GET_RTX_CLASS (GET_CODE (x)) != '<') - output_operand_lossage ("invalid %%T value"); - - else if ((GET_MODE (XEXP (x, 0)) == CCFPmode - && GET_CODE (x) != NE) - || GET_CODE (x) == EQ - || GET_CODE (x) == LT || GET_CODE (x) == GT - || GET_CODE (x) == LTU || GET_CODE (x) == GTU) - putc ('4', file); - else - fputs ("12", file); - return; - - case 'u': - /* High-order 16 bits of constant for use in unsigned operand. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%u value"); - - fprintf (file, "0x%x", (INT_LOWPART (x) >> 16) & 0xffff); - return; - - case 'v': - /* High-order 16 bits of constant for use in signed operand. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%v value"); - - { - int value = (INT_LOWPART (x) >> 16) & 0xffff; - - /* Solaris assembler doesn't like lis 0,0x80000 */ - if (DEFAULT_ABI == ABI_SOLARIS && (value & 0x8000) != 0) - fprintf (file, "%d", value | (~0 << 16)); - else - fprintf (file, "0x%x", value); - return; - } - - case 'U': - /* Print `u' if this has an auto-increment or auto-decrement. */ - if (GET_CODE (x) == MEM - && (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC)) - putc ('u', file); - return; - - case 'V': - /* Print the trap code for this operand. */ - switch (GET_CODE (x)) - { - case EQ: - fputs ("eq", file); /* 4 */ - break; - case NE: - fputs ("ne", file); /* 24 */ - break; - case LT: - fputs ("lt", file); /* 16 */ - break; - case LE: - fputs ("le", file); /* 20 */ - break; - case GT: - fputs ("gt", file); /* 8 */ - break; - case GE: - fputs ("ge", file); /* 12 */ - break; - case LTU: - fputs ("llt", file); /* 2 */ - break; - case LEU: - fputs ("lle", file); /* 6 */ - break; - case GTU: - fputs ("lgt", file); /* 1 */ - break; - case GEU: - fputs ("lge", file); /* 5 */ - break; - default: - abort (); - } - break; - - case 'w': - /* If constant, low-order 16 bits of constant, signed. Otherwise, write - normally. */ - if (INT_P (x)) - fprintf (file, "%d", - (INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000)); - else - print_operand (file, x, 0); - return; - - case 'W': - /* If constant, low-order 16 bits of constant, unsigned. - Otherwise, write normally. */ - if (INT_P (x)) - fprintf (file, "%d", INT_LOWPART (x) & 0xffff); - else - print_operand (file, x, 0); - return; - - case 'X': - if (GET_CODE (x) == MEM - && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0))) - putc ('x', file); - return; - - case 'Y': - /* Like 'L', for third word of TImode */ - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x) + 2]); - else if (GET_CODE (x) == MEM) - { - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8)); - else - output_address (plus_constant (XEXP (x, 0), 8)); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - case 'z': - /* X is a SYMBOL_REF. Write out the name preceded by a - period and without any trailing data in brackets. Used for function - names. If we are configured for System V (or the embedded ABI) on - the PowerPC, do not emit the period, since those systems do not use - TOCs and the like. */ - if (GET_CODE (x) != SYMBOL_REF) - abort (); - - if (XSTR (x, 0)[0] != '.') - { - switch (DEFAULT_ABI) - { - default: - abort (); - - case ABI_AIX: - putc ('.', file); - break; - - case ABI_V4: - case ABI_AIX_NODESC: - case ABI_SOLARIS: - break; - - case ABI_NT: - fputs ("..", file); - break; - } - } - RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); - return; - - case 'Z': - /* Like 'L', for last word of TImode. */ - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x) + 3]); - else if (GET_CODE (x) == MEM) - { - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12)); - else - output_address (plus_constant (XEXP (x, 0), 12)); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - case 0: - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (GET_CODE (x) == MEM) - { - /* We need to handle PRE_INC and PRE_DEC here, since we need to - know the width from the mode. */ - if (GET_CODE (XEXP (x, 0)) == PRE_INC) - fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)), - REGNO (XEXP (XEXP (x, 0), 0))); - else if (GET_CODE (XEXP (x, 0)) == PRE_DEC) - fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)), - REGNO (XEXP (XEXP (x, 0), 0))); - else - output_address (XEXP (x, 0)); - } - else - output_addr_const (file, x); - return; - - default: - output_operand_lossage ("invalid %%xn code"); - } -} - -/* Print the address of an operand. */ - -void -print_operand_address (file, x) - FILE *file; - register rtx x; -{ - if (GET_CODE (x) == REG) - fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); - else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST || GET_CODE (x) == LABEL_REF) - { - output_addr_const (file, x); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - -#ifdef TARGET_NO_TOC - else if (TARGET_NO_TOC) - ; -#endif - else - fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]); - } - else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) - { - if (REGNO (XEXP (x, 0)) == 0) - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ], - reg_names[ REGNO (XEXP (x, 0)) ]); - else - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ], - reg_names[ REGNO (XEXP (x, 1)) ]); - } - else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) - fprintf (file, "%d(%s)", INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]); - else if (TARGET_ELF && !TARGET_64BIT && GET_CODE (x) == LO_SUM - && GET_CODE (XEXP (x, 0)) == REG && CONSTANT_P (XEXP (x, 1))) - { - output_addr_const (file, XEXP (x, 1)); - fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); - } - else - abort (); -} - -/* This page contains routines that are used to determine what the function - prologue and epilogue code will do and write them out. */ - -/* Return the first fixed-point register that is required to be saved. 32 if - none. */ - -int -first_reg_to_save () -{ - int first_reg; - - /* Find lowest numbered live register. */ - for (first_reg = 13; first_reg <= 31; first_reg++) - if (regs_ever_live[first_reg]) - break; - - /* If profiling, then we must save/restore every register that contains - a parameter before/after the .__mcount call. Use registers from 30 down - to 23 to do this. Don't use the frame pointer in reg 31. - - For now, save enough room for all of the parameter registers. */ - if (DEFAULT_ABI == ABI_AIX && profile_flag) - if (first_reg > 23) - first_reg = 23; - - return first_reg; -} - -/* Similar, for FP regs. */ - -int -first_fp_reg_to_save () -{ - int first_reg; - - /* Find lowest numbered live register. */ - for (first_reg = 14 + 32; first_reg <= 63; first_reg++) - if (regs_ever_live[first_reg]) - break; - - return first_reg; -} - -/* Return non-zero if this function makes calls. */ - -int -rs6000_makes_calls () -{ - rtx insn; - - /* If we are profiling, we will be making a call to __mcount. - Under the System V ABI's, we store the LR directly, so - we don't need to do it here. */ - if (DEFAULT_ABI == ABI_AIX && profile_flag) - return 1; - - for (insn = get_insns (); insn; insn = next_insn (insn)) - if (GET_CODE (insn) == CALL_INSN) - return 1; - - return 0; -} - - -/* Calculate the stack information for the current function. This is - complicated by having two separate calling sequences, the AIX calling - sequence and the V.4 calling sequence. - - AIX stack frames look like: - 32-bit 64-bit - SP----> +---------------------------------------+ - | back chain to caller | 0 0 - +---------------------------------------+ - | saved CR | 4 8 (8-11) - +---------------------------------------+ - | saved LR | 8 16 - +---------------------------------------+ - | reserved for compilers | 12 24 - +---------------------------------------+ - | reserved for binders | 16 32 - +---------------------------------------+ - | saved TOC pointer | 20 40 - +---------------------------------------+ - | Parameter save area (P) | 24 48 - +---------------------------------------+ - | Alloca space (A) | 24+P etc. - +---------------------------------------+ - | Local variable space (L) | 24+P+A - +---------------------------------------+ - | Float/int conversion temporary (X) | 24+P+A+L - +---------------------------------------+ - | Save area for GP registers (G) | 24+P+A+X+L - +---------------------------------------+ - | Save area for FP registers (F) | 24+P+A+X+L+G - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - The required alignment for AIX configurations is two words (i.e., 8 - or 16 bytes). - - - V.4 stack frames look like: - - SP----> +---------------------------------------+ - | back chain to caller | 0 - +---------------------------------------+ - | caller's saved LR | 4 - +---------------------------------------+ - | Parameter save area (P) | 8 - +---------------------------------------+ - | Alloca space (A) | 8+P - +---------------------------------------+ - | Varargs save area (V) | 8+P+A - +---------------------------------------+ - | Local variable space (L) | 8+P+A+V - +---------------------------------------+ - | Float/int conversion temporary (X) | 8+P+A+V+L - +---------------------------------------+ - | saved CR (C) | 8+P+A+V+L+X - +---------------------------------------+ - | Save area for GP registers (G) | 8+P+A+V+L+X+C - +---------------------------------------+ - | Save area for FP registers (F) | 8+P+A+V+L+X+C+G - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is - given. (But note below and in sysv4.h that we require only 8 and - may round up the size of our stack frame anyways. The historical - reason is early versions of powerpc-linux which didn't properly - align the stack at program startup. A happy side-effect is that - -mno-eabi libraries can be used with -meabi programs.) - - - A PowerPC Windows/NT frame looks like: - - SP----> +---------------------------------------+ - | back chain to caller | 0 - +---------------------------------------+ - | reserved | 4 - +---------------------------------------+ - | reserved | 8 - +---------------------------------------+ - | reserved | 12 - +---------------------------------------+ - | reserved | 16 - +---------------------------------------+ - | reserved | 20 - +---------------------------------------+ - | Parameter save area (P) | 24 - +---------------------------------------+ - | Alloca space (A) | 24+P - +---------------------------------------+ - | Local variable space (L) | 24+P+A - +---------------------------------------+ - | Float/int conversion temporary (X) | 24+P+A+L - +---------------------------------------+ - | Save area for FP registers (F) | 24+P+A+L+X - +---------------------------------------+ - | Possible alignment area (Y) | 24+P+A+L+X+F - +---------------------------------------+ - | Save area for GP registers (G) | 24+P+A+L+X+F+Y - +---------------------------------------+ - | Save area for CR (C) | 24+P+A+L+X+F+Y+G - +---------------------------------------+ - | Save area for TOC (T) | 24+P+A+L+X+F+Y+G+C - +---------------------------------------+ - | Save area for LR (R) | 24+P+A+L+X+F+Y+G+C+T - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - For NT, there is no specific order to save the registers, but in - order to support __builtin_return_address, the save area for the - link register needs to be in a known place, so we use -4 off of the - old SP. To support calls through pointers, we also allocate a - fixed slot to store the TOC, -8 off the old SP. - - The required alignment for NT is 16 bytes. - - - The EABI configuration defaults to the V.4 layout, unless - -mcall-aix is used, in which case the AIX layout is used. However, - the stack alignment requirements may differ. If -mno-eabi is not - given, the required stack alignment is 8 bytes; if -mno-eabi is - given, the required alignment is 16 bytes. (But see V.4 comment - above.) */ - -#ifndef ABI_STACK_BOUNDARY -#define ABI_STACK_BOUNDARY STACK_BOUNDARY -#endif - -rs6000_stack_t * -rs6000_stack_info () -{ - static rs6000_stack_t info, zero_info; - rs6000_stack_t *info_ptr = &info; - int reg_size = TARGET_32BIT ? 4 : 8; - enum rs6000_abi abi; - int total_raw_size; - - /* Zero all fields portably */ - info = zero_info; - - /* Select which calling sequence */ - info_ptr->abi = abi = DEFAULT_ABI; - - /* Calculate which registers need to be saved & save area size */ - info_ptr->first_gp_reg_save = first_reg_to_save (); - info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save); - - info_ptr->first_fp_reg_save = first_fp_reg_to_save (); - info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); - - /* Does this function call anything? */ - info_ptr->calls_p = rs6000_makes_calls (); - - /* Allocate space to save the toc. */ - if (abi == ABI_NT && info_ptr->calls_p) - { - info_ptr->toc_save_p = 1; - info_ptr->toc_size = reg_size; - } - - /* Does this machine need the float/int conversion area? */ - info_ptr->fpmem_p = regs_ever_live[FPMEM_REGNUM]; - - /* If this is main and we need to call a function to set things up, - save main's arguments around the call. */ -#ifdef TARGET_EABI - if (TARGET_EABI) -#endif - { - if (strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), "main") == 0 - && DECL_CONTEXT (current_function_decl) == NULL_TREE) - { - info_ptr->main_p = 1; - -#ifdef NAME__MAIN - info_ptr->calls_p = 1; - - if (DECL_ARGUMENTS (current_function_decl)) - { - int i; - tree arg; - - info_ptr->main_save_p = 1; - info_ptr->main_size = 0; - - for ((i = 0), (arg = DECL_ARGUMENTS (current_function_decl)); - arg != NULL_TREE && i < 8; - (arg = TREE_CHAIN (arg)), i++) - { - info_ptr->main_size += reg_size; - } - } -#endif - } - } - - /* Determine if we need to save the link register */ - if (regs_ever_live[65] - || (DEFAULT_ABI == ABI_AIX && profile_flag) -#ifdef TARGET_RELOCATABLE - || (TARGET_RELOCATABLE && (get_pool_size () != 0)) -#endif - || (info_ptr->first_fp_reg_save != 64 - && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save)) - || (abi == ABI_V4 && current_function_calls_alloca) - || (abi == ABI_SOLARIS && current_function_calls_alloca) - || info_ptr->calls_p) - { - info_ptr->lr_save_p = 1; - regs_ever_live[65] = 1; - if (abi == ABI_NT) - info_ptr->lr_size = reg_size; - } - - /* Determine if we need to save the condition code registers */ - if (regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72]) - { - info_ptr->cr_save_p = 1; - if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS) - info_ptr->cr_size = reg_size; - } - - /* Determine various sizes */ - info_ptr->reg_size = reg_size; - info_ptr->fixed_size = RS6000_SAVE_AREA; - info_ptr->varargs_size = RS6000_VARARGS_AREA; - info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8); - info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size, 8); - info_ptr->fpmem_size = (info_ptr->fpmem_p) ? 8 : 0; - info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size - + info_ptr->gp_size - + info_ptr->cr_size - + info_ptr->lr_size - + info_ptr->toc_size - + info_ptr->main_size, 8); - - /* Calculate the offsets */ - switch (abi) - { - case ABI_NONE: - default: - abort (); - - case ABI_AIX: - case ABI_AIX_NODESC: - info_ptr->fp_save_offset = - info_ptr->fp_size; - info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; - info_ptr->main_save_offset = info_ptr->gp_save_offset - info_ptr->main_size; - info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */ - info_ptr->lr_save_offset = 2*reg_size; - break; - - case ABI_V4: - case ABI_SOLARIS: - info_ptr->fp_save_offset = - info_ptr->fp_size; - info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; - info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size; - info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size; - info_ptr->main_save_offset = info_ptr->toc_save_offset - info_ptr->main_size; - info_ptr->lr_save_offset = reg_size; - break; - - case ABI_NT: - info_ptr->lr_save_offset = -reg_size; - info_ptr->toc_save_offset = info_ptr->lr_save_offset - info_ptr->lr_size; - info_ptr->cr_save_offset = info_ptr->toc_save_offset - info_ptr->toc_size; - info_ptr->gp_save_offset = info_ptr->cr_save_offset - info_ptr->cr_size - info_ptr->gp_size + reg_size; - info_ptr->fp_save_offset = info_ptr->gp_save_offset - info_ptr->fp_size; - if (info_ptr->fp_size && ((- info_ptr->fp_save_offset) % 8) != 0) - info_ptr->fp_save_offset -= reg_size; - - info_ptr->main_save_offset = info_ptr->fp_save_offset - info_ptr->main_size; - break; - } - - /* Ensure that fpmem_offset will be aligned to an 8-byte boundary. */ - if (info_ptr->fpmem_p - && (info_ptr->main_save_offset - info_ptr->fpmem_size) % 8) - info_ptr->fpmem_size += reg_size; - - total_raw_size = (info_ptr->vars_size - + info_ptr->parm_size - + info_ptr->fpmem_size - + info_ptr->save_size - + info_ptr->varargs_size - + info_ptr->fixed_size); - - info_ptr->total_size = RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT); - - /* Determine if we need to allocate any stack frame: - - For AIX we need to push the stack if a frame pointer is needed (because - the stack might be dynamically adjusted), if we are debugging, if we - make calls, or if the sum of fp_save, gp_save, fpmem, and local variables - are more than the space needed to save all non-volatile registers: - 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 + 19*8 = 296 - - For V.4 we don't have the stack cushion that AIX uses, but assume that - the debugger can handle stackless frames. */ - - if (info_ptr->calls_p) - info_ptr->push_p = 1; - - else if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS) - info_ptr->push_p = (total_raw_size > info_ptr->fixed_size - || (abi == ABI_NT ? info_ptr->lr_save_p - : info_ptr->calls_p)); - - else - info_ptr->push_p = (frame_pointer_needed - || write_symbols != NO_DEBUG - || ((total_raw_size - info_ptr->fixed_size) - > (TARGET_32BIT ? 220 : 296))); - - if (info_ptr->fpmem_p) - { - info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size; - rs6000_fpmem_size = info_ptr->fpmem_size; - rs6000_fpmem_offset = (info_ptr->push_p - ? info_ptr->total_size + info_ptr->fpmem_offset - : info_ptr->fpmem_offset); - } - else - info_ptr->fpmem_offset = 0; - - /* Zero offsets if we're not saving those registers */ - if (info_ptr->fp_size == 0) - info_ptr->fp_save_offset = 0; - - if (info_ptr->gp_size == 0) - info_ptr->gp_save_offset = 0; - - if (!info_ptr->lr_save_p) - info_ptr->lr_save_offset = 0; - - if (!info_ptr->cr_save_p) - info_ptr->cr_save_offset = 0; - - if (!info_ptr->toc_save_p) - info_ptr->toc_save_offset = 0; - - if (!info_ptr->main_save_p) - info_ptr->main_save_offset = 0; - - return info_ptr; -} - -void -debug_stack_info (info) - rs6000_stack_t *info; -{ - char *abi_string; - - if (!info) - info = rs6000_stack_info (); - - fprintf (stderr, "\nStack information for function %s:\n", - ((current_function_decl && DECL_NAME (current_function_decl)) - ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl)) - : "<unknown>")); - - switch (info->abi) - { - default: abi_string = "Unknown"; break; - case ABI_NONE: abi_string = "NONE"; break; - case ABI_AIX: abi_string = "AIX"; break; - case ABI_AIX_NODESC: abi_string = "AIX"; break; - case ABI_V4: abi_string = "V.4"; break; - case ABI_SOLARIS: abi_string = "Solaris"; break; - case ABI_NT: abi_string = "NT"; break; - } - - fprintf (stderr, "\tABI = %5s\n", abi_string); - - if (info->first_gp_reg_save != 32) - fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save); - - if (info->first_fp_reg_save != 64) - fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save); - - if (info->lr_save_p) - fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p); - - if (info->cr_save_p) - fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p); - - if (info->toc_save_p) - fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p); - - if (info->push_p) - fprintf (stderr, "\tpush_p = %5d\n", info->push_p); - - if (info->calls_p) - fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p); - - if (info->main_p) - fprintf (stderr, "\tmain_p = %5d\n", info->main_p); - - if (info->main_save_p) - fprintf (stderr, "\tmain_save_p = %5d\n", info->main_save_p); - - if (info->fpmem_p) - fprintf (stderr, "\tfpmem_p = %5d\n", info->fpmem_p); - - if (info->gp_save_offset) - fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset); - - if (info->fp_save_offset) - fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset); - - if (info->lr_save_offset) - fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset); - - if (info->cr_save_offset) - fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset); - - if (info->toc_save_offset) - fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset); - - if (info->varargs_save_offset) - fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset); - - if (info->main_save_offset) - fprintf (stderr, "\tmain_save_offset = %5d\n", info->main_save_offset); - - if (info->fpmem_offset) - fprintf (stderr, "\tfpmem_offset = %5d\n", info->fpmem_offset); - - if (info->total_size) - fprintf (stderr, "\ttotal_size = %5d\n", info->total_size); - - if (info->varargs_size) - fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size); - - if (info->vars_size) - fprintf (stderr, "\tvars_size = %5d\n", info->vars_size); - - if (info->parm_size) - fprintf (stderr, "\tparm_size = %5d\n", info->parm_size); - - if (info->fpmem_size) - fprintf (stderr, "\tfpmem_size = %5d\n", info->fpmem_size); - - if (info->fixed_size) - fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size); - - if (info->gp_size) - fprintf (stderr, "\tgp_size = %5d\n", info->gp_size); - - if (info->fp_size) - fprintf (stderr, "\tfp_size = %5d\n", info->fp_size); - - if (info->lr_size) - fprintf (stderr, "\tlr_size = %5d\n", info->cr_size); - - if (info->cr_size) - fprintf (stderr, "\tcr_size = %5d\n", info->cr_size); - - if (info->toc_size) - fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size); - - if (info->main_size) - fprintf (stderr, "\tmain_size = %5d\n", info->main_size); - - if (info->save_size) - fprintf (stderr, "\tsave_size = %5d\n", info->save_size); - - if (info->reg_size != 4) - fprintf (stderr, "\treg_size = %5d\n", info->reg_size); - - fprintf (stderr, "\n"); -} - - -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ -#if 0 -/* END CYGNUS LOCAL */ - -/* Write out an instruction to load the TOC_TABLE address into register 30. - This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is - a constant pool. */ - -void -rs6000_output_load_toc_table (file, reg) - FILE *file; - int reg; -{ - char buf[256]; - -#ifdef USING_SVR4_H - if (TARGET_RELOCATABLE) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "\tbl "); - assemble_name (file, buf); - fprintf (file, "\n"); - - /* possibly create the toc section */ - if (!toc_initialized) - { - toc_section (); - function_section (current_function_decl); - } - - /* If not first call in this function, we need to put the - different between .LCTOC1 and the address we get to right - after the bl. It will mess up disassembling the instructions - but that can't be helped. We will later need to bias the - address before loading. */ - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - { - char *init_ptr = TARGET_32BIT ? ".long" : ".quad"; - char *buf_ptr; - - ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno); - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - STRIP_NAME_ENCODING (buf_ptr, buf); - fprintf (file, "\t%s %s-", init_ptr, buf_ptr); - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "%s\n", buf_ptr); - } - - ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno); - fprintf (file, "\tmflr %s\n", reg_names[reg]); - - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - asm_fprintf(file, "\t{cal|la} %s,%d(%s)\n", reg_names[reg], - (TARGET_32BIT ? 4 : 8), reg_names[reg]); - - asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s,(" : "\tld %s,(", - reg_names[0]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); - assemble_name (file, buf); - fputs ("-", file); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - assemble_name (file, buf); - fprintf (file, ")(%s)\n", reg_names[reg]); - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", - reg_names[reg], reg_names[0], reg_names[reg]); - rs6000_pic_labelno++; - } - else if (!TARGET_64BIT) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - asm_fprintf (file, "\t{liu|lis} %s,", reg_names[reg]); - assemble_name (file, buf); - fputs ("@ha\n", file); - asm_fprintf (file, "\t{cal|la} %s,", reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "@l(%s)\n", reg_names[reg]); - } - else - abort (); - -#else /* !USING_SVR4_H */ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0); - asm_fprintf (file, TARGET_32BIT ? "\t{l|lwz} %s," : "\tld %s,", - reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", reg_names[2]); -#endif /* USING_SVR4_H */ -} - - -/* Emit the correct code for allocating stack space. If COPY_R12, make sure a copy - of the old frame is left in r12. */ - -void -rs6000_allocate_stack_space (file, size, copy_r12) - FILE *file; - int size; - int copy_r12; -{ - int neg_size = -size; - if (TARGET_UPDATE) - { - if (size < 32767) - asm_fprintf (file, - (TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); - else - { - if (copy_r12) - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - - asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, - (TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n", - reg_names[1], reg_names[1], reg_names[0]); - } - } - else - { - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - if (size < 32767) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); - else - { - asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", reg_names[1], - reg_names[0], reg_names[1]); - } - - asm_fprintf (file, - (TARGET_32BIT) ? "\t{st|stw} %s,0(%s)\n" : "\tstd %s,0(%s)\n", - reg_names[12], reg_names[1]); - } -} - - -/* Write function prologue. */ -void -output_prolog (file, size) - FILE *file; - int size ATTRIBUTE_UNUSED; -{ - rs6000_stack_t *info = rs6000_stack_info (); - int reg_size = info->reg_size; - char *store_reg; - char *load_reg; - int sp_reg = 1; - int sp_offset = 0; - - if (TARGET_32BIT) - { - store_reg = "\t{st|stw} %s,%d(%s)\n"; - load_reg = "\t{l|lwz} %s,%d(%s)\n"; - } - else - { - store_reg = "\tstd %s,%d(%s)\n"; - load_reg = "\tlld %s,%d(%s)\n"; - } - - if (TARGET_DEBUG_STACK) - debug_stack_info (info); - - /* Write .extern for any function we will call to save and restore fp - values. */ - if (info->first_fp_reg_save < 64 && !FP_SAVE_INLINE (info->first_fp_reg_save)) - fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n", - SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX, - RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - - /* Write .extern for truncation routines, if needed. */ - if (rs6000_trunc_used && ! trunc_defined) - { - fprintf (file, "\t.extern .%s\n\t.extern .%s\n", - RS6000_ITRUNC, RS6000_UITRUNC); - trunc_defined = 1; - } - - /* Write .extern for AIX common mode routines, if needed. */ - if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined) - { - fputs ("\t.extern __mulh\n", file); - fputs ("\t.extern __mull\n", file); - fputs ("\t.extern __divss\n", file); - fputs ("\t.extern __divus\n", file); - fputs ("\t.extern __quoss\n", file); - fputs ("\t.extern __quous\n", file); - common_mode_defined = 1; - } - - /* For V.4, update stack before we do any saving and set back pointer. */ - if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - { - if (info->total_size < 32767) - sp_offset = info->total_size; - else - sp_reg = 12; - rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12); - } - - /* If we use the link register, get it into r0. */ - if (info->lr_save_p) - asm_fprintf (file, "\tmflr %s\n", reg_names[0]); - - /* If we need to save CR, put it into r12. */ - if (info->cr_save_p && sp_reg != 12) - asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); - - /* Do any required saving of fpr's. If only one or two to save, do it - ourself. Otherwise, call function. Note that since they are statically - linked, we do not need a nop following them. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) - { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; - - for ( ; regno < 64; regno++, loc += 8) - asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); - } - else if (info->first_fp_reg_save != 64) - asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, - info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); - - /* Now save gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) - { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - - for ( ; regno < 32; regno++, loc += reg_size) - asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]); - } - - else if (info->first_gp_reg_save != 32) - asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Save main's arguments if we need to call a function */ -#ifdef NAME__MAIN - if (info->main_save_p) - { - int regno; - int loc = info->main_save_offset + sp_offset; - int size = info->main_size; - - for (regno = 3; size > 0; regno++, loc += reg_size, size -= reg_size) - asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]); - } -#endif - - /* Save lr if we used it. */ - if (info->lr_save_p) - asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Save CR if we use any that must be preserved. */ - if (info->cr_save_p) - { - if (sp_reg == 12) /* If r12 is used to hold the original sp, copy cr now */ - { - asm_fprintf (file, "\tmfcr %s\n", reg_names[0]); - asm_fprintf (file, store_reg, reg_names[0], - info->cr_save_offset + sp_offset, - reg_names[sp_reg]); - } - else - asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset, - reg_names[sp_reg]); - } - - /* NT needs us to probe the stack frame every 4k pages for large frames, so - do it here. */ - if (DEFAULT_ABI == ABI_NT && info->total_size > 4096) - { - if (info->total_size < 32768) - { - int probe_offset = 4096; - while (probe_offset < info->total_size) - { - asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", reg_names[0], -probe_offset, reg_names[1]); - probe_offset += 4096; - } - } - else - { - int probe_iterations = info->total_size / 4096; - static int probe_labelno = 0; - char buf[256]; - - if (probe_iterations < 32768) - asm_fprintf (file, "\tli %s,%d\n", reg_names[12], probe_iterations); - else - { - asm_fprintf (file, "\tlis %s,%d\n", reg_names[12], probe_iterations >> 16); - if (probe_iterations & 0xffff) - asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], reg_names[12], - probe_iterations & 0xffff); - } - asm_fprintf (file, "\tmtctr %s\n", reg_names[12]); - asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno); - asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", reg_names[0], reg_names[12]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno++); - fputs ("\tbdnz ", file); - assemble_name (file, buf); - fputs ("\n", file); - } - } - - /* Update stack and set back pointer unless this is V.4, which was done previously */ - if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - rs6000_allocate_stack_space (file, info->total_size, FALSE); - - /* Set frame pointer, if needed. */ - if (frame_pointer_needed) - asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]); - -#ifdef NAME__MAIN - /* If we need to call a function to set things up for main, do so now - before dealing with the TOC. */ - if (info->main_p) - { - char *prefix = ""; - - switch (DEFAULT_ABI) - { - case ABI_AIX: prefix = "."; break; - case ABI_NT: prefix = ".."; break; - } - - fprintf (file, "\tbl %s%s\n", prefix, NAME__MAIN); -#ifdef RS6000_CALL_GLUE2 - fprintf (file, "\t%s%s%s\n", RS6000_CALL_GLUE2, prefix, NAME_MAIN); -#else -#ifdef RS6000_CALL_GLUE - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - fprintf (file, "\t%s\n", RS6000_CALL_GLUE); -#endif -#endif - - if (info->main_save_p) - { - int regno; - int loc; - int size = info->main_size; - - if (info->total_size < 32767) - { - loc = info->total_size + info->main_save_offset; - for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]); - } - else - { - int neg_size = info->main_save_offset - info->total_size; - loc = 0; - asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - - asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", reg_names[0], reg_names[0], - reg_names[1]); - - for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[0]); - } - } - } -#endif - - - /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the - TOC_TABLE address into register 30. */ - if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) - { -#ifdef USING_SVR4_H - if (!profile_flag) - rs6000_pic_func_labelno = rs6000_pic_labelno; -#endif - rs6000_output_load_toc_table (file, 30); - } - - if (DEFAULT_ABI == ABI_NT) - { - assemble_name (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".b:\n", file); - } -} - -/* Write function epilogue. */ - -void -output_epilog (file, size) - FILE *file; - int size ATTRIBUTE_UNUSED; -{ - rs6000_stack_t *info = rs6000_stack_info (); - char *load_reg = (TARGET_32BIT) ? "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n"; - rtx insn = get_last_insn (); - int sp_reg = 1; - int sp_offset = 0; - - /* If the last insn was a BARRIER, we don't have to write anything except - the trace table. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn == 0 || GET_CODE (insn) != BARRIER) - { - /* If we have a frame pointer, a call to alloca, or a large stack - frame, restore the old stack pointer using the backchain. Otherwise, - we know what size to update it with. */ - if (frame_pointer_needed || current_function_calls_alloca - || info->total_size > 32767) - { - /* Under V.4, don't reset the stack pointer until after we're done - loading the saved registers. */ - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - sp_reg = 11; - - asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]); - } - else if (info->push_p) - { - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - sp_offset = info->total_size; - else - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], info->total_size, reg_names[1]); - } - - /* Get the old lr if we saved it. */ - if (info->lr_save_p) - asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]); - - /* Get the old cr if we saved it. */ - if (info->cr_save_p) - asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]); - - /* Set LR here to try to overlap restores below. */ - if (info->lr_save_p) - asm_fprintf (file, "\tmtlr %s\n", reg_names[0]); - - /* Restore gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) - { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - int reg_size = (TARGET_32BIT) ? 4 : 8; - - for ( ; regno < 32; regno++, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]); - } - - else if (info->first_gp_reg_save != 32) - asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Restore fpr's if we can do it without calling a function. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) - { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; - - for ( ; regno < 64; regno++, loc += 8) - asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); - } - - /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 - that were used. */ - if (info->cr_save_p) - asm_fprintf (file, "\tmtcrf %d,%s\n", - (regs_ever_live[70] != 0) * 0x20 - + (regs_ever_live[71] != 0) * 0x10 - + (regs_ever_live[72] != 0) * 0x8, reg_names[12]); - - /* If this is V.4, unwind the stack pointer after all of the loads - have been done */ - if (sp_offset != 0) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], sp_offset, reg_names[1]); - else if (sp_reg != 1) - asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]); - - /* If we have to restore more than two FP registers, branch to the - restore function. It will return to our caller. */ - if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save)) - asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX, - info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - else - asm_fprintf (file, "\t{br|blr}\n"); - } - - /* Output a traceback table here. See /usr/include/sys/debug.h for info - on its format. - - We don't output a traceback table if -finhibit-size-directive was - used. The documentation for -finhibit-size-directive reads - ``don't output a @code{.size} assembler directive, or anything - else that would cause trouble if the function is split in the - middle, and the two halves are placed at locations far apart in - memory.'' The traceback table has this property, since it - includes the offset from the start of the function to the - traceback table itself. - - System V.4 Powerpc's (and the embedded ABI derived from it) use a - different traceback table. */ - if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive) - { - char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); - int fixed_parms, float_parms, parm_info; - int i; - - while (*fname == '.') /* V.4 encodes . in the name */ - fname++; - - /* Need label immediately before tbtab, so we can compute its offset - from the function start. */ - if (*fname == '*') - ++fname; - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - ASM_OUTPUT_LABEL (file, fname); - - /* The .tbtab pseudo-op can only be used for the first eight - expressions, since it can't handle the possibly variable - length fields that follow. However, if you omit the optional - fields, the assembler outputs zeros for all optional fields - anyways, giving each variable length field is minimum length - (as defined in sys/debug.h). Thus we can not use the .tbtab - pseudo-op at all. */ - - /* An all-zero word flags the start of the tbtab, for debuggers - that have to find it by searching forward from the entry - point or from the current pc. */ - fputs ("\t.long 0\n", file); - - /* Tbtab format type. Use format type 0. */ - fputs ("\t.byte 0,", file); - - /* Language type. Unfortunately, there doesn't seem to be any - official way to get this info, so we use language_string. C - is 0. C++ is 9. No number defined for Obj-C, so use the - value for C for now. There is no official value for Java, - although IBM appears to be using 13. There is no official value - for Chill, so we've choosen 44 pseudo-randomly. */ - if (! strcmp (language_string, "GNU C") - || ! strcmp (language_string, "GNU Obj-C")) - i = 0; - else if (! strcmp (language_string, "GNU F77")) - i = 1; - else if (! strcmp (language_string, "GNU Ada")) - i = 3; - else if (! strcmp (language_string, "GNU Pascal")) - i = 2; - else if (! strcmp (language_string, "GNU C++")) - i = 9; - else if (! strcmp (language_string, "GNU Java")) - i = 13; - else if (! strcmp (language_string, "GNU CHILL")) - i = 44; - else - abort (); - fprintf (file, "%d,", i); - - /* 8 single bit fields: global linkage (not set for C extern linkage, - apparently a PL/I convention?), out-of-line epilogue/prologue, offset - from start of procedure stored in tbtab, internal function, function - has controlled storage, function has no toc, function uses fp, - function logs/aborts fp operations. */ - /* Assume that fp operations are used if any fp reg must be saved. */ - fprintf (file, "%d,", (1 << 5) | ((info->first_fp_reg_save != 64) << 1)); - - /* 6 bitfields: function is interrupt handler, name present in - proc table, function calls alloca, on condition directives - (controls stack walks, 3 bits), saves condition reg, saves - link reg. */ - /* The `function calls alloca' bit seems to be set whenever reg 31 is - set up as a frame pointer, even when there is no alloca call. */ - fprintf (file, "%d,", - ((1 << 6) | (frame_pointer_needed << 5) - | (info->cr_save_p << 1) | (info->lr_save_p))); - - /* 3 bitfields: saves backchain, spare bit, number of fpr saved - (6 bits). */ - fprintf (file, "%d,", - (info->push_p << 7) | (64 - info->first_fp_reg_save)); - - /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */ - fprintf (file, "%d,", (32 - first_reg_to_save ())); - - { - /* Compute the parameter info from the function decl argument - list. */ - tree decl; - int next_parm_info_bit; - - next_parm_info_bit = 31; - parm_info = 0; - fixed_parms = 0; - float_parms = 0; - - for (decl = DECL_ARGUMENTS (current_function_decl); - decl; decl = TREE_CHAIN (decl)) - { - rtx parameter = DECL_INCOMING_RTL (decl); - enum machine_mode mode = GET_MODE (parameter); - - if (GET_CODE (parameter) == REG) - { - if (GET_MODE_CLASS (mode) == MODE_FLOAT) - { - int bits; - - float_parms++; - - if (mode == SFmode) - bits = 0x2; - else if (mode == DFmode) - bits = 0x3; - else - abort (); - - /* If only one bit will fit, don't or in this entry. */ - if (next_parm_info_bit > 0) - parm_info |= (bits << (next_parm_info_bit - 1)); - next_parm_info_bit -= 2; - } - else - { - fixed_parms += ((GET_MODE_SIZE (mode) - + (UNITS_PER_WORD - 1)) - / UNITS_PER_WORD); - next_parm_info_bit -= 1; - } - } - } - } - - /* Number of fixed point parameters. */ - /* This is actually the number of words of fixed point parameters; thus - an 8 byte struct counts as 2; and thus the maximum value is 8. */ - fprintf (file, "%d,", fixed_parms); - - /* 2 bitfields: number of floating point parameters (7 bits), parameters - all on stack. */ - /* This is actually the number of fp registers that hold parameters; - and thus the maximum value is 13. */ - /* Set parameters on stack bit if parameters are not in their original - registers, regardless of whether they are on the stack? Xlc - seems to set the bit when not optimizing. */ - fprintf (file, "%d\n", ((float_parms << 1) | (! optimize))); - - /* Optional fields follow. Some are variable length. */ - - /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float, - 11 double float. */ - /* There is an entry for each parameter in a register, in the order that - they occur in the parameter list. Any intervening arguments on the - stack are ignored. If the list overflows a long (max possible length - 34 bits) then completely leave off all elements that don't fit. */ - /* Only emit this long if there was at least one parameter. */ - if (fixed_parms || float_parms) - fprintf (file, "\t.long %d\n", parm_info); - - /* Offset from start of code to tb table. */ - fputs ("\t.long ", file); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - RS6000_OUTPUT_BASENAME (file, fname); - fputs ("-.", file); - RS6000_OUTPUT_BASENAME (file, fname); - putc ('\n', file); - - /* Interrupt handler mask. */ - /* Omit this long, since we never set the interrupt handler bit - above. */ - - /* Number of CTL (controlled storage) anchors. */ - /* Omit this long, since the has_ctl bit is never set above. */ - - /* Displacement into stack of each CTL anchor. */ - /* Omit this list of longs, because there are no CTL anchors. */ - - /* Length of function name. */ - fprintf (file, "\t.short %d\n", (int) strlen (fname)); - - /* Function name. */ - assemble_string (fname, strlen (fname)); - - /* Register for alloca automatic storage; this is always reg 31. - Only emit this if the alloca bit was set above. */ - if (frame_pointer_needed) - fputs ("\t.byte 31\n", file); - } - - if (DEFAULT_ABI == ABI_NT) - { - RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".e:\nFE_MOT_RESVD..", file); - RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (":\n", file); - } -} - -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ -#endif - -/* This part (from CYGNUS LOCAL to CYGNUS local) contains code needed - for scheduling of prologue and epilogue. The part is based on the - analogous functions above. Now it works only for EABI. The code - contains new code for RTL generation and old code for assembler - output (for output prologue/epilogue for other ABI besides EABI). - So now this implementation is different from MIPS one. When RTL - generation for all other ABI is written, the assembler code output - (and code above between #if 0 and #endif) can be removed and the - implementation will become analogous to MIPS/ARM one. The code for - RTL generation for the following ABI must be finished and tested - for this (please pay attention onto 64 bit targets too): - - ABI_AIX, ABI_AIX_NODESC - ABI_NT, ABI_SOLARIS (did they die???) - -*/ - -/* Write out an assembler instruction (if !RTX_FLAG) otherwise RTL - insns to load the TOC_TABLE address into register 30. This is only - necessary when TARGET_TOC, TARGET_MINIMAL_TOC, and there is a - constant pool. */ - -void -rs6000_output_load_toc_table (file, reg, rtx_flag) - FILE *file; - int reg; - int rtx_flag; -{ - char buf[256]; - rtx insn; - enum machine_mode reg_mode = (TARGET_32BIT) ? SImode : DImode; - -#ifdef USING_SVR4_H - if (TARGET_RELOCATABLE) - { - if (rtx_flag) - { - if (reg != 30) - abort; - insn = emit_call_insn - (TARGET_32BIT - ? gen_loadsi_svr4_relocatable_toc (gen_rtx - (REG, reg_mode, 0)) - : gen_loaddi_svr4_relocatable_toc (gen_rtx - (REG, reg_mode, 0))); - RTX_FRAME_RELATED_P (insn) = 1; - return; - } - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "\tbl "); - assemble_name (file, buf); - fprintf (file, "\n"); - - /* possibly create the toc section */ - if (!toc_initialized) - { - toc_section (); - function_section (current_function_decl); - } - - /* If not first call in this function, we need to put the - different between .LCTOC1 and the address we get to right - after the bl. It will mess up disassembling the instructions - but that can't be helped. We will later need to bias the - address before loading. */ - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - { - char *init_ptr = TARGET_32BIT ? ".long" : ".quad"; - char *buf_ptr; - - ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno); - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - STRIP_NAME_ENCODING (buf_ptr, buf); - fprintf (file, "\t%s %s-", init_ptr, buf_ptr); - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "%s\n", buf_ptr); - } - - ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno); - fprintf (file, "\tmflr %s\n", reg_names[reg]); - - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - asm_fprintf(file, "\t{cal|la} %s,%d(%s)\n", reg_names[reg], - (TARGET_32BIT ? 4 : 8), reg_names[reg]); - - asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s,(" : "\tld %s,(", - reg_names[0]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); - assemble_name (file, buf); - fputs ("-", file); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - assemble_name (file, buf); - fprintf (file, ")(%s)\n", reg_names[reg]); - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", - reg_names[reg], reg_names[0], reg_names[reg]); - rs6000_pic_labelno++; - } - else if (!TARGET_64BIT) - { - if (rtx_flag) - { - if (reg != 30) - abort; - insn = emit_insn (gen_loadsi_svr4_toc ()); - RTX_FRAME_RELATED_P (insn) = 1; - return; - } - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - asm_fprintf (file, "\t{liu|lis} %s,", reg_names[reg]); - assemble_name (file, buf); - fputs ("@ha\n", file); - asm_fprintf (file, "\t{cal|la} %s,", reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "@l(%s)\n", reg_names[reg]); - } - else - abort (); - -#else /* !USING_SVR4_H */ - if (rtx_flag) - { - if (reg != 30) - abort (); - insn - = emit_insn (TARGET_32BIT - ? gen_loadsi_nonsvr4_toc (gen_rtx (REG, reg_mode, 2)) - : gen_loaddi_nonsvr4_toc (gen_rtx (REG, reg_mode, 2))); - RTX_FRAME_RELATED_P (insn) = 1; - return; - } - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0); - asm_fprintf (file, TARGET_32BIT ? "\t{l|lwz} %s," : "\tld %s,", - reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", reg_names[2]); -#endif /* USING_SVR4_H */ -} - - - -/* Emit the correct code for allocating stack space. If COPY_R12, - make sure a copy of the old frame is left in r12. We generate RTX - instead of assembler code when RTX_FLAG is true. */ -static void -rs6000_allocate_stack_space (file, size, copy_r12, rtx_flag) - FILE *file; - int size; - int copy_r12; - int rtx_flag; -{ - int neg_size = -size; - rtx insn; - enum machine_mode reg_mode = (TARGET_32BIT) ? SImode : DImode; - - if (TARGET_UPDATE) - { - if (size < 32767) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, - (TARGET_32BIT) - ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); - else if (rtx_flag) - { - rtx incr = GEN_INT (neg_size); - - if (TARGET_32BIT) - insn = emit_insn (gen_movsi_update (stack_pointer_rtx, - stack_pointer_rtx, incr, - stack_pointer_rtx)); - else - insn = emit_insn (gen_movdi_update (stack_pointer_rtx, - stack_pointer_rtx, incr, - stack_pointer_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - if (copy_r12) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - else if (rtx_flag) - { - rtx r12_rtx = gen_rtx (REG, Pmode, 12); - - insn = emit_move_insn (r12_rtx, stack_pointer_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, - (TARGET_32BIT) - ? "\t{stux|stwux} %s,%s,%s\n" - : "\tstdux %s,%s,%s\n", - reg_names[1], reg_names[1], reg_names[0]); - } - else if (rtx_flag) - { - rtx r0_rtx = gen_rtx (REG, reg_mode, 0); - rtx const_int_rtx; - - const_int_rtx = GEN_INT (((neg_size >> 16) & 0xffff) << 16); - insn = emit_insn (gen_rtx (SET, VOIDmode, - r0_rtx, const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - const_int_rtx = GEN_INT (neg_size & 0xffff); - insn = emit_insn (TARGET_32BIT - ? gen_iorsi3 (r0_rtx, r0_rtx, const_int_rtx) - : gen_iordi3 (r0_rtx, r0_rtx, const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_insn (TARGET_32BIT - ? gen_movsi_update (stack_pointer_rtx, - stack_pointer_rtx, r0_rtx, - stack_pointer_rtx) - : gen_movdi_update (stack_pointer_rtx, - stack_pointer_rtx, r0_rtx, - stack_pointer_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - else - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - else if (rtx_flag) - { - rtx r12_rtx = gen_rtx (REG, Pmode, 12); - - insn = emit_move_insn (r12_rtx, stack_pointer_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - if (size < 32767) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); - else if (rtx_flag) - { - rtx reg_rtx = gen_rtx (REG, reg_mode, 1); - - insn = emit_insn (gen_addsi3 (reg_rtx, reg_rtx, - GEN_INT (neg_size))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - asm_fprintf (file, - "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - } - else if (rtx_flag) - { - rtx r0_rtx = gen_rtx (REG, reg_mode, 0); - rtx const_int_rtx; - - const_int_rtx = GEN_INT (((neg_size >> 16) & 0xffff) << 16); - insn = emit_insn (gen_rtx (SET, VOIDmode, r0_rtx, - const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - const_int_rtx = GEN_INT (neg_size & 0xffff); - insn = emit_insn (TARGET_32BIT - ? gen_iorsi3 (r0_rtx, r0_rtx, const_int_rtx) - : gen_iordi3 (r0_rtx, r0_rtx, const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", reg_names[1], - reg_names[0], reg_names[1]); - else if (rtx_flag) - { - rtx r0_rtx = gen_rtx (REG, reg_mode, 0); - rtx r1_rtx = gen_rtx (REG, reg_mode, 1); - - insn = emit_insn (TARGET_32BIT - ? gen_addsi3 (r1_rtx, r0_rtx, r1_rtx) - : gen_adddi3 (r1_rtx, r0_rtx, r1_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, - (TARGET_32BIT) - ? "\t{st|stw} %s,0(%s)\n" : "\tstd %s,0(%s)\n", - reg_names[12], reg_names[1]); - else if (rtx_flag) - { - rtx r12_rtx = gen_rtx (REG, reg_mode, 12); - rtx r1_rtx = gen_rtx (REG, Pmode, 1); - - insn = emit_move_insn (gen_rtx (MEM, reg_mode, r1_rtx), r12_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - } -} - - -/* Write function prologue. The function is called twice with two - different values of RTX_FLAG. Generate or not rtl or assembler - code is depended from value of TARGET_SCHED_PROLOG. */ - -static void -rs6000_prolog (file, rtx_flag, info) - FILE *file; - int rtx_flag; - rs6000_stack_t *info; -{ - int reg_size = info->reg_size; - char *store_reg; - char *load_reg; - int sp_reg = 1; - int sp_offset = 0; - enum machine_mode reg_mode; - rtx insn; - rtx sp_reg_rtx = stack_pointer_rtx; - - if (TARGET_32BIT) - { - store_reg = "\t{st|stw} %s,%d(%s)\n"; - load_reg = "\t{l|lwz} %s,%d(%s)\n"; - reg_mode = SImode; - } - else - { - store_reg = "\tstd %s,%d(%s)\n"; - load_reg = "\tlld %s,%d(%s)\n"; - reg_mode = DImode; - } - - if (TARGET_DEBUG_STACK) - debug_stack_info (info); - - /* Write .extern for any function we will call to save and restore fp - values. */ - if (!rtx_flag && info->first_fp_reg_save < 64 - && !FP_SAVE_INLINE (info->first_fp_reg_save)) - fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n", - SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX, - RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, - RESTORE_FP_SUFFIX); - - /* Write .extern for truncation routines, if needed. */ - if (!rtx_flag && rs6000_trunc_used && ! trunc_defined) - { - fprintf (file, "\t.extern .%s\n\t.extern .%s\n", - RS6000_ITRUNC, RS6000_UITRUNC); - trunc_defined = 1; - } - - /* Write .extern for AIX common mode routines, if needed. */ - if (!rtx_flag && !TARGET_POWER && !TARGET_POWERPC && !common_mode_defined) - { - fputs ("\t.extern __mulh\n", file); - fputs ("\t.extern __mull\n", file); - fputs ("\t.extern __divss\n", file); - fputs ("\t.extern __divus\n", file); - fputs ("\t.extern __quoss\n", file); - fputs ("\t.extern __quous\n", file); - common_mode_defined = 1; - } - - /* For V.4, update stack before we do any saving and set back pointer. */ - if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - { - if (info->total_size < 32767) - sp_offset = info->total_size; - else - { - sp_reg = 12; - sp_reg_rtx = gen_rtx (REG, Pmode, 12); - } - rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12, - rtx_flag); - } - - /* If we use the link register, get it into r0. */ - if (info->lr_save_p) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tmflr %s\n", reg_names[0]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, Pmode, 0), - gen_rtx (REG, Pmode, 65)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - /* If we need to save CR, put it into r12. */ - if (info->cr_save_p && sp_reg != 12) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); - else if (rtx_flag) - { - insn = emit_insn (TARGET_32BIT - ? gen_movesi_from_cr (gen_rtx (REG, reg_mode, 12)) - : gen_movedi_from_cr (gen_rtx - (REG, reg_mode, 12))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Do any required saving of fpr's. If only one or two to save, do it - ourself. Otherwise, call function. Note that since they are statically - linked, we do not need a nop following them. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) - { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; - - for ( ; regno < 64; regno++, loc += 8) - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tstfd %s,%d(%s)\n", - reg_names[regno], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx - (MEM, DFmode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, GEN_INT (loc))), - gen_rtx (REG, DFmode, regno)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else if (info->first_fp_reg_save != 64) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, - info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); - else if (rtx_flag) - { - static char label [100]; - - sprintf (label, "%s%d%s", SAVE_FP_PREFIX, - info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); - insn = emit_jump_insn (gen_jump (gen_rtx (SYMBOL_REF, Pmode, - label))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Now save gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) - { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - - for ( ; regno < 32; regno++, loc += reg_size) - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, store_reg, - reg_names[regno], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, regno)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else if (info->first_gp_reg_save != 32) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - else if (rtx_flag) - { - int loc; - int regno; - - for (loc = info->gp_save_offset + sp_offset, - regno = info->first_gp_reg_save; - regno <= 31; - regno++, loc += reg_size) - { - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, regno)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - /* Save main's arguments if we need to call a function */ -#ifdef NAME__MAIN - if (info->main_save_p) - { - int regno; - int loc = info->main_save_offset + sp_offset; - int size = info->main_size; - - for (regno = 3; size > 0; regno++, loc += reg_size, size -= reg_size) - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, store_reg, - reg_names[regno], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, regno)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } -#endif - - /* Save lr if we used it. */ - if (info->lr_save_p) - { - int loc = info->lr_save_offset + sp_offset; - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, store_reg, reg_names[0], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, 0)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Save CR if we use any that must be preserved. */ - if (info->cr_save_p) - { - int loc = info->cr_save_offset + sp_offset; - - if (sp_reg == 12) - /* If r12 is used to hold the original sp, copy cr now */ - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - asm_fprintf (file, "\tmfcr %s\n", reg_names[0]); - asm_fprintf (file, store_reg, reg_names[0], - loc, reg_names[sp_reg]); - } - else if (rtx_flag) - { - insn = emit_insn (TARGET_32BIT - ? gen_movesi_from_cr (gen_rtx - (REG, reg_mode, 0)) - : gen_movedi_from_cr (gen_rtx - (REG, reg_mode, 0))); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, 0)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - - asm_fprintf (file, store_reg, reg_names[12], - loc, reg_names[sp_reg]); - - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (loc))), - gen_rtx (REG, reg_mode, 12)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - - /* NT needs us to probe the stack frame every 4k pages for large frames, so - do it here. */ - if (DEFAULT_ABI == ABI_NT && info->total_size > 4096) - { - if (info->total_size < 32768) - { - int probe_offset = 4096; - while (probe_offset < info->total_size) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", - reg_names[0], -probe_offset, reg_names[1]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 0), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - stack_pointer_rtx, - GEN_INT (-probe_offset)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - probe_offset += 4096; - } - } - else - { - int probe_iterations = info->total_size / 4096; - static int probe_labelno = 0; - char buf[256]; - rtx r12_rtx = gen_rtx (REG, reg_mode, 12); - rtx r0_rtx = gen_rtx (REG, reg_mode, 0); - - if (probe_iterations < 32768) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tli %s,%d\n", - reg_names[12], probe_iterations); - else if (rtx_flag) - { - insn - = emit_insn (TARGET_32BIT - ? gen_addsi3 (r12_rtx, r0_rtx, - GEN_INT (probe_iterations)) - : gen_adddi3 (r12_rtx, r0_rtx, - GEN_INT (probe_iterations))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tlis %s,%d\n", - reg_names[12], probe_iterations >> 16); - else if (rtx_flag) - { - insn = emit_insn (TARGET_32BIT - ? gen_addsi3 (r12_rtx, r0_rtx, - GEN_INT ((probe_iterations - >> 16) << 16)) - : gen_adddi3 (r12_rtx, r0_rtx, - GEN_INT ((probe_iterations - >> 16) << 16))); - RTX_FRAME_RELATED_P (insn) = 1; - } - if (probe_iterations & 0xffff) - { - rtx const_int_rtx; - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], - reg_names[12], probe_iterations & 0xffff); - else if (rtx_flag) - { - const_int_rtx = GEN_INT (probe_iterations & 0xffff); - - insn = emit_insn (TARGET_32BIT - ? gen_iorsi3 (r12_rtx, r12_rtx, - const_int_rtx) - : gen_iordi3 (r12_rtx, r12_rtx, - const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - asm_fprintf (file, "\tmtctr %s\n", reg_names[12]); - asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno); - asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", - reg_names[0], reg_names[12]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno++); - fputs ("\tbdnz ", file); - assemble_name (file, buf); - fputs ("\n", file); - } - else if (rtx_flag) - { - abort (); /* ??? vmakarov: Not implemented yet (ABI_NT). */ - } - } - } - - /* Update stack and set back pointer unless this is V.4, which was - done previously */ - if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - rs6000_allocate_stack_space (file, info->total_size, FALSE, rtx_flag); - - /* Set frame pointer, if needed. */ - if (frame_pointer_needed) - { - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 31), - gen_rtx (REG, reg_mode, 1)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - -#ifdef NAME__MAIN - /* If we need to call a function to set things up for main, do so now - before dealing with the TOC. */ - if (info->main_p) - { - char *prefix = ""; - - switch (DEFAULT_ABI) - { - case ABI_AIX: prefix = "."; break; - case ABI_NT: prefix = ".."; break; - } - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - fprintf (file, "\tbl %s%s\n", prefix, NAME__MAIN); -#ifdef RS6000_CALL_GLUE2 - fprintf (file, "\t%s%s%s\n", RS6000_CALL_GLUE2, prefix, NAME_MAIN); -#else -#ifdef RS6000_CALL_GLUE - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - fprintf (file, "\t%s\n", RS6000_CALL_GLUE); -#endif -#endif - } - else if (rtx_flag) - { - static char name [100]; - - sprintf (name, "%s%s", prefix, NAME__MAIN); - insn = emit_call_insn (gen_rtx - (PARALLEL, VOIDmode, - gen_rtvec - (3, - gen_rtx (CALL, VOIDmode, - gen_rtx (MEM, FUNCTION_MODE, - gen_rtx (SYMBOL_REF, - Pmode, name)), - const0_rtx), - gen_rtx (USE, VOIDmode, const0_rtx), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, reg_mode, 65))))); - RTX_FRAME_RELATED_P (insn) = 1; - } - - if (info->main_save_p) - { - int regno; - int loc; - int size = info->main_size; - - if (info->total_size < 32767) - { - loc = info->total_size + info->main_save_offset; - for (regno = 3; - size > 0; - regno++, size -= reg_size, loc += reg_size) - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, load_reg, - reg_names[regno], loc, reg_names[1]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, regno), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - stack_pointer_rtx, - GEN_INT (loc)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - int neg_size = info->main_save_offset - info->total_size; - loc = 0; - - if (!rtx_flag && !TARGET_SCHED_PROLOG) - { - asm_fprintf (file, - "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", - reg_names[0], reg_names[0], reg_names[1]); - } - else if (rtx_flag) - { - rtx r0_rtx = gen_rtx (REG, reg_mode, 0); - rtx const_int_rtx; - - const_int_rtx = GEN_INT (((neg_size >> 16) & 0xffff) << 16); - insn = emit_insn (gen_rtx (SET, VOIDmode, r0_rtx, - const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - const_int_rtx = GEN_INT (neg_size & 0xffff); - insn = emit_insn (TARGET_32BIT - ? gen_iorsi3 (r0_rtx, r0_rtx, - const_int_rtx) - : gen_iordi3 (r0_rtx, r0_rtx, - const_int_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_insn (gen_rtx (MINUS, reg_mode, - r0_rtx, - gen_rtx (REG, reg_mode, 1), - r0_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - - for (regno = 3; - size > 0; - regno++, size -= reg_size, loc += reg_size) - if (!rtx_flag && !TARGET_SCHED_PROLOG) - asm_fprintf (file, load_reg, - reg_names[regno], loc, reg_names[0]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, regno), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - gen_rtx (REG, reg_mode, - 0), - GEN_INT (loc)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - } -#endif - - - /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the - TOC_TABLE address into register 30. */ - if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) - { -#ifdef USING_SVR4_H - if (!profile_flag) - rs6000_pic_func_labelno = rs6000_pic_labelno; -#endif - /* There is no oportuntity to optimize loading toc table -- - linear dependecies. */ - if (!rtx_flag && !TARGET_SCHED_PROLOG) - rs6000_output_load_toc_table (file, 30, FALSE); - else if (rtx_flag) - rs6000_output_load_toc_table (file, 30, TRUE); - } - - if (DEFAULT_ABI == ABI_NT) - { - assemble_name (file, - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".b:\n", file); - } -} - -/* Write function epilogue. The function is called twice with two - different values of RTX_FLAG. Generate or not rtl or assembler - code is depended from value of TARGET_SCHED_PROLOG. */ - -static void -rs6000_epilog (file, rtx_flag, info) - FILE *file; - int rtx_flag; - rs6000_stack_t *info; -{ - char *load_reg = ((TARGET_32BIT) ? - "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n"); - enum machine_mode reg_mode = (TARGET_32BIT) ? SImode : DImode; - rtx insn = get_last_insn (); - int sp_reg = 1; - rtx sp_reg_rtx = gen_rtx (REG, reg_mode, 1); - int sp_offset = 0; - - /* If the last insn was a BARRIER, we don't have to write anything except - the trace table. */ - if (insn != 0 && GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn == 0 || GET_CODE (insn) != BARRIER) - { - /* If we have a frame pointer, a call to alloca, or a large stack - frame, restore the old stack pointer using the backchain. Otherwise, - we know what size to update it with. */ - if (frame_pointer_needed || current_function_calls_alloca - || info->total_size > 32767) - { - /* Under V.4, don't reset the stack pointer until after we're done - loading the saved registers. */ - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - { - sp_reg = 11; - sp_reg_rtx = gen_rtx (REG, reg_mode, 11); - } - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]); - else if (rtx_flag) - { - insn = emit_move_insn (sp_reg_rtx, - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - gen_rtx (REG, reg_mode, 1), - const0_rtx))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else if (info->push_p) - { - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - sp_offset = info->total_size; - else - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], info->total_size, reg_names[1]); - else if (rtx_flag) - { - rtx reg_rtx = gen_rtx (REG, reg_mode, 1); - - insn - = emit_insn (TARGET_32BIT - ? gen_addsi3 (reg_rtx, reg_rtx, - GEN_INT (info->total_size)) - : gen_adddi3 (reg_rtx, reg_rtx, - GEN_INT (info->total_size))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - - /* Get the old lr if we saved it. */ - if (info->lr_save_p) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, load_reg, reg_names[0], - info->lr_save_offset + sp_offset, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 0), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (info->lr_save_offset - + sp_offset)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Get the old cr if we saved it. */ - if (info->cr_save_p) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, load_reg, reg_names[12], - info->cr_save_offset + sp_offset, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 12), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (info->cr_save_offset - + sp_offset)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Set LR here to try to overlap restores below. */ - if (info->lr_save_p) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\tmtlr %s\n", reg_names[0]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 65), - gen_rtx (REG, reg_mode, 0)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* Restore gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) - { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - int reg_size = (TARGET_32BIT) ? 4 : 8; - - for ( ; regno < 32; regno++, loc += reg_size) - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, load_reg, - reg_names[regno], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, regno), - gen_rtx - (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, GEN_INT (loc)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else if (info->first_gp_reg_save != 32) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - else if (rtx_flag) - { - int loc; - int regno; - int reg_size = (TARGET_32BIT) ? 4 : 8; - - for (loc = info->gp_save_offset + sp_offset, - regno = info->first_gp_reg_save; - regno <= 31; - regno++, loc += reg_size) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, regno), - gen_rtx (MEM, reg_mode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, - GEN_INT (loc)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - - /* Restore fpr's if we can do it without calling a function. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) - { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; - - for ( ; regno < 64; regno++, loc += 8) - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\tlfd %s,%d(%s)\n", - reg_names[regno], loc, reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, DFmode, regno), - gen_rtx - (MEM, DFmode, - gen_rtx (PLUS, Pmode, - sp_reg_rtx, GEN_INT (loc)))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 - that were used. */ - if (info->cr_save_p) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\tmtcrf %d,%s\n", - (regs_ever_live[70] != 0) * 0x20 - + (regs_ever_live[71] != 0) * 0x10 - + (regs_ever_live[72] != 0) * 0x8, reg_names[12]); - else if (rtx_flag) - { - rtx r12_rtx = gen_rtx (REG, reg_mode, 12); - - insn = emit_insn (TARGET_32BIT - ? gen_movesi_to_cr (r12_rtx) - : gen_movedi_to_cr (r12_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - - /* If this is V.4, unwind the stack pointer after all of the loads - have been done */ - if (sp_offset != 0) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], sp_offset, reg_names[1]); - else if (rtx_flag) - { - rtx reg_rtx = gen_rtx (REG, reg_mode, 1); - - insn = emit_insn (TARGET_32BIT - ? gen_addsi3 (reg_rtx, reg_rtx, - GEN_INT (sp_offset)) - : gen_adddi3 (reg_rtx, reg_rtx, - GEN_INT (sp_offset))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else if (sp_reg != 1) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\tmr %s,%s\n", - reg_names[1], reg_names[sp_reg]); - else if (rtx_flag) - { - insn = emit_move_insn (gen_rtx (REG, reg_mode, 1), sp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - /* If we have to restore more than two FP registers, branch to the - restore function. It will return to our caller. */ - if (info->first_fp_reg_save != 64 - && !FP_SAVE_INLINE (info->first_fp_reg_save)) - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX, - info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - else if (rtx_flag) - { - static char label [100]; - - sprintf (label, "%s%d%s", RESTORE_FP_PREFIX, - info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - insn = emit_jump_insn (gen_jump (gen_rtx (SYMBOL_REF, Pmode, - label))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - else - { - if (!rtx_flag && !TARGET_SCHED_EPILOG) - asm_fprintf (file, "\t{br|blr}\n"); - else if (rtx_flag) - { - insn = emit_jump_insn (gen_indirect_jump - (gen_rtx (REG, reg_mode, 65))); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - } - - /* Output a traceback table here. See /usr/include/sys/debug.h for info - on its format. - - We don't output a traceback table if -finhibit-size-directive was - used. The documentation for -finhibit-size-directive reads - ``don't output a @code{.size} assembler directive, or anything - else that would cause trouble if the function is split in the - middle, and the two halves are placed at locations far apart in - memory.'' The traceback table has this property, since it - includes the offset from the start of the function to the - traceback table itself. - - System V.4 Powerpc's (and the embedded ABI derived from it) use a - different traceback table. */ - if (!rtx_flag && DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive) - { - char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); - int fixed_parms, float_parms, parm_info; - int i; - - while (*fname == '.') /* V.4 encodes . in the name */ - fname++; - - /* Need label immediately before tbtab, so we can compute its offset - from the function start. */ - if (*fname == '*') - ++fname; - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - ASM_OUTPUT_LABEL (file, fname); - - /* The .tbtab pseudo-op can only be used for the first eight - expressions, since it can't handle the possibly variable - length fields that follow. However, if you omit the optional - fields, the assembler outputs zeros for all optional fields - anyways, giving each variable length field is minimum length - (as defined in sys/debug.h). Thus we can not use the .tbtab - pseudo-op at all. */ - - /* An all-zero word flags the start of the tbtab, for debuggers - that have to find it by searching forward from the entry - point or from the current pc. */ - fputs ("\t.long 0\n", file); - - /* Tbtab format type. Use format type 0. */ - fputs ("\t.byte 0,", file); - - /* Language type. Unfortunately, there doesn't seem to be any - official way to get this info, so we use language_string. C - is 0. C++ is 9. No number defined for Obj-C, so use the - value for C for now. There is no official value for Java, - although IBM appears to be using 13. There is no official value - for Chill, so we've choosen 44 pseudo-randomly. */ - if (! strcmp (language_string, "GNU C") - || ! strcmp (language_string, "GNU Obj-C")) - i = 0; - else if (! strcmp (language_string, "GNU F77")) - i = 1; - else if (! strcmp (language_string, "GNU Ada")) - i = 3; - else if (! strcmp (language_string, "GNU Pascal")) - i = 2; - else if (! strcmp (language_string, "GNU C++")) - i = 9; - else if (! strcmp (language_string, "GNU Java")) - i = 13; - else if (! strcmp (language_string, "GNU CHILL")) - i = 44; - else - abort (); - fprintf (file, "%d,", i); - - /* 8 single bit fields: global linkage (not set for C extern linkage, - apparently a PL/I convention?), out-of-line epilogue/prologue, offset - from start of procedure stored in tbtab, internal function, function - has controlled storage, function has no toc, function uses fp, - function logs/aborts fp operations. */ - /* Assume that fp operations are used if any fp reg must be saved. */ - fprintf (file, "%d,", - (1 << 5) | ((info->first_fp_reg_save != 64) << 1)); - - /* 6 bitfields: function is interrupt handler, name present in - proc table, function calls alloca, on condition directives - (controls stack walks, 3 bits), saves condition reg, saves - link reg. */ - /* The `function calls alloca' bit seems to be set whenever reg 31 is - set up as a frame pointer, even when there is no alloca call. */ - fprintf (file, "%d,", - ((1 << 6) | (frame_pointer_needed << 5) - | (info->cr_save_p << 1) | (info->lr_save_p))); - - /* 3 bitfields: saves backchain, spare bit, number of fpr saved - (6 bits). */ - fprintf (file, "%d,", - (info->push_p << 7) | (64 - info->first_fp_reg_save)); - - /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */ - fprintf (file, "%d,", (32 - first_reg_to_save ())); - - { - /* Compute the parameter info from the function decl argument - list. */ - tree decl; - int next_parm_info_bit; - - next_parm_info_bit = 31; - parm_info = 0; - fixed_parms = 0; - float_parms = 0; - - for (decl = DECL_ARGUMENTS (current_function_decl); - decl; decl = TREE_CHAIN (decl)) - { - rtx parameter = DECL_INCOMING_RTL (decl); - enum machine_mode mode = GET_MODE (parameter); - - if (GET_CODE (parameter) == REG) - { - if (GET_MODE_CLASS (mode) == MODE_FLOAT) - { - int bits; - - float_parms++; - - if (mode == SFmode) - bits = 0x2; - else if (mode == DFmode) - bits = 0x3; - else - abort (); - - /* If only one bit will fit, don't or in this entry. */ - if (next_parm_info_bit > 0) - parm_info |= (bits << (next_parm_info_bit - 1)); - next_parm_info_bit -= 2; - } - else - { - fixed_parms += ((GET_MODE_SIZE (mode) - + (UNITS_PER_WORD - 1)) - / UNITS_PER_WORD); - next_parm_info_bit -= 1; - } - } - } - } - - /* Number of fixed point parameters. */ - /* This is actually the number of words of fixed point parameters; thus - an 8 byte struct counts as 2; and thus the maximum value is 8. */ - fprintf (file, "%d,", fixed_parms); - - /* 2 bitfields: number of floating point parameters (7 bits), parameters - all on stack. */ - /* This is actually the number of fp registers that hold parameters; - and thus the maximum value is 13. */ - /* Set parameters on stack bit if parameters are not in their original - registers, regardless of whether they are on the stack? Xlc - seems to set the bit when not optimizing. */ - fprintf (file, "%d\n", ((float_parms << 1) | (! optimize))); - - /* Optional fields follow. Some are variable length. */ - - /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float, - 11 double float. */ - /* There is an entry for each parameter in a register, in the order that - they occur in the parameter list. Any intervening arguments on the - stack are ignored. If the list overflows a long (max possible length - 34 bits) then completely leave off all elements that don't fit. */ - /* Only emit this long if there was at least one parameter. */ - if (fixed_parms || float_parms) - fprintf (file, "\t.long %d\n", parm_info); - - /* Offset from start of code to tb table. */ - fputs ("\t.long ", file); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - RS6000_OUTPUT_BASENAME (file, fname); - fputs ("-.", file); - RS6000_OUTPUT_BASENAME (file, fname); - putc ('\n', file); - - /* Interrupt handler mask. */ - /* Omit this long, since we never set the interrupt handler bit - above. */ - - /* Number of CTL (controlled storage) anchors. */ - /* Omit this long, since the has_ctl bit is never set above. */ - - /* Displacement into stack of each CTL anchor. */ - /* Omit this list of longs, because there are no CTL anchors. */ - - /* Length of function name. */ - fprintf (file, "\t.short %d\n", (int) strlen (fname)); - - /* Function name. */ - assemble_string (fname, strlen (fname)); - - /* Register for alloca automatic storage; this is always reg 31. - Only emit this if the alloca bit was set above. */ - if (frame_pointer_needed) - fputs ("\t.byte 31\n", file); - } - - if (!rtx_flag && DEFAULT_ABI == ABI_NT) - { - RS6000_OUTPUT_BASENAME - (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".e:\nFE_MOT_RESVD..", file); - RS6000_OUTPUT_BASENAME - (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (":\n", file); - } -} - - - - -/* Write function prologue. */ -void -output_prolog (file, size) - FILE *file; - int size; -{ - rs6000_prolog (file, FALSE, rs6000_stack_info ()); -} - -/* Write function epilogue. */ - -void -output_epilog (file, size) - FILE *file; - int size; -{ - rs6000_epilog (file, FALSE, rs6000_stack_info ()); -} - -/* END CYGNUS LOCAL */ - - -/* A C compound statement that outputs the assembler code for a thunk function, - used to implement C++ virtual function calls with multiple inheritance. The - thunk acts as a wrapper around a virtual function, adjusting the implicit - object parameter before handing control off to the real function. - - First, emit code to add the integer DELTA to the location that contains the - incoming first argument. Assume that this argument contains a pointer, and - is the one used to pass the `this' pointer in C++. This is the incoming - argument *before* the function prologue, e.g. `%o0' on a sparc. The - addition must preserve the values of all other incoming arguments. - - After the addition, emit code to jump to FUNCTION, which is a - `FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch - the return address. Hence returning from FUNCTION will return to whoever - called the current `thunk'. - - The effect must be as if FUNCTION had been called directly with the adjusted - first argument. This macro is responsible for emitting all of the code for - a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not - invoked. - - The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already been - extracted from it.) It might possibly be useful on some targets, but - probably not. - - If you do not define this macro, the target-independent code in the C++ - frontend will generate a less efficient heavyweight thunk that calls - FUNCTION instead of jumping to it. The generic approach does not support - varargs. */ - -void -output_mi_thunk (file, thunk_fndecl, delta, function) - FILE *file; - tree thunk_fndecl; - int delta; - tree function; -{ - char *this_reg = reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ]; - char *r0 = reg_names[0]; - char *sp = reg_names[1]; - char *toc = reg_names[2]; - char *schain = reg_names[11]; - char *r12 = reg_names[12]; - char *prefix; - char *fname; - char buf[512]; - static int labelno = 0; - - /* Small constants that can be done by one add instruction */ - if (delta >= -32768 && delta <= 32767) - { - if (!TARGET_NEW_MNEMONICS) - fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg); - else - fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta); - } - - /* Large constants that can be done by one addis instruction */ - else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1) - asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg, - delta >> 16); - - /* 32-bit constants that can be done by an add and addis instruction. */ - else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1) - { - /* Break into two pieces, propigating the sign bit from the low word to - the upper word. */ - int delta_high = delta >> 16; - int delta_low = delta & 0xffff; - if ((delta_low & 0x8000) != 0) - { - delta_high++; - delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */ - } - - asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg, - delta_high); - - if (!TARGET_NEW_MNEMONICS) - fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg); - else - fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low); - } - - /* 64-bit constants, fixme */ - else - abort (); - - /* Get the prefix in front of the names. */ - switch (DEFAULT_ABI) - { - default: - abort (); - - case ABI_AIX: - prefix = "."; - break; - - case ABI_V4: - case ABI_AIX_NODESC: - case ABI_SOLARIS: - prefix = ""; - break; - - case ABI_NT: - prefix = ".."; - break; - } - - /* If the function is compiled in this module, jump to it directly. - Otherwise, load up its address and jump to it. */ - - fname = XSTR (XEXP (DECL_RTL (function), 0), 0); -#if 1 - /* For now, just emit a branch always, until we can figure out better when we - need to load the address into the count register and emit the slower bctr - instruction. */ - fprintf (file, "\tb %s", prefix); - assemble_name (file, fname); - fprintf (file, "\n"); - -#else - if (current_file_function_operand (XEXP (DECL_RTL (function), 0)) - && !lookup_attribute ("longcall", TYPE_ATTRIBUTES (TREE_TYPE (function)))) - { - fprintf (file, "\tb %s", prefix); - assemble_name (file, fname); - fprintf (file, "\n"); - } - - else - { - switch (DEFAULT_ABI) - { - default: - case ABI_NT: - abort (); - - case ABI_AIX: - /* Set up a TOC entry for the function. */ - ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno); - toc_section (); - ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno); - labelno++; - - /* Note, MINIMAL_TOC doesn't make sense in the case of a thunk, since - there will be only one TOC entry for this function. */ - fputs ("\t.tc\t", file); - assemble_name (file, buf); - fputs ("[TC],", file); - assemble_name (file, buf); - putc ('\n', file); - text_section (); - asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s", r12); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", reg_names[2]); - asm_fprintf (file, - (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n", - r0, r12); - - asm_fprintf (file, - (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n", - toc, r12); - - asm_fprintf (file, "\tmtctr %s\n", r0); - asm_fprintf (file, - (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n", - schain, r12); - - asm_fprintf (file, "\tbctr\n"); - break; - - /* Don't use r11, that contains the static chain, just use r0/r12. */ - case ABI_V4: - case ABI_AIX_NODESC: - case ABI_SOLARIS: - if (flag_pic == 1) - { - fprintf (file, "\tmflr %s\n", r0); - fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\tmflr %s\n", r12); - asm_fprintf (file, "\tmtlr %s\n", r0); - asm_fprintf (file, "\t{l|lwz} %s,", r0); - assemble_name (file, fname); - asm_fprintf (file, "@got(%s)\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r0); - asm_fprintf (file, "\tbctr\n"); - } -#if TARGET_ELF - else if (flag_pic > 1 || TARGET_RELOCATABLE) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno); - labelno++; - fprintf (file, "\tmflr %s\n", r0); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", r0, sp); - rs6000_pic_func_labelno = rs6000_pic_labelno; - rs6000_output_load_toc_table (file, 12 -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ - , FALSE -/* END CYGNUS LOCAL */ - ); - asm_fprintf (file, "\t{l|lwz} %s,", r0); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", r12); - asm_fprintf (file, "\t{l|lwz} %s,4(%s)\n", r12, sp); - asm_fprintf (file, "\tmtlr %s\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r0); - asm_fprintf (file, "\tbctr\n"); - asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - assemble_name (file, buf); - fputs (" = .-.LCTOC1\n", file); - fputs ("\t.long ", file); - assemble_name (file, fname); - fputs ("\n\t.previous\n", file); - } -#endif /* TARGET_ELF */ - - else - { - asm_fprintf (file, "\t{liu|lis} %s,", r12); - assemble_name (file, fname); - asm_fprintf (file, "@ha\n"); - asm_fprintf (file, "\t{cal|la} %s,", r12); - assemble_name (file, fname); - asm_fprintf (file, "@l(%s)\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r12); - asm_fprintf (file, "\tbctr\n"); - } - - break; - } - } -#endif /* #if 0 out code to use bctr for far away jumps */ -} - - -/* Output a TOC entry. We derive the entry name from what is - being written. */ - -void -output_toc (file, x, labelno) - FILE *file; - rtx x; - int labelno; -{ - char buf[256]; - char *name = buf; - char *real_name; - rtx base = x; - int offset = 0; - - if (TARGET_NO_TOC) - abort (); - - /* if we're going to put a double constant in the TOC, make sure it's - aligned properly when strict alignment is on. */ - if (GET_CODE (x) == CONST_DOUBLE - && STRICT_ALIGNMENT - && GET_MODE (x) == DFmode - && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { - ASM_OUTPUT_ALIGN (file, 3); - } - - - if (TARGET_ELF && TARGET_MINIMAL_TOC) - { - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); - fprintf (file, "%d = .-", labelno); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC"); - fputs ("1\n", file); - } - else - ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); - - /* Handle FP constants specially. Note that if we have a minimal - TOC, things we put here aren't actually in the TOC, so we can allow - FP constants. */ - if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode - && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) - { - REAL_VALUE_TYPE rv; - long k[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, x); - REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.llong 0x%lx%08lx\n", k[0], k[1]); - else - fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx%08lx\n", - k[0], k[1], k[0] & 0xffffffff, k[1] & 0xffffffff); - return; - } - else - { - if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.long %ld\n\t.long %ld\n", k[0], k[1]); - else - fprintf (file, "\t.tc FD_%lx_%lx[TC],%ld,%ld\n", - k[0], k[1], k[0], k[1]); - return; - } - } - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode - && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) - { - REAL_VALUE_TYPE rv; - long l; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, x); - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - - if (TARGET_MINIMAL_TOC) - fprintf (file, TARGET_32BIT ? "\t.long %ld\n" : "\t.llong %ld\n", l); - else - fprintf (file, "\t.tc FS_%lx[TC],%ld\n", l, l); - return; - } - else if (GET_MODE (x) == DImode - && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE) - && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) - { - HOST_WIDE_INT low; - HOST_WIDE_INT high; - - if (GET_CODE (x) == CONST_DOUBLE) - { - low = CONST_DOUBLE_LOW (x); - high = CONST_DOUBLE_HIGH (x); - } - else -#if HOST_BITS_PER_WIDE_INT == 32 - { - low = INTVAL (x); - high = (low < 0) ? ~0 : 0; - } -#else - { - low = INTVAL (x) & 0xffffffff; - high = (HOST_WIDE_INT) INTVAL (x) >> 32; - } -#endif - - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.llong 0x%lx%08lx\n", (long)high, (long)low); - else - fprintf (file, "\t.tc ID_%lx_%lx[TC],0x%lx%08lx\n", - (long)high, (long)low, (long)high, (long)low); - return; - } - else - { - if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.long %ld\n\t.long %ld\n", - (long)high, (long)low); - else - fprintf (file, "\t.tc ID_%lx_%lx[TC],%ld,%ld\n", - (long)high, (long)low, (long)high, (long)low); - return; - } - } - - if (GET_CODE (x) == CONST) - { - base = XEXP (XEXP (x, 0), 0); - offset = INTVAL (XEXP (XEXP (x, 0), 1)); - } - - if (GET_CODE (base) == SYMBOL_REF) - name = XSTR (base, 0); - else if (GET_CODE (base) == LABEL_REF) - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0))); - else if (GET_CODE (base) == CODE_LABEL) - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base)); - else - abort (); - - STRIP_NAME_ENCODING (real_name, name); - if (TARGET_MINIMAL_TOC) - fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", file); - else - { - fprintf (file, "\t.tc %s", real_name); - - if (offset < 0) - fprintf (file, ".N%d", - offset); - else if (offset) - fprintf (file, ".P%d", offset); - - fputs ("[TC],", file); - } - - /* Currently C++ toc references to vtables can be emitted before it - is decided whether the vtable is public or private. If this is - the case, then the linker will eventually complain that there is - a TOC reference to an unknown section. Thus, for vtables only, - we emit the TOC reference to reference the symbol and not the - section. */ - if (!strncmp ("_vt.", name, 4)) - { - RS6000_OUTPUT_BASENAME (file, name); - if (offset < 0) - fprintf (file, "%d", offset); - else if (offset > 0) - fprintf (file, "+%d", offset); - } - else - output_addr_const (file, x); - putc ('\n', file); -} - -/* Output an assembler pseudo-op to write an ASCII string of N characters - starting at P to FILE. - - On the RS/6000, we have to do this using the .byte operation and - write out special characters outside the quoted string. - Also, the assembler is broken; very long strings are truncated, - so we must artificially break them up early. */ - -void -output_ascii (file, p, n) - FILE *file; - char *p; - int n; -{ - char c; - int i, count_string; - char *for_string = "\t.byte \""; - char *for_decimal = "\t.byte "; - char *to_close = NULL; - - count_string = 0; - for (i = 0; i < n; i++) - { - c = *p++; - if (c >= ' ' && c < 0177) - { - if (for_string) - fputs (for_string, file); - putc (c, file); - - /* Write two quotes to get one. */ - if (c == '"') - { - putc (c, file); - ++count_string; - } - - for_string = NULL; - for_decimal = "\"\n\t.byte "; - to_close = "\"\n"; - ++count_string; - - if (count_string >= 512) - { - fputs (to_close, file); - - for_string = "\t.byte \""; - for_decimal = "\t.byte "; - to_close = NULL; - count_string = 0; - } - } - else - { - if (for_decimal) - fputs (for_decimal, file); - fprintf (file, "%d", c); - - for_string = "\n\t.byte \""; - for_decimal = ", "; - to_close = "\n"; - count_string = 0; - } - } - - /* Now close the string if we have written one. Then end the line. */ - if (to_close) - fprintf (file, to_close); -} - -/* Generate a unique section name for FILENAME for a section type - represented by SECTION_DESC. Output goes into BUF. - - SECTION_DESC can be any string, as long as it is different for each - possible section type. - - We name the section in the same manner as xlc. The name begins with an - underscore followed by the filename (after stripping any leading directory - names) with the last period replaced by the string SECTION_DESC. If - FILENAME does not contain a period, SECTION_DESC is appended to the end of - the name. */ - -void -rs6000_gen_section_name (buf, filename, section_desc) - char **buf; - char *filename; - char *section_desc; -{ - char *q, *after_last_slash, *last_period; - char *p; - int len; - - after_last_slash = filename; - for (q = filename; *q; q++) - { - if (*q == '/') - after_last_slash = q + 1; - else if (*q == '.') - last_period = q; - } - - len = strlen (after_last_slash) + strlen (section_desc) + 2; - *buf = (char *) permalloc (len); - - p = *buf; - *p++ = '_'; - - for (q = after_last_slash; *q; q++) - { - if (q == last_period) - { - strcpy (p, section_desc); - p += strlen (section_desc); - } - - else if (ISALNUM (*q)) - *p++ = *q; - } - - if (last_period == 0) - strcpy (p, section_desc); - else - *p = '\0'; -} - -/* Write function profiler code. */ - -void -output_function_profiler (file, labelno) - FILE *file; - int labelno; -{ - /* The last used parameter register. */ - int last_parm_reg; - int i, j; - char buf[100]; - - ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); - switch (DEFAULT_ABI) - { - default: - abort (); - - case ABI_V4: - case ABI_SOLARIS: - case ABI_AIX_NODESC: - fprintf (file, "\tmflr %s\n", reg_names[0]); - if (flag_pic == 1) - { - fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", - reg_names[0], reg_names[1]); - asm_fprintf (file, "\tmflr %s\n", reg_names[12]); - asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); - assemble_name (file, buf); - asm_fprintf (file, "@got(%s)\n", reg_names[12]); - } -#if TARGET_ELF - else if (flag_pic > 1 || TARGET_RELOCATABLE) - { - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", - reg_names[0], reg_names[1]); - rs6000_pic_func_labelno = rs6000_pic_labelno; - rs6000_output_load_toc_table (file, 12 -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ - , FALSE -/* END CYGNUS LOCAL */ - ); - asm_fprintf (file, "\t{l|lwz} %s,", reg_names[12]); - assemble_name (file, buf); - asm_fprintf (file, "X(%s)\n", reg_names[12]); - asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - assemble_name (file, buf); - fputs ("X = .-.LCTOC1\n", file); - fputs ("\t.long ", file); - assemble_name (file, buf); - fputs ("\n\t.previous\n", file); - } -#endif - else - { - asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); - assemble_name (file, buf); - fputs ("@ha\n", file); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]); - asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); - assemble_name (file, buf); - asm_fprintf (file, "@l(%s)\n", reg_names[12]); - } - - fprintf (file, "\tbl %s\n", RS6000_MCOUNT); - break; - - case ABI_AIX: - /* Set up a TOC entry for the profiler label. */ - toc_section (); - ASM_OUTPUT_INTERNAL_LABEL (file, "LPC", labelno); - if (TARGET_MINIMAL_TOC) - { - fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", file); - assemble_name (file, buf); - putc ('\n', file); - } - else - { - fputs ("\t.tc\t", file); - assemble_name (file, buf); - fputs ("[TC],", file); - assemble_name (file, buf); - putc ('\n', file); - } - text_section (); - - /* Figure out last used parameter register. The proper thing to do is - to walk incoming args of the function. A function might have live - parameter registers even if it has no incoming args. */ - - for (last_parm_reg = 10; - last_parm_reg > 2 && ! regs_ever_live [last_parm_reg]; - last_parm_reg--) - ; - - /* Save parameter registers in regs 23-30. Don't overwrite reg 31, since - it might be set up as the frame pointer. */ - - for (i = 3, j = 30; i <= last_parm_reg; i++, j--) - asm_fprintf (file, "\tmr %d,%d\n", j, i); - - /* Load location address into r3, and call mcount. */ - - ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno); - asm_fprintf (file, TARGET_32BIT ? "\t{l|lwz} %s," : "\tld %s,", - reg_names[3]); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n\tbl %s\n\t%s\n", - reg_names[2], RS6000_MCOUNT, RS6000_CALL_GLUE); - - /* Restore parameter registers. */ - - for (i = 3, j = 30; i <= last_parm_reg; i++, j--) - asm_fprintf (file, "\tmr %d,%d\n", i, j); - break; - } -} - -/* Adjust the cost of a scheduling dependency. Return the new cost of - a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ - -int -rs6000_adjust_cost (insn, link, dep_insn, cost) - rtx insn; - rtx link; - rtx dep_insn ATTRIBUTE_UNUSED; - int cost; -{ - if (! recog_memoized (insn)) - return 0; - - if (REG_NOTE_KIND (link) != 0) - return 0; - - if (REG_NOTE_KIND (link) == 0) - { - /* Data dependency; DEP_INSN writes a register that INSN reads some - cycles later. */ - - /* Tell the first scheduling pass about the latency between a mtctr - and bctr (and mtlr and br/blr). The first scheduling pass will not - know about this latency since the mtctr instruction, which has the - latency associated to it, will be generated by reload. */ - if (get_attr_type (insn) == TYPE_JMPREG) - return TARGET_POWER ? 5 : 4; - - /* Fall out to return default cost. */ - } - - return cost; -} - -/* A C statement (sans semicolon) to update the integer scheduling priority - INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier, - increase the priority to execute INSN later. Do not define this macro if - you do not need to adjust the scheduling priorities of insns. */ - -int -rs6000_adjust_priority (insn, priority) - rtx insn; - int priority; -{ - /* On machines (like the 750) which have asymetric integer units, where one - integer unit can do multiply and divides and the other can't, reduce the - priority of multiply/divide so it is scheduled before other integer - operationss. */ - -#if 0 - if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') - return priority; - - if (GET_CODE (PATTERN (insn)) == USE) - return priority; - - switch (rs6000_cpu_attr) { - case CPU_PPC750: - switch (get_attr_type (insn)) - { - default: - break; - - case TYPE_IMUL: - case TYPE_IDIV: - fprintf (stderr, "priority was %#x (%d) before adjustment\n", priority, priority); - if (priority >= 0 && priority < 0x01000000) - priority >>= 3; - break; - } - } -#endif - - return priority; -} - -/* Return how many instructions the machine can issue per cycle */ -int get_issue_rate() -{ - switch (rs6000_cpu_attr) { - case CPU_RIOS1: - return 3; /* ? */ - case CPU_RIOS2: - return 4; - case CPU_PPC601: - return 3; /* ? */ - case CPU_PPC603: - return 2; - case CPU_PPC750: - return 2; - case CPU_PPC604: - return 4; - case CPU_PPC620: - return 4; - default: - return 1; - } -} - - - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - The trampoline should set the static chain pointer to value placed - into the trampoline and should branch to the specified routine. */ - -void -rs6000_trampoline_template (file) - FILE *file; -{ - char *sc = reg_names[STATIC_CHAIN_REGNUM]; - char *r0 = reg_names[0]; - char *r2 = reg_names[2]; - - switch (DEFAULT_ABI) - { - default: - abort (); - - /* Under AIX, this is not code at all, but merely a data area, - since that is the way all functions are called. The first word is - the address of the function, the second word is the TOC pointer (r2), - and the third word is the static chain value. */ - case ABI_AIX: - break; - - - /* V.4/eabi function pointers are just a single pointer, so we need to - do the full gory code to load up the static chain. */ - case ABI_V4: - case ABI_SOLARIS: - case ABI_AIX_NODESC: - break; - - /* NT function pointers point to a two word area (real address, TOC) - which unfortunately does not include a static chain field. So we - use the function field to point to ..LTRAMP1 and the toc field - to point to the whole table. */ - case ABI_NT: - if (STATIC_CHAIN_REGNUM == 0 - || STATIC_CHAIN_REGNUM == 2 - || TARGET_64BIT - || !TARGET_NEW_MNEMONICS) - abort (); - - fprintf (file, "\t.ualong 0\n"); /* offset 0 */ - fprintf (file, "\t.ualong 0\n"); /* offset 4 */ - fprintf (file, "\t.ualong 0\n"); /* offset 8 */ - fprintf (file, "\t.ualong 0\n"); /* offset 12 */ - fprintf (file, "\t.ualong 0\n"); /* offset 16 */ - fprintf (file, "..LTRAMP1..0:\n"); /* offset 20 */ - fprintf (file, "\tlwz %s,8(%s)\n", r0, r2); /* offset 24 */ - fprintf (file, "\tlwz %s,12(%s)\n", sc, r2); /* offset 28 */ - fprintf (file, "\tmtctr %s\n", r0); /* offset 32 */ - fprintf (file, "\tlwz %s,16(%s)\n", r2, r2); /* offset 36 */ - fprintf (file, "\tbctr\n"); /* offset 40 */ - break; - } - - return; -} - -/* Length in units of the trampoline for entering a nested function. */ - -int -rs6000_trampoline_size () -{ - int ret = 0; - - switch (DEFAULT_ABI) - { - default: - abort (); - - case ABI_AIX: - ret = (TARGET_32BIT) ? 12 : 24; - break; - - case ABI_V4: - case ABI_SOLARIS: - case ABI_AIX_NODESC: - ret = (TARGET_32BIT) ? 40 : 48; - break; - - case ABI_NT: - ret = 20; - break; - } - - return ret; -} - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -void -rs6000_initialize_trampoline (addr, fnaddr, cxt) - rtx addr; - rtx fnaddr; - rtx cxt; -{ - enum machine_mode pmode = Pmode; - int regsize = (TARGET_32BIT) ? 4 : 8; - rtx ctx_reg = force_reg (pmode, cxt); - - switch (DEFAULT_ABI) - { - default: - abort (); - -/* Macros to shorten the code expansions below. */ -#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr)) -#define MEM_PLUS(addr,offset) gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset))) - - /* Under AIX, just build the 3 word function descriptor */ - case ABI_AIX: - { - rtx fn_reg = gen_reg_rtx (pmode); - rtx toc_reg = gen_reg_rtx (pmode); - emit_move_insn (fn_reg, MEM_DEREF (fnaddr)); - emit_move_insn (toc_reg, MEM_PLUS (fnaddr, 4)); - emit_move_insn (MEM_DEREF (addr), fn_reg); - emit_move_insn (MEM_PLUS (addr, regsize), toc_reg); - emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg); - } - break; - - /* Under V.4/eabi, call __trampoline_setup to do the real work. */ - case ABI_V4: - case ABI_SOLARIS: - case ABI_AIX_NODESC: - emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"), - FALSE, VOIDmode, 4, - addr, pmode, - GEN_INT (rs6000_trampoline_size ()), SImode, - fnaddr, pmode, - ctx_reg, pmode); - break; - - /* Under NT, update the first word to point to the ..LTRAMP1..0 header, - the second word will point to the whole trampoline, third-fifth words - will then have the real address, static chain, and toc value. */ - case ABI_NT: - { - rtx tramp_reg = gen_reg_rtx (pmode); - rtx fn_reg = gen_reg_rtx (pmode); - rtx toc_reg = gen_reg_rtx (pmode); - - emit_move_insn (tramp_reg, gen_rtx_SYMBOL_REF (pmode, "..LTRAMP1..0")); - addr = force_reg (pmode, addr); - emit_move_insn (fn_reg, MEM_DEREF (fnaddr)); - emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize)); - emit_move_insn (MEM_DEREF (addr), tramp_reg); - emit_move_insn (MEM_PLUS (addr, regsize), addr); - emit_move_insn (MEM_PLUS (addr, 2*regsize), fn_reg); - emit_move_insn (MEM_PLUS (addr, 3*regsize), ctx_reg); - emit_move_insn (MEM_PLUS (addr, 4*regsize), gen_rtx_REG (pmode, 2)); - } - break; - } - - return; -} - - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for DECL. - The attributes in ATTRIBUTES have previously been assigned to DECL. */ - -int -rs6000_valid_decl_attribute_p (decl, attributes, identifier, args) - tree decl ATTRIBUTE_UNUSED; - tree attributes ATTRIBUTE_UNUSED; - tree identifier ATTRIBUTE_UNUSED; - tree args ATTRIBUTE_UNUSED; -{ - return 0; -} - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for TYPE. - The attributes in ATTRIBUTES have previously been assigned to TYPE. */ - -int -rs6000_valid_type_attribute_p (type, attributes, identifier, args) - tree type; - tree attributes ATTRIBUTE_UNUSED; - tree identifier; - tree args; -{ - if (TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != FIELD_DECL - && TREE_CODE (type) != TYPE_DECL) - return 0; - - /* Longcall attribute says that the function is not within 2**26 bytes - of the current function, and to do an indirect call. */ - if (is_attribute_p ("longcall", identifier)) - return (args == NULL_TREE); - - if (DEFAULT_ABI == ABI_NT) - { - /* Stdcall attribute says callee is responsible for popping arguments - if they are not variable. */ - if (is_attribute_p ("stdcall", identifier)) - return (args == NULL_TREE); - - /* Cdecl attribute says the callee is a normal C declaration */ - if (is_attribute_p ("cdecl", identifier)) - return (args == NULL_TREE); - - /* Dllimport attribute says the caller is to call the function - indirectly through a __imp_<name> pointer. */ - if (is_attribute_p ("dllimport", identifier)) - return (args == NULL_TREE); - - /* Dllexport attribute says the callee is to create a __imp_<name> - pointer. */ - if (is_attribute_p ("dllexport", identifier)) - return (args == NULL_TREE); - - /* Exception attribute allows the user to specify 1-2 strings or identifiers - that will fill in the 3rd and 4th fields of the structured exception - table. */ - if (is_attribute_p ("exception", identifier)) - { - int i; - - if (args == NULL_TREE) - return 0; - - for (i = 0; i < 2 && args != NULL_TREE; i++) - { - tree this_arg = TREE_VALUE (args); - args = TREE_PURPOSE (args); - - if (TREE_CODE (this_arg) != STRING_CST - && TREE_CODE (this_arg) != IDENTIFIER_NODE) - return 0; - } - - return (args == NULL_TREE); - } - } - - return 0; -} - -/* If defined, a C expression whose value is zero if the attributes on - TYPE1 and TYPE2 are incompatible, one if they are compatible, and - two if they are nearly compatible (which causes a warning to be - generated). */ - -int -rs6000_comp_type_attributes (type1, type2) - tree type1 ATTRIBUTE_UNUSED; - tree type2 ATTRIBUTE_UNUSED; -{ - return 1; -} - -/* If defined, a C statement that assigns default attributes to newly - defined TYPE. */ - -void -rs6000_set_default_type_attributes (type) - tree type ATTRIBUTE_UNUSED; -{ -} - -/* Return a dll import reference corresponding to a call's SYMBOL_REF */ -struct rtx_def * -rs6000_dll_import_ref (call_ref) - rtx call_ref; -{ - char *call_name; - int len; - char *p; - rtx reg1, reg2; - tree node; - - if (GET_CODE (call_ref) != SYMBOL_REF) - abort (); - - call_name = XSTR (call_ref, 0); - len = sizeof ("__imp_") + strlen (call_name); - p = alloca (len); - reg2 = gen_reg_rtx (Pmode); - - strcpy (p, "__imp_"); - strcat (p, call_name); - node = get_identifier (p); - - reg1 = force_reg (Pmode, gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node))); - emit_move_insn (reg2, gen_rtx_MEM (Pmode, reg1)); - - return reg2; -} - -/* Return a reference suitable for calling a function with the longcall attribute. */ -struct rtx_def * -rs6000_longcall_ref (call_ref) - rtx call_ref; -{ - char *call_name; - tree node; - - if (GET_CODE (call_ref) != SYMBOL_REF) - return call_ref; - - /* System V adds '.' to the internal name, so skip them. */ - call_name = XSTR (call_ref, 0); - if (*call_name == '.') - { - while (*call_name == '.') - call_name++; - - node = get_identifier (call_name); - call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node)); - } - - return force_reg (Pmode, call_ref); -} - - -/* A C statement or statements to switch to the appropriate section - for output of RTX in mode MODE. You can assume that RTX is some - kind of constant in RTL. The argument MODE is redundant except in - the case of a `const_int' rtx. Select the section by calling - `text_section' or one of the alternatives for other sections. - - Do not define this macro if you put all constants in the read-only - data section. */ - -#ifdef USING_SVR4_H - -void -rs6000_select_rtx_section (mode, x) - enum machine_mode mode; - rtx x; -{ - if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x)) - toc_section (); - else - const_section (); -} - -/* A C statement or statements to switch to the appropriate - section for output of DECL. DECL is either a `VAR_DECL' node - or a constant of some sort. RELOC indicates whether forming - the initial value of DECL requires link-time relocations. */ - -void -rs6000_select_section (decl, reloc) - tree decl; - int reloc; -{ - int size = int_size_in_bytes (TREE_TYPE (decl)); - - if (TREE_CODE (decl) == STRING_CST) - { - if (! flag_writable_strings) - const_section (); - else - data_section (); - } - else if (TREE_CODE (decl) == VAR_DECL) - { - if ((flag_pic && reloc) - || !TREE_READONLY (decl) - || TREE_SIDE_EFFECTS (decl) - || !DECL_INITIAL (decl) - || (DECL_INITIAL (decl) != error_mark_node - && !TREE_CONSTANT (DECL_INITIAL (decl)))) - { - if (rs6000_sdata != SDATA_NONE && (size > 0) && (size <= g_switch_value)) - sdata_section (); - else - data_section (); - } - else - { - if (rs6000_sdata != SDATA_NONE && (size > 0) && (size <= g_switch_value)) - { - if (rs6000_sdata == SDATA_EABI) - sdata2_section (); - else - sdata_section (); /* System V doesn't have .sdata2/.sbss2 */ - } - else - const_section (); - } - } - else - const_section (); -} - - - -/* If we are referencing a function that is static or is known to be - in this file, make the SYMBOL_REF special. We can use this to indicate - that we can branch to this function without emitting a no-op after the - call. For real AIX and NT calling sequences, we also replace the - function name with the real name (1 or 2 leading .'s), rather than - the function descriptor name. This saves a lot of overriding code - to read the prefixes. */ - -void -rs6000_encode_section_info (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - rtx sym_ref = XEXP (DECL_RTL (decl), 0); - if (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl)) - SYMBOL_REF_FLAG (sym_ref) = 1; - - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - { - char *prefix = (DEFAULT_ABI == ABI_AIX) ? "." : ".."; - char *str = permalloc (strlen (prefix) + 1 - + strlen (XSTR (sym_ref, 0))); - strcpy (str, prefix); - strcat (str, XSTR (sym_ref, 0)); - XSTR (sym_ref, 0) = str; - } - } - else if (rs6000_sdata != SDATA_NONE - && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && TREE_CODE (decl) == VAR_DECL) - { - int size = int_size_in_bytes (TREE_TYPE (decl)); - tree section_name = DECL_SECTION_NAME (decl); - char *name = (char *)0; - int len = 0; - - if (section_name) - { - if (TREE_CODE (section_name) == STRING_CST) - { - name = TREE_STRING_POINTER (section_name); - len = TREE_STRING_LENGTH (section_name); - } - else - abort (); - } - - if ((size > 0 && size <= g_switch_value) - || (name - && ((len == sizeof (".sdata")-1 && strcmp (name, ".sdata") == 0) - || (len == sizeof (".sdata2")-1 && strcmp (name, ".sdata2") == 0) - || (len == sizeof (".sbss")-1 && strcmp (name, ".sbss") == 0) - || (len == sizeof (".sbss2")-1 && strcmp (name, ".sbss2") == 0) - || (len == sizeof (".PPC.EMB.sdata0")-1 && strcmp (name, ".PPC.EMB.sdata0") == 0) - || (len == sizeof (".PPC.EMB.sbss0")-1 && strcmp (name, ".PPC.EMB.sbss0") == 0)))) - { - rtx sym_ref = XEXP (DECL_RTL (decl), 0); - char *str = permalloc (2 + strlen (XSTR (sym_ref, 0))); - strcpy (str, "@"); - strcat (str, XSTR (sym_ref, 0)); - XSTR (sym_ref, 0) = str; - } - } -} - -#endif /* USING_SVR4_H */ - -void -rs6000_fatal_bad_address (op) - rtx op; -{ - fatal_insn ("bad address", op); -} - -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ - - -void -rs6000_expand_prologue (void) -{ - rs6000_stack_t *info; - - /* Trick is here. We need information about function but we have - started new insn sequence in `gen_prologue'. */ - end_sequence (); - info = rs6000_stack_info (); - start_sequence (); - rs6000_prolog (NULL, TRUE, info); -} - -void -rs6000_expand_epilogue (void) -{ - rs6000_stack_t *info; - - /* Trick is here. We need information about function but we have - started new insn sequence in `gen_epilogue'. */ - end_sequence (); - info = rs6000_stack_info (); - start_sequence (); - rs6000_epilog (NULL, TRUE, info); -} - -/* END CYGNUS LOCAL */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h deleted file mode 100755 index 5890aaa..0000000 --- a/gcc/config/rs6000/rs6000.h +++ /dev/null @@ -1,3403 +0,0 @@ -/* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992, 93-8, 1999 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Note that some other tm.h files include this one and then override - many of the definitions that relate to assembler syntax. */ - - -/* Names to predefine in the preprocessor for this target machine. */ - -#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \ --Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" - -/* Print subsidiary information on the compiler version in use. */ -#define TARGET_VERSION ; - -/* Default string to use for cpu if not specified. */ -#ifndef TARGET_CPU_DEFAULT -#define TARGET_CPU_DEFAULT ((char *)0) -#endif - -/* Tell the assembler to assume that all undefined names are external. - - Don't do this until the fixed IBM assembler is more generally available. - When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL, - ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no - longer be needed. Also, the extern declaration of mcount in ASM_FILE_START - will no longer be needed. */ - -/* #define ASM_SPEC "-u %(asm_cpu)" */ - -/* Define appropriate architecture macros for preprocessor depending on - target switches. */ - -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_cpu)" - -/* Common CPP definitions used by CPP_SPEC among the various targets - for handling -mcpu=xxx switches. */ -#define CPP_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -D_ARCH_PWR}} \ - %{mpower2: -D_ARCH_PWR2} \ - %{mpowerpc*: -D_ARCH_PPC} \ - %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \ - %{!mno-power: %{!mpower2: %(cpp_default)}}} \ -%{mcpu=common: -D_ARCH_COM} \ -%{mcpu=power: -D_ARCH_PWR} \ -%{mcpu=power2: -D_ARCH_PWR2} \ -%{mcpu=powerpc: -D_ARCH_PPC} \ -%{mcpu=rios: -D_ARCH_PWR} \ -%{mcpu=rios1: -D_ARCH_PWR} \ -%{mcpu=rios2: -D_ARCH_PWR2} \ -%{mcpu=rsc: -D_ARCH_PWR} \ -%{mcpu=rsc1: -D_ARCH_PWR} \ -%{mcpu=401: -D_ARCH_PPC} \ -%{mcpu=403: -D_ARCH_PPC} \ -%{mcpu=505: -D_ARCH_PPC} \ -%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \ -%{mcpu=602: -D_ARCH_PPC} \ -%{mcpu=603: -D_ARCH_PPC} \ -%{mcpu=603e: -D_ARCH_PPC} \ -%{mcpu=ec603e: -D_ARCH_PPC} \ -%{mcpu=604: -D_ARCH_PPC} \ -%{mcpu=604e: -D_ARCH_PPC} \ -%{mcpu=620: -D_ARCH_PPC} \ -%{mcpu=740: -D_ARCH_PPC} \ -%{mcpu=750: -D_ARCH_PPC} \ -%{mcpu=801: -D_ARCH_PPC} \ -%{mcpu=821: -D_ARCH_PPC} \ -%{mcpu=823: -D_ARCH_PPC} \ -%{mcpu=860: -D_ARCH_PPC}" - -#ifndef CPP_DEFAULT_SPEC -#define CPP_DEFAULT_SPEC "-D_ARCH_PWR" -#endif - -#ifndef CPP_SYSV_SPEC -#define CPP_SYSV_SPEC "" -#endif - -#ifndef CPP_ENDIAN_SPEC -#define CPP_ENDIAN_SPEC "" -#endif - -#ifndef CPP_ENDIAN_DEFAULT_SPEC -#define CPP_ENDIAN_DEFAULT_SPEC "" -#endif - -#ifndef CPP_SYSV_DEFAULT_SPEC -#define CPP_SYSV_DEFAULT_SPEC "" -#endif - -/* Common ASM definitions used by ASM_SPEC among the various targets - for handling -mcpu=xxx switches. */ -#define ASM_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -mpwr}} \ - %{mpower2: -mpwrx} \ - %{mpowerpc*: -mppc} \ - %{mno-power: %{!mpowerpc*: -mcom}} \ - %{!mno-power: %{!mpower2: %(asm_default)}}} \ -%{mcpu=common: -mcom} \ -%{mcpu=power: -mpwr} \ -%{mcpu=power2: -mpwrx} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rios: -mpwr} \ -%{mcpu=rios1: -mpwr} \ -%{mcpu=rios2: -mpwrx} \ -%{mcpu=rsc: -mpwr} \ -%{mcpu=rsc1: -mpwr} \ -%{mcpu=401: -mppc} \ -%{mcpu=403: -mppc} \ -%{mcpu=505: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -mppc} \ -%{mcpu=603e: -mppc} \ -%{mcpu=ec603e: -mppc} \ -%{mcpu=604: -mppc} \ -%{mcpu=604e: -mppc} \ -%{mcpu=620: -mppc} \ -%{mcpu=740: -mppc} \ -%{mcpu=750: -mppc} \ -%{mcpu=821: -mppc} \ -%{mcpu=823: -mppc} \ -%{mcpu=860: -mppc}" - -#ifndef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "" -#endif - -/* This macro defines names of additional specifications to put in the specs - that can be used in various specifications like CC1_SPEC. Its definition - is an initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - specification name, and a string constant that used by the GNU CC driver - program. - - Do not define this macro if it does not need to do anything. */ - -#ifndef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS -#endif - -#define EXTRA_SPECS \ - { "cpp_cpu", CPP_CPU_SPEC }, \ - { "cpp_default", CPP_DEFAULT_SPEC }, \ - { "cpp_sysv", CPP_SYSV_SPEC }, \ - { "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \ - { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \ - { "cpp_endian", CPP_ENDIAN_SPEC }, \ - { "asm_cpu", ASM_CPU_SPEC }, \ - { "asm_default", ASM_DEFAULT_SPEC }, \ - { "link_syscalls", LINK_SYSCALLS_SPEC }, \ - { "link_libg", LINK_LIBG_SPEC }, \ - SUBTARGET_EXTRA_SPECS - -/* Default location of syscalls.exp under AIX */ -#ifndef CROSS_COMPILE -#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp" -#else -#define LINK_SYSCALLS_SPEC "" -#endif - -/* Default location of libg.exp under AIX */ -#ifndef CROSS_COMPILE -#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp" -#else -#define LINK_LIBG_SPEC "" -#endif - -/* Define the options for the binder: Start text at 512, align all segments - to 512 bytes, and warn if there is text relocation. - - The -bhalt:4 option supposedly changes the level at which ld will abort, - but it also suppresses warnings about multiply defined symbols and is - used by the AIX cc command. So we use it here. - - -bnodelcsect undoes a poor choice of default relating to multiply-defined - csects. See AIX documentation for more information about this. - - -bM:SRE tells the linker that the output file is Shared REusable. Note - that to actually build a shared library you will also need to specify an - export list with the -Wl,-bE option. */ - -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso %(link_syscalls) } \ - %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" - -/* Profiled library versions are used by linking with special directories. */ -#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ - %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" - -/* gcc must do the search itself to find libgcc.a, not use -l. */ -#define LIBGCC_SPEC "libgcc.a%s" - -/* Don't turn -B into -L if the argument specifies a relative file name. */ -#define RELATIVE_PREFIX_NOT_LINKDIR - -/* Architecture type. */ - -extern int target_flags; - -/* Use POWER architecture instructions and MQ register. */ -#define MASK_POWER 0x00000001 - -/* Use POWER2 extensions to POWER architecture. */ -#define MASK_POWER2 0x00000002 - -/* Use PowerPC architecture instructions. */ -#define MASK_POWERPC 0x00000004 - -/* Use PowerPC General Purpose group optional instructions, e.g. fsqrt. */ -#define MASK_PPC_GPOPT 0x00000008 - -/* Use PowerPC Graphics group optional instructions, e.g. fsel. */ -#define MASK_PPC_GFXOPT 0x00000010 - -/* Use PowerPC-64 architecture instructions. */ -#define MASK_POWERPC64 0x00000020 - -/* Use revised mnemonic names defined for PowerPC architecture. */ -#define MASK_NEW_MNEMONICS 0x00000040 - -/* Disable placing fp constants in the TOC; can be turned on when the - TOC overflows. */ -#define MASK_NO_FP_IN_TOC 0x00000080 - -/* Disable placing symbol+offset constants in the TOC; can be turned on when - the TOC overflows. */ -#define MASK_NO_SUM_IN_TOC 0x00000100 - -/* Output only one TOC entry per module. Normally linking fails if - there are more than 16K unique variables/constants in an executable. With - this option, linking fails only if there are more than 16K modules, or - if there are more than 16K unique variables/constant in a single module. - - This is at the cost of having 2 extra loads and one extra store per - function, and one less allocable register. */ -#define MASK_MINIMAL_TOC 0x00000200 - -/* Nonzero for the 64bit model: ints, longs, and pointers are 64 bits. */ -#define MASK_64BIT 0x00000400 - -/* Disable use of FPRs. */ -#define MASK_SOFT_FLOAT 0x00000800 - -/* Enable load/store multiple, even on powerpc */ -#define MASK_MULTIPLE 0x00001000 -#define MASK_MULTIPLE_SET 0x00002000 - -/* Use string instructions for block moves */ -#define MASK_STRING 0x00004000 -#define MASK_STRING_SET 0x00008000 - -/* Disable update form of load/store */ -#define MASK_NO_UPDATE 0x00010000 - -/* Disable fused multiply/add operations */ -#define MASK_NO_FUSED_MADD 0x00020000 - -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ -/* Nonzero if we need to make scheduling prolog */ -#define MASK_SCHED_PROLOG (0x40000) -/* Nonzero if we need to make scheduling epilog */ -#define MASK_SCHED_EPILOG (0x80000) -/* END CYGNUS LOCAL */ - -#define TARGET_POWER (target_flags & MASK_POWER) -#define TARGET_POWER2 (target_flags & MASK_POWER2) -#define TARGET_POWERPC (target_flags & MASK_POWERPC) -#define TARGET_PPC_GPOPT (target_flags & MASK_PPC_GPOPT) -#define TARGET_PPC_GFXOPT (target_flags & MASK_PPC_GFXOPT) -#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64) -#define TARGET_NEW_MNEMONICS (target_flags & MASK_NEW_MNEMONICS) -#define TARGET_NO_FP_IN_TOC (target_flags & MASK_NO_FP_IN_TOC) -#define TARGET_NO_SUM_IN_TOC (target_flags & MASK_NO_SUM_IN_TOC) -#define TARGET_MINIMAL_TOC (target_flags & MASK_MINIMAL_TOC) -#define TARGET_64BIT (target_flags & MASK_64BIT) -#define TARGET_SOFT_FLOAT (target_flags & MASK_SOFT_FLOAT) -#define TARGET_MULTIPLE (target_flags & MASK_MULTIPLE) -#define TARGET_MULTIPLE_SET (target_flags & MASK_MULTIPLE_SET) -#define TARGET_STRING (target_flags & MASK_STRING) -#define TARGET_STRING_SET (target_flags & MASK_STRING_SET) -#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE) -#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD) - -#define TARGET_32BIT (! TARGET_64BIT) -#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT) -#define TARGET_UPDATE (! TARGET_NO_UPDATE) -#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD) - -/* Pseudo target to indicate whether the object format is ELF - (to get around not having conditional compilation in the md file) */ -#ifndef TARGET_ELF -#define TARGET_ELF 0 -#endif - -/* If this isn't V.4, don't support -mno-toc. */ -#ifndef TARGET_NO_TOC -#define TARGET_NO_TOC 0 -#define TARGET_TOC 1 -#endif - -/* Pseudo target to say whether this is Windows NT */ -#ifndef TARGET_WINDOWS_NT -#define TARGET_WINDOWS_NT 0 -#endif - -/* Pseudo target to say whether this is MAC */ -#ifndef TARGET_MACOS -#define TARGET_MACOS 0 -#endif - -/* Pseudo target to say whether this is AIX */ -#ifndef TARGET_AIX -#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS) -#define TARGET_AIX 0 -#else -#define TARGET_AIX 1 -#endif -#endif - -#ifndef TARGET_XL_CALL -#define TARGET_XL_CALL 0 -#endif - -/* Run-time compilation parameters selecting different hardware subsets. - - Macro to define tables used to set the flags. - This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } - where VALUE is the bits to set or minus the bits to clear. - An empty string NAME is used to identify the default VALUE. */ - -/* This is meant to be redefined in the host dependent files */ -#ifndef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES -#endif - -#define TARGET_SWITCHES \ - {{"power", MASK_POWER | MASK_MULTIPLE | MASK_STRING}, \ - {"power2", (MASK_POWER | MASK_MULTIPLE | MASK_STRING \ - | MASK_POWER2)}, \ - {"no-power2", - MASK_POWER2}, \ - {"no-power", - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE \ - | MASK_STRING)}, \ - {"powerpc", MASK_POWERPC}, \ - {"no-powerpc", - (MASK_POWERPC | MASK_PPC_GPOPT \ - | MASK_PPC_GFXOPT | MASK_POWERPC64)}, \ - {"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT}, \ - {"no-powerpc-gpopt", - MASK_PPC_GPOPT}, \ - {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT}, \ - {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT}, \ - {"powerpc64", MASK_POWERPC64}, \ - {"no-powerpc64", - MASK_POWERPC64}, \ - {"new-mnemonics", MASK_NEW_MNEMONICS}, \ - {"old-mnemonics", -MASK_NEW_MNEMONICS}, \ - {"full-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC \ - | MASK_MINIMAL_TOC)}, \ - {"fp-in-toc", - MASK_NO_FP_IN_TOC}, \ - {"no-fp-in-toc", MASK_NO_FP_IN_TOC}, \ - {"sum-in-toc", - MASK_NO_SUM_IN_TOC}, \ - {"no-sum-in-toc", MASK_NO_SUM_IN_TOC}, \ - {"minimal-toc", MASK_MINIMAL_TOC}, \ - {"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)}, \ - {"no-minimal-toc", - MASK_MINIMAL_TOC}, \ - {"hard-float", - MASK_SOFT_FLOAT}, \ - {"soft-float", MASK_SOFT_FLOAT}, \ - {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET}, \ - {"no-multiple", - MASK_MULTIPLE}, \ - {"no-multiple", MASK_MULTIPLE_SET}, \ - {"string", MASK_STRING | MASK_STRING_SET}, \ - {"no-string", - MASK_STRING}, \ - {"no-string", MASK_STRING_SET}, \ - {"update", - MASK_NO_UPDATE}, \ - {"no-update", MASK_NO_UPDATE}, \ - {"fused-madd", - MASK_NO_FUSED_MADD}, \ - {"no-fused-madd", MASK_NO_FUSED_MADD}, \ -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling */ \ - {"sched-prolog", MASK_SCHED_PROLOG}, \ - {"no-sched-prolog", -MASK_SCHED_PROLOG}, \ - {"sched-epilog", MASK_SCHED_EPILOG}, \ - {"no-sched-epilog", -MASK_SCHED_EPILOG}, \ -/* END CYGNUS LOCAL */ \ - SUBTARGET_SWITCHES \ - {"", TARGET_DEFAULT}} - -#define TARGET_DEFAULT (MASK_POWER | MASK_MULTIPLE | MASK_STRING) - -/* Processor type. Order must match cpu attribute in MD file. */ -enum processor_type -{ - PROCESSOR_RIOS1, - PROCESSOR_RIOS2, - PROCESSOR_MPCCORE, - PROCESSOR_PPC403, - PROCESSOR_PPC601, - PROCESSOR_PPC603, - PROCESSOR_PPC604, - PROCESSOR_PPC604e, - PROCESSOR_PPC620, - PROCESSOR_PPC750 -}; - -extern enum processor_type rs6000_cpu; - -/* Recast the processor type to the cpu attribute. */ -#define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu) - -/* Define generic processor types based upon current deployment. */ -#define PROCESSOR_COMMON PROCESSOR_PPC601 -#define PROCESSOR_POWER PROCESSOR_RIOS1 -#define PROCESSOR_POWERPC PROCESSOR_PPC604 - -/* Define the default processor. This is overridden by other tm.h files. */ -#define PROCESSOR_DEFAULT PROCESSOR_RIOS1 - -/* Specify the dialect of assembler to use. New mnemonics is dialect one - and the old mnemonics are dialect zero. */ -#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0 - -/* This macro is similar to `TARGET_SWITCHES' but defines names of - command options that have values. Its definition is an - initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - fixed part of the option name, and the address of a variable. - The variable, type `char *', is set to the variable part of the - given option if the fixed part matches. The actual option name - is made by appending `-m' to the specified name. - - Here is an example which defines `-mshort-data-NUMBER'. If the - given option is `-mshort-data-512', the variable `m88k_short_data' - will be set to the string `"512"'. - - extern char *m88k_short_data; - #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ - -/* This is meant to be overridden in target specific files. */ -#ifndef SUBTARGET_OPTIONS -#define SUBTARGET_OPTIONS -#endif - -#define TARGET_OPTIONS \ -{ \ - {"cpu=", &rs6000_select[1].string}, \ - {"tune=", &rs6000_select[2].string}, \ - {"debug-", &rs6000_debug_name}, \ - {"debug=", &rs6000_debug_name}, \ - /* CYGNUS LOCAL -- vmakarov */ \ - {"branch-cost=", &rs6000_branch_cost_string},\ - /* END CYGNUS LOCAL */ \ - SUBTARGET_OPTIONS \ -} - -/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */ -struct rs6000_cpu_select -{ - char *string; - char *name; - int set_tune_p; - int set_arch_p; -}; - -extern struct rs6000_cpu_select rs6000_select[]; - -/* Debug support */ -extern char *rs6000_debug_name; /* Name for -mdebug-xxxx option */ -extern int rs6000_debug_stack; /* debug stack applications */ -extern int rs6000_debug_arg; /* debug argument handling */ - -#define TARGET_DEBUG_STACK rs6000_debug_stack -#define TARGET_DEBUG_ARG rs6000_debug_arg - -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling. */ -#define TARGET_SCHED_PROLOG ((target_flags & MASK_SCHED_PROLOG)\ - && rs6000_current_abi == ABI_V4) -#define TARGET_SCHED_EPILOG ((target_flags & MASK_SCHED_EPILOG)\ - && rs6000_current_abi == ABI_V4) -/* END CYGNUS LOCAL */ - -/* CYGNUS LOCAL -- vmakarov */ -/* Override for BRANCH_COST */ -extern char *rs6000_branch_cost_string; -int rs6000_branch_cost; -/* END CYGNUS LOCAL */ - -/* Sometimes certain combinations of command options do not make sense - on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - Don't use this macro to turn on various extra optimizations for - `-O'. That is what `OPTIMIZATION_OPTIONS' is for. - - On the RS/6000 this is used to define the target cpu type. */ - -#define OVERRIDE_OPTIONS rs6000_override_options (TARGET_CPU_DEFAULT) - -/* Define this to change the optimizations performed by default. */ -#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) optimization_options(LEVEL,SIZE) - - -/* Show we can debug even without a frame pointer. */ -#define CAN_DEBUG_WITHOUT_FP - -/* target machine storage layout */ - -/* Define to support cross compilation to an RS6000 target. */ -#define REAL_ARITHMETIC - -/* Define this macro if it is advisable to hold scalars in registers - in a wider mode than that declared by the program. In such cases, - the value is constrained to be within the bounds of the declared - type, but kept valid in the wider mode. The signedness of the - extension may differ from that of the type. */ - -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - (MODE) = (! TARGET_POWERPC64 ? SImode : DImode); - -/* Define this if function arguments should also be promoted using the above - procedure. */ - -#define PROMOTE_FUNCTION_ARGS - -/* Likewise, if the function return value is promoted. */ - -#define PROMOTE_FUNCTION_RETURN - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. */ -/* That is true on RS/6000. */ -#define BITS_BIG_ENDIAN 1 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is true on RS/6000. */ -#define BYTES_BIG_ENDIAN 1 - -/* Define this if most significant word of a multiword number is lowest - numbered. - - For RS/6000 we can decide arbitrarily since there are no machine - instructions for them. Might as well be consistent with bits and bytes. */ -#define WORDS_BIG_ENDIAN 1 - -/* number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 68000, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD (! TARGET_POWERPC64 ? 32 : 64) -#define MAX_BITS_PER_WORD 64 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8) -#define MIN_UNITS_PER_WORD 4 -#define UNITS_PER_FP_WORD 8 - -/* Type used for ptrdiff_t, as a string used in a declaration. */ -#define PTRDIFF_TYPE "int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#define WCHAR_TYPE "short unsigned int" - -/* Width of wchar_t in bits. */ -#define WCHAR_TYPE_SIZE 16 - -/* A C expression for the size in bits of the type `short' on the - target machine. If you don't define this, the default is half a - word. (If this would be less than one storage unit, it is - rounded up to one unit.) */ -#define SHORT_TYPE_SIZE 16 - -/* A C expression for the size in bits of the type `int' on the - target machine. If you don't define this, the default is one - word. */ -#define INT_TYPE_SIZE 32 - -/* A C expression for the size in bits of the type `long' on the - target machine. If you don't define this, the default is one - word. */ -#define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64) -#define MAX_LONG_TYPE_SIZE 64 - -/* A C expression for the size in bits of the type `long long' on the - target machine. If you don't define this, the default is two - words. */ -#define LONG_LONG_TYPE_SIZE 64 - -/* A C expression for the size in bits of the type `char' on the - target machine. If you don't define this, the default is one - quarter of a word. (If this would be less than one storage unit, - it is rounded up to one unit.) */ -#define CHAR_TYPE_SIZE BITS_PER_UNIT - -/* A C expression for the size in bits of the type `float' on the - target machine. If you don't define this, the default is one - word. */ -#define FLOAT_TYPE_SIZE 32 - -/* A C expression for the size in bits of the type `double' on the - target machine. If you don't define this, the default is two - words. */ -#define DOUBLE_TYPE_SIZE 64 - -/* A C expression for the size in bits of the type `long double' on - the target machine. If you don't define this, the default is two - words. */ -#define LONG_DOUBLE_TYPE_SIZE 64 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE (TARGET_32BIT ? 32 : 64) - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64) - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128) - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 32 - -/* No data type wants to be aligned rounder than this. */ -#define BIGGEST_ALIGNMENT 64 - -/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ -#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ - (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \ - ? get_inner_array_type (FIELD) \ - : TREE_TYPE (FIELD)) == DFmode \ - ? MIN ((COMPUTED), 32) : (COMPUTED)) - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 32 - -/* Every structure's size must be a multiple of this. */ -#define STRUCTURE_SIZE_BOUNDARY 8 - -/* A bitfield declared as `int' forces `int' alignment for the struct. */ -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* AIX increases natural record alignment to doubleword if the first - field is an FP double while the FP fields remain word aligned. */ -#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \ - ((TREE_CODE (STRUCT) == RECORD_TYPE \ - || TREE_CODE (STRUCT) == UNION_TYPE \ - || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ - && TYPE_FIELDS (STRUCT) != 0 \ - && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \ - ? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \ - : MAX ((COMPUTED), (SPECIFIED))) - -/* Make strings word-aligned so strcpy from constants will be faster. */ -#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ - (TREE_CODE (EXP) == STRING_CST \ - && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) - -/* Make arrays of chars word-aligned for the same reasons. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) - -/* Non-zero if move instructions will actually fail to work - when given unaligned data. */ -#define STRICT_ALIGNMENT 0 - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - - RS/6000 has 32 fixed-point registers, 32 floating-point registers, - an MQ register, a count register, a link register, and 8 condition - register fields, which we view here as separate registers. - - In addition, the difference between the frame and argument pointers is - a function of the number of registers saved, so we need to have a - register for AP that will later be eliminated in favor of SP or FP. - This is a normal register, but it is fixed. - - We also create a pseudo register for float/int conversions, that will - really represent the memory location used. It is represented here as - a register, in order to work around problems in allocating stack storage - in inline functions. */ - -#define FIRST_PSEUDO_REGISTER 77 - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - - On RS/6000, r1 is used for the stack and r2 is used as the TOC pointer. - - cr5 is not supposed to be used. - - On System V implementations, r13 is fixed and not available for use. */ - -#ifndef FIXED_R13 -#define FIXED_R13 0 -#endif - -#define FIXED_REGISTERS \ - {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1} - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ - -#define CALL_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1} - -/* List the order in which to allocate registers. Each register must be - listed once, even those in FIXED_REGISTERS. - - We allocate in the following order: - fp0 (not saved or used for anything) - fp13 - fp2 (not saved; incoming fp arg registers) - fp1 (not saved; return value) - fp31 - fp14 (saved; order given to save least number) - cr7, cr6 (not saved or special) - cr1 (not saved, but used for FP operations) - cr0 (not saved, but used for arithmetic operations) - cr4, cr3, cr2 (saved) - r0 (not saved; cannot be base reg) - r9 (not saved; best for TImode) - r11, r10, r8-r4 (not saved; highest used first to make less conflict) - r3 (not saved; return value register) - r31 - r13 (saved; order given to save least number) - r12 (not saved; if used for DImode or DFmode would use r13) - mq (not saved; best to use it if we can) - ctr (not saved; when we have the choice ctr is better) - lr (saved) - cr5, r1, r2, ap, fpmem (fixed) */ - -#define REG_ALLOC_ORDER \ - {32, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \ - 33, \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ - 50, 49, 48, 47, 46, \ - 75, 74, 69, 68, 72, 71, 70, \ - 0, \ - 9, 11, 10, 8, 7, 6, 5, 4, \ - 3, \ - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \ - 18, 17, 16, 15, 14, 13, 12, \ - 64, 66, 65, \ - 73, 1, 2, 67, 76} - -/* True if register is floating-point. */ -#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63) - -/* True if register is a condition register. */ -#define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75) - -/* True if register is condition register 0. */ -#define CR0_REGNO_P(N) ((N) == 68) - -/* True if register is a condition register, but not cr0. */ -#define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75) - -/* True if register is an integer register. */ -#define INT_REGNO_P(N) ((N) <= 31 || (N) == 67) - -/* True if register is the temporary memory location used for int/float - conversion. */ -#define FPMEM_REGNO_P(N) ((N) == FPMEM_REGNUM) - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - - POWER and PowerPC GPRs hold 32 bits worth; - PowerPC64 GPRs and FPRs point register holds 64 bits worth. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO) \ - ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - For POWER and PowerPC, the GPRs can hold any mode, but the float - registers only can hold floating modes and DImode, and CR register only - can hold CC modes. We cannot put TImode anywhere except general - register and it must be able to fit within the register set. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - (FP_REGNO_P (REGNO) ? \ - (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \ - : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ - : FPMEM_REGNO_P (REGNO) ? ((MODE) == DImode || (MODE) == DFmode) \ - : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ - : 1) - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (GET_MODE_CLASS (MODE1) == MODE_FLOAT \ - ? GET_MODE_CLASS (MODE2) == MODE_FLOAT \ - : GET_MODE_CLASS (MODE2) == MODE_FLOAT \ - ? GET_MODE_CLASS (MODE1) == MODE_FLOAT \ - : GET_MODE_CLASS (MODE1) == MODE_CC \ - ? GET_MODE_CLASS (MODE2) == MODE_CC \ - : GET_MODE_CLASS (MODE2) == MODE_CC \ - ? GET_MODE_CLASS (MODE1) == MODE_CC \ - : 1) - -/* A C expression returning the cost of moving data from a register of class - CLASS1 to one of CLASS2. - - On the RS/6000, copying between floating-point and fixed-point - registers is expensive. */ - -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \ - : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10 \ - : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10 \ - : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS \ - || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS \ - || (CLASS1) == LINK_OR_CTR_REGS) \ - && ((CLASS2) == SPECIAL_REGS || (CLASS2) == MQ_REGS \ - || (CLASS2) == LINK_REGS || (CLASS2) == CTR_REGS \ - || (CLASS2) == LINK_OR_CTR_REGS)) ? 10 \ - : 2) - -/* A C expressions returning the cost of moving data of MODE from a register to - or from memory. - - On the RS/6000, bump this up a bit. */ - -#define MEMORY_MOVE_COST(MODE,CLASS,IN) \ - ((GET_MODE_CLASS (MODE) == MODE_FLOAT \ - && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \ - ? 3 : 2) \ - + 4) - -/* Specify the cost of a branch insn; roughly the number of extra insns that - should be added to avoid a branch. - - Set this to 3 on the RS/6000 since that is roughly the average cost of an - unscheduled conditional branch. */ - -/* CYGNUS LOCAL -- vmakarov */ -#define BRANCH_COST_DEFAULT 3 -#define BRANCH_COST rs6000_branch_cost -/* END CYGNUS LOCAL */ - -/* A C statement (sans semicolon) to update the integer variable COST - based on the relationship between INSN that is dependent on - DEP_INSN through the dependence LINK. The default is to make no - adjustment to COST. On the RS/6000, ignore the cost of anti- and - output-dependencies. In fact, output dependencies on the CR do have - a cost, but it is probably not worthwhile to track it. */ - -#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \ - (COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST) - -/* A C statement (sans semicolon) to update the integer scheduling priority - INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier, - increase the priority to execute INSN later. Do not define this macro if - you do not need to adjust the scheduling priorities of insns. */ - -#define ADJUST_PRIORITY(INSN) \ - INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN)) - -/* Define this macro to change register usage conditional on target flags. - Set MQ register fixed (already call_used) if not POWER architecture - (RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated. - 64-bit AIX reserves GPR13 for thread-private data. - Conditionally disable FPRs. */ - -#define CONDITIONAL_REGISTER_USAGE \ -{ \ - if (! TARGET_POWER) \ - fixed_regs[64] = 1; \ - if (TARGET_64BIT) \ - fixed_regs[13] = call_used_regs[13] = 1; \ - if (TARGET_SOFT_FLOAT) \ - for (i = 32; i < 64; i++) \ - fixed_regs[i] = call_used_regs[i] = 1; \ -} - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* RS/6000 pc isn't overloaded on a register that the compiler knows about. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 1 - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 31 - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ -#define FRAME_POINTER_REQUIRED 0 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 67 - -/* Place to put static chain when calling a function that requires it. */ -#define STATIC_CHAIN_REGNUM 11 - -/* count register number for special purposes */ -#define COUNT_REGISTER_REGNUM 66 - -/* Special register that represents memory, used for float/int conversions. */ -#define FPMEM_REGNUM 76 - -/* Register to use as a placeholder for the GOT/allocated TOC register. - FINALIZE_PIC will change all uses of this register to a an appropriate - pseudo register when it adds the code to setup the GOT. We use r2 - because it is a reserved register in all of the ABI's. */ -#define GOT_TOC_REGNUM 2 - -/* Place that structure value return address is placed. - - On the RS/6000, it is passed as an extra parameter. */ -#define STRUCT_VALUE 0 - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -/* The RS/6000 has three types of registers, fixed-point, floating-point, - and condition registers, plus three special registers, MQ, CTR, and the - link register. - - However, r0 is special in that it cannot be used as a base register. - So make a class for registers valid as base registers. - - Also, cr0 is the only condition code register that can be used in - arithmetic insns, so make a separate class for it. - - There is a special 'register' (76), which is not a register, but a - placeholder for memory allocated to convert between floating point and - integral types. This works around a problem where if we allocate memory - with allocate_stack_{local,temp} and the function is an inline function, the - memory allocated will clobber memory in the caller. So we use a special - register, and if that is used, we allocate stack space for it. */ - -enum reg_class -{ - NO_REGS, - BASE_REGS, - GENERAL_REGS, - FLOAT_REGS, - NON_SPECIAL_REGS, - MQ_REGS, - LINK_REGS, - CTR_REGS, - LINK_OR_CTR_REGS, - SPECIAL_REGS, - SPEC_OR_GEN_REGS, - CR0_REGS, - CR_REGS, - NON_FLOAT_REGS, - FPMEM_REGS, - FLOAT_OR_FPMEM_REGS, - ALL_REGS, - LIM_REG_CLASSES -}; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ -{ \ - "NO_REGS", \ - "BASE_REGS", \ - "GENERAL_REGS", \ - "FLOAT_REGS", \ - "NON_SPECIAL_REGS", \ - "MQ_REGS", \ - "LINK_REGS", \ - "CTR_REGS", \ - "LINK_OR_CTR_REGS", \ - "SPECIAL_REGS", \ - "SPEC_OR_GEN_REGS", \ - "CR0_REGS", \ - "CR_REGS", \ - "NON_FLOAT_REGS", \ - "FPMEM_REGS", \ - "FLOAT_OR_FPMEM_REGS", \ - "ALL_REGS" \ -} - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS \ -{ \ - { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ - { 0xfffffffe, 0x00000000, 0x00000008 }, /* BASE_REGS */ \ - { 0xffffffff, 0x00000000, 0x00000008 }, /* GENERAL_REGS */ \ - { 0x00000000, 0xffffffff, 0x00000000 }, /* FLOAT_REGS */ \ - { 0xffffffff, 0xffffffff, 0x00000008 }, /* NON_SPECIAL_REGS */ \ - { 0x00000000, 0x00000000, 0x00000001 }, /* MQ_REGS */ \ - { 0x00000000, 0x00000000, 0x00000002 }, /* LINK_REGS */ \ - { 0x00000000, 0x00000000, 0x00000004 }, /* CTR_REGS */ \ - { 0x00000000, 0x00000000, 0x00000006 }, /* LINK_OR_CTR_REGS */ \ - { 0x00000000, 0x00000000, 0x00000007 }, /* SPECIAL_REGS */ \ - { 0xffffffff, 0x00000000, 0x0000000f }, /* SPEC_OR_GEN_REGS */ \ - { 0x00000000, 0x00000000, 0x00000010 }, /* CR0_REGS */ \ - { 0x00000000, 0x00000000, 0x00000ff0 }, /* CR_REGS */ \ - { 0xffffffff, 0x00000000, 0x0000ffff }, /* NON_FLOAT_REGS */ \ - { 0x00000000, 0x00000000, 0x00010000 }, /* FPMEM_REGS */ \ - { 0x00000000, 0xffffffff, 0x00010000 }, /* FLOAT_OR_FPMEM_REGS */ \ - { 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \ -} - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) == 0 ? GENERAL_REGS \ - : (REGNO) < 32 ? BASE_REGS \ - : FP_REGNO_P (REGNO) ? FLOAT_REGS \ - : (REGNO) == 68 ? CR0_REGS \ - : CR_REGNO_P (REGNO) ? CR_REGS \ - : (REGNO) == 64 ? MQ_REGS \ - : (REGNO) == 65 ? LINK_REGS \ - : (REGNO) == 66 ? CTR_REGS \ - : (REGNO) == 67 ? BASE_REGS \ - : (REGNO) == 76 ? FPMEM_REGS \ - : NO_REGS) - -/* The class value for index registers, and the one for base regs. */ -#define INDEX_REG_CLASS GENERAL_REGS -#define BASE_REG_CLASS BASE_REGS - -/* Get reg_class from a letter such as appears in the machine description. */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'f' ? FLOAT_REGS \ - : (C) == 'b' ? BASE_REGS \ - : (C) == 'h' ? SPECIAL_REGS \ - : (C) == 'q' ? MQ_REGS \ - : (C) == 'c' ? CTR_REGS \ - : (C) == 'l' ? LINK_REGS \ - : (C) == 'x' ? CR0_REGS \ - : (C) == 'y' ? CR_REGS \ - : (C) == 'z' ? FPMEM_REGS \ - : NO_REGS) - -/* The letters I, J, K, L, M, N, and P in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - `I' is signed 16-bit constants - `J' is a constant with only the high-order 16 bits non-zero - `K' is a constant with only the low-order 16 bits non-zero - `L' is a constant that can be placed into a mask operand - `M' is a constant that is greater than 31 - `N' is a constant that is an exact power of two - `O' is the constant zero - `P' is a constant whose negation is a signed 16-bit constant */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \ - : (C) == 'J' ? ((VALUE) & 0xffff) == 0 \ - : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \ - : (C) == 'L' ? mask_constant (VALUE) \ - : (C) == 'M' ? (VALUE) > 31 \ - : (C) == 'N' ? exact_log2 (VALUE) >= 0 \ - : (C) == 'O' ? (VALUE) == 0 \ - : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x1000 \ - : 0) - -/* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. - - We flag for special constants when we can copy the constant into - a general register in two insns for DF/DI and one insn for SF. - - 'H' is used for DI/DF constants that take 3 insns. */ - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \ - == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \ - : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \ - : 0) - -/* Optional extra constraints for this machine. - - 'Q' means that is a memory operand that is just an offset from a reg. - 'R' is for AIX TOC entries. - 'S' is a constant that can be placed into a 64-bit mask operand - 'U' is for V.4 small data references. */ - -#define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \ - : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \ - : (C) == 'S' ? mask64_operand (OP, VOIDmode) \ - : (C) == 'U' ? ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \ - && small_data_operand (OP, GET_MODE (OP))) \ - : 0) - -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. - - On the RS/6000, we have to return NO_REGS when we want to reload a - floating-point CONST_DOUBLE to force it to be copied to memory. */ - -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((GET_CODE (X) == CONST_DOUBLE \ - && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ - ? NO_REGS : (CLASS)) - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ - secondary_reload_class (CLASS, MODE, IN) - -/* If we are copying between FP registers and anything else, we need a memory - location. */ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS)) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. - - On RS/6000, this is the size of MODE in words, - except in the FP regs, where a single reg is enough for two words. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - (((CLASS) == FLOAT_REGS || (CLASS) == FPMEM_REGS \ - || (CLASS) == FLOAT_OR_FPMEM_REGS) \ - ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* If defined, gives a class of registers that cannot be used as the - operand of a SUBREG that changes the size of the object. */ - -#define CLASS_CANNOT_CHANGE_SIZE FLOAT_OR_FPMEM_REGS - -/* Stack layout; function entry, exit and calling. */ - -/* Enumeration to give which calling sequence to use. */ -enum rs6000_abi { - ABI_NONE, - ABI_AIX, /* IBM's AIX */ - ABI_AIX_NODESC, /* AIX calling sequence minus function descriptors */ - ABI_V4, /* System V.4/eabi */ - ABI_NT, /* Windows/NT */ - ABI_SOLARIS /* Solaris */ -}; - -extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ - -/* Default ABI to compile code for */ -#ifndef DEFAULT_ABI -#define DEFAULT_ABI ABI_AIX -/* The prefix to add to user-visible assembler symbols. */ -#define USER_LABEL_PREFIX "." -#endif - -/* Structure used to define the rs6000 stack */ -typedef struct rs6000_stack { - int first_gp_reg_save; /* first callee saved GP register used */ - int first_fp_reg_save; /* first callee saved FP register used */ - int lr_save_p; /* true if the link reg needs to be saved */ - int cr_save_p; /* true if the CR reg needs to be saved */ - int toc_save_p; /* true if the TOC needs to be saved */ - int push_p; /* true if we need to allocate stack space */ - int calls_p; /* true if the function makes any calls */ - int main_p; /* true if this is main */ - int main_save_p; /* true if this is main and we need to save args */ - int fpmem_p; /* true if float/int conversion temp needed */ - enum rs6000_abi abi; /* which ABI to use */ - int gp_save_offset; /* offset to save GP regs from initial SP */ - int fp_save_offset; /* offset to save FP regs from initial SP */ - int lr_save_offset; /* offset to save LR from initial SP */ - int cr_save_offset; /* offset to save CR from initial SP */ - int toc_save_offset; /* offset to save the TOC pointer */ - int varargs_save_offset; /* offset to save the varargs registers */ - int main_save_offset; /* offset to save main's args */ - int fpmem_offset; /* offset for float/int conversion temp */ - int reg_size; /* register size (4 or 8) */ - int varargs_size; /* size to hold V.4 args passed in regs */ - int vars_size; /* variable save area size */ - int parm_size; /* outgoing parameter size */ - int main_size; /* size to hold saving main's args */ - int save_size; /* save area size */ - int fixed_size; /* fixed size of stack frame */ - int gp_size; /* size of saved GP registers */ - int fp_size; /* size of saved FP registers */ - int cr_size; /* size to hold CR if not in save_size */ - int lr_size; /* size to hold LR if not in save_size */ - int fpmem_size; /* size to hold float/int conversion */ - int toc_size; /* size to hold TOC if not in save_size */ - int total_size; /* total bytes allocated for stack */ -} rs6000_stack_t; - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. - - On the RS/6000, we grow upwards, from the area after the outgoing - arguments. */ -/* #define FRAME_GROWS_DOWNWARD */ - -/* Size of the outgoing register save area */ -#define RS6000_REG_SAVE (TARGET_32BIT ? 32 : 64) - -/* Size of the fixed area on the stack */ -#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48) - -/* Address to save the TOC register */ -#define RS6000_SAVE_TOC plus_constant (stack_pointer_rtx, (TARGET_32BIT ? 20 : 40)) - -/* Offset & size for fpmem stack locations used for converting between - float and integral types. */ -extern int rs6000_fpmem_offset; -extern int rs6000_fpmem_size; - -/* Size of the V.4 varargs area if needed */ -#define RS6000_VARARGS_AREA 0 - -/* Whether a V.4 varargs area is needed */ -extern int rs6000_sysv_varargs_p; - -/* Align an address */ -#define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) - -/* Initialize data used by insn expanders. This is called from - init_emit, once for each function, before code is generated. */ -#define INIT_EXPANDERS rs6000_init_expanders () - -/* Size of V.4 varargs area in bytes */ -#define RS6000_VARARGS_SIZE \ - ((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8) - -/* Offset of V.4 varargs area */ -#define RS6000_VARARGS_OFFSET \ - (RS6000_ALIGN (current_function_outgoing_args_size, 8) \ - + RS6000_SAVE_AREA) - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. - - On the RS/6000, the frame pointer is the same as the stack pointer, - except for dynamic allocations. So we start after the fixed area and - outgoing parameter area. */ - -#define STARTING_FRAME_OFFSET \ - (RS6000_ALIGN (current_function_outgoing_args_size, 8) \ - + RS6000_VARARGS_AREA \ - + RS6000_SAVE_AREA) - -/* Offset from the stack pointer register to an item dynamically - allocated on the stack, e.g., by `alloca'. - - The default value for this macro is `STACK_POINTER_OFFSET' plus the - length of the outgoing arguments. The default is correct for most - machines. See `function.c' for details. */ -#define STACK_DYNAMIC_OFFSET(FUNDECL) \ - (RS6000_ALIGN (current_function_outgoing_args_size, 8) \ - + (STACK_POINTER_OFFSET)) - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On RS/6000, don't define this because there are no push insns. */ -/* #define PUSH_ROUNDING(BYTES) */ - -/* Offset of first parameter from the argument pointer register value. - On the RS/6000, we define the argument pointer to the start of the fixed - area. */ -#define FIRST_PARM_OFFSET(FNDECL) RS6000_SAVE_AREA - -/* Define this if stack space is still allocated for a parameter passed - in a register. The value is the number of bytes allocated to this - area. */ -#define REG_PARM_STACK_SPACE(FNDECL) RS6000_REG_SAVE - -/* Define this if the above stack space is to be considered part of the - space allocated by the caller. */ -#define OUTGOING_REG_PARM_STACK_SPACE - -/* This is the difference between the logical top of stack and the actual sp. - - For the RS/6000, sp points past the fixed area. */ -#define STACK_POINTER_OFFSET RS6000_SAVE_AREA - -/* Define this if the maximum size of all the outgoing args is to be - accumulated and pushed during the prologue. The amount can be - found in the variable current_function_outgoing_args_size. */ -#define ACCUMULATE_OUTGOING_ARGS - -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. - - On RS/6000 an integer value is in r3 and a floating-point value is in - fp1, unless -msoft-float. */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \ - && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ - || POINTER_TYPE_P (VALTYPE) \ - ? word_mode : TYPE_MODE (VALTYPE), \ - TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 33 : 3) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) \ - gen_rtx_REG (MODE, \ - GET_MODE_CLASS (MODE) == MODE_FLOAT && TARGET_HARD_FLOAT ? 33 : 3) - -/* The definition of this macro implies that there are cases where - a scalar value cannot be returned in registers. - - For the RS/6000, any structure or union type is returned in memory, except for - Solaris, which returns structures <= 8 bytes in registers. */ - -#define RETURN_IN_MEMORY(TYPE) \ - (TYPE_MODE (TYPE) == BLKmode \ - && (DEFAULT_ABI != ABI_SOLARIS || int_size_in_bytes (TYPE) > 8)) - -/* Mode of stack savearea. - FUNCTION is VOIDmode because calling convention maintains SP. - BLOCK needs Pmode for SP. - NONLOCAL needs twice Pmode to maintain both backchain and SP. */ -#define STACK_SAVEAREA_MODE(LEVEL) \ - (LEVEL == SAVE_FUNCTION ? VOIDmode \ - : LEVEL == SAVE_NONLOCAL ? (TARGET_32BIT ? DImode : TImode) : Pmode) - -/* Minimum and maximum general purpose registers used to hold arguments. */ -#define GP_ARG_MIN_REG 3 -#define GP_ARG_MAX_REG 10 -#define GP_ARG_NUM_REG (GP_ARG_MAX_REG - GP_ARG_MIN_REG + 1) - -/* Minimum and maximum floating point registers used to hold arguments. */ -#define FP_ARG_MIN_REG 33 -#define FP_ARG_AIX_MAX_REG 45 -#define FP_ARG_V4_MAX_REG 40 -#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG -#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1) - -/* Return registers */ -#define GP_ARG_RETURN GP_ARG_MIN_REG -#define FP_ARG_RETURN FP_ARG_MIN_REG - -/* Flags for the call/call_value rtl operations set up by function_arg */ -#define CALL_NORMAL 0x00000000 /* no special processing */ -#define CALL_NT_DLLIMPORT 0x00000001 /* NT, this is a DLL import call */ -#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */ -#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */ -#define CALL_LONG 0x00000008 /* always call indirect */ - -/* Define cutoff for using external functions to save floating point */ -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) - -/* 1 if N is a possible register number for a function value - as seen by the caller. - - On RS/6000, this is r3 and fp1. */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN)) - -/* 1 if N is a possible register number for function argument passing. - On RS/6000, these are r3-r10 and fp1-fp13. */ -#define FUNCTION_ARG_REGNO_P(N) \ - (((unsigned)((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \ - || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG))) - - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. - - On the RS/6000, this is a structure. The first element is the number of - total argument words, the second is used to store the next - floating-point register number, and the third says how many more args we - have prototype types for. - - The System V.4 varargs/stdarg support requires that this structure's size - be a multiple of sizeof(int), and that WORDS, FREGNO, NARGS_PROTOTYPE, - ORIG_NARGS, and VARARGS_OFFSET be the first five ints. */ - -typedef struct rs6000_args -{ - int words; /* # words uses for passing GP registers */ - int fregno; /* next available FP register */ - int nargs_prototype; /* # args left in the current prototype */ - int orig_nargs; /* Original value of nargs_prototype */ - int varargs_offset; /* offset of the varargs save area */ - int prototype; /* Whether a prototype was defined */ - int call_cookie; /* Do special things for this call */ -} CUMULATIVE_ARGS; - -/* Define intermediate macro to compute the size (in registers) of an argument - for the RS/6000. */ - -#define RS6000_ARG_SIZE(MODE, TYPE, NAMED) \ -(! (NAMED) ? 0 \ - : (MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ - : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ - init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE) - -/* Similar, but when scanning the definition of a procedure. We always - set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */ - -#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \ - init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE) - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - function_arg_advance (&CUM, MODE, TYPE, NAMED) - -/* Non-zero if we can use a floating-point register to pass this arg. */ -#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \ - (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - && (CUM).fregno <= FP_ARG_MAX_REG \ - && TARGET_HARD_FLOAT) - -/* Determine where to put an argument to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). - - On RS/6000 the first eight words of non-FP are normally in registers - and the rest are pushed. The first 13 FP args are in registers. - - If this is floating-point and no prototype is specified, we use - both an FP and integer register (or possibly FP reg and stack). Library - functions (when TYPE is zero) always have the proper types for args, - so we can pass the FP value just in one register. emit_library_function - doesn't support EXPR_LIST anyway. */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - function_arg (&CUM, MODE, TYPE, NAMED) - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ - function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) - -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED) - -/* If defined, a C expression which determines whether, and in which - direction, to pad out an argument with extra space. The value - should be of type `enum direction': either `upward' to pad above - the argument, `downward' to pad below, or `none' to inhibit - padding. */ - -#define FUNCTION_ARG_PADDING(MODE, TYPE) \ - (enum direction) function_arg_padding (MODE, TYPE) - -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - function_arg_boundary (MODE, TYPE) - -/* Perform any needed actions needed for a function that is receiving a - variable number of arguments. - - CUM is as above. - - MODE and TYPE are the mode and type of the current parameter. - - PRETEND_SIZE is a variable that should be set to the amount of stack - that must be pushed by the prolog to pretend that our caller pushed - it. - - Normally, this macro will push all remaining incoming registers on the - stack and set PRETEND_SIZE to the length of the registers pushed. */ - -#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ - setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL) - -/* If defined, is a C expression that produces the machine-specific - code for a call to `__builtin_saveregs'. This code will be moved - to the very beginning of the function, before any parameter access - are made. The return value of this function should be an RTX that - contains the value to use as the return of `__builtin_saveregs'. - - The argument ARGS is a `tree_list' containing the arguments that - were passed to `__builtin_saveregs'. - - If this macro is not defined, the compiler will output an ordinary - call to the library function `__builtin_saveregs'. */ - -#define EXPAND_BUILTIN_SAVEREGS(ARGS) \ - expand_builtin_saveregs (ARGS) - -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. */ - -#define FUNCTION_PROLOGUE(FILE, SIZE) output_prolog (FILE, SIZE) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - output_function_profiler ((FILE), (LABELNO)); - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. No definition is equivalent to - always zero. - - On the RS/6000, this is non-zero because we can restore the stack from - its backpointer, which we maintain. */ -#define EXIT_IGNORE_STACK 1 - -/* This macro generates the assembly code for function exit, - on machines that need it. If FUNCTION_EPILOGUE is not defined - then individual return instructions are generated for each - return statement. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer! - It should use the frame pointer only. This is mandatory because - of alloca; we also take advantage of it to omit stack adjustments - before returning. */ - -#define FUNCTION_EPILOGUE(FILE, SIZE) output_epilog (FILE, SIZE) - -/* A C compound statement that outputs the assembler code for a thunk function, - used to implement C++ virtual function calls with multiple inheritance. The - thunk acts as a wrapper around a virtual function, adjusting the implicit - object parameter before handing control off to the real function. - - First, emit code to add the integer DELTA to the location that contains the - incoming first argument. Assume that this argument contains a pointer, and - is the one used to pass the `this' pointer in C++. This is the incoming - argument *before* the function prologue, e.g. `%o0' on a sparc. The - addition must preserve the values of all other incoming arguments. - - After the addition, emit code to jump to FUNCTION, which is a - `FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch - the return address. Hence returning from FUNCTION will return to whoever - called the current `thunk'. - - The effect must be as if FUNCTION had been called directly with the adjusted - first argument. This macro is responsible for emitting all of the code for - a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not - invoked. - - The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already been - extracted from it.) It might possibly be useful on some targets, but - probably not. - - If you do not define this macro, the target-independent code in the C++ - frontend will generate a less efficient heavyweight thunk that calls - FUNCTION instead of jumping to it. The generic approach does not support - varargs. */ -#if TARGET_ELF -#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ - output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION) -#endif - -/* TRAMPOLINE_TEMPLATE deleted */ - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE rs6000_trampoline_size () - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \ - rs6000_initialize_trampoline (ADDR, FNADDR, CXT) - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for DECL. - The attributes in ATTRIBUTES have previously been assigned to DECL. */ - -#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \ - (rs6000_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS)) - -/* If defined, a C expression whose value is nonzero if IDENTIFIER - with arguments ARGS is a valid machine specific attribute for TYPE. - The attributes in ATTRIBUTES have previously been assigned to TYPE. */ - -#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \ - (rs6000_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS)) - -/* If defined, a C expression whose value is zero if the attributes on - TYPE1 and TYPE2 are incompatible, one if they are compatible, and - two if they are nearly compatible (which causes a warning to be - generated). */ - -#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \ - (rs6000_comp_type_attributes (TYPE1, TYPE2)) - -/* If defined, a C statement that assigns default attributes to newly - defined TYPE. */ - -#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \ - (rs6000_set_default_type_attributes (TYPE)) - - -/* Definitions for __builtin_return_address and __builtin_frame_address. - __builtin_return_address (0) should give link register (65), enable - this. */ -/* This should be uncommented, so that the link register is used, but - currently this would result in unmatched insns and spilling fixed - registers so we'll leave it for another day. When these problems are - taken care of one additional fetch will be necessary in RETURN_ADDR_RTX. - (mrs) */ -/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */ - -/* Number of bytes into the frame return addresses can be found. See - rs6000_stack_info in rs6000.c for more information on how the different - abi's store the return address. */ -#define RETURN_ADDRESS_OFFSET \ - ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_AIX_NODESC) ? 8 : \ - (DEFAULT_ABI == ABI_V4 \ - || DEFAULT_ABI == ABI_SOLARIS) ? (TARGET_32BIT ? 4 : 8) : \ - (DEFAULT_ABI == ABI_NT) ? -4 : \ - (fatal ("RETURN_ADDRESS_OFFSET not supported"), 0)) - -/* The current return address is in link register (65). The return address - of anything farther back is accessed normally at an offset of 8 from the - frame pointer. */ -#define RETURN_ADDR_RTX(count, frame) \ - ((count == -1) \ - ? gen_rtx_REG (Pmode, 65) \ - : gen_rtx_MEM (Pmode, \ - memory_address (Pmode, \ - plus_constant (copy_to_reg (gen_rtx_MEM (Pmode, \ - memory_address (Pmode, frame))), \ - RETURN_ADDRESS_OFFSET)))) - -/* Definitions for register eliminations. - - We have two registers that can be eliminated on the RS/6000. First, the - frame pointer register can often be eliminated in favor of the stack - pointer register. Secondly, the argument pointer register can always be - eliminated; it is replaced with either the stack or frame pointer. - - In addition, we use the elimination mechanism to see if r30 is needed - Initially we assume that it isn't. If it is, we spill it. This is done - by making it an eliminable register. We replace it with itself so that - if it isn't needed, then existing uses won't be modified. */ - -/* This is an array of structures. Each structure initializes one pair - of eliminable registers. The "from" register number is given first, - followed by "to". Eliminations of the same "from" register are listed - in order of preference. */ -#define ELIMINABLE_REGS \ -{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ - { 30, 30} } - -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - For the RS/6000, if frame pointer elimination is being done, we would like - to convert ap into fp, not sp. - - We need r30 if -mminimal-toc was specified, and there are constant pool - references. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : (FROM) == 30 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \ - : 1) - -/* Define the offset between two registers, one to be eliminated, and the other - its replacement, at the start of a routine. */ -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ \ - rs6000_stack_t *info = rs6000_stack_info (); \ - \ - if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) = (info->push_p) ? 0 : - info->total_size; \ - else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ - (OFFSET) = info->total_size; \ - else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) = (info->push_p) ? info->total_size : 0; \ - else if ((FROM) == 30) \ - (OFFSET) = 0; \ - else \ - abort (); \ -} - -/* Addressing modes, and classification of registers for them. */ - -/* #define HAVE_POST_INCREMENT 0 */ -/* #define HAVE_POST_DECREMENT 0 */ - -#define HAVE_PRE_DECREMENT 1 -#define HAVE_PRE_INCREMENT 1 - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < FIRST_PSEUDO_REGISTER \ - ? (REGNO) <= 31 || (REGNO) == 67 \ - : (reg_renumber[REGNO] >= 0 \ - && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67))) - -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < FIRST_PSEUDO_REGISTER \ - ? ((REGNO) > 0 && (REGNO) <= 31) || (REGNO) == 67 \ - : (reg_renumber[REGNO] > 0 \ - && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67))) - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. - - On the RS/6000, all integer constants are acceptable, most won't be valid - for particular insns, though. Only easy FP constants are - acceptable. */ - -#define LEGITIMATE_CONSTANT_P(X) \ - (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \ - || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \ - || easy_fp_constant (X, GET_MODE (X))) - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - After reload, it makes no difference, since pseudo regs have - been eliminated by then. */ - -#ifndef REG_OK_STRICT - -/* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg. */ -#define REG_OK_FOR_INDEX_P(X) \ - (REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER) - -/* Nonzero if X is a hard reg that can be used as a base reg - or if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) \ - (REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X)) - -#else - -/* Nonzero if X is a hard reg that can be used as an index. */ -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -/* Nonzero if X is a hard reg that can be used as a base reg. */ -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) - -#endif - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - On the RS/6000, there are four valid address: a SYMBOL_REF that - refers to a constant pool entry of an address (or the sum of it - plus a constant), a short (16-bit signed) constant plus a register, - the sum of two registers, or a register indirect, possibly with an - auto-increment. For DFmode and DImode with an constant plus register, - we must ensure that both words are addressable or PowerPC64 with offset - word aligned. - - For modes spanning multiple registers (DFmode in 32-bit GPRs, - 32-bit DImode, TImode), indexed addressing cannot be used because - adjacent memory cells are accessed by adding word-sized offsets - during assembly output. */ - -#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) \ - (TARGET_TOC && GET_CODE (X) == SYMBOL_REF \ - && CONSTANT_POOL_ADDRESS_P (X) \ - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X))) - -/* AIX64 guaranteed to have 64 bit TOC alignment. */ -#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \ - (LEGITIMATE_CONSTANT_POOL_BASE_P (X) \ - || (TARGET_TOC \ - && GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ - && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0)))) - -#define LEGITIMATE_SMALL_DATA_P(MODE, X) \ - ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \ - && !flag_pic && !TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \ - && small_data_operand (X, MODE)) - -#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \ - (GET_CODE (X) == CONST_INT \ - && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000) - -#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X) \ - (GET_CODE (X) == PLUS \ - && GET_CODE (XEXP (X, 0)) == REG \ - && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \ - && (((MODE) != DFmode && (MODE) != DImode) \ - || (TARGET_32BIT \ - ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \ - : ! (INTVAL (XEXP (X, 1)) & 3))) \ - && ((MODE) != TImode \ - || (TARGET_32BIT \ - ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \ - : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \ - && ! (INTVAL (XEXP (X, 1)) & 3))))) - -#define LEGITIMATE_INDEXED_ADDRESS_P(X) \ - (GET_CODE (X) == PLUS \ - && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) == REG \ - && ((REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && REG_OK_FOR_INDEX_P (XEXP (X, 1))) \ - || (REG_OK_FOR_BASE_P (XEXP (X, 1)) \ - && REG_OK_FOR_INDEX_P (XEXP (X, 0))))) - -#define LEGITIMATE_INDIRECT_ADDRESS_P(X) \ - (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) - -#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \ - (TARGET_ELF \ - && !flag_pic && !TARGET_TOC \ - && (MODE) != DImode \ - && (MODE) != TImode \ - && (TARGET_HARD_FLOAT || (MODE) != DFmode) \ - && GET_CODE (X) == LO_SUM \ - && GET_CODE (XEXP (X, 0)) == REG \ - && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && CONSTANT_P (XEXP (X, 1))) - -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \ - goto ADDR; \ - if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \ - && TARGET_UPDATE \ - && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \ - goto ADDR; \ - if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \ - goto ADDR; \ - if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X)) \ - goto ADDR; \ - if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X)) \ - goto ADDR; \ - if ((MODE) != TImode \ - && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \ - && (TARGET_POWERPC64 || (MODE) != DImode) \ - && LEGITIMATE_INDEXED_ADDRESS_P (X)) \ - goto ADDR; \ - if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X)) \ - goto ADDR; \ -} - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. - - On RS/6000, first check for the sum of a register with a constant - integer that is out of range. If so, generate code to add the - constant with the low-order 16 bits masked to the register and force - this result into another register (this can be done with `cau'). - Then generate an address of REG+(CONST&0xffff), allowing for the - possibility of bit 16 being a one. - - Then check for the sum of a register and something not constant, try to - load the other things into a register and return the sum. */ - -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ -{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \ - { HOST_WIDE_INT high_int, low_int; \ - rtx sum; \ - high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff); \ - low_int = INTVAL (XEXP (X, 1)) & 0xffff; \ - if (low_int & 0x8000) \ - high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16; \ - sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - GEN_INT (high_int)), 0); \ - (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); \ - goto WIN; \ - } \ - else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) != CONST_INT \ - && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \ - && (TARGET_POWERPC64 || (MODE) != DImode) \ - && (MODE) != TImode) \ - { \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \ - goto WIN; \ - } \ - else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC \ - && !flag_pic \ - && GET_CODE (X) != CONST_INT \ - && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X) \ - && (TARGET_HARD_FLOAT || (MODE) != DFmode) \ - && (MODE) != DImode && (MODE) != TImode) \ - { \ - rtx reg = gen_reg_rtx (Pmode); \ - emit_insn (gen_elf_high (reg, (X))); \ - (X) = gen_rtx_LO_SUM (Pmode, reg, (X)); \ - goto WIN; \ - } \ -} - -/* Try a machine-dependent way of reloading an illegitimate address - operand. If we find one, push the reload and jump to WIN. This - macro is used in only one place: `find_reloads_address' in reload.c. - - For RS/6000, we wish to handle large displacements off a base - register by splitting the addend across an addiu/addis and the mem insn. - This cuts number of extra insns needed from 3 to 1. */ - -#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ -do { \ - /* We must recognize output that we have already generated ourselves. */ \ - if (GET_CODE (X) == PLUS \ - && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ - && GET_CODE (XEXP (X, 1)) == CONST_INT) \ - { \ - push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \ - BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ - OPNUM, TYPE); \ - goto WIN; \ - } \ - if (GET_CODE (X) == PLUS \ - && GET_CODE (XEXP (X, 0)) == REG \ - && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \ - && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \ - && GET_CODE (XEXP (X, 1)) == CONST_INT) \ - { \ - HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \ - HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; \ - HOST_WIDE_INT high \ - = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; \ - \ - /* Check for 32-bit overflow. */ \ - if (high + low != val) \ - break; \ - \ - /* Reload the high part into a base reg; leave the low part \ - in the mem directly. */ \ - \ - X = gen_rtx_PLUS (GET_MODE (X), \ - gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \ - GEN_INT (high)), \ - GEN_INT (low)); \ - \ - push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \ - BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ - OPNUM, TYPE); \ - goto WIN; \ - } \ -} while (0) - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - - On the RS/6000 this is true if the address is valid with a zero offset - but not with an offset of four (this means it cannot be used as an - address for DImode or DFmode) or is a pre-increment or decrement. Since - we know it is valid, we just check for an address that is not valid with - an offset of four. */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ -{ if (GET_CODE (ADDR) == PLUS \ - && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), 0) \ - && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \ - (TARGET_32BIT ? 4 : 8))) \ - goto LABEL; \ - if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \ - goto LABEL; \ - if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \ - goto LABEL; \ - if (GET_CODE (ADDR) == LO_SUM) \ - goto LABEL; \ -} - -/* The register number of the register used to address a table of - static data addresses in memory. In some cases this register is - defined by a processor's "application binary interface" (ABI). - When this macro is defined, RTL is generated for this register - once, as with the stack pointer and frame pointer registers. If - this macro is not defined, it is up to the machine-dependent files - to allocate such a register (if necessary). */ - -/* #define PIC_OFFSET_TABLE_REGNUM */ - -/* Define this macro if the register defined by - `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define - this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */ - -/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */ - -/* By generating position-independent code, when two different - programs (A and B) share a common library (libC.a), the text of - the library can be shared whether or not the library is linked at - the same address for both programs. In some of these - environments, position-independent code requires not only the use - of different addressing modes, but also special code to enable the - use of these addressing modes. - - The `FINALIZE_PIC' macro serves as a hook to emit these special - codes once the function is being compiled into assembly code, but - not before. (It is not done before, because in the case of - compiling an inline function, it would lead to multiple PIC - prologues being included in functions which used inline functions - and were compiled to assembly language.) */ - -#define FINALIZE_PIC rs6000_finalize_pic () - -/* A C expression that is nonzero if X is a legitimate immediate - operand on the target machine when generating position independent - code. You can assume that X satisfies `CONSTANT_P', so you need - not check this. You can also assume FLAG_PIC is true, so you need - not check it either. You need not define this macro if all - constants (including `SYMBOL_REF') can be immediate operands when - generating position independent code. */ - -/* #define LEGITIMATE_PIC_OPERAND_P (X) */ - -/* In rare cases, correct code generation requires extra machine - dependent processing between the second jump optimization pass and - delayed branch scheduling. On those machines, define this macro - as a C statement to act on the code starting at INSN. - - On the RS/6000, we use it to make sure the GOT_TOC register marker - that FINALIZE_PIC is supposed to remove actually got removed. */ - -#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN) - - -/* Define this if some processing needs to be done immediately before - emitting code for an insn. */ - -/* #define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) */ - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE (TARGET_32BIT ? SImode : DImode) - -/* Define as C expression which evaluates to nonzero if the tablejump - instruction expects the table to contain offsets from the address of the - table. - Do not define this if the table should contain absolute addresses. */ -#define CASE_VECTOR_PC_RELATIVE 1 - -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 0 - -/* This flag, if defined, says the same insns that convert to a signed fixnum - also convert validly to an unsigned one. */ - -/* #define FIXUNS_TRUNC_LIKE_FIX_TRUNC */ - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX (! TARGET_POWERPC64 ? 4 : 8) -#define MAX_MOVE_MAX 8 - -/* Nonzero if access to memory by bytes is no faster than for words. - Also non-zero if doing byte operations (specifically shifts) in registers - is undesirable. */ -#define SLOW_BYTE_ACCESS 1 - -/* Define if operations between registers always perform the operation - on the full register even if a narrower mode is specified. */ -#define WORD_REGISTER_OPERATIONS - -/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD - will either zero-extend or sign-extend. The value of this macro should - be the code that says which one of the two operations is implicitly - done, NIL if none. */ -#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND - -/* Define if loading short immediate values into registers sign extends. */ -#define SHORT_IMMEDIATES_SIGN_EXTEND - -/* The RS/6000 uses the XCOFF format. */ - -#define XCOFF_DEBUGGING_INFO - -/* Define if the object format being used is COFF or a superset. */ -#define OBJECT_FORMAT_COFF - -/* Define the magic numbers that we recognize as COFF. - AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c - does not include files in the correct order to conditionally define - the symbolic name in this macro. */ -#define MY_ISCOFF(magic) \ - ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \ - || (magic) == U802TOCMAGIC || (magic) == 0757) - -/* This is the only version of nm that collect2 can work with. */ -#define REAL_NM_FILE_NAME "/usr/ucb/nm" - -/* We don't have GAS for the RS/6000 yet, so don't write out special - .stabs in cc1plus. */ - -#define FASCIST_ASSEMBLER - -/* AIX does not have any init/fini or ctor/dtor sections, so create - static constructors and destructors as normal functions. */ -/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */ -/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */ - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ -#define Pmode (TARGET_32BIT ? SImode : DImode) - -/* Mode of a function address in a call instruction (for indexing purposes). - Doesn't matter on RS/6000. */ -#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode) - -/* Define this if addresses of constant functions - shouldn't be put through pseudo regs where they can be cse'd. - Desirable on machines where ordinary constants are expensive - but a CALL with constant address is cheap. */ -#define NO_FUNCTION_CSE - -/* Define this to be nonzero if shift instructions ignore all but the low-order - few bits. - - The sle and sre instructions which allow SHIFT_COUNT_TRUNCATED - have been dropped from the PowerPC architecture. */ - -#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0) - -/* Use atexit for static constructors/destructors, instead of defining - our own exit function. */ -#define HAVE_ATEXIT - -/* Compute the cost of computing a constant rtl expression RTX - whose rtx-code is CODE. The body of this macro is a portion - of a switch statement. If the code is computed here, - return it with a return statement. Otherwise, break from the switch. - - On the RS/6000, if it is valid in the insn, it is free. So this - always returns 0. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - case CONST: \ - case LABEL_REF: \ - case SYMBOL_REF: \ - case CONST_DOUBLE: \ - case HIGH: \ - return 0; - -/* Provide the costs of a rtl expression. This is in the body of a - switch on CODE. */ - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case PLUS: \ - return ((GET_CODE (XEXP (X, 1)) == CONST_INT \ - && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) \ - + 0x8000) >= 0x10000) \ - && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \ - ? COSTS_N_INSNS (2) \ - : COSTS_N_INSNS (1)); \ - case AND: \ - case IOR: \ - case XOR: \ - return ((GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0 \ - && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \ - ? COSTS_N_INSNS (2) \ - : COSTS_N_INSNS (1)); \ - case MULT: \ - switch (rs6000_cpu) \ - { \ - case PROCESSOR_RIOS1: \ - return (GET_CODE (XEXP (X, 1)) != CONST_INT \ - ? COSTS_N_INSNS (5) \ - : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \ - ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \ - case PROCESSOR_RIOS2: \ - case PROCESSOR_MPCCORE: \ - case PROCESSOR_PPC604e: \ - return COSTS_N_INSNS (2); \ - case PROCESSOR_PPC601: \ - return COSTS_N_INSNS (5); \ - case PROCESSOR_PPC603: \ - case PROCESSOR_PPC750: \ - return (GET_CODE (XEXP (X, 1)) != CONST_INT \ - ? COSTS_N_INSNS (5) \ - : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \ - ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \ - case PROCESSOR_PPC403: \ - case PROCESSOR_PPC604: \ - case PROCESSOR_PPC620: \ - return COSTS_N_INSNS (4); \ - } \ - case DIV: \ - case MOD: \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \ - return COSTS_N_INSNS (2); \ - /* otherwise fall through to normal divide. */ \ - case UDIV: \ - case UMOD: \ - switch (rs6000_cpu) \ - { \ - case PROCESSOR_RIOS1: \ - return COSTS_N_INSNS (19); \ - case PROCESSOR_RIOS2: \ - return COSTS_N_INSNS (13); \ - case PROCESSOR_MPCCORE: \ - return COSTS_N_INSNS (6); \ - case PROCESSOR_PPC403: \ - return COSTS_N_INSNS (33); \ - case PROCESSOR_PPC601: \ - return COSTS_N_INSNS (36); \ - case PROCESSOR_PPC603: \ - return COSTS_N_INSNS (37); \ - case PROCESSOR_PPC604: \ - case PROCESSOR_PPC604e: \ - case PROCESSOR_PPC620: \ - return COSTS_N_INSNS (20); \ - case PROCESSOR_PPC750: \ - return COSTS_N_INSNS (19); \ - } \ - case FFS: \ - return COSTS_N_INSNS (4); \ - case MEM: \ - /* MEM should be slightly more expensive than (plus (reg) (const)) */ \ - return 5; - -/* Compute the cost of an address. This is meant to approximate the size - and/or execution delay of an insn using that address. If the cost is - approximated by the RTL complexity, including CONST_COSTS above, as - is usually the case for CISC machines, this macro should not be defined. - For aggressively RISCy machines, only one insn format is allowed, so - this macro should be a constant. The value of this macro only matters - for valid addresses. - - For the RS/6000, everything is cost 0. */ - -#define ADDRESS_COST(RTX) 0 - -/* Adjust the length of an INSN. LENGTH is the currently-computed length and - should be adjusted to reflect any required changes. This macro is used when - there is some systematic length adjustment required that would be difficult - to express in the length attribute. */ - -/* #define ADJUST_INSN_LENGTH(X,LENGTH) */ - -/* Add any extra modes needed to represent the condition code. - - For the RS/6000, we need separate modes when unsigned (logical) comparisons - are being done and we need a separate mode for floating-point. We also - use a mode for the case when we are comparing the results of two - comparisons. */ - -#define EXTRA_CC_MODES CCUNSmode, CCFPmode, CCEQmode - -/* Define the names for the modes specified above. */ -#define EXTRA_CC_NAMES "CCUNS", "CCFP", "CCEQ" - -/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, - return the mode to be used for the comparison. For floating-point, CCFPmode - should be used. CCUNSmode should be used for unsigned comparisons. - CCEQmode should be used when we are doing an inequality comparison on - the result of a comparison. CCmode should be used in all other cases. */ - -#define SELECT_CC_MODE(OP,X,Y) \ - (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \ - : (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \ - : (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<' \ - ? CCEQmode : CCmode)) - -/* Define the information needed to generate branch and scc insns. This is - stored from the compare operation. Note that we can't use "rtx" here - since it hasn't been defined! */ - -extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1; -extern int rs6000_compare_fp_p; - -/* Set to non-zero by "fix" operation to indicate that itrunc and - uitrunc must be defined. */ - -extern int rs6000_trunc_used; - -/* Function names to call to do floating point truncation. */ - -#define RS6000_ITRUNC "__itrunc" -#define RS6000_UITRUNC "__uitrunc" - -/* Prefix and suffix to use to saving floating point */ -#ifndef SAVE_FP_PREFIX -#define SAVE_FP_PREFIX "._savef" -#define SAVE_FP_SUFFIX "" -#endif - -/* Prefix and suffix to use to restoring floating point */ -#ifndef RESTORE_FP_PREFIX -#define RESTORE_FP_PREFIX "._restf" -#define RESTORE_FP_SUFFIX "" -#endif - -/* Function name to call to do profiling. */ -#define RS6000_MCOUNT ".__mcount" - - -/* Control the assembler format that we output. */ - -/* A C string constant describing how to begin a comment in the target - assembler language. The compiler assumes that the comment will end at - the end of the line. */ -#define ASM_COMMENT_START " #" - -/* Output at beginning of assembler file. - - Initialize the section names for the RS/6000 at this point. - - Specify filename to assembler. - - We want to go into the TOC section so at least one .toc will be emitted. - Also, in order to output proper .bs/.es pairs, we need at least one static - [RW] section emitted. - - We then switch back to text to force the gcc2_compiled. label and the space - allocated after it (when profiling) into the text section. - - Finally, declare mcount when profiling to make the assembler happy. */ - -#define ASM_FILE_START(FILE) \ -{ \ - rs6000_gen_section_name (&xcoff_bss_section_name, \ - main_input_filename, ".bss_"); \ - rs6000_gen_section_name (&xcoff_private_data_section_name, \ - main_input_filename, ".rw_"); \ - rs6000_gen_section_name (&xcoff_read_only_section_name, \ - main_input_filename, ".ro_"); \ - \ - output_file_directive (FILE, main_input_filename); \ - if (TARGET_64BIT) \ - fputs ("\t.machine\t\"ppc64\"\n", FILE); \ - toc_section (); \ - if (write_symbols != NO_DEBUG) \ - private_data_section (); \ - text_section (); \ - if (profile_flag) \ - fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT); \ - rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ -} - -/* Output at end of assembler file. - - On the RS/6000, referencing data should automatically pull in text. */ - -#define ASM_FILE_END(FILE) \ -{ \ - text_section (); \ - fputs ("_section_.text:\n", FILE); \ - data_section (); \ - fputs ("\t.long _section_.text\n", FILE); \ -} - -/* We define this to prevent the name mangler from putting dollar signs into - function names. */ - -#define NO_DOLLAR_IN_LABEL - -/* We define this to 0 so that gcc will never accept a dollar sign in a - variable name. This is needed because the AIX assembler will not accept - dollar signs. */ - -#define DOLLARS_IN_IDENTIFIERS 0 - -/* Implicit library calls should use memcpy, not bcopy, etc. */ - -#define TARGET_MEM_FUNCTIONS - -/* Define the extra sections we need. We define three: one is the read-only - data section which is used for constants. This is a csect whose name is - derived from the name of the input file. The second is for initialized - global variables. This is a csect whose name is that of the variable. - The third is the TOC. */ - -#define EXTRA_SECTIONS \ - read_only_data, private_data, read_only_private_data, toc, bss - -/* Define the name of our readonly data section. */ - -#define READONLY_DATA_SECTION read_only_data_section - - -/* Define the name of the section to use for the exception tables. - TODO: test and see if we can use read_only_data_section, if so, - remove this. */ - -#define EXCEPTION_SECTION data_section - -/* If we are referencing a function that is static or is known to be - in this file, make the SYMBOL_REF special. We can use this to indicate - that we can branch to this function without emitting a no-op after the - call. */ - -#define ENCODE_SECTION_INFO(DECL) \ - if (TREE_CODE (DECL) == FUNCTION_DECL \ - && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \ - SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; - -/* Indicate that jump tables go in the text section. */ - -#define JUMP_TABLES_IN_TEXT_SECTION 1 - -/* Define the routines to implement these extra sections. */ - -#define EXTRA_SECTION_FUNCTIONS \ - \ -void \ -read_only_data_section () \ -{ \ - if (in_section != read_only_data) \ - { \ - fprintf (asm_out_file, ".csect %s[RO]\n", \ - xcoff_read_only_section_name); \ - in_section = read_only_data; \ - } \ -} \ - \ -void \ -private_data_section () \ -{ \ - if (in_section != private_data) \ - { \ - fprintf (asm_out_file, ".csect %s[RW]\n", \ - xcoff_private_data_section_name); \ - \ - in_section = private_data; \ - } \ -} \ - \ -void \ -read_only_private_data_section () \ -{ \ - if (in_section != read_only_private_data) \ - { \ - fprintf (asm_out_file, ".csect %s[RO]\n", \ - xcoff_private_data_section_name); \ - in_section = read_only_private_data; \ - } \ -} \ - \ -void \ -toc_section () \ -{ \ - if (TARGET_MINIMAL_TOC) \ - { \ - /* toc_section is always called at least once from ASM_FILE_START, \ - so this is guaranteed to always be defined once and only once \ - in each file. */ \ - if (! toc_initialized) \ - { \ - fputs (".toc\nLCTOC..0:\n", asm_out_file); \ - fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \ - toc_initialized = 1; \ - } \ - \ - if (in_section != toc) \ - fputs (".csect toc_table[RW]\n", asm_out_file); \ - } \ - else \ - { \ - if (in_section != toc) \ - fputs (".toc\n", asm_out_file); \ - } \ - in_section = toc; \ -} - -/* Flag to say the TOC is initialized */ -extern int toc_initialized; - -/* This macro produces the initial definition of a function name. - On the RS/6000, we need to place an extra '.' in the function name and - output the function descriptor. - - The csect for the function will have already been created by the - `text_section' call previously done. We do have to go back to that - csect, however. */ - -/* ??? What do the 16 and 044 in the .function line really mean? */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ -{ if (TREE_PUBLIC (DECL)) \ - { \ - fputs ("\t.globl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - putc ('\n', FILE); \ - } \ - else \ - { \ - fputs ("\t.lglobl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - putc ('\n', FILE); \ - } \ - fputs (".csect ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (":\n", FILE); \ - fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (", TOC[tc0], 0\n", FILE); \ - fputs (".csect .text[PR]\n.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (":\n", FILE); \ - if (write_symbols == XCOFF_DEBUG) \ - xcoffout_declare_function (FILE, DECL, NAME); \ -} - -/* Return non-zero if this entry is to be written into the constant pool - in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST - containing one of them. If -mfp-in-toc (the default), we also do - this for floating-point constants. We actually can only do this - if the FP formats of the target and host machines are the same, but - we can't check that since not every file that uses - GO_IF_LEGITIMATE_ADDRESS_P includes real.h. */ - -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \ - && GET_CODE (X) == CONST_DOUBLE \ - && (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - || (TARGET_POWERPC64 && GET_MODE (X) == DImode))))) -#if 0 - && BITS_PER_WORD == HOST_BITS_PER_INT))) -#endif - -/* Select section for constant in constant pool. - - On RS/6000, all constants are in the private read-only data area. - However, if this is being placed in the TOC it must be output as a - toc entry. */ - -#define SELECT_RTX_SECTION(MODE, X) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ - toc_section (); \ - else \ - read_only_private_data_section (); \ -} - -/* Macro to output a special constant pool entry. Go to WIN if we output - it. Otherwise, it is written the usual way. - - On the RS/6000, toc entries are handled this way. */ - -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ - { \ - output_toc (FILE, X, LABELNO); \ - goto WIN; \ - } \ -} - -/* Select the section for an initialized data object. - - On the RS/6000, we have a special section for all variables except those - that are static. */ - -#define SELECT_SECTION(EXP,RELOC) \ -{ \ - if ((TREE_CODE (EXP) == STRING_CST \ - && !flag_writable_strings) \ - || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd' \ - && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \ - && DECL_INITIAL (EXP) \ - && (DECL_INITIAL (EXP) == error_mark_node \ - || TREE_CONSTANT (DECL_INITIAL (EXP))) \ - && ! (RELOC))) \ - { \ - if (TREE_PUBLIC (EXP)) \ - read_only_data_section (); \ - else \ - read_only_private_data_section (); \ - } \ - else \ - { \ - if (TREE_PUBLIC (EXP)) \ - data_section (); \ - else \ - private_data_section (); \ - } \ -} - -/* This outputs NAME to FILE up to the first null or '['. */ - -#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ - { \ - char *_p; \ - \ - STRIP_NAME_ENCODING (_p, (NAME)); \ - assemble_name ((FILE), _p); \ - } - -/* Remove any trailing [DS] or the like from the symbol name. */ - -#define STRIP_NAME_ENCODING(VAR,NAME) \ - do \ - { \ - char *_name = (NAME); \ - int _len; \ - if (_name[0] == '*') \ - _name++; \ - _len = strlen (_name); \ - if (_name[_len - 1] != ']') \ - (VAR) = _name; \ - else \ - { \ - (VAR) = (char *) alloca (_len + 1); \ - strcpy ((VAR), _name); \ - (VAR)[_len - 4] = '\0'; \ - } \ - } \ - while (0) - -/* Output something to declare an external symbol to the assembler. Most - assemblers don't need this. - - If we haven't already, add "[RW]" (or "[DS]" for a function) to the - name. Normally we write this out along with the name. In the few cases - where we can't, it gets stripped off. */ - -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ - fputs ("\t.extern ", FILE); \ - assemble_name (FILE, XSTR (_symref, 0)); \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - { \ - fputs ("\n\t.extern .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0)); \ - } \ - putc ('\n', FILE); \ -} - -/* Similar, but for libcall. We only have to worry about the function name, - not that of the descriptor. */ - -#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ -{ fputs ("\t.extern .", FILE); \ - assemble_name (FILE, XSTR (FUN, 0)); \ - putc ('\n', FILE); \ -} - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#define ASM_APP_ON "" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "" - -/* Output before instructions. */ - -#define TEXT_SECTION_ASM_OP ".csect .text[PR]" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP ".csect .data[RW]" - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ - -#define REGISTER_NAMES \ -{ \ - &rs6000_reg_names[ 0][0], /* r0 */ \ - &rs6000_reg_names[ 1][0], /* r1 */ \ - &rs6000_reg_names[ 2][0], /* r2 */ \ - &rs6000_reg_names[ 3][0], /* r3 */ \ - &rs6000_reg_names[ 4][0], /* r4 */ \ - &rs6000_reg_names[ 5][0], /* r5 */ \ - &rs6000_reg_names[ 6][0], /* r6 */ \ - &rs6000_reg_names[ 7][0], /* r7 */ \ - &rs6000_reg_names[ 8][0], /* r8 */ \ - &rs6000_reg_names[ 9][0], /* r9 */ \ - &rs6000_reg_names[10][0], /* r10 */ \ - &rs6000_reg_names[11][0], /* r11 */ \ - &rs6000_reg_names[12][0], /* r12 */ \ - &rs6000_reg_names[13][0], /* r13 */ \ - &rs6000_reg_names[14][0], /* r14 */ \ - &rs6000_reg_names[15][0], /* r15 */ \ - &rs6000_reg_names[16][0], /* r16 */ \ - &rs6000_reg_names[17][0], /* r17 */ \ - &rs6000_reg_names[18][0], /* r18 */ \ - &rs6000_reg_names[19][0], /* r19 */ \ - &rs6000_reg_names[20][0], /* r20 */ \ - &rs6000_reg_names[21][0], /* r21 */ \ - &rs6000_reg_names[22][0], /* r22 */ \ - &rs6000_reg_names[23][0], /* r23 */ \ - &rs6000_reg_names[24][0], /* r24 */ \ - &rs6000_reg_names[25][0], /* r25 */ \ - &rs6000_reg_names[26][0], /* r26 */ \ - &rs6000_reg_names[27][0], /* r27 */ \ - &rs6000_reg_names[28][0], /* r28 */ \ - &rs6000_reg_names[29][0], /* r29 */ \ - &rs6000_reg_names[30][0], /* r30 */ \ - &rs6000_reg_names[31][0], /* r31 */ \ - \ - &rs6000_reg_names[32][0], /* fr0 */ \ - &rs6000_reg_names[33][0], /* fr1 */ \ - &rs6000_reg_names[34][0], /* fr2 */ \ - &rs6000_reg_names[35][0], /* fr3 */ \ - &rs6000_reg_names[36][0], /* fr4 */ \ - &rs6000_reg_names[37][0], /* fr5 */ \ - &rs6000_reg_names[38][0], /* fr6 */ \ - &rs6000_reg_names[39][0], /* fr7 */ \ - &rs6000_reg_names[40][0], /* fr8 */ \ - &rs6000_reg_names[41][0], /* fr9 */ \ - &rs6000_reg_names[42][0], /* fr10 */ \ - &rs6000_reg_names[43][0], /* fr11 */ \ - &rs6000_reg_names[44][0], /* fr12 */ \ - &rs6000_reg_names[45][0], /* fr13 */ \ - &rs6000_reg_names[46][0], /* fr14 */ \ - &rs6000_reg_names[47][0], /* fr15 */ \ - &rs6000_reg_names[48][0], /* fr16 */ \ - &rs6000_reg_names[49][0], /* fr17 */ \ - &rs6000_reg_names[50][0], /* fr18 */ \ - &rs6000_reg_names[51][0], /* fr19 */ \ - &rs6000_reg_names[52][0], /* fr20 */ \ - &rs6000_reg_names[53][0], /* fr21 */ \ - &rs6000_reg_names[54][0], /* fr22 */ \ - &rs6000_reg_names[55][0], /* fr23 */ \ - &rs6000_reg_names[56][0], /* fr24 */ \ - &rs6000_reg_names[57][0], /* fr25 */ \ - &rs6000_reg_names[58][0], /* fr26 */ \ - &rs6000_reg_names[59][0], /* fr27 */ \ - &rs6000_reg_names[60][0], /* fr28 */ \ - &rs6000_reg_names[61][0], /* fr29 */ \ - &rs6000_reg_names[62][0], /* fr30 */ \ - &rs6000_reg_names[63][0], /* fr31 */ \ - \ - &rs6000_reg_names[64][0], /* mq */ \ - &rs6000_reg_names[65][0], /* lr */ \ - &rs6000_reg_names[66][0], /* ctr */ \ - &rs6000_reg_names[67][0], /* ap */ \ - \ - &rs6000_reg_names[68][0], /* cr0 */ \ - &rs6000_reg_names[69][0], /* cr1 */ \ - &rs6000_reg_names[70][0], /* cr2 */ \ - &rs6000_reg_names[71][0], /* cr3 */ \ - &rs6000_reg_names[72][0], /* cr4 */ \ - &rs6000_reg_names[73][0], /* cr5 */ \ - &rs6000_reg_names[74][0], /* cr6 */ \ - &rs6000_reg_names[75][0], /* cr7 */ \ - \ - &rs6000_reg_names[76][0], /* fpmem */ \ -} - -/* print-rtl can't handle the above REGISTER_NAMES, so define the - following for it. Switch to use the alternate names since - they are more mnemonic. */ - -#define DEBUG_REGISTER_NAMES \ -{ \ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \ - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ - "mq", "lr", "ctr", "ap", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "fpmem" \ -} - -/* Table of additional register names to use in user input. */ - -#define ADDITIONAL_REGISTER_NAMES \ - {{"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3}, \ - {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7}, \ - {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11}, \ - {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15}, \ - {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19}, \ - {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23}, \ - {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27}, \ - {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31}, \ - {"fr0", 32}, {"fr1", 33}, {"fr2", 34}, {"fr3", 35}, \ - {"fr4", 36}, {"fr5", 37}, {"fr6", 38}, {"fr7", 39}, \ - {"fr8", 40}, {"fr9", 41}, {"fr10", 42}, {"fr11", 43}, \ - {"fr12", 44}, {"fr13", 45}, {"fr14", 46}, {"fr15", 47}, \ - {"fr16", 48}, {"fr17", 49}, {"fr18", 50}, {"fr19", 51}, \ - {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \ - {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \ - {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63}, \ - /* no additional names for: mq, lr, ctr, ap */ \ - {"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \ - {"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \ - {"cc", 68}, {"sp", 1}, {"toc", 2} } - -/* How to renumber registers for dbx and gdb. */ - -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) - -/* Text to write out after a CALL that may be replaced by glue code by - the loader. This depends on the AIX version. */ -#define RS6000_CALL_GLUE "cror 31,31,31" - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fputs ("\t.globl ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); fputs ("\n", FILE);} while (0) - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fputs (NAME, FILE) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s..%d:\n", PREFIX, NUM) - -/* This is how to output an internal label prefix. rs6000.c uses this - when generating traceback tables. */ - -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, "%s..", PREFIX) - -/* This is how to output a label for a jump table. Arguments are the same as - for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is - passed. */ - -#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \ -{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); } - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s..%d", PREFIX, NUM) - -/* This is how to output an assembler line defining a `double' constant. */ - -#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \ - t[0] & 0xffffffff, t[1] & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \ - fprintf (FILE, "\t.double 0d%s\n", str); \ - } \ - } - -/* This is how to output an assembler line defining a `float' constant. */ - -#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t.float 0d%s\n", str); \ - } \ - } - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE) \ -do { \ - if (TARGET_32BIT) \ - { \ - assemble_integer (operand_subword ((VALUE), 0, 0, DImode), \ - UNITS_PER_WORD, 1); \ - assemble_integer (operand_subword ((VALUE), 1, 0, DImode), \ - UNITS_PER_WORD, 1); \ - } \ - else \ - { \ - fputs ("\t.llong ", FILE); \ - output_addr_const (FILE, (VALUE)); \ - putc ('\n', FILE); \ - } \ -} while (0) - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fputs ("\t.long ", FILE), \ - output_addr_const (FILE, (VALUE)), \ - putc ('\n', FILE)) - -/* Likewise for `char' and `short' constants. */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fputs ("\t.short ", FILE), \ - output_addr_const (FILE, (VALUE)), \ - putc ('\n', FILE)) - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fputs ("\t.byte ", FILE), \ - output_addr_const (FILE, (VALUE)), \ - putc ('\n', FILE)) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf (FILE, "\t.byte 0x%x\n", (VALUE)) - -/* This is how to output an assembler line to define N characters starting - at P to FILE. */ - -#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N)) - -/* This is how to output code to push a register on the stack. - It need not be very fast code. - - On the rs6000, we must keep the backchain up to date. In order - to simplify things, always allocate 16 bytes for a push (System V - wants to keep stack aligned to a 16 byte boundary). */ - -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ -do { \ - extern char *reg_names[]; \ - asm_fprintf (FILE, "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,8(%s)\n", \ - reg_names[1], reg_names[1], reg_names[REGNO], \ - reg_names[1]); \ -} while (0) - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ -do { \ - extern char *reg_names[]; \ - asm_fprintf (FILE, "\t{l|lwz} %s,8(%s)\n\t{ai|addic} %s,%s,16\n", \ - reg_names[REGNO], reg_names[1], reg_names[1], \ - reg_names[1]); \ -} while (0) - -/* This is how to output an element of a case-vector that is absolute. - (RS/6000 does not use such vectors, but we must define this macro - anyway.) */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - do { char buf[100]; \ - fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ - assemble_name (FILE, buf); \ - putc ('\n', FILE); \ - } while (0) - -/* This is how to output an element of a case-vector that is relative. */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)\ - do { char buf[100]; \ - fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ - assemble_name (FILE, buf); \ - putc ('-', FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", REL); \ - assemble_name (FILE, buf); \ - putc ('\n', FILE); \ - } while (0) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) != 0) \ - fprintf (FILE, "\t.align %d\n", (LOG)) - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.space %d\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \ - do { fputs (".comm ", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - if ( (SIZE) > 4) \ - fprintf ((FILE), ",%d,3\n", (SIZE)); \ - else \ - fprintf( (FILE), ",%d\n", (SIZE)); \ - } while (0) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \ - do { fputs (".lcomm ", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fprintf ((FILE), ",%d,%s\n", (SIZE), xcoff_bss_section_name); \ - } while (0) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) - -/* Define the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "(" -#define ASM_CLOSE_PAREN ")" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and X is null. */ - -#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE) - -/* Define which CODE values are valid. */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '.' || (CODE) == '*' || (CODE) == '$') - -/* Print a memory address as an operand to reference that memory location. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) - -/* Define the codes that are matched by predicates in rs6000.c. */ - -#define PREDICATE_CODES \ - {"short_cint_operand", {CONST_INT, CONSTANT_P_RTX}}, \ - {"u_short_cint_operand", {CONST_INT, CONSTANT_P_RTX}}, \ - {"non_short_cint_operand", {CONST_INT}}, \ - {"gpc_reg_operand", {SUBREG, REG}}, \ - {"cc_reg_operand", {SUBREG, REG}}, \ - {"cc_reg_not_cr0_operand", {SUBREG, REG}}, \ - {"reg_or_short_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \ - {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"reg_or_cint_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ - {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \ - {"easy_fp_constant", {CONST_DOUBLE}}, \ - {"reg_or_mem_operand", {SUBREG, MEM, REG}}, \ - {"lwa_operand", {SUBREG, MEM, REG}}, \ - {"volatile_mem_operand", {MEM}}, \ - {"offsettable_addr_operand", {REG, SUBREG, PLUS}}, \ - {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \ - {"add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"non_add_cint_operand", {CONST_INT}}, \ - {"and_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"and64_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX, \ - CONST_DOUBLE}}, \ - {"logical_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"non_logical_cint_operand", {CONST_INT}}, \ - {"mask_operand", {CONST_INT}}, \ - {"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \ - {"count_register_operand", {REG}}, \ - {"fpmem_operand", {REG}}, \ - {"call_operand", {SYMBOL_REF, REG}}, \ - {"current_file_function_operand", {SYMBOL_REF}}, \ - {"input_operand", {SUBREG, MEM, REG, CONST_INT, CONSTANT_P_RTX, \ - CONST_DOUBLE, SYMBOL_REF}}, \ - {"load_multiple_operation", {PARALLEL}}, \ - {"store_multiple_operation", {PARALLEL}}, \ - {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \ - GT, LEU, LTU, GEU, GTU}}, \ - {"scc_comparison_operator", {EQ, NE, LE, LT, GE, \ - GT, LEU, LTU, GEU, GTU}}, \ - {"trap_comparison_operator", {EQ, NE, LE, LT, GE, \ - GT, LEU, LTU, GEU, GTU}}, - -/* uncomment for disabling the corresponding default options */ -/* #define MACHINE_no_sched_interblock */ -/* #define MACHINE_no_sched_speculative */ -/* #define MACHINE_no_sched_speculative_load */ - -/* indicate that issue rate is defined for this machine - (no need to use the default) */ -#define ISSUE_RATE get_issue_rate () - -/* General flags. */ -extern int flag_pic; -extern int optimize; -extern int flag_expensive_optimizations; -extern int frame_pointer_needed; - -/* Declare functions in rs6000.c */ -extern void output_options (); -extern void rs6000_override_options (); -extern void rs6000_file_start (); -extern struct rtx_def *rs6000_float_const (); -extern struct rtx_def *rs6000_got_register (); -extern int direct_return (); -extern int get_issue_rate (); -extern int any_operand (); -extern int short_cint_operand (); -extern int u_short_cint_operand (); -extern int non_short_cint_operand (); -extern int gpc_reg_operand (); -extern int cc_reg_operand (); -extern int cc_reg_not_cr0_operand (); -extern int reg_or_short_operand (); -extern int reg_or_neg_short_operand (); -extern int reg_or_u_short_operand (); -extern int reg_or_cint_operand (); -extern int got_operand (); -extern int got_no_const_operand (); -extern int num_insns_constant (); -extern int easy_fp_constant (); -extern int volatile_mem_operand (); -extern int offsettable_addr_operand (); -extern int mem_or_easy_const_operand (); -extern int add_operand (); -extern int non_add_cint_operand (); -extern int non_logical_cint_operand (); -extern int logical_operand (); -extern int mask_constant (); -extern int mask_operand (); -extern int mask64_operand (); -extern int and64_operand (); -extern int and_operand (); -extern int count_register_operand (); -extern int fpmem_operand (); -extern int reg_or_mem_operand (); -extern int lwa_operand (); -extern int call_operand (); -extern int current_file_function_operand (); -extern int input_operand (); -extern int small_data_operand (); -extern void init_cumulative_args (); -extern void function_arg_advance (); -extern int function_arg_boundary (); -extern struct rtx_def *function_arg (); -extern int function_arg_partial_nregs (); -extern int function_arg_pass_by_reference (); -extern void setup_incoming_varargs (); -extern struct rtx_def *expand_builtin_saveregs (); -extern struct rtx_def *rs6000_stack_temp (); -extern int expand_block_move (); -extern int load_multiple_operation (); -extern int store_multiple_operation (); -extern int branch_comparison_operator (); -extern int scc_comparison_operator (); -extern int trap_comparison_operator (); -extern int includes_lshift_p (); -extern int includes_rshift_p (); -extern int registers_ok_for_quad_peep (); -extern int addrs_ok_for_quad_peep (); -extern enum reg_class secondary_reload_class (); -extern int ccr_bit (); -extern void rs6000_finalize_pic (); -extern void rs6000_reorg (); -extern void rs6000_save_machine_status (); -extern void rs6000_restore_machine_status (); -extern void rs6000_init_expanders (); -extern void print_operand (); -extern void print_operand_address (); -extern int first_reg_to_save (); -extern int first_fp_reg_to_save (); -extern int rs6000_makes_calls (); -extern rs6000_stack_t *rs6000_stack_info (); -extern void output_prolog (); -extern void output_epilog (); -extern void output_mi_thunk (); -extern void output_toc (); -extern void output_ascii (); -extern void rs6000_gen_section_name (); -extern void output_function_profiler (); -extern int rs6000_adjust_cost (); -extern int rs6000_adjust_priority (); -extern void rs6000_trampoline_template (); -extern int rs6000_trampoline_size (); -extern void rs6000_initialize_trampoline (); -extern void rs6000_output_load_toc_table (); -extern int rs6000_comp_type_attributes (); -extern int rs6000_valid_decl_attribute_p (); -extern int rs6000_valid_type_attribute_p (); -extern void rs6000_set_default_type_attributes (); -extern struct rtx_def *rs6000_dll_import_ref (); -extern struct rtx_def *rs6000_longcall_ref (); -extern int function_arg_padding (); -extern void toc_section (); -extern void private_data_section (); -extern void rs6000_fatal_bad_address (); -/* CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling. */ -extern void rs6000_expand_prologue (); -extern void rs6000_expand_epilogue (); -/* END CYGNUS LOCAL */ - -/* See nonlocal_goto_receiver for when this must be set. */ - -#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_TOC && TARGET_MINIMAL_TOC) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md deleted file mode 100755 index 9891796..0000000 --- a/gcc/config/rs6000/rs6000.md +++ /dev/null @@ -1,13242 +0,0 @@ -;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990, 91-98, 1999 Free Software Foundation, Inc. -;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - -;; This file is part of GNU CC. - -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Define an insn type attribute. This is used in function unit delay -;; computations. -(define_attr "type" "integer,load,store,fpload,fpstore,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg" - (const_string "integer")) - -;; Length (in bytes). -(define_attr "length" "" - (if_then_else (eq_attr "type" "branch") - (if_then_else (and (ge (minus (pc) (match_dup 0)) - (const_int -32768)) - (lt (minus (pc) (match_dup 0)) - (const_int 32767))) - (const_int 8) - (const_int 12)) - (const_int 4))) - -;; Processor type -- this attribute must exactly match the processor_type -;; enumeration in rs6000.h. - -(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750" - (const (symbol_ref "rs6000_cpu_attr"))) - -; (define_function_unit NAME MULTIPLICITY SIMULTANEITY -; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) - -; Load/Store Unit -- pure PowerPC only -; (POWER and 601 use Integer Unit) -(define_function_unit "lsu" 1 0 - (and (eq_attr "type" "load") - (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620,ppc750")) - 2 1) - -(define_function_unit "lsu" 1 0 - (and (eq_attr "type" "store,fpstore") - (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620,ppc750")) - 1 1) - -(define_function_unit "lsu" 1 0 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "mpccore,ppc603,ppc750")) - 2 1) - -(define_function_unit "lsu" 1 0 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "ppc604,ppc604e,ppc620")) - 3 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "load") - (eq_attr "cpu" "rios1,ppc403,ppc601")) - 2 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "store,fpstore") - (eq_attr "cpu" "rios1,ppc403,ppc601")) - 1 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "rios1,ppc601")) - 0 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "rios1")) - 2 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "ppc601")) - 3 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "load,fpload") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "store,fpstore") - (eq_attr "cpu" "rios2")) - 1 1) - -; Integer Unit (RIOS1, PPC601, PPC603) -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "integer") - (eq_attr "cpu" "rios1,mpccore,ppc403,ppc601,ppc603")) - 1 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppc403")) - 4 4) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "rios1,ppc601,ppc603")) - 5 5) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "rios1")) - 19 19) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc403")) - 33 33) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc601")) - 36 36) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc603")) - 37 36) - -; RIOS2 has two integer units: a primary one which can perform all -; operations and a secondary one which is fed in lock step with the first -; and can perform "simple" integer operations. -; To catch this we define a 'dummy' imuldiv-unit that is also needed -; for the complex insns. -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "integer") - (eq_attr "cpu" "rios2")) - 1 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "rios2")) - 2 2) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "rios2")) - 13 13) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "rios2")) - 2 2) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "rios2")) - 13 13) - -; MPCCORE has separate IMUL/IDIV unit for multicycle instructions -; Divide latency varies greatly from 2-11, use 6 as average -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "mpccore")) - 2 1) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "mpccore")) - 6 6) - -; PPC604{,e} has two units that perform integer operations -; and one unit for divide/multiply operations (and move -; from/to spr). -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "integer") - (eq_attr "cpu" "ppc604,ppc604e,ppc620")) - 1 1) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppc604,ppc620")) - 4 2) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppc604e")) - 2 1) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc604,ppc604e,ppc620")) - 20 19) - -; PPC750 has two integer units: a primary one which can perform all -; operations and a secondary one which is fed in lock step with the first -; and can perform "simple" integer operations. -; To catch this we define a 'dummy' imuldiv-unit that is also needed -; for the complex insns. -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "integer") - (eq_attr "cpu" "ppc750")) - 1 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppc750")) - 4 2) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppc750")) - 4 2) - -(define_function_unit "imuldiv" 1 0 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc750")) - 19 19) - -; compare is done on integer unit, but feeds insns which -; execute on the branch unit. -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "compare") - (eq_attr "cpu" "rios1")) - 4 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "delayed_compare") - (eq_attr "cpu" "rios1")) - 5 1) - -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "compare,delayed_compare") - (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750")) - 3 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "compare,delayed_compare") - (eq_attr "cpu" "rios2")) - 3 1) - -(define_function_unit "iu2" 2 0 - (and (eq_attr "type" "compare,delayed_compare") - (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc750")) - 1 1) - -; fp compare uses fp unit -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "rios1")) - 9 1) - -; rios1 and rios2 have different fpcompare delays -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "rios2")) - 5 1) - -; on ppc601 and ppc603, fpcompare takes also 2 cycles from -; the integer unit -; here we do not define delays, just occupy the unit. The dependencies -; will be assigned by the fpcompare definition in the fpu. -(define_function_unit "iu" 1 0 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppc601,ppc603")) - 0 2) - -; fp compare uses fp unit -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750")) - 5 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "mpccore")) - 1 1) - -(define_function_unit "bpu" 1 0 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "rios1,rios2")) - 5 1) - -(define_function_unit "bpu" 1 0 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750")) - 4 1) - -; all jumps/branches are executing on the bpu, in 1 cycle, for all machines. -(define_function_unit "bpu" 1 0 - (eq_attr "type" "jmpreg") - 1 1) - -(define_function_unit "bpu" 1 0 - (eq_attr "type" "branch") - 1 1) - -; Floating Point Unit -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fp,dmul") - (eq_attr "cpu" "rios1")) - 2 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "mpccore")) - 4 4) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppc601")) - 4 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620,ppc750")) - 3 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "mpccore")) - 5 5) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppc601")) - 5 2) - -; is this true? -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppc603,ppc750")) - 4 2) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppc604,ppc604e,ppc620")) - 3 1) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "sdiv,ddiv") - (eq_attr "cpu" "rios1")) - 19 19) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppc601")) - 17 17) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "mpccore")) - 10 10) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620")) - 18 18) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "mpccore")) - 17 17) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppc601,ppc604,ppc604e,ppc620,ppc750")) - 31 31) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppc603")) - 33 33) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "ssqrt") - (eq_attr "cpu" "ppc620")) - 31 31) - -(define_function_unit "fpu" 1 0 - (and (eq_attr "type" "dsqrt") - (eq_attr "cpu" "ppc620")) - 31 31) - -; RIOS2 has two symmetric FPUs. -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "sdiv,ddiv") - (eq_attr "cpu" "rios2")) - 17 17) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "ssqrt,dsqrt") - (eq_attr "cpu" "rios2")) - 26 26) - - -;; Start with fixed-point load and store insns. Here we put only the more -;; complex forms. Basic data transfer is done later. - -(define_expand "zero_extendqidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lbz%U1%X1 %0,%1 - rldicl %0,%1,0,56" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - rldicl. %2,%1,0,56 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - rldicl. %0,%1,0,56 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "extendqidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "extsb %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "zero_extendhidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lhz%U1%X1 %0,%1 - rldicl %0,%1,0,48" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - rldicl. %2,%1,0,48 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - rldicl. %0,%1,0,48 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendhidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lha%U1%X1 %0,%1 - extsh %0,%1" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - extsh. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - extsh. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "zero_extendsidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lwz%U1%X1 %0,%1 - rldicl %0,%1,0,32" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - rldicl. %2,%1,0,32 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - rldicl. %0,%1,0,32 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendsidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lwa%U1%X1 %0,%1 - extsw %0,%1" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - extsw. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - extsw. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lbz%U1%X1 %0,%1 - {rlinm|rlwinm} %0,%1,0,0xff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - {andil.|andi.} %2,%1,0xff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_dup 1)))] - "" - "@ - {andil.|andi.} %0,%1,0xff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendqisi2" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:QI 1 "gpc_reg_operand" ""))] - "" - " -{ - if (TARGET_POWERPC) - emit_insn (gen_extendqisi2_ppc (operands[0], operands[1])); - else if (TARGET_POWER) - emit_insn (gen_extendqisi2_power (operands[0], operands[1])); - else - emit_insn (gen_extendqisi2_no_power (operands[0], operands[1])); - DONE; -}") - -(define_insn "extendqisi2_ppc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC" - "extsb %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "TARGET_POWERPC" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 2) - (sign_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_dup 1)))] - "TARGET_POWERPC" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_dup 1)))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendqisi2_power" - [(parallel [(set (match_dup 2) - (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") - (const_int 24))) - (clobber (scratch:SI))]) - (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 2) - (const_int 24))) - (clobber (scratch:SI))])] - "TARGET_POWER" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_reg_rtx (SImode); }") - -(define_expand "extendqisi2_no_power" - [(set (match_dup 2) - (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") - (const_int 24))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 2) - (const_int 24)))] - "! TARGET_POWER && ! TARGET_POWERPC" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_reg_rtx (SImode); }") - -(define_expand "zero_extendqihi2" - [(set (match_operand:HI 0 "gpc_reg_operand" "") - (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lbz%U1%X1 %0,%1 - {rlinm|rlwinm} %0,%1,0,0xff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:HI 2 "=r,r"))] - "" - "@ - {andil.|andi.} %2,%1,0xff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - " -{ - rtx reg; - int offset; - if (GET_CODE (operands[2]) == REG) - { - reg = operands[2]; - offset = 0; - } - else if (GET_CODE (operands[2]) == SUBREG) - { - reg = SUBREG_REG (operands[2]); - offset = SUBREG_WORD (operands[2]); - } - else - abort (); - - operands[3] = gen_rtx_SUBREG (SImode, reg, offset); -}") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (zero_extend:HI (match_dup 1)))] - "" - "@ - {andil.|andi.} %0,%1,0xff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (zero_extend:HI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:HI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 3) - (const_int 0)))] - " -{ - rtx reg; - int offset; - if (GET_CODE (operands[0]) == REG) - { - reg = operands[2]; - offset = 0; - } - else if (GET_CODE (operands[2]) == SUBREG) - { - reg = SUBREG_REG (operands[2]); - offset = SUBREG_WORD (operands[2]); - } - else - abort (); - - operands[3] = gen_rtx_SUBREG (SImode, reg, offset); -}") - -(define_expand "extendqihi2" - [(use (match_operand:HI 0 "gpc_reg_operand" "")) - (use (match_operand:QI 1 "gpc_reg_operand" ""))] - "" - " -{ - if (TARGET_POWERPC) - emit_insn (gen_extendqihi2_ppc (operands[0], operands[1])); - else if (TARGET_POWER) - emit_insn (gen_extendqihi2_power (operands[0], operands[1])); - else - emit_insn (gen_extendqihi2_no_power (operands[0], operands[1])); - DONE; -}") - -(define_insn "extendqihi2_ppc" - [(set (match_operand:HI 0 "gpc_reg_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC" - "extsb %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:HI 2 "=r,r"))] - "TARGET_POWERPC" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:HI 2 ""))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 2) - (zero_extend:HI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - " -{ - rtx reg; - int offset; - if (GET_CODE (operands[2]) == REG) - { - reg = operands[2]; - offset = 0; - } - else if (GET_CODE (operands[2]) == SUBREG) - { - reg = SUBREG_REG (operands[2]); - offset = SUBREG_WORD (operands[2]); - } - else - abort (); - - operands[3] = gen_rtx_SUBREG (SImode, reg, offset); -}") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (sign_extend:HI (match_dup 1)))] - "TARGET_POWERPC" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (sign_extend:HI (match_dup 1)))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 0) - (zero_extend:HI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 3) - (const_int 0)))] - " -{ - rtx reg; - int offset; - if (GET_CODE (operands[0]) == REG) - { - reg = operands[0]; - offset = 0; - } - else if (GET_CODE (operands[0]) == SUBREG) - { - reg = SUBREG_REG (operands[0]); - offset = SUBREG_WORD (operands[0]); - } - else - abort (); - - operands[3] = gen_rtx_SUBREG (SImode, reg, offset); -}") - -(define_expand "extendqihi2_power" - [(parallel [(set (match_dup 2) - (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") - (const_int 24))) - (clobber (scratch:SI))]) - (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 2) - (const_int 24))) - (clobber (scratch:SI))])] - "TARGET_POWER" - " -{ operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_reg_rtx (SImode); }") - -(define_expand "extendqihi2_no_power" - [(set (match_dup 2) - (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") - (const_int 24))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 2) - (const_int 24)))] - "! TARGET_POWER && ! TARGET_POWERPC" - " -{ operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_reg_rtx (SImode); }") - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lhz%U1%X1 %0,%1 - {rlinm|rlwinm} %0,%1,0,0xffff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - {andil.|andi.} %2,%1,0xffff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_dup 1)))] - "" - "@ - {andil.|andi.} %0,%1,0xffff - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lha%U1%X1 %0,%1 - {exts|extsh} %0,%1" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - {exts.|extsh.} %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_dup 1)))] - "" - "@ - {exts.|extsh.} %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_operand" "") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - -;; Fixed-point arithmetic insns. - -;; Discourage ai/addic because of carry but provide it in an alternative -;; allowing register zero as source. -(define_expand "addsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT && !add_operand (operands[2], SImode)) - { - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - - HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; - HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); - - if (low & 0x8000) - high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - - emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (high))); - emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low))); - DONE; - } -}") - -(define_insn "*addsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b") - (match_operand:SI 2 "add_operand" "r,I,I,J")))] - "" - "@ - {cax|add} %0,%1,%2 - {cal %0,%2(%1)|addi %0,%1,%2} - {ai|addic} %0,%1,%2 - {cau|addis} %0,%1,%v2" - [(set_attr "length" "4,4,4,4")]) - -(define_insn "*addsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" - "@ - {cax.|add.} %3,%1,%2 - {ai.|addic.} %3,%1,%2 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (plus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*addsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (match_dup 1) - (match_dup 2)))] - "" - "@ - {cax.|add.} %0,%1,%2 - {ai.|addic.} %0,%1,%2 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (plus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an add that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. Note that the low-order -;; add should be last in case the result gets used in an address. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_add_cint_operand" "")))] - "" - [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] -" -{ - HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; - HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); - - if (low & 0x8000) - high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - - operands[3] = GEN_INT (high); - operands[4] = GEN_INT (low); -}") - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" - "nor %0,%1,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - nor. %2,%1,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (not:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (not:SI (match_dup 1)))] - "" - "@ - nor. %0,%1,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (not:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (not:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI") - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "! TARGET_POWERPC" - "{sf%I1|subf%I1c} %0,%2,%1") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I") - (match_operand:SI 2 "gpc_reg_operand" "r,r")))] - "TARGET_POWERPC" - "@ - subf %0,%2,%1 - subfic %0,%2,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC" - "@ - {sf.|subfc.} %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC && reload_completed" - [(set (match_dup 3) - (minus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWERPC" - "@ - subf. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 3) - (minus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (minus:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC" - "@ - {sf.|subfc.} %0,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_dup 1) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (minus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (minus:SI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC" - "subf. %0,%2,%1" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC && reload_completed" - [(set (match_dup 0) - (minus:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "subsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_operand:SI 1 "reg_or_short_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_addsi3 (operands[0], operands[1], - negate_rtx (SImode, operands[2]))); - DONE; - } -}") - -;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i] -;; instruction and some auxiliary computations. Then we just have a single -;; DEFINE_INSN for doz[i] and the define_splits to make them if made by -;; combine. - -(define_expand "sminsi3" - [(set (match_dup 3) - (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1)))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" - " -{ operands[3] = gen_reg_rtx (SImode); }") - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (smin:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] - "TARGET_POWER" - [(set (match_dup 3) - (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1)))) - (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))] - "") - -(define_expand "smaxsi3" - [(set (match_dup 3) - (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1)))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" - " -{ operands[3] = gen_reg_rtx (SImode); }") - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (smax:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] - "TARGET_POWER" - [(set (match_dup 3) - (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1)))) - (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))] - "") - -(define_expand "uminsi3" - [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_dup 5))) - (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "") - (match_dup 5))) - (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4)) - (const_int 0) - (minus:SI (match_dup 4) (match_dup 3)))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" - " -{ - operands[3] = gen_reg_rtx (SImode); - operands[4] = gen_reg_rtx (SImode); - operands[5] = GEN_INT (-2147483647 - 1); -}") - -(define_expand "umaxsi3" - [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_dup 5))) - (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "") - (match_dup 5))) - (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4)) - (const_int 0) - (minus:SI (match_dup 4) (match_dup 3)))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" - " -{ - operands[3] = gen_reg_rtx (SImode); - operands[4] = gen_reg_rtx (SImode); - operands[5] = GEN_INT (-2147483647 - 1); -}") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))))] - "TARGET_POWER" - "doz%I2 %0,%1,%2") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWER" - "@ - doz%I2. %3,%1,%2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "=x,?y") - (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWER && reload_completed" - [(set (match_dup 3) - (if_then_else:SI (gt (match_dup 1) - (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) - (match_dup 1)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (if_then_else:SI (gt (match_dup 1) (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))))] - "TARGET_POWER" - "doz%I2. %0,%1,%2" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "=x,?y") - (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0) - (minus:SI (match_dup 2) (match_dup 1))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (if_then_else:SI (gt (match_dup 1) - (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) - (match_dup 1))))] - "TARGET_POWER && reload_completed" - [(set (match_dup 0) - (if_then_else:SI (gt (match_dup 1) - (match_dup 2)) - (const_int 0) - (minus:SI (match_dup 2) - (match_dup 1)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; We don't need abs with condition code because such comparisons should -;; never be done. -(define_expand "abssi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))] - "" - " -{ - if (!TARGET_POWER) - { - emit_insn (gen_abssi2_nopower (operands[0], operands[1])); - DONE; - } -}") - -(define_insn "abssi2_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_POWER" - "abs %0,%1") - -(define_insn "abssi2_nopower" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER && reload_completed" - [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) - (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))] - "") - -(define_insn "*nabs_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))] - "TARGET_POWER" - "nabs %0,%1") - -(define_insn "*nabs_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER && reload_completed" - [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) - (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))] - "") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" - "neg %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - neg. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (neg:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (match_dup 1)))] - "" - "@ - neg. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (neg:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "ffssi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") - (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" - "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32" - [(set_attr "length" "16")]) - -(define_expand "mulsi3" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:SI 1 "gpc_reg_operand" "")) - (use (match_operand:SI 2 "reg_or_short_operand" ""))] - "" - " -{ - if (TARGET_POWER) - emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2])); - else - emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "mulsi3_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (clobber (match_scratch:SI 3 "=q,q"))] - "TARGET_POWER" - "@ - {muls|mullw} %0,%1,%2 - {muli|mulli} %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "mulsi3_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))] - "! TARGET_POWER" - "@ - {muls|mullw} %0,%1,%2 - {muli|mulli} %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r")) - (clobber (match_scratch:SI 4 "=q,q"))] - "TARGET_POWER" - "@ - {muls.|mullw.} %3,%1,%2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 3) - (mult:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWER" - "@ - {muls.|mullw.} %3,%1,%2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (mult:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,q"))] - "TARGET_POWER" - "@ - {muls.|mullw.} %0,%1,%2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (mult:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 0) - (mult:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" - "@ - {muls.|mullw.} %0,%1,%2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (mult:SI (match_dup 1) - (match_dup 2)))] - "!TARGET_POWER && reload_completed" - [(set (match_dup 0) - (mult:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Operand 1 is divided by operand 2; quotient goes to operand -;; 0 and remainder to operand 3. -;; ??? At some point, see what, if anything, we can do about if (x % y == 0). - -(define_expand "divmodsi4" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" ""))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mod:SI (match_dup 1) (match_dup 2)))])] - "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)" - " -{ - if (! TARGET_POWER && ! TARGET_POWERPC) - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_divss_call ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - emit_move_insn (operands[3], gen_rtx_REG (SImode, 4)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (set (match_operand:SI 3 "gpc_reg_operand" "=q") - (mod:SI (match_dup 1) (match_dup 2)))] - "TARGET_POWER" - "divs %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_expand "udivsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")))] - "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)" - " -{ - if (! TARGET_POWER && ! TARGET_POWERPC) - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_quous_call ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - DONE; - } - else if (TARGET_POWER) - { - emit_insn (gen_udivsi3_mq (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "udivsi3_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWERPC && TARGET_POWER" - "divwu %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_insn "*udivsi3_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC && ! TARGET_POWER" - "divwu %0,%1,%2" - [(set_attr "type" "idiv")]) - -;; For powers of two we can do srai/aze for divide and then adjust for -;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be -;; used; for PowerPC, force operands into register and do a normal divide; -;; for AIX common-mode, use quoss call on register operands. -(define_expand "divsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && exact_log2 (INTVAL (operands[2])) >= 0) - ; - else if (TARGET_POWERPC) - { - operands[2] = force_reg (SImode, operands[2]); - if (TARGET_POWER) - { - emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2])); - DONE; - } - } - else if (TARGET_POWER) - FAIL; - else - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_quoss_call ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - DONE; - } -}") - -(define_insn "divsi3_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWERPC && TARGET_POWER" - "divw %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_insn "*divsi3_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC && ! TARGET_POWER" - "divw %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_expand "modsi3" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:SI 1 "gpc_reg_operand" "")) - (use (match_operand:SI 2 "reg_or_cint_operand" ""))] - "" - " -{ - int i = exact_log2 (INTVAL (operands[2])); - rtx temp1; - rtx temp2; - - if (GET_CODE (operands[2]) != CONST_INT || i < 0) - FAIL; - - temp1 = gen_reg_rtx (SImode); - temp2 = gen_reg_rtx (SImode); - - emit_insn (gen_divsi3 (temp1, operands[1], operands[2])); - emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i))); - emit_insn (gen_subsi3 (operands[0], operands[1], temp2)); - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "N")))] - "exact_log2 (INTVAL (operands[2])) >= 0" - "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "N,N")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "exact_log2 (INTVAL (operands[2])) >= 0" - "@ - {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed && exact_log2 (INTVAL (operands[2])) >= 0" - [(set (match_dup 3) - (div:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "N,N")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (div:SI (match_dup 1) - (match_dup 2)))] - "exact_log2 (INTVAL (operands[2])) >= 0" - "@ - {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (div:SI (match_dup 1) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 3) - (div:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (udiv:SI - (plus:DI (ashift:DI - (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) - (const_int 32)) - (zero_extend:DI (match_operand:SI 4 "register_operand" "2"))) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (set (match_operand:SI 2 "register_operand" "=*q") - (umod:SI - (plus:DI (ashift:DI - (zero_extend:DI (match_dup 1)) (const_int 32)) - (zero_extend:DI (match_dup 4))) - (match_dup 3)))] - "TARGET_POWER" - "div %0,%1,%3" - [(set_attr "type" "idiv")]) - -;; To do unsigned divide we handle the cases of the divisor looking like a -;; negative number. If it is a constant that is less than 2**31, we don't -;; have to worry about the branches. So make a few subroutines here. -;; -;; First comes the normal case. -(define_expand "udivmodsi4_normal" - [(set (match_dup 4) (const_int 0)) - (parallel [(set (match_operand:SI 0 "" "") - (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4)) - (const_int 32)) - (zero_extend:DI (match_operand:SI 1 "" ""))) - (match_operand:SI 2 "" ""))) - (set (match_operand:SI 3 "" "") - (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4)) - (const_int 32)) - (zero_extend:DI (match_dup 1))) - (match_dup 2)))])] - "TARGET_POWER" - " -{ operands[4] = gen_reg_rtx (SImode); }") - -;; This handles the branches. -(define_expand "udivmodsi4_tests" - [(set (match_operand:SI 0 "" "") (const_int 0)) - (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" "")) - (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" ""))) - (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0)) - (label_ref (match_operand:SI 4 "" "")) (pc))) - (set (match_dup 0) (const_int 1)) - (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) - (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0))) - (set (pc) (if_then_else (lt (match_dup 6) (const_int 0)) - (label_ref (match_dup 4)) (pc)))] - "TARGET_POWER" - " -{ operands[5] = gen_reg_rtx (CCUNSmode); - operands[6] = gen_reg_rtx (CCmode); -}") - -(define_expand "udivmodsi4" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" ""))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (umod:SI (match_dup 1) (match_dup 2)))])] - "" - " -{ - rtx label = 0; - - if (! TARGET_POWER) - { - if (! TARGET_POWERPC) - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_divus_call ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - emit_move_insn (operands[3], gen_rtx_REG (SImode, 4)); - DONE; - } - else - FAIL; - } - - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0) - { - operands[2] = force_reg (SImode, operands[2]); - label = gen_label_rtx (); - emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2], - operands[3], label)); - } - else - operands[2] = force_reg (SImode, operands[2]); - - emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2], - operands[3])); - if (label) - emit_label (label); - - DONE; -}") - -;; AIX architecture-independent common-mode multiply (DImode), -;; divide/modulus, and quotient subroutine calls. Input operands in R3 and -;; R4; results in R3 and sometimes R4; link register always clobbered by bla -;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but -;; assumed unused if generating common-mode, so ignore. -(define_insn "mulh_call" - [(set (reg:SI 3) - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3)) - (sign_extend:DI (reg:SI 4))) - (const_int 32)))) - (clobber (match_scratch:SI 0 "=l"))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __mulh" - [(set_attr "type" "imul")]) - -(define_insn "mull_call" - [(set (reg:DI 3) - (mult:DI (sign_extend:DI (reg:SI 3)) - (sign_extend:DI (reg:SI 4)))) - (clobber (match_scratch:SI 0 "=l")) - (clobber (reg:SI 0))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __mull" - [(set_attr "type" "imul")]) - -(define_insn "divss_call" - [(set (reg:SI 3) - (div:SI (reg:SI 3) (reg:SI 4))) - (set (reg:SI 4) - (mod:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) - (clobber (reg:SI 0))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __divss" - [(set_attr "type" "idiv")]) - -(define_insn "divus_call" - [(set (reg:SI 3) - (udiv:SI (reg:SI 3) (reg:SI 4))) - (set (reg:SI 4) - (umod:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) - (clobber (reg:SI 0)) - (clobber (match_scratch:CC 1 "=x")) - (clobber (reg:CC 69))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __divus" - [(set_attr "type" "idiv")]) - -(define_insn "quoss_call" - [(set (reg:SI 3) - (div:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l"))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __quoss" - [(set_attr "type" "idiv")]) - -(define_insn "quous_call" - [(set (reg:SI 3) - (udiv:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) - (clobber (reg:SI 0)) - (clobber (match_scratch:CC 1 "=x")) - (clobber (reg:CC 69))] - "! TARGET_POWER && ! TARGET_POWERPC" - "bla __quous" - [(set_attr "type" "idiv")]) - -;; Logical instructions -(define_expand "andsi3" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "and_operand" "?r,L,K,J"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))])] - "" - "") - -;; If cr0 isn't available, and we want to do an andi, load the register into -;; the destination first. - -(define_insn "andsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,&??r,&??r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "?r,L,K,J,K,J"))) - (clobber (match_operand:CC 3 "scratch_operand" "=X,X,x,x,X,X"))] - "" - "@ - and %0,%1,%2 - {rlinm|rlwinm} %0,%1,0,%m2,%M2 - {andil.|andi.} %0,%1,%b2 - {andiu.|andis.} %0,%1,%u2 - # - #" - [(set_attr "length" "4,4,4,4,8,8")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" ""))) - (clobber (scratch:CC))] - "reload_completed && !mask_constant (INTVAL (operands[2]))" - [(set (match_dup 0) - (match_dup 2)) - (parallel [(set (match_dup 0) - (and:SI (match_dup 0) - (match_dup 1))) - (clobber (scratch:CC))])] - "") - -;; Note to set cr's other than cr0 we do the and immediate and then -;; the test again -- this avoids a mcrf which on the higher end -;; machines causes an execution serialization - -(define_insn "*andsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y,???y,???y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,J,L,r,K,J,L,K,L")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r,&r,&r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X,X,X"))] - "" - "@ - and. %3,%1,%2 - {andil.|andi.} %3,%1,%b2 - {andiu.|andis.} %3,%1,%u2 - {rlinm.|rlwinm.} %3,%1,0,%m2,%M2 - # - # - # - # - # - #" - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8,12,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*andsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y,???y,???y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,J,L,r,K,J,L,K,J")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,&r,&r") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X,X,X"))] - "" - "@ - and. %0,%1,%2 - {andil.|andi.} %0,%1,%b2 - {andiu.|andis.} %0,%1,%u2 - {rlinm.|rlwinm.} %0,%1,0,%m2,%M2 - # - # - # - # - # - #" - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8,12,12")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 0) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "iorsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && !logical_operand (operands[2], SImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - - emit_insn (gen_iorsi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*iorsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:SI 2 "logical_operand" "r,K,J")))] - "" - "@ - or %0,%1,%2 - {oril|ori} %0,%1,%b2 - {oriu|oris} %0,%1,%u2" - [(set_attr "length" "4,4,4")]) - -(define_insn "*iorsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - or. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*iorsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (match_dup 1) - (match_dup 2)))] - "" - "@ - or. %0,%1,%2 - #" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ior:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an IOR that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_logical_cint_operand" "")))] - "" - [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))] -" -{ - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); -}") - -(define_expand "xorsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && !logical_operand (operands[2], SImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - - emit_insn (gen_xorsi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*xorsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:SI 2 "logical_operand" "r,K,J")))] - "" - "@ - xor %0,%1,%2 - {xoril|xori} %0,%1,%b2 - {xoriu|xoris} %0,%1,%u2" - [(set_attr "length" "4,4,4")]) - -(define_insn "*xorsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - xor. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (xor:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*xorsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (xor:SI (match_dup 1) - (match_dup 2)))] - "" - "@ - xor. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (xor:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (xor:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an XOR that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_logical_cint_operand" "")))] - "" - [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))] -" -{ - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); -}") - -(define_insn "*eqvsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "" - "eqv %0,%1,%2") - -(define_insn "*eqvsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - eqv. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (not:SI (xor:SI (match_dup 1) - (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*eqvsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (not:SI (xor:SI (match_dup 1) (match_dup 2))))] - "" - "@ - eqv. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (not:SI (xor:SI (match_dup 1) - (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (not:SI (xor:SI (match_dup 1) - (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*andcsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "" - "andc %0,%2,%1") - -(define_insn "*andcsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - andc. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (and:SI (not:SI (match_dup 1)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*andcsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (not:SI (match_dup 1)) - (match_dup 2)))] - "" - "@ - andc. %0,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (not:SI (match_dup 1)) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (and:SI (not:SI (match_dup 1)) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*iorcsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "" - "orc %0,%2,%1") - -(define_insn "*iorcsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - orc. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:SI (not:SI (match_dup 1)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*iorcsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (not:SI (match_dup 1)) (match_dup 2)))] - "" - "@ - orc. %0,%2,%1 - #" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (not:SI (match_dup 1)) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ior:SI (not:SI (match_dup 1)) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*nandsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "" - "nand %0,%1,%2") - -(define_insn "*nandsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - nand. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*nandsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2))))] - "" - "@ - nand. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (ior:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*norsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "" - "nor %0,%1,%2") - -(define_insn "*norsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - nor. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (and:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*norsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2))))] - "" - "@ - nor. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (and:SI (not:SI (match_dup 1)) - (not:SI (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; maskir insn. We need four forms because things might be in arbitrary -;; orders. Don't define forms that only set CR fields because these -;; would modify an input register. - -(define_insn "*maskir_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) - (match_operand:SI 1 "gpc_reg_operand" "0")) - (and:SI (match_dup 2) - (match_operand:SI 3 "gpc_reg_operand" "r"))))] - "TARGET_POWER" - "maskir %0,%3,%2") - -(define_insn "*maskir_internal2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) - (match_operand:SI 1 "gpc_reg_operand" "0")) - (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_dup 2))))] - "TARGET_POWER" - "maskir %0,%3,%2") - -(define_insn "*maskir_internal3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand:SI 3 "gpc_reg_operand" "r")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0"))))] - "TARGET_POWER" - "maskir %0,%3,%2") - -(define_insn "*maskir_internal4" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0"))))] - "TARGET_POWER" - "maskir %0,%3,%2") - -(define_insn "*maskir_internal5" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (match_operand:SI 1 "gpc_reg_operand" "0,0")) - (and:SI (match_dup 2) - (match_operand:SI 3 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) - (and:SI (match_dup 2) (match_dup 3))))] - "TARGET_POWER" - "@ - maskir. %0,%3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) - (match_operand:SI 1 "gpc_reg_operand" "")) - (and:SI (match_dup 2) - (match_operand:SI 3 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) - (and:SI (match_dup 2) (match_dup 3))))] - "TARGET_POWER && reload_completed" - [(set (match_dup 0) - (ior:SI (and:SI (not:SI (match_dup 2)) - (match_dup 1)) - (and:SI (match_dup 2) - (match_dup 3)))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - -(define_insn "*maskir_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (match_operand:SI 1 "gpc_reg_operand" "0,0")) - (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") - (match_dup 2))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) - (and:SI (match_dup 3) (match_dup 2))))] - "TARGET_POWER" - "@ - maskir. %0,%3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) - (match_operand:SI 1 "gpc_reg_operand" "")) - (and:SI (match_operand:SI 3 "gpc_reg_operand" "") - (match_dup 2))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) - (and:SI (match_dup 3) (match_dup 2))))] - "TARGET_POWER && reload_completed" - [(set (match_dup 0) - (ior:SI (and:SI (not:SI (match_dup 2)) - (match_dup 1)) - (and:SI (match_dup 3) - (match_dup 2)))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*maskir_internal7" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r,r") - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0,0"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (and:SI (match_dup 2) (match_dup 3)) - (and:SI (not:SI (match_dup 2)) (match_dup 1))))] - "TARGET_POWER" - "@ - maskir. %0,%3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "") - (match_operand:SI 3 "gpc_reg_operand" "")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (and:SI (match_dup 2) (match_dup 3)) - (and:SI (not:SI (match_dup 2)) (match_dup 1))))] - "TARGET_POWER" - [(set (match_dup 0) - (ior:SI (and:SI (match_dup 2) - (match_dup 3)) - (and:SI (not:SI (match_dup 2)) - (match_dup 1)))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*maskir_internal8" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0,0"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (and:SI (match_dup 3) (match_dup 2)) - (and:SI (not:SI (match_dup 2)) (match_dup 1))))] - "TARGET_POWER" - "@ - maskir. %0,%3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ior:SI (and:SI (match_dup 3) (match_dup 2)) - (and:SI (not:SI (match_dup 2)) (match_dup 1))))] - "TARGET_POWER && reload_completed" - [(set (match_dup 0) - (ior:SI (and:SI (match_dup 3) - (match_dup 2)) - (and:SI (not:SI (match_dup 2)) - (match_dup 1)))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - -;; Rotate and shift insns, in all their variants. These support shifts, -;; field inserts and extracts, and various combinations thereof. -(define_expand "insv" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "gpc_reg_operand" "r"))] - "" - " -{ - /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since - the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the - compiler if the address of the structure is taken later. */ - if (GET_CODE (operands[0]) == SUBREG - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) - FAIL; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "gpc_reg_operand" "r"))] - "" - "* -{ - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i") - (match_operand:SI 5 "const_int_operand" "i")))] - "INTVAL (operands[4]) >= INTVAL (operands[1])" - "* -{ - int extract_start = INTVAL (operands[5]) & 31; - int extract_size = INTVAL (operands[4]) & 31; - int insert_start = INTVAL (operands[2]) & 31; - int insert_size = INTVAL (operands[1]) & 31; - -/* Align extract field with insert field */ - operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size); - operands[1] = GEN_INT (insert_start + insert_size - 1); - return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\"; -}") - -(define_insn "" - [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") - (match_operand:DI 1 "const_int_operand" "i") - (match_operand:DI 2 "const_int_operand" "i")) - (match_operand:DI 3 "gpc_reg_operand" "r"))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[2]) & 63; - int size = INTVAL (operands[1]) & 63; - - operands[2] = GEN_INT (64 - start - size); - return \"rldimi %0,%3,%H2,%H1\"; -}") - -(define_expand "extzv" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "" - " -{ - /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since - the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the - compiler if the address of the structure is taken later. */ - if (GET_CODE (operands[0]) == SUBREG - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) - FAIL; -}") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\"; -}") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i") - (match_operand:SI 3 "const_int_operand" "i,i")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - /* Split insn if not setting cr0. */ - if (cc_reg_not_cr0_operand (operands[0], CCmode)) - return \"#\"; - - /* If the bitfield being tested fits in the upper or lower half of a - word, it is possible to use andiu. or andil. to test it. This is - useful because the condition register set-use delay is smaller for - andi[ul]. than for rlinm. This doesn't work when the starting bit - position is 0 because the LT and GT bits may be set wrong. */ - - if ((start > 0 && start + size <= 16) || start >= 16) - { - operands[3] = GEN_INT (((1 << (16 - (start & 15))) - - (1 << (16 - (start & 15) - size)))); - if (start < 16) - return \"{andiu.|andis.} %4,%1,%3\"; - else - return \"{andil.|andi.} %4,%1,%3\"; - } - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\"; -}" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed" - [(set (match_dup 4) - (zero_extract:SI (match_dup 1) - (match_dup 2) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i") - (match_operand:SI 3 "const_int_operand" "i,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - /* Split insn if not setting cr0. */ - if (cc_reg_not_cr0_operand (operands[0], CCmode)) - return \"#\"; - - if (start >= 16 && start + size == 32) - { - operands[3] = GEN_INT ((1 << (32 - start)) - 1); - return \"{andil.|andi.} %0,%1,%3\"; - } - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\"; -}" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_dup 0) - (zero_extract:SI (match_dup 1) - (match_dup 2) - (match_dup 3)))] - "reload_completed" - [(set (match_dup 0) - (zero_extract:SI (match_dup 1) - (match_dup 2) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "i") - (match_operand:DI 3 "const_int_operand" "i")))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl %0,%1,%3,%2\"; -}") - -(define_insn "" - [(set (match_operand:CC 0 "gpc_reg_operand" "=x,?y") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "const_int_operand" "i,i") - (match_operand:DI 3 "const_int_operand" "i,i")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - /* Split insn if not setting cr0. */ - if (cc_reg_not_cr0_operand (operands[0], CCmode)) - return \"#\"; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl. %4,%1,%3,%2\"; -}") - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "const_int_operand" "") - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "reload_completed" - [(set (match_dup 4) - (zero_extract:DI (match_dup 1) - (match_dup 2) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "gpc_reg_operand" "=x,?y") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "const_int_operand" "i,i") - (match_operand:DI 3 "const_int_operand" "i,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - /* Split insn if not setting cr0. */ - if (cc_reg_not_cr0_operand (operands[0], CCmode)) - return \"#\"; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl. %0,%1,%3,%2\"; -}") - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "const_int_operand" "") - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_dup 0) - (zero_extract:DI (match_dup 1) - (match_dup 2) - (match_dup 3)))] - "reload_completed" - [(set (match_dup 0) - (zero_extract:DI (match_dup 1) - (match_dup 2) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") - -(define_insn "*rotlsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (rotate:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (rotate:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (rotate:SI (match_dup 1) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (rotate:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal4" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) - (match_operand:SI 3 "mask_operand" "L")))] - "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") - -(define_insn "*rotlsi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed" - [(set (match_dup 4) - (and:SI (rotate:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI - (rotate:SI (match_dup 1) - (match_dup 2)) - (match_dup 3)))] - "reload_completed" - [(set (match_dup 0) - (and:SI (rotate:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal7" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] - "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff") - -(define_insn "*rotlsi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (zero_extend:SI - (subreg:QI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI - (subreg:QI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal10" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] - "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") - -(define_insn "*rotlsi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (zero_extend:SI - (subreg:HI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "" - "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "=x,?y") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI - (subreg:HI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Note that we use "sle." instead of "sl." so that we can set -;; SHIFT_COUNT_TRUNCATED. - -(define_expand "ashlsi3" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:SI 1 "gpc_reg_operand" "")) - (use (match_operand:SI 2 "reg_or_cint_operand" ""))] - "" - " -{ - if (TARGET_POWER) - emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2])); - else - emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "ashlsi3_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) - (clobber (match_scratch:SI 3 "=q,X"))] - "TARGET_POWER" - "@ - sle %0,%1,%2 - {sli|slwi} %0,%1,%h2" - [(set_attr "length" "8")]) - -(define_insn "ashlsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "! TARGET_POWER" - "{sl|slw}%I2 %0,%1,%h2" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r")) - (clobber (match_scratch:SI 4 "=q,X,q,X"))] - "TARGET_POWER" - "@ - sle. %3,%1,%2 - {sli.|slwi.} %3,%1,%h2 - # - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 3) - (ashift:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWER" - "@ - {sl|slw}%I2. %3,%1,%h2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWER && reload_completed" - [(set (match_dup 3) - (ashift:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashift:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X,q,X"))] - "TARGET_POWER" - "@ - sle. %0,%1,%2 - {sli.|slwi.} %0,%1,%h2 - # - #" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashift:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 0) - (ashift:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashift:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" - "{sl|slw}%I2. %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashift:SI (match_dup 1) - (match_dup 2)))] - "! TARGET_POWER && reload_completed" - [(set (match_dup 0) - (ashift:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "L")))] - "includes_lshift_p (operands[2], operands[3])" - "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "includes_lshift_p (operands[2], operands[3])" - "@ - {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed && includes_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:SI (ashift:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_lshift_p (operands[2], operands[3])" - "@ - {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (ashift:SI (match_dup 1) - (match_dup 2)) - (match_dup 3)))] - "reload_completed && includes_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:SI (ashift:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -;; The AIX assembler mis-handles "sri x,x,0", so write that case as -;; "sli x,x,0". -(define_expand "lshrsi3" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:SI 1 "gpc_reg_operand" "")) - (use (match_operand:SI 2 "reg_or_cint_operand" ""))] - "" - " -{ - if (TARGET_POWER) - emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2])); - else - emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "lshrsi3_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))) - (clobber (match_scratch:SI 3 "=q,X,X"))] - "TARGET_POWER" - "@ - sre %0,%1,%2 - mr %0,%1 - {s%A2i|s%A2wi} %0,%1,%h2") - -(define_insn "lshrsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))] - "! TARGET_POWER" - "@ - mr %0,%1 - {sr|srw}%I2 %0,%1,%h2") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,X,r,r,X,r")) - (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))] - "TARGET_POWER" - "@ - sre. %3,%1,%2 - mr. %1,%1 - {s%A2i.|s%A2wi.} %3,%1,%h2 - # - cmpli %0,%1,0 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,4,8,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" - [(parallel [(set (match_dup 3) - (lshiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=X,r,X,r"))] - "! TARGET_POWER" - "@ - mr. %1,%1 - {sr|srw}%I2. %3,%1,%h2 - cmpli %0,%1,0 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWER && reload_completed - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" - [(set (match_dup 3) - (lshiftrt:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,rOi")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (lshiftrt:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X,X,q"))] - "TARGET_POWER" - "@ - sre. %0,%1,%2 - mr. %0,%1 - {s%A2i.|s%A2wi.} %0,%1,%h2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (lshiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 3) - (lshiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" - "@ - mr. %0,%1 - {sr|srw}%I2. %0,%1,%h2 - # - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (lshiftrt:SI (match_dup 1) - (match_dup 2)))] - "! TARGET_POWER && reload_completed" - [(set (match_dup 0) - (lshiftrt:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "L")))] - "includes_rshift_p (operands[2], operands[3])" - "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "includes_rshift_p (operands[2], operands[3])" - "@ - {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed && includes_rshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:SI (lshiftrt:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "L,L")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_rshift_p (operands[2], operands[3])" - "@ - {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (lshiftrt:SI (match_dup 1) - (match_dup 2)) - (match_dup 3)))] - "reload_completed && includes_rshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:SI (lshiftrt:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "{rlinm|rlwinm} %0,%1,%s2,0xff") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "@ - {rlinm.|rlwinm.} %3,%1,%s2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed && includes_rshift_p (operands[2], GEN_INT (255))" - [(set (match_dup 3) - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "@ - {rlinm.|rlwinm.} %0,%1,%s2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0)))] - "reload_completed && includes_rshift_p (operands[2], GEN_INT (255))" - [(set (match_dup 0) - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "{rlinm|rlwinm} %0,%1,%s2,0xffff") - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed && includes_rshift_p (operands[2], GEN_INT (255))" - [(set (match_dup 3) - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "@ - {rlinm.|rlwinm.} %3,%1,%s2,0xffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "{rlinm.|rlwinm.} %0,%1,%s2,0xffff" - [(set_attr "type" "delayed_compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0)))] - "reload_completed && includes_rshift_p (operands[2], GEN_INT (255))" - [(set (match_dup 0) - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (const_int 1) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 31)))] - "TARGET_POWER" - "rrib %0,%1,%2") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (const_int 1) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 31)))] - "TARGET_POWER" - "rrib %0,%1,%2") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (const_int 1) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 1) - (const_int 0)))] - "TARGET_POWER" - "rrib %0,%1,%2") - -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (TARGET_POWER) - emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2])); - else - emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "ashrsi3_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) - (clobber (match_scratch:SI 3 "=q,X"))] - "TARGET_POWER" - "@ - srea %0,%1,%2 - {srai|srawi} %0,%1,%h2") - -(define_insn "ashrsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "! TARGET_POWER" - "{sra|sraw}%I2 %0,%1,%h2") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r")) - (clobber (match_scratch:SI 4 "=q,X,q,X"))] - "TARGET_POWER" - "@ - srea. %3,%1,%2 - {srai.|srawi.} %3,%1,%h2 - # - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 3) - (ashiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWER" - "@ - {sra|sraw}%I2. %3,%1,%h2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ashiftrt:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashiftrt:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X,q,X"))] - "TARGET_POWER" - "@ - srea. %0,%1,%2 - {srai.|srawi.} %0,%1,%h2 - # - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(parallel [(set (match_dup 0) - (ashiftrt:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" - "@ - {sra|sraw}%I2. %0,%1,%h2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 1) - (match_dup 2)))] - "! TARGET_POWER && reload_completed" - [(set (match_dup 0) - (ashiftrt:SI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Floating-point insns, excluding normal data motion. -;; -;; PowerPC has a full set of single-precision floating point instructions. -;; -;; For the POWER architecture, we pretend that we have both SFmode and -;; DFmode insns, while, in fact, all fp insns are actually done in double. -;; The only conversions we will do will be when storing to memory. In that -;; case, we will use the "frsp" instruction before storing. -;; -;; Note that when we store into a single-precision memory location, we need to -;; use the frsp insn first. If the register being stored isn't dead, we -;; need a scratch register for the frsp. But this is difficult when the store -;; is done by reload. It is not incorrect to do the frsp on the register in -;; this case, we just lose precision that we would have otherwise gotten but -;; is not guaranteed. Perhaps this should be tightened up at some point. - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"\"; - else - return \"fmr %0,%1\"; -}" - [(set_attr "type" "fp")]) - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "frsp %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "aux_truncdfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" - "frsp %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "negsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "abssf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "addsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" - "fadds %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" - "{fa|fadd} %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_expand "subsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" - "fsubs %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" - "{fs|fsub} %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_expand "mulsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" - "fmuls %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" - "{fm|fmul} %0,%1,%2" - [(set_attr "type" "dmul")]) - -(define_expand "divsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" - "fdivs %0,%1,%2" - [(set_attr "type" "sdiv")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" - "{fd|fdiv} %0,%1,%2" - [(set_attr "type" "ddiv")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "fmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fma|fmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "fmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fms|fmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "fnmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fnma|fnmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "fnmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")) - (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fnms|fnmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_expand "sqrtsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT" - "fsqrts %0,%1" - [(set_attr "type" "ssqrt")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_POWER2 && TARGET_HARD_FLOAT" - "fsqrt %0,%1" - [(set_attr "type" "dsqrt")]) - -;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a -;; fsel instruction and some auxiliary computations. Then we just have a -;; single DEFINE_INSN for fsel and the define_splits to make them if made by -;; combine. -(define_expand "maxsf3" - [(set (match_dup 3) - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" ""))) - (set (match_operand:SF 0 "gpc_reg_operand" "") - (if_then_else:SF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ operands[3] = gen_reg_rtx (SFmode); }") - -(define_split - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (smax:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" ""))) - (clobber (match_operand:SF 3 "gpc_reg_operand" ""))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - [(set (match_dup 3) - (minus:SF (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (if_then_else:SF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "") - -(define_expand "minsf3" - [(set (match_dup 3) - (minus:SF (match_operand:SF 2 "gpc_reg_operand" "") - (match_operand:SF 1 "gpc_reg_operand" ""))) - (set (match_operand:SF 0 "gpc_reg_operand" "") - (if_then_else:SF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ operands[3] = gen_reg_rtx (SFmode); }") - -(define_split - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (smin:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" ""))) - (clobber (match_operand:SF 3 "gpc_reg_operand" ""))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - [(set (match_dup 3) - (minus:SF (match_dup 2) (match_dup 1))) - (set (match_dup 0) - (if_then_else:SF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "") - -(define_expand "movsfcc" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (match_operand 1 "comparison_operator" "") - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ - rtx temp, op0, op1; - enum rtx_code code = GET_CODE (operands[1]); - if (! rs6000_compare_fp_p) - FAIL; - switch (code) - { - case GE: case EQ: case NE: - op0 = rs6000_compare_op0; - op1 = rs6000_compare_op1; - break; - case GT: - op0 = rs6000_compare_op1; - op1 = rs6000_compare_op0; - temp = operands[2]; operands[2] = operands[3]; operands[3] = temp; - break; - case LE: - op0 = rs6000_compare_op1; - op1 = rs6000_compare_op0; - break; - case LT: - op0 = rs6000_compare_op0; - op1 = rs6000_compare_op1; - temp = operands[2]; operands[2] = operands[3]; operands[3] = temp; - break; - default: - FAIL; - } - if (GET_MODE (rs6000_compare_op0) == DFmode) - { - temp = gen_reg_rtx (DFmode); - emit_insn (gen_subdf3 (temp, op0, op1)); - emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3])); - if (code == EQ) - { - emit_insn (gen_negdf2 (temp, temp)); - emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3])); - } - else if (code == NE) - { - emit_insn (gen_negdf2 (temp, temp)); - emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0])); - } - } - else - { - temp = gen_reg_rtx (SFmode); - emit_insn (gen_subsf3 (temp, op0, op1)); - emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3])); - if (code == EQ) - { - emit_insn (gen_negsf2 (temp, temp)); - emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3])); - } - else if (code == NE) - { - emit_insn (gen_negsf2 (temp, temp)); - emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0])); - } - } - DONE; -}") - -(define_insn "fselsfsf4" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f") - (const_int 0)) - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "fseldfsf4" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f") - (const_int 0)) - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "negdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "absdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "adddf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "{fa|fadd} %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "subdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "{fs|fsub} %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "muldf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "{fm|fmul} %0,%1,%2" - [(set_attr "type" "dmul")]) - -(define_insn "divdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (div:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "{fd|fdiv} %0,%1,%2" - [(set_attr "type" "ddiv")]) - -(define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fma|fmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fms|fmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fnma|fnmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" - "{fnms|fnmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" - "fsqrt %0,%1" - [(set_attr "type" "dsqrt")]) - -;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a -;; fsel instruction and some auxiliary computations. Then we just have a -;; single DEFINE_INSN for fsel and the define_splits to make them if made by -;; combine. - -(define_expand "maxdf3" - [(set (match_dup 3) - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" ""))) - (set (match_operand:DF 0 "gpc_reg_operand" "") - (if_then_else:DF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ operands[3] = gen_reg_rtx (DFmode); }") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (smax:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" ""))) - (clobber (match_operand:DF 3 "gpc_reg_operand" ""))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - [(set (match_dup 3) - (minus:DF (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (if_then_else:DF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "") - -(define_expand "mindf3" - [(set (match_dup 3) - (minus:DF (match_operand:DF 2 "gpc_reg_operand" "") - (match_operand:DF 1 "gpc_reg_operand" ""))) - (set (match_operand:DF 0 "gpc_reg_operand" "") - (if_then_else:DF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ operands[3] = gen_reg_rtx (DFmode); }") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (smin:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" ""))) - (clobber (match_operand:DF 3 "gpc_reg_operand" ""))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - [(set (match_dup 3) - (minus:DF (match_dup 2) (match_dup 1))) - (set (match_dup 0) - (if_then_else:DF (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] - "") - -(define_expand "movdfcc" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (if_then_else:DF (match_operand 1 "comparison_operator" "") - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - " -{ - rtx temp, op0, op1; - enum rtx_code code = GET_CODE (operands[1]); - if (! rs6000_compare_fp_p) - FAIL; - switch (code) - { - case GE: case EQ: case NE: - op0 = rs6000_compare_op0; - op1 = rs6000_compare_op1; - break; - case GT: - op0 = rs6000_compare_op1; - op1 = rs6000_compare_op0; - temp = operands[2]; operands[2] = operands[3]; operands[3] = temp; - break; - case LE: - op0 = rs6000_compare_op1; - op1 = rs6000_compare_op0; - break; - case LT: - op0 = rs6000_compare_op0; - op1 = rs6000_compare_op1; - temp = operands[2]; operands[2] = operands[3]; operands[3] = temp; - break; - default: - FAIL; - } - if (GET_MODE (rs6000_compare_op0) == DFmode) - { - temp = gen_reg_rtx (DFmode); - emit_insn (gen_subdf3 (temp, op0, op1)); - emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3])); - if (code == EQ) - { - emit_insn (gen_negdf2 (temp, temp)); - emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3])); - } - else if (code == NE) - { - emit_insn (gen_negdf2 (temp, temp)); - emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0])); - } - } - else - { - temp = gen_reg_rtx (SFmode); - emit_insn (gen_subsf3 (temp, op0, op1)); - emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3])); - if (code == EQ) - { - emit_insn (gen_negsf2 (temp, temp)); - emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3])); - } - else if (code == NE) - { - emit_insn (gen_negsf2 (temp, temp)); - emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0])); - } - } - DONE; -}") - -(define_insn "fseldfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f") - (const_int 0)) - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "fselsfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f") - (const_int 0)) - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -;; Conversions to and from floating-point. - -(define_expand "floatsidf2" - [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (reg:DF 76))])] - "TARGET_HARD_FLOAT" - " -{ - operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode)); - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (Pmode); -}") - -(define_insn "*floatsidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") - (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) - (clobber (match_operand 5 "gpc_reg_operand" "=b")) - (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" - "#" - [(set_attr "length" "24")]) - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "")) - (clobber (match_operand 5 "gpc_reg_operand" "")) - (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" - [(set (match_dup 4) - (xor:SI (match_dup 1) - (match_dup 6))) - (set (match_dup 5) - (unspec [(const_int 0)] 11)) - (set (match_dup 7) - (unspec [(match_dup 4) - (match_dup 5)] 12)) ;; low word - (set (match_dup 7) - (unspec [(match_dup 2) - (match_dup 5) - (match_dup 7)] 13)) ;; high word - (set (match_dup 0) - (unspec [(match_dup 7) - (match_dup 5)] 14)) - (set (match_dup 0) - (minus:DF (match_dup 0) - (match_dup 3)))] - " -{ - operands[6] = GEN_INT (0x80000000); - operands[7] = gen_rtx_REG (DFmode, FPMEM_REGNUM); -}") - -(define_expand "floatunssidf2" - [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:DF 76))])] - "TARGET_HARD_FLOAT" - " -{ - operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode)); - operands[4] = gen_reg_rtx (Pmode); -}") - -(define_insn "*floatunssidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (clobber (match_operand 4 "gpc_reg_operand" "=b")) - (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" - "#" - [(set_attr "length" "20")]) - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand 4 "gpc_reg_operand" "")) - (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" - [(set (match_dup 4) - (unspec [(const_int 0)] 11)) - (set (match_dup 5) - (unspec [(match_dup 1) - (match_dup 4)] 12)) ;; low word - (set (match_dup 5) - (unspec [(match_dup 2) - (match_dup 4) - (match_dup 5)] 13)) ;; high word - (set (match_dup 0) - (unspec [(match_dup 5) - (match_dup 4)] 14)) - (set (match_dup 0) - (minus:DF (match_dup 0) - (match_dup 3)))] - "operands[5] = gen_rtx_REG (DFmode, FPMEM_REGNUM);") - -;; Load up scratch register with base address + offset if needed -(define_insn "*floatsidf2_loadaddr" - [(set (match_operand 0 "gpc_reg_operand" "=b") - (unspec [(const_int 0)] 11))] - "TARGET_HARD_FLOAT" - "* -{ - if (rs6000_fpmem_offset > 32760) - { - rtx xop[3]; - - xop[0] = operands[0]; - xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx; - xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15)); - output_asm_insn (\"{cau|addis} %0,%1,%2\", xop); - } - - return \"\"; -}" - [(set_attr "length" "4")]) - -(define_insn "*floatsidf2_store1" - [(set (reg:DF 76) - (unspec [(match_operand:SI 0 "gpc_reg_operand" "r") - (match_operand 1 "gpc_reg_operand" "b")] 12))] - "TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (SImode, - gen_rtx_PLUS (Pmode, - indx, - GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000) - + ((WORDS_BIG_ENDIAN != 0) * 4)))); - - return \"{st|stw} %0,%2\"; -}" - [(set_attr "type" "store")]) - -(define_insn "*floatsidf2_store2" - [(set (reg:DF 76) - (unspec [(match_operand:SI 0 "gpc_reg_operand" "r") - (match_operand 1 "gpc_reg_operand" "b") - (reg:DF 76)] 13))] - "TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (SImode, - gen_rtx_PLUS (Pmode, - indx, - GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000) - + ((WORDS_BIG_ENDIAN == 0) * 4)))); - - return \"{st|stw} %0,%2\"; -}" - [(set_attr "type" "store")]) - -(define_insn "*floatsidf2_load" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec [(reg:DF 76) - (match_operand 1 "gpc_reg_operand" "b")] 14))] - "TARGET_HARD_FLOAT" - "* -{ - rtx indx; - HOST_WIDE_INT offset = rs6000_fpmem_offset; - - if (rs6000_fpmem_offset > 32760) - { - indx = operands[1]; - offset = (((offset & 0xffff) ^ 0x8000) - 0x8000); - } - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (SImode, - gen_rtx_PLUS (Pmode, indx, GEN_INT (offset))); - - return \"lfd %0,%2\"; -}" - [(set_attr "type" "fpload")]) - -(define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4))])] - "TARGET_HARD_FLOAT" - " -{ - if (!TARGET_POWER2 && !TARGET_POWERPC) - { - emit_insn (gen_trunc_call (operands[0], operands[1], - gen_rtx_SYMBOL_REF (Pmode, RS6000_ITRUNC))); - DONE; - } - - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_reg_rtx (Pmode); - operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM); -}") - -(define_insn "*fix_truncdfsi2_internal" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) - (clobber (match_operand 3 "gpc_reg_operand" "=b")) - (clobber (reg:DI 76))] - "TARGET_HARD_FLOAT" - "#" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand 3 "gpc_reg_operand" "")) - (clobber (reg:DI 76))] - "TARGET_HARD_FLOAT" - [(set (match_dup 2) - (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))) - (set (match_dup 3) - (unspec [(const_int 0)] 11)) - (set (match_dup 4) - (unspec [(match_dup 2) - (match_dup 3)] 15)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec [(match_dup 4) - (match_dup 3)] 16))] - "operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM);") - -(define_insn "*fix_truncdfsi2_store" - [(set (reg:DI 76) - (unspec [(match_operand:DI 0 "gpc_reg_operand" "f") - (match_operand 1 "gpc_reg_operand" "b")] 15))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (DFmode, - gen_rtx_PLUS (Pmode, - indx, - GEN_INT ((((rs6000_fpmem_offset & 0xffff) - ^ 0x8000) - 0x8000)))); - - return \"stfd %0,%2\"; -}" - [(set_attr "type" "fpstore")]) - -(define_insn "*fix_truncdfsi2_load" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(reg:DI 76) - (match_operand 1 "gpc_reg_operand" "b")] 16))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (DFmode, - gen_rtx_PLUS (Pmode, - indx, - GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000) - + ((WORDS_BIG_ENDIAN) ? 4 : 0)))); - - return \"{l|lwz} %0,%2\"; -}" - [(set_attr "type" "load")]) - -(define_expand "fixuns_truncdfsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))] - "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT" - " -{ - emit_insn (gen_trunc_call (operands[0], operands[1], - gen_rtx_SYMBOL_REF (Pmode, RS6000_UITRUNC))); - DONE; -}") - -(define_expand "trunc_call" - [(parallel [(set (match_operand:SI 0 "" "") - (fix:SI (match_operand:DF 1 "" ""))) - (use (match_operand:SI 2 "" ""))])] - "TARGET_HARD_FLOAT" - " -{ - rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]); - rtx first = XVECEXP (insns, 0, 0); - rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1); - - REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, - REG_NOTES (first)); - REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); - - emit_insn (insns); - DONE; -}") - -(define_expand "trunc_call_rtl" - [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" "")) - (use (reg:DF 33)) - (parallel [(set (reg:SI 3) - (call (mem:SI (match_operand 2 "" "")) (const_int 0))) - (use (const_int 0)) - (clobber (scratch:SI))]) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (reg:SI 3))] - "TARGET_HARD_FLOAT" - " -{ - rs6000_trunc_used = 1; -}") - -(define_insn "*fctiwz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - "{fcirz|fctiwz} %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "floatdidf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" - "fcfid %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "fix_truncdfdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" - "fctidz %0,%1" - [(set_attr "type" "fp")]) - -;; Define the DImode operations that can be done in a small number -;; of instructions. The & constraints are to prevent the register -;; allocator from allocating registers that overlap with the inputs -;; (for example, having an input in 7,8 and an output in 6,7). We -;; also allow for the output being the same as one of the inputs. - -(define_insn "*adddi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))] - "! TARGET_POWERPC64" - "* -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[2])) != CONST_INT - ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\" - : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\"; - else - return (GET_CODE (operands[2])) != CONST_INT - ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\" - : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\"; -}" - [(set_attr "length" "8")]) - -(define_insn "*subdi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))] - "! TARGET_POWERPC64" - "* -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[1]) != CONST_INT) - ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\" - : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\"; - else - return (GET_CODE (operands[1]) != CONST_INT) - ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\" - : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\"; -}" - [(set_attr "length" "8")]) - -(define_insn "*negdi2_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\" - : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\"; -}" - [(set_attr "length" "8")]) - -(define_expand "mulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64" - " -{ - if (! TARGET_POWER && ! TARGET_POWERPC) - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_mull_call ()); - if (WORDS_BIG_ENDIAN) - emit_move_insn (operands[0], gen_rtx_REG (DImode, 3)); - else - { - emit_move_insn (operand_subword (operands[0], 0, 0, DImode), - gen_rtx_REG (SImode, 3)); - emit_move_insn (operand_subword (operands[0], 1, 0, DImode), - gen_rtx_REG (SImode, 4)); - } - DONE; - } - else if (TARGET_POWER) - { - emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "mulsidi3_mq" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWER" - "mul %0,%1,%2\;mfmq %L0" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_insn "*mulsidi3_no_mq" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_expand "umulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "TARGET_POWERPC && ! TARGET_POWERPC64" - " -{ - if (TARGET_POWER) - { - emit_insn (gen_umulsidi3_mq (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "umulsidi3_mq" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWERPC && TARGET_POWER" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_insn "*umulsidi3_no_mq" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_expand "smulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - " -{ - if (! TARGET_POWER && ! TARGET_POWERPC) - { - emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); - emit_insn (gen_mulh_call ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - DONE; - } - else if (TARGET_POWER) - { - emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "smulsi3_highpart_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32)))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWER" - "mul %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "*smulsi3_highpart_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "TARGET_POWERPC && ! TARGET_POWER" - "mulhw %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_expand "umulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" ""))) - (const_int 32))))] - "TARGET_POWERPC" - " -{ - if (TARGET_POWER) - { - emit_insn (gen_umulsi3_highpart_mq (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "umulsi3_highpart_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32)))) - (clobber (match_scratch:SI 3 "=q"))] - "TARGET_POWERPC && TARGET_POWER" - "mulhwu %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "*umulsi3_highpart_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "TARGET_POWERPC && ! TARGET_POWER" - "mulhwu %0,%1,%2" - [(set_attr "type" "imul")]) - -;; If operands 0 and 2 are in the same register, we have a problem. But -;; operands 0 and 1 (the usual case) can be in the same register. That's -;; why we have the strange constraints below. -(define_insn "ashldi3_power" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r") - (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) - (clobber (match_scratch:SI 3 "=X,q,q,q"))] - "TARGET_POWER" - "@ - {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0} - sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 - sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 - sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2" - [(set_attr "length" "8")]) - -(define_insn "lshrdi3_power" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r") - (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) - (clobber (match_scratch:SI 3 "=X,q,q,q"))] - "TARGET_POWER" - "@ - {s%A2i|s%A2wi} %L0,%1,%h2\;{cal %0,0(0)|li %0,0} - sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 - sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 - sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2" - [(set_attr "length" "8")]) - -;; Shift by a variable amount is too complex to be worth open-coding. We -;; just handle shifts by constants. -(define_insn "ashrdi3_power" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "M,i"))) - (clobber (match_scratch:SI 3 "=X,q"))] - "TARGET_POWER" - "@ - {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 - sraiq %0,%1,%h2\;srliq %L0,%L1,%h2" - [(set_attr "length" "8")]) - -;; PowerPC64 DImode operations. - -(define_expand "adddi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (! TARGET_POWERPC64) - { - if (non_short_cint_operand (operands[2], DImode)) - FAIL; - } - else - if (GET_CODE (operands[2]) == CONST_INT - && !add_operand (operands[2], DImode)) - { - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; - HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); - - if (low & 0x8000) - high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - - emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (high))); - emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low))); - DONE; - } -}") - -;; Discourage ai/addic because of carry but provide it in an alternative -;; allowing register zero as source. - -(define_insn "*adddi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b") - (match_operand:DI 2 "add_operand" "r,I,I,J")))] - "TARGET_POWERPC64" - "@ - add %0,%1,%2 - addi %0,%1,%2 - addic %0,%1,%2 - addis %0,%1,%v2") - -(define_insn "*adddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_POWERPC64" - "@ - add. %3,%1,%2 - addic. %3,%1,%2 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (plus:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*adddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - add. %0,%1,%2 - addic. %0,%1,%2 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_dup 1) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (plus:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an add that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. Note that the low-order -;; add should be last in case the result gets used in an address. - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_add_cint_operand" "")))] - "TARGET_POWERPC64" - [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] -" -{ - HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; - HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); - - if (low & 0x8000) - high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - - operands[3] = GEN_INT (high); - operands[4] = GEN_INT (low); -}") - -(define_insn "one_cmpldi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "nor %0,%1,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "nor. %2,%1,%1" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (not:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (not:DI (match_dup 1)))] - "TARGET_POWERPC64" - "nor. %0,%1,%1" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (not:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (not:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I") - (match_operand:DI 2 "gpc_reg_operand" "r,r")))] - "TARGET_POWERPC64" - "@ - subf %0,%2,%1 - subfic %0,%2,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "subf. %3,%2,%1" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (minus:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (minus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "subf. %0,%2,%1" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (minus:DI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (minus:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "subdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_adddi3 (operands[0], operands[1], - negate_rtx (DImode, operands[2]))); - DONE; - } -}") - -(define_insn "absdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) - (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%2,%0" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) - (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) - (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) - (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%0,%2" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) - (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) - (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] - "") - -(define_expand "negdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "neg %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - neg. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (neg:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (neg:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - neg. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (neg:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "ffsdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64" - [(set_attr "length" "16")]) - -(define_insn "muldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "mulld %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "smuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (sign_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (sign_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhd %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (zero_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhdu %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_expand "divdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && exact_log2 (INTVAL (operands[2])) >= 0) - ; - else - operands[2] = force_reg (DImode, operands[2]); -}") - -(define_expand "moddi3" - [(use (match_operand:DI 0 "gpc_reg_operand" "")) - (use (match_operand:DI 1 "gpc_reg_operand" "")) - (use (match_operand:DI 2 "reg_or_cint_operand" ""))] - "TARGET_POWERPC64" - " -{ - int i = exact_log2 (INTVAL (operands[2])); - rtx temp1; - rtx temp2; - - if (GET_CODE (operands[2]) != CONST_INT || i < 0) - FAIL; - - temp1 = gen_reg_rtx (DImode); - temp2 = gen_reg_rtx (DImode); - - emit_insn (gen_divdi3 (temp1, operands[1], operands[2])); - emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i))); - emit_insn (gen_subdi3 (operands[0], operands[1], temp2)); - DONE; -}") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "N")))] - "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0" - "sradi %0,%1,%p2\;addze %0,%0" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "const_int_operand" "N,N")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0" - "@ - sradi %3,%1,%p2\;addze. %3,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed && exact_log2 (INTVAL (operands[2])) >= 0" - [(set (match_dup 3) - (div:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "const_int_operand" "N,N")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (div:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0" - "@ - sradi %0,%1,%p2\;addze. %0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "const_int_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (div:DI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed && exact_log2 (INTVAL (operands[2])) >= 0" - [(set (match_dup 0) - (div:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "divd %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_insn "udivdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "divdu %0,%1,%2" - [(set_attr "type" "idiv")]) - -(define_insn "rotldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,0") - -(define_insn "*rotldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %3,%1,%H2,0 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (rotate:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %0,%1,%H2,0 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (rotate:DI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (rotate:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal4" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) - (match_operand:DI 3 "mask64_operand" "S")))] - "TARGET_POWERPC64" - "rld%I2c%B3 %0,%1,%H2,%S3") - -(define_insn "*rotldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2c%B3. %4,%1,%H2,%S3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 4) - (and:DI - (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64" - "@ - rld%I2c%B3. %0,%1,%H2,%S3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI - (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (and:DI - (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal7" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,56") - -(define_insn "*rotldi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %3,%1,%H2,56 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI - (subreg:QI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %0,%1,%H2,56 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI - (subreg:QI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI - (subreg:QI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal10" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,48") - -(define_insn "*rotldi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %3,%1,%H2,48 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI - (subreg:HI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %0,%1,%H2,48 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI - (subreg:HI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI - (subreg:QI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal13" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,32") - -(define_insn "*rotldi3_internal14" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %3,%1,%H2,32 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI - (subreg:SI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal15" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %0,%1,%H2,32 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI - (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI - (subreg:SI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI - (subreg:QI - (rotate:DI - (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" - " -{ - if (TARGET_POWERPC64) - ; - else if (TARGET_POWER) - { - emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "TARGET_POWERPC64" - "sld%I2 %0,%1,%H2" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - sld%I2. %3,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashift:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - sld%I2. %0,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashift:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "lshrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" - " -{ - if (TARGET_POWERPC64) - ; - else if (TARGET_POWER) - { - emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "TARGET_POWERPC64" - "srd%I2 %0,%1,%H2") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - srd%I2. %3,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (lshiftrt:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - srd%I2. %0,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (lshiftrt:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" - " -{ - if (TARGET_POWERPC64) - ; - else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "TARGET_POWERPC64" - "srad%I2 %0,%1,%H2") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - srad%I2. %3,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashiftrt:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - srad%I2. %0,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt (match_dup 1) - (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashiftrt (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "anddi3" - [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and_operand" "?r,L,K,J"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))])] - "TARGET_POWERPC64" - "") - -;; If cr0 isn't available, and we want to do an andi, load the register into -;; the destination first. - -(define_insn "anddi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,&??r,&??r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r") - (match_operand:DI 2 "and_operand" "?r,L,K,J,K,J"))) - (clobber (match_operand:CC 3 "scratch_operand" "=X,X,x,x,X,X"))] - "TARGET_POWERPC64" - "@ - and %0,%1,%2 - {rlinm|rlwinm} %0,%1,0,%m2,%M2 - andil %0,%1,%b2 - andis. %0,%1,%u2 - # - #" - [(set_attr "length" "4,4,4,4,8,8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "const_int_operand" ""))) - (clobber (scratch:CC))] - "TARGET_POWERPC64 && reload_completed && !mask_constant (INTVAL (operands[2]))" - [(set (match_dup 0) - (match_dup 2)) - (parallel [(set (match_dup 0) - (and:DI (match_dup 0) - (match_dup 1))) - (clobber (scratch:CC))])] - "") - -;; Note to set cr's other than cr0 we do the and immediate and then -;; the test again -- this avoids a mcrf which on the higher end -;; machines causes an execution serialization - -(define_insn "*anddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y,???y,???y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and_operand" "r,K,J,L,r,K,J,L,K,L")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,&r,&r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X,X,X"))] - "TARGET_POWERPC64" - "@ - and. %3,%1,%2 - {andil.|andi.} %3,%1,%b2 - {andiu.|andis.} %3,%1,%u2 - {rlinm.|rlwinm.} %3,%1,0,%m2,%M2 - # - # - # - # - # - #" - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8,12,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 3) - (and:DI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*anddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y,???y,???y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and_operand" "r,K,J,L,r,K,J,L,K,J")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,&r,&r") - (and:DI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X,X,X"))] - "TARGET_POWERPC64" - "@ - and. %0,%1,%2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - rldic%B2 %0,%1,0,%m2,%M2 - # - # - # - # - # - #" - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8,12,12")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 0) - (and:DI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "iordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && !logical_operand (operands[2], DImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - emit_insn (gen_iordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*iordi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] - "TARGET_POWERPC64" - "@ - or %0,%1,%2 - ori %0,%1,%b2 - oris %0,%1,%u2") - -(define_insn "*iordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - or. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*iordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ior:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - or. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ior:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an IOR that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] - "TARGET_POWERPC64" - [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))] -" -{ - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); -}") - -(define_expand "xordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && !logical_operand (operands[2], DImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((reload_in_progress || reload_completed - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - emit_insn (gen_xordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*xordi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] - "TARGET_POWERPC64" - "@ - xor %0,%1,%2 - xori %0,%1,%b2 - xoris %0,%1,%u2") - -(define_insn "*xordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - xor. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (xor:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*xordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (xor:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - xor. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (xor:DI (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an XOR that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] - "TARGET_POWERPC64" - [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))] -" -{ - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); -}") - -(define_insn "*eqvdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r"))))] - "TARGET_POWERPC64" - "eqv %0,%1,%2") - -(define_insn "*eqvdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - eqv. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (not:DI (xor:DI (match_dup 1) - (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*eqvdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (not:DI (xor:DI (match_dup 1) (match_dup 2))))] - "TARGET_POWERPC64" - "@ - eqv. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" ""))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (not:DI (xor:DI (match_dup 1) - (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (not:DI (xor:DI (match_dup 1) - (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*andcdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "andc %0,%2,%1") - -(define_insn "*andcdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - andc. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (and:DI (not:DI (match_dup 1)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*andcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (not:DI (match_dup 1)) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - andc. %0,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (not:DI (match_dup 1)) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (and:DI (not:DI (match_dup 1)) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*iorcdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "orc %0,%2,%1") - -(define_insn "*iorcdi3_inernal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - orc. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:DI (not:DI (match_dup 1)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*iorcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ior:DI (not:DI (match_dup 1)) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - orc. %0,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (not:DI (match_dup 1)) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ior:DI (not:DI (match_dup 1)) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*nanddi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))] - "TARGET_POWERPC64" - "nand %0,%1,%2") - -(define_insn "*nanddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - nand. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ior:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*nanddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] - "TARGET_POWERPC64" - "@ - nand. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (ior:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*nordi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))] - "TARGET_POWERPC64" - "nor %0,%1,%2") - -(define_insn "*nordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - nor. %3,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (and:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2)))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*nordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] - "TARGET_POWERPC64" - "@ - nor. %0,%1,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2))))] - "reload_completed" - [(set (match_dup 0) - (and:DI (not:DI (match_dup 1)) - (not:DI (match_dup 2)))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - -;; Now define ways of moving data around. - -;; Elf specific ways of loading addresses for non-PIC code. -;; The output of this could be r0, but we limit it to base -;; registers, since almost all uses of this will need it -;; in a base register shortly. -(define_insn "elf_high" - [(set (match_operand:SI 0 "register_operand" "=b") - (high:SI (match_operand 1 "" "")))] - "TARGET_ELF && !TARGET_64BIT" - "{liu|lis} %0,%1@ha") - -(define_insn "elf_low" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "b") - (match_operand 2 "" "")))] - "TARGET_ELF && !TARGET_64BIT" - "{cal|la} %0,%2@l(%1)") - -;; Set up a register with a value from the GOT table - -(define_expand "movsi_got" - [(set (match_operand:SI 0 "register_operand" "") - (unspec [(match_operand:SI 1 "got_operand" "") - (match_dup 2)] 8))] - "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1" - " -{ - if (GET_CODE (operands[1]) == CONST) - { - rtx offset = const0_rtx; - HOST_WIDE_INT value; - - operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); - value = INTVAL (offset); - if (value != 0) - { - rtx tmp = ((reload_in_progress || reload_completed) - ? operands[0] - : gen_reg_rtx (Pmode)); - emit_insn (gen_movsi_got (tmp, operands[1])); - emit_insn (gen_addsi3 (operands[0], tmp, offset)); - DONE; - } - } - - operands[2] = rs6000_got_register (operands[1]); -}") - -(define_insn "*movsi_got_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "register_operand" "b")] 8))] - "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1" - "{l|lwz} %0,%a1@got(%2)" - [(set_attr "type" "load")]) - -;; Sometimes, though, the GOT `register' will be on the stack. Deal with -;; this case specially. -;; Force final to split this insn (if it hasn't been split already) to -;; avoid having to create a suitable output template. -(define_insn "*movsi_got_internal_mem" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "memory_operand" "m")] 8))] - "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 - && (reload_in_progress || reload_completed)" - "#" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -;; Used by sched, shorten_branches and final when the GOT pseudo reg -;; didn't get allocated to a hard register. -(define_split - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "memory_operand" "m")] 8))] - "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 - && (reload_in_progress || reload_completed)" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (unspec [(match_dup 1)(match_dup 0)] 8))] - "") - -;; For SI, we special-case integers that can't be loaded in one insn. We -;; do the load 16-bits at a time. We could do this by loading from memory, -;; and this is even supposed to be faster, but it is simpler not to get -;; integers in the TOC. -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "any_operand" ""))] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (SImode, operands[1]); - - /* Convert a move of a CONST_DOUBLE into a CONST_INT */ - if (GET_CODE (operands[1]) == CONST_DOUBLE) - operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - - /* Use default pattern for address of ELF small data */ - if (TARGET_ELF - && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) - && small_data_operand (operands[1], SImode)) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; - } - - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 && got_operand (operands[1], SImode)) - { - emit_insn (gen_movsi_got (operands[0], operands[1])); - DONE; - } - - if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT - && !flag_pic - && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != HIGH - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != CONSTANT_P_RTX) - { - rtx target = (reload_completed || reload_in_progress) - ? operands[0] : gen_reg_rtx (SImode); - - /* If this is a function address on -mcall-aixdesc or -mcall-nt, - convert it to the address of the descriptor. */ - if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - && GET_CODE (operands[1]) == SYMBOL_REF - && XSTR (operands[1], 0)[0] == '.') - { - char *name = XSTR (operands[1], 0); - rtx new_ref; - while (*name == '.') - name++; - new_ref = gen_rtx_SYMBOL_REF (Pmode, name); - CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]); - SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]); - SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]); - operands[1] = new_ref; - } - - emit_insn (gen_elf_high (target, operands[1])); - emit_insn (gen_elf_low (operands[0], target, operands[1])); - DONE; - } - - if (GET_CODE (operands[1]) == CONST - && DEFAULT_ABI == ABI_NT - && !side_effects_p (operands[0])) - { - rtx const_term = const0_rtx; - rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term); - if (sym && GET_CODE (const_term) == CONST_INT - && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF)) - { - unsigned HOST_WIDE_INT value = INTVAL (const_term); - int new_reg_p = (flag_expensive_optimizations - && !reload_completed - && !reload_in_progress); - rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0]; - - emit_insn (gen_movsi (tmp1, sym)); - if (INTVAL (const_term) != 0) - emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value))); - DONE; - } - else - rs6000_fatal_bad_address (operands[1]); - } - - if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT) - && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != CONSTANT_P_RTX - && GET_CODE (operands[1]) != HIGH - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])) - { - /* Emit a USE operation so that the constant isn't deleted if - expensive optimizations are turned on because nobody - references it. This should only be done for operands that - contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. - This should not be done for operands that contain LABEL_REFs. - For now, we just handle the obvious case. */ - if (GET_CODE (operands[1]) != LABEL_REF) - emit_insn (gen_rtx_USE (VOIDmode, operands[1])); - - /* If we are to limit the number of things we put in the TOC and - this is a symbol plus a constant we can add in one insn, - just put the symbol in the TOC and add the constant. Don't do - this if reload is in progress. */ - if (GET_CODE (operands[1]) == CONST - && TARGET_NO_SUM_IN_TOC && ! reload_in_progress - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode) - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) - && ! side_effects_p (operands[0])) - { - rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0)); - rtx other = XEXP (XEXP (operands[1], 0), 1); - - emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other)); - DONE; - } - - operands[1] = force_const_mem (SImode, operands[1]); - if (! memory_address_p (SImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], SImode, - XEXP (operands[1], 0)); - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h") - (match_operand:SI 1 "input_operand" "r,U,m,r,I,J,n,R,*h,r,r,0"))] - "gpc_reg_operand (operands[0], SImode) - || gpc_reg_operand (operands[1], SImode)" - "@ - mr %0,%1 - {cal|la} %0,%a1 - {l%U1%X1|lwz%U1%X1} %0,%1 - {st%U0%X0|stw%U0%X0} %1,%0 - {lil|li} %0,%1 - {liu|lis} %0,%v1 - # - {cal|la} %0,%1(%*) - mf%1 %0 - mt%0 %1 - mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*") - (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4")]) - -;; Split a load of a large constant into the appropriate two-insn -;; sequence. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 - && (INTVAL (operands[1]) & 0xffff) != 0" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ior:SI (match_dup 0) - (match_dup 3)))] - " -{ - operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000); - operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff); -}") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] - "" - "@ - mr. %0,%1 - #" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 1))] - "reload_completed && rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 2) - (compare:CC (match_dup 1) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 1))] - "reload_completed && !rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 2) - (compare:CC (match_dup 1) - (const_int 0))) - (set (match_dup 0) - (match_dup 1))] - "") - - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "any_operand" ""))] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (HImode, operands[1]); - - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != CONSTANT_P_RTX) - { - operands[1] = force_const_mem (HImode, operands[1]); - if (! memory_address_p (HImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], HImode, - XEXP (operands[1], 0)); - } -}") - -(define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") - (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] - "gpc_reg_operand (operands[0], HImode) - || gpc_reg_operand (operands[1], HImode)" - "@ - mr %0,%1 - lhz%U1%X1 %0,%1 - sth%U0%X0 %1,%0 - {lil|li} %0,%w1 - mf%1 %0 - mt%0 %1 - mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "any_operand" ""))] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (QImode, operands[1]); - - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != CONSTANT_P_RTX) - { - operands[1] = force_const_mem (QImode, operands[1]); - if (! memory_address_p (QImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], QImode, - XEXP (operands[1], 0)); - } -}") - -(define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") - (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] - "gpc_reg_operand (operands[0], QImode) - || gpc_reg_operand (operands[1], QImode)" - "@ - mr %0,%1 - lbz%U1%X1 %0,%1 - stb%U0%X0 %1,%0 - {lil|li} %0,%1 - mf%1 %0 - mt%0 %1 - mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) - -;; Here is how to move condition codes around. When we store CC data in -;; an integer register or memory, we store just the high-order 4 bits. -;; This lets us not shift in the most common case of CR0. -(define_expand "movcc" - [(set (match_operand:CC 0 "nonimmediate_operand" "") - (match_operand:CC 1 "nonimmediate_operand" ""))] - "" - "") - -(define_insn "" - [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m") - (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))] - "register_operand (operands[0], CCmode) - || register_operand (operands[1], CCmode)" - "@ - mcrf %0,%1 - mtcrf 128,%1 - {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff - mfcr %0 - mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 - mr %0,%1 - {l%U1%X1|lwz%U1%X1} %0,%1 - {st%U0%U1|stw%U0%U1} %1,%0" - [(set_attr "type" "*,*,*,compare,*,*,load,store") - (set_attr "length" "*,*,12,*,8,*,*,*")]) - -;; For floating-point, we normally deal with the floating-point registers -;; unless -msoft-float is used. The sole exception is that parameter passing -;; can produce floating-point values in fixed-point registers. Unless the -;; value is a simple constant or already in memory, we deal with this by -;; allocating memory and copying the value explicitly via that memory location. -(define_expand "movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "") - (match_operand:SF 1 "any_operand" ""))] - "" - " -{ - /* If we are called from reload, we might be getting a SUBREG of a hard - reg. So expand it. */ - if (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER) - operands[0] = alter_subreg (operands[0]); - if (GET_CODE (operands[1]) == SUBREG - && GET_CODE (SUBREG_REG (operands[1])) == REG - && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER) - operands[1] = alter_subreg (operands[1]); - - if (GET_CODE (operands[0]) == MEM) - { - /* If operands[1] is a register, it may have double-precision data - in it, so truncate it to single precision. We need not do - this for POWERPC. */ - if (! TARGET_POWERPC && TARGET_HARD_FLOAT - && GET_CODE (operands[1]) == REG - && (FP_REGNO_P (REGNO (operands[1])) - || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)) - { - rtx newreg - = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode); - emit_insn (gen_aux_truncdfsf2 (newreg, operands[1])); - operands[1] = newreg; - } - - operands[1] = force_reg (SFmode, operands[1]); - } - - if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT) - { - operands[1] = force_const_mem (SFmode, operands[1]); - if (! memory_address_p (SFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], SFmode, - XEXP (operands[1], 0)); - } -}") - -(define_split - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "const_double_operand" ""))] - "reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 3))] - " -{ - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - - if (! TARGET_POWERPC64) - operands[2] = operand_subword (operands[0], 0, 0, SFmode); - else - operands[2] = gen_lowpart (SImode, operands[0]); - - operands[3] = GEN_INT(l); -}") - -(define_insn "*movsf_hardfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r") - (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))] - "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT" - "@ - mr %0,%1 - {l%U1%X1|lwz%U1%X1} %0,%1 - {st%U0%X0|stw%U0%X0} %1,%0 - fmr %0,%1 - lfs%U1%X1 %0,%1 - stfs%U0%X0 %1,%0 - # - #" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) - -(define_insn "*movsf_softfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r") - (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))] - "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT" - "@ - mr %0,%1 - {l%U1%X1|lwz%U1%X1} %0,%1 - {st%U0%X0|stw%U0%X0} %1,%0 - {lil|li} %0,%1 - {liu|lis} %0,%v1 - {cal|la} %0,%1(%*) - # - #" - [(set_attr "type" "*,load,store,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) - - -(define_expand "movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "any_operand" ""))] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (DFmode, operands[1]); - - if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode)) - { - operands[1] = force_const_mem (DFmode, operands[1]); - if (! memory_address_p (DFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], DFmode, - XEXP (operands[1], 0)); - } -}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 1))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[2] = operand_subword (operands[0], endian, 0, DFmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); - operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx; -}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "const_double_operand" ""))] - "! TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (rv, l); - - operands[2] = operand_subword (operands[0], endian, 0, DFmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); - operands[4] = GEN_INT (l[endian]); - operands[5] = GEN_INT (l[1 - endian]); -}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "easy_fp_constant" ""))] - "TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 3))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (rv, l); - - operands[2] = gen_lowpart (DImode, operands[0]); - /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ - operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); -}") - -;; Don't have reload use general registers to load a constant. First, -;; it might not work if the output operand is the equivalent of -;; a non-offsettable memref, but also it is less efficient than loading -;; the constant into an FP register, since it will probably be used there. -;; The "??" is a kludge until we can figure out a more reasonable way -;; of handling these non-offsettable values. -;; CYGNUS LOCAL -- meissner/add non-offsetable load -(define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,&????r,o,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,o,m,r,G,H,F,f,m,f"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - /* We don't have an offsetable address for the load, use the bottom register - being loaded to hold the address. */ - case 2: - { - rtx addr = XEXP (operands[1], 0); - - if ((GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM) - && GET_CODE (XEXP (addr, 0)) == REG) - { - rtx left = XEXP (addr, 0); - rtx right = XEXP (addr, 1); - - operands[2] = left; - operands[3] = right; - - if (GET_CODE (right) == REG) - return \"{cax|add} %L0,%2,%3\;{l|lwz} %0,0(%L0)\;{l|lwz} %L0,4(%L0)\"; - - else if (TARGET_ELF && CONSTANT_P (right)) - return \"{cal|la} %L0,%3@l(%2)\;{l|lwz} %0,0(%L0)\;{l|lwz} %L0,4(%L0)\"; - } - fatal_insn (\"nonoffsetable movdf case not handled\", insn); - } - case 3: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - case 4: - case 5: - case 6: - return \"#\"; - case 7: - return \"fmr %0,%1\"; - case 8: - return \"lfd%U1%X1 %0,%1\"; - case 9: - return \"stfd%U0%X0 %1,%0\"; - } -}" - [(set_attr "type" "*,load,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "8,8,12,8,8,12,16,*,*,*")]) -;; END CYGNUS LOCAL -- meissner/add non-offsetable load - -(define_insn "*movdf_softfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - case 3: - case 4: - case 5: - return \"#\"; - } -}" - [(set_attr "type" "*,load,store,*,*,*") - (set_attr "length" "8,8,8,8,12,16")]) - -(define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "@ - mr %0,%1 - ld%U1%X1 %0,%1 - std%U0%X0 %1,%0 - # - # - # - fmr %0,%1 - lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0" - [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "4,4,4,8,12,16,4,4,4")]) - -(define_insn "*movdf_softfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))] - "TARGET_POWERPC64 && TARGET_SOFT_FLOAT - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "@ - mr %0,%1 - ld%U1%X1 %0,%1 - std%U0%X0 %1,%0 - # - # - #" - [(set_attr "type" "*,load,store,*,*,*") - (set_attr "length" "*,*,*,8,12,16")]) - -;; Next come the multi-word integer load and store and the load and store -;; multiple insns. -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "any_operand" ""))] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[1] = force_reg (DImode, operands[1]); - - /* Convert a move of a CONST_DOUBLE into a CONST_INT - only if sign-extended lower-half for 32-bit host. */ - if (GET_CODE (operands[1]) == CONST_DOUBLE -#if HOST_BITS_PER_WIDE_INT == 32 - && ((CONST_DOUBLE_HIGH (operands[1]) == 0 - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) - || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0)) -#endif - ) - operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - - if (TARGET_64BIT - && CONSTANT_P (operands[1]) -#if HOST_BITS_PER_WIDE_INT == 32 - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[1]) != CONSTANT_P_RTX -#endif - && ! easy_fp_constant (operands[1], DImode) - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])) - { - /* Emit a USE operation so that the constant isn't deleted if - expensive optimizations are turned on because nobody - references it. This should only be done for operands that - contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. - This should not be done for operands that contain LABEL_REFs. - For now, we just handle the obvious case. */ - if (GET_CODE (operands[1]) != LABEL_REF) - emit_insn (gen_rtx_USE (VOIDmode, operands[1])); - - /* If we are to limit the number of things we put in the TOC and - this is a symbol plus a constant we can add in one insn, - just put the symbol in the TOC and add the constant. Don't do - this if reload is in progress. */ - if (GET_CODE (operands[1]) == CONST - && TARGET_NO_SUM_IN_TOC && ! reload_in_progress - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && add_operand (XEXP (XEXP (operands[1], 0), 1), DImode) - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) - && ! side_effects_p (operands[0])) - { - rtx sym = force_const_mem (DImode, XEXP (XEXP (operands[1], 0), 0)); - rtx other = XEXP (XEXP (operands[1], 0), 1); - - emit_insn (gen_adddi3 (operands[0], force_reg (DImode, sym), other)); - DONE; - } - - operands[1] = force_const_mem (DImode, operands[1]); - if (! memory_address_p (DImode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], DImode, - XEXP (operands[1], 0)); - } -}") - -(define_insn "*movdi_32" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r") - (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))] - "! TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], DImode) - || gpc_reg_operand (operands[1], DImode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - case 3: - return \"fmr %0,%1\"; - case 4: - return \"lfd%U1%X1 %0,%1\"; - case 5: - return \"stfd%U0%X0 %1,%0\"; - case 6: - case 7: - case 8: - case 9: - case 10: - return \"#\"; - } -}" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*") - (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 1))] - " -{ - operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0); - operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0); -#if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx; -#else - operands[4] = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32; - operands[1] = INTVAL (operands[1]) & 0xffffffff; -#endif -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - " -{ - operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0); - operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0); - operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); -}") - -(define_insn "*movdi_64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") - (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))] - "TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], DImode) - || gpc_reg_operand (operands[1], DImode))" - "@ - mr %0,%1 - ld%U1%X1 %0,%1 - std%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - # - {cal|la} %0,%1(%*) - fmr %0,%1 - lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0 - mf%1 %0 - mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*") - (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operand:DI 1 "const_double_operand" "F"))] - "TARGET_POWERPC64 && GET_CODE (operands[1]) == CONST_DOUBLE - && num_insns_constant (operands[1], DImode) == 1" - "* -{ - return ((unsigned HOST_WIDE_INT) - (CONST_DOUBLE_LOW (operands[1]) + 0x8000) < 0x10000) - ? \"li %0,%1\" : \"lis %0,%v1\"; -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 - && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ior:DI (match_dup 0) - (match_dup 3)))] - " -{ - operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000); - operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff); -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 - && GET_CODE (operands[1]) == CONST_DOUBLE - && ((CONST_DOUBLE_HIGH (operands[1]) == 0 - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) - || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ior:DI (match_dup 0) - (match_dup 3)))] - " -{ - operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff0000); - operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff); -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 - && GET_CODE (operands[1]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[1]) == 0 - && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (zero_extend:DI (subreg:SI (match_dup 0) 0)))] - " -{ operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); }") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 - && GET_CODE (operands[1]) == CONST_DOUBLE - && CONST_DOUBLE_LOW (operands[1]) == 0" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ashift:DI (match_dup 0) - (const_int 32)))] - " -{ operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); }") - -;; Generate all one-bits and clear left or right. -;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber. -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "mask64_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) (const_int -1)) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (const_int 0)) - (match_dup 1)))] - "") - -;; Split a load of a large constant into the appropriate five-instruction -;; sequence. Handle anything in a constant number of insns. -;; When non-easy constants can go in the TOC, this should use -;; easy_fp_constant predicate. -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ashift:DI (match_dup 0) - (const_int 32))) - (set (match_dup 0) - (ior:DI (match_dup 0) - (match_dup 3)))] - " -{ - HOST_WIDE_INT low; - HOST_WIDE_INT high; - - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - low = CONST_DOUBLE_LOW (operands[1]); - high = CONST_DOUBLE_HIGH (operands[1]); - } - else -#if HOST_BITS_PER_WIDE_INT == 32 - { - low = INTVAL (operands[1]); - high = (low < 0) ? ~0 : 0; - } -#else - { - low = INTVAL (operands[1]) & 0xffffffff; - high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32; - } -#endif - - operands[2] = GEN_INT (high); - operands[3] = GEN_INT (low); -}") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] - "TARGET_POWERPC64" - "@ - mr. %0,%1 - #" - [(set_attr "type" "compare")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 1))] - "reload_completed && rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 2) - (compare:CC (match_dup 1) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 1))] - "reload_completed && !rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 2) - (compare:CC (match_dup 1) - (const_int 0))) - (set (match_dup 0) - (match_dup 1))] - "") - -;; TImode is similar, except that we usually want to compute the address into -;; a register and use lsi/stsi (the exception is during reload). MQ is also -;; clobbered in stsi for POWER, so we need a SCRATCH for it. -(define_expand "movti" - [(parallel [(set (match_operand:TI 0 "general_operand" "") - (match_operand:TI 1 "general_operand" "")) - (clobber (scratch:SI))])] - "TARGET_STRING || TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[0]) == MEM) - operands[1] = force_reg (TImode, operands[1]); - - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) != REG - && ! reload_in_progress) - operands[0] = change_address (operands[0], TImode, - copy_addr_to_reg (XEXP (operands[0], 0))); - - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) != REG - && ! reload_in_progress) - operands[1] = change_address (operands[1], TImode, - copy_addr_to_reg (XEXP (operands[1], 0))); -}") - -;; We say that MQ is clobbered in the last alternative because the first -;; alternative would never get used otherwise since it would need a reload -;; while the 2nd alternative would not. We put memory cases first so they -;; are preferred. Otherwise, we'd try to reload the output instead of -;; giving the SCRATCH mq. -(define_insn "*movti_power" - [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r") - (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m")) - (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] - "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - - case 0: - return \"{stsi|stswi} %1,%P0,16\"; - - case 1: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; - - case 2: - /* Normally copy registers with lowest numbered register copied first. - But copy in the other order if the first register of the output - is the second, third, or fourth register in the input. */ - if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 - && REGNO (operands[0]) <= REGNO (operands[1]) + 3) - return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\"; - case 3: - /* If the address is not used in the output, we can use lsi. Otherwise, - fall through to generating four loads. */ - if (! reg_overlap_mentioned_p (operands[0], operands[1])) - return \"{lsi|lswi} %0,%P1,16\"; - /* ... fall through ... */ - case 4: - /* If the address register is the same as the register for the lowest- - addressed word, load it last. Similarly for the next two words. - Otherwise load lowest address to highest. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 1, - REGNO (operands[0]) + 2, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 2, - REGNO (operands[0]) + 3, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; - } -}" - [(set_attr "type" "store,store,*,load,load") - (set_attr "length" "*,16,16,*,16")]) - -(define_insn "*movti_string" - [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r") - (match_operand:TI 1 "reg_or_mem_operand" "r,r,m")) - (clobber (match_scratch:SI 2 "=X,X,X"))] - "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - - case 0: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; - - case 1: - /* Normally copy registers with lowest numbered register copied first. - But copy in the other order if the first register of the output - is the second, third, or fourth register in the input. */ - if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 - && REGNO (operands[0]) <= REGNO (operands[1]) + 3) - return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\"; - case 2: - /* If the address register is the same as the register for the lowest- - addressed word, load it last. Similarly for the next two words. - Otherwise load lowest address to highest. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 1, - REGNO (operands[0]) + 2, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 2, - REGNO (operands[0]) + 3, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; - } -}" - [(set_attr "type" "store,*,load") - (set_attr "length" "16,16,16")]) - -(define_insn "*movti_ppc64" - [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") - (match_operand:TI 1 "input_operand" "r,m,r"))] - "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) - || gpc_reg_operand (operands[1], TImode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"ld %L0,%L1\;ld %0,%1\"; - else - return \"ld%U1 %0,%1\;ld %L0,%L1\"; - case 2: - return \"std%U0 %1,%0\;std %L1,%L0\"; - } -}" - [(set_attr "type" "*,load,store") - (set_attr "length" "8,8,8")]) - -(define_expand "load_multiple" - [(match_par_dup 3 [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" "")) - (use (match_operand:SI 2 "" ""))])] - "TARGET_STRING" - " -{ - int regno; - int count; - rtx from; - int i; - - /* Support only loading a constant number of fixed-point registers from - memory and only bother with this if more than two; the machine - doesn't support more than eight. */ - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 2 - || INTVAL (operands[2]) > 8 - || GET_CODE (operands[1]) != MEM - || GET_CODE (operands[0]) != REG - || REGNO (operands[0]) >= 32) - FAIL; - - count = INTVAL (operands[2]); - regno = REGNO (operands[0]); - - operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); - from = force_reg (SImode, XEXP (operands[1], 0)); - - for (i = 0; i < count; i++) - XVECEXP (operands[3], 0, i) - = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i), - change_address (operands[1], SImode, - plus_constant (from, i * 4))); -}") - -(define_insn "" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 1 "gpc_reg_operand" "=r") - (mem:SI (match_operand:SI 2 "register_operand" "b")))])] - "TARGET_STRING" - "* -{ - /* We have to handle the case where the pseudo used to contain the address - is assigned to one of the output registers. */ - int i, j; - int words = XVECLEN (operands[0], 0); - rtx xop[10]; - - if (XVECLEN (operands[0], 0) == 1) - return \"{l|lwz} %1,0(%2)\"; - - for (i = 0; i < words; i++) - if (refers_to_regno_p (REGNO (operands[1]) + i, - REGNO (operands[1]) + i + 1, operands[2], 0)) - { - if (i == words-1) - { - xop[0] = operands[1]; - xop[1] = operands[2]; - xop[2] = GEN_INT (4 * (words-1)); - output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop); - return \"\"; - } - else if (i == 0) - { - xop[0] = operands[1]; - xop[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); - xop[2] = GEN_INT (4 * (words-1)); - output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop); - return \"\"; - } - else - { - for (j = 0; j < words; j++) - if (j != i) - { - xop[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + j); - xop[1] = operands[2]; - xop[2] = GEN_INT (j * 4); - output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop); - } - xop[0] = operands[2]; - xop[1] = GEN_INT (i * 4); - output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop); - return \"\"; - } - } - - return \"{lsi|lswi} %1,%2,%N0\"; -}" - [(set_attr "type" "load") - (set_attr "length" "32")]) - - -(define_expand "store_multiple" - [(match_par_dup 3 [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" "")) - (clobber (scratch:SI)) - (use (match_operand:SI 2 "" ""))])] - "TARGET_STRING" - " -{ - int regno; - int count; - rtx to; - int i; - - /* Support only storing a constant number of fixed-point registers to - memory and only bother with this if more than two; the machine - doesn't support more than eight. */ - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 2 - || INTVAL (operands[2]) > 8 - || GET_CODE (operands[0]) != MEM - || GET_CODE (operands[1]) != REG - || REGNO (operands[1]) >= 32) - FAIL; - - count = INTVAL (operands[2]); - regno = REGNO (operands[1]); - - operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); - to = force_reg (SImode, XEXP (operands[0], 0)); - - XVECEXP (operands[3], 0, 0) - = gen_rtx_SET (VOIDmode, change_address (operands[0], SImode, to), - operands[1]); - XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, - gen_rtx_SCRATCH (SImode)); - - for (i = 1; i < count; i++) - XVECEXP (operands[3], 0, i + 1) - = gen_rtx_SET (VOIDmode, - change_address (operands[0], SImode, - plus_constant (to, i * 4)), - gen_rtx_REG (SImode, regno + i)); -}") - -(define_insn "" - [(match_parallel 0 "store_multiple_operation" - [(set (match_operand:SI 1 "indirect_operand" "=Q") - (match_operand:SI 2 "gpc_reg_operand" "r")) - (clobber (match_scratch:SI 3 "=q"))])] - "TARGET_STRING && TARGET_POWER" - "{stsi|stswi} %2,%P1,%O0" - [(set_attr "type" "store")]) - -(define_insn "" - [(match_parallel 0 "store_multiple_operation" - [(set (mem:SI (match_operand:SI 1 "register_operand" "b")) - (match_operand:SI 2 "gpc_reg_operand" "r")) - (clobber (match_scratch:SI 3 "X"))])] - "TARGET_STRING && !TARGET_POWER" - "{stsi|stswi} %2,%1,%O0" - [(set_attr "type" "store")]) - - -;; String/block move insn. -;; Argument 0 is the destination -;; Argument 1 is the source -;; Argument 2 is the length -;; Argument 3 is the alignment - -(define_expand "movstrsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand:BLK 1 "" "")) - (use (match_operand:SI 2 "" "")) - (use (match_operand:SI 3 "" ""))])] - "" - " -{ - if (expand_block_move (operands)) - DONE; - else - FAIL; -}") - -;; Move up to 32 bytes at a time. The fixed registers are needed because the -;; register allocator doesn't have a clue about allocating 8 word registers -(define_expand "movstrsi_8reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 5)) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER - && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0) - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 5" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER - && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0) - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 5" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -;; Move up to 24 bytes at a time. The fixed registers are needed because the -;; register allocator doesn't have a clue about allocating 6 word registers -(define_expand "movstrsi_6reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24 - && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 7" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 - && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 7" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems -;; with TImode -(define_expand "movstrsi_4reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER - && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 - && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 9" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "register_operand" "=r")) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER - && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 - && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 9" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -;; Move up to 8 bytes at a time. -(define_expand "movstrsi_2reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (match_scratch:DI 4 "")) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_STRING && !TARGET_64BIT" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:DI 4 "=&r")) - (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER && !TARGET_64BIT - && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:DI 4 "=&r")) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT - && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -;; Move up to 4 bytes at a time. -(define_expand "movstrsi_1reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (match_scratch:SI 4 "")) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) - (mem:BLK (match_operand:SI 1 "register_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - - -;; Define insns that do load or store with update. Some of these we can -;; get by using pre-decrement or pre-increment, but the hardware can also -;; do cases where the increment is not the size of the object. -;; -;; In all these cases, we use operands 0 and 1 for the register being -;; incremented because those are the operands that local-alloc will -;; tie and these are the pair most likely to be tieable (and the ones -;; that will benefit the most). - -(define_insn "*movdi_update1" - [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") - (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") - (match_operand:DI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE" - "@ - ldux %3,%0,%2 - ldu %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movdi_update2" - [(set (match_operand:DI 3 "gpc_reg_operand" "=r") - (sign_extend:DI - (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0") - (match_operand:DI 2 "gpc_reg_operand" "r"))))) - (set (match_operand:DI 0 "gpc_reg_operand" "=b") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "lwaux %3,%0,%2" - [(set_attr "type" "load")]) - -(define_insn "movdi_update" - [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") - (match_operand:DI 2 "reg_or_short_operand" "r,I"))) - (match_operand:DI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE" - "@ - stdux %3,%0,%2 - stdu %3,%2(%0)" - [(set_attr "type" "store")]) - -(define_insn "*movsi_update1" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {lux|lwzux} %3,%0,%2 - {lu|lwzu} %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "movsi_update" - [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - {stux|stwux} %3,%0,%2 - {stu|stwu} %3,%2(%0)" - [(set_attr "type" "store")]) - -(define_insn "*movhi_update" - [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") - (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - lhzux %3,%0,%2 - lhzu %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movhi_update2" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (zero_extend:SI - (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - lhzux %3,%0,%2 - lhzu %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movhi_update3" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (sign_extend:SI - (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - lhaux %3,%0,%2 - lhau %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movhi_update4" - [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:HI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - sthux %3,%0,%2 - sthu %3,%2(%0)" - [(set_attr "type" "store")]) - -(define_insn "*movqi_update1" - [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") - (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - lbzux %3,%0,%2 - lbzu %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movqi_update2" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (zero_extend:SI - (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - lbzux %3,%0,%2 - lbzu %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movqi_update3" - [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:QI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" - "@ - stbux %3,%0,%2 - stbu %3,%2(%0)" - [(set_attr "type" "store")]) - -(define_insn "*movsf_update1" - [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") - (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" - "@ - lfsux %3,%0,%2 - lfsu %3,%2(%0)" - [(set_attr "type" "fpload")]) - -(define_insn "*movsf_update2" - [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SF 3 "gpc_reg_operand" "f,f")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" - "@ - stfsux %3,%0,%2 - stfsu %3,%2(%0)" - [(set_attr "type" "fpstore")]) - -(define_insn "*movsf_update3" - [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") - (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_SOFT_FLOAT && TARGET_UPDATE" - "@ - {lux|lwzux} %3,%0,%2 - {lu|lwzu} %3,%2(%0)" - [(set_attr "type" "load")]) - -(define_insn "*movsf_update4" - [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SF 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_SOFT_FLOAT && TARGET_UPDATE" - "@ - {stux|stwux} %3,%0,%2 - {stu|stwu} %3,%2(%0)" - [(set_attr "type" "store")]) - -(define_insn "*movdf_update1" - [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f") - (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" - "@ - lfdux %3,%0,%2 - lfdu %3,%2(%0)" - [(set_attr "type" "fpload")]) - -(define_insn "*movdf_update2" - [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:DF 3 "gpc_reg_operand" "f,f")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" - "@ - stfdux %3,%0,%2 - stfdu %3,%2(%0)" - [(set_attr "type" "fpstore")]) - -;; Peephole to convert two consecutive FP loads or stores into lfq/stfq. - -(define_peephole - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (match_operand:DF 1 "memory_operand" "")) - (set (match_operand:DF 2 "gpc_reg_operand" "=f") - (match_operand:DF 3 "memory_operand" ""))] - "TARGET_POWER2 - && TARGET_HARD_FLOAT - && registers_ok_for_quad_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "lfq%U1%X1 %0,%1") - -(define_peephole - [(set (match_operand:DF 0 "memory_operand" "") - (match_operand:DF 1 "gpc_reg_operand" "f")) - (set (match_operand:DF 2 "memory_operand" "") - (match_operand:DF 3 "gpc_reg_operand" "f"))] - "TARGET_POWER2 - && TARGET_HARD_FLOAT - && registers_ok_for_quad_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "stfq%U0%X0 %1,%0") - -;; Next come insns related to the calling sequence. -;; -;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). -;; We move the back-chain and decrement the stack pointer. - -(define_expand "allocate_stack" - [(set (match_operand 0 "register_operand" "=r") - (minus (reg 1) (match_operand 1 "reg_or_short_operand" ""))) - (set (reg 1) - (minus (reg 1) (match_dup 1)))] - "" - " -{ rtx chain = gen_reg_rtx (Pmode); - rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); - rtx neg_op0; - - emit_move_insn (chain, stack_bot); - - /* Under Windows NT, we need to add stack probes for large/variable - allocations, so do it via a call to the external function alloca - instead of doing it inline. */ - if (DEFAULT_ABI == ABI_NT - && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096)) - { - rtx tmp = gen_reg_rtx (Pmode); - emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__allocate_stack\"), - tmp, 0, Pmode, 1, operands[1], Pmode); - emit_insn (gen_set_sp (tmp)); - emit_move_insn (operands[0], tmp); - DONE; - } - - if (GET_CODE (operands[1]) != CONST_INT - || INTVAL (operands[1]) < -32767 - || INTVAL (operands[1]) > 32768) - { - neg_op0 = gen_reg_rtx (Pmode); - if (TARGET_32BIT) - emit_insn (gen_negsi2 (neg_op0, operands[1])); - else - emit_insn (gen_negdi2 (neg_op0, operands[1])); - } - else - neg_op0 = GEN_INT (- INTVAL (operands[1])); - - if (TARGET_UPDATE) - emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update)) - (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); - - else - { - emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3)) - (stack_pointer_rtx, stack_pointer_rtx, neg_op0)); - emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx), chain); - } - - emit_move_insn (operands[0], virtual_stack_dynamic_rtx); - DONE; -}") - -;; Marker to indicate that the stack pointer was changed under NT in -;; ways not known to the compiler - -(define_insn "set_sp" - [(set (reg:SI 1) - (unspec [(match_operand:SI 0 "register_operand" "r")] 7))] - "" - "" - [(set_attr "length" "0")]) - -;; These patterns say how to save and restore the stack pointer. We need not -;; save the stack pointer at function level since we are careful to -;; preserve the backchain. At block level, we have to restore the backchain -;; when we restore the stack pointer. -;; -;; For nonlocal gotos, we must save both the stack pointer and its -;; backchain and restore both. Note that in the nonlocal case, the -;; save area is a memory location. - -(define_expand "save_stack_function" - [(match_operand 0 "any_operand" "") - (match_operand 1 "any_operand" "")] - "" - "DONE;") - -(define_expand "restore_stack_function" - [(match_operand 0 "any_operand" "") - (match_operand 1 "any_operand" "")] - "" - "DONE;") - -(define_expand "restore_stack_block" - [(use (match_operand 0 "register_operand" "")) - (set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (match_operand 1 "register_operand" "")) - (set (match_dup 3) (match_dup 2))] - "" - " -{ - operands[2] = gen_reg_rtx (Pmode); - operands[3] = gen_rtx_MEM (Pmode, operands[0]); -}") - -(define_expand "save_stack_nonlocal" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "register_operand" "")] - "" - " -{ - rtx temp = gen_reg_rtx (Pmode); - - /* Copy the backchain to the first word, sp to the second. */ - emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1])); - emit_move_insn (operand_subword (operands[0], 0, 0, (TARGET_32BIT ? DImode : TImode)), - temp); - emit_move_insn (operand_subword (operands[0], 1, 0, (TARGET_32BIT ? DImode : TImode)), - operands[1]); - DONE; -}") - -(define_expand "restore_stack_nonlocal" - [(match_operand 0 "register_operand" "") - (match_operand 1 "memory_operand" "")] - "" - " -{ - rtx temp = gen_reg_rtx (Pmode); - - /* Restore the backchain from the first word, sp from the second. */ - emit_move_insn (temp, - operand_subword (operands[1], 0, 0, (TARGET_32BIT ? DImode : TImode))); - emit_move_insn (operands[0], - operand_subword (operands[1], 1, 0, (TARGET_32BIT ? DImode : TImode))); - emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp); - DONE; -}") - -;; If we have -mminimal-toc, we need to reload r30 after a nonlocal goto. - -;; NB. Kenner removed the '&& get_pool_size() != 0' part of the condition -;; on Oct 18, 1997 for an as yet undetermined reason. Without this condition, -;; the powerpc-eabi targets mistakenly force a load of r30 at the beginning -;; of exception handlers in functions which have no constant section. -;; Presumably the original reason for the change will re-surface at some -;; point, and this comment will help sort out the right thing to do. -;; If this needs to be changed back again, it may be that the rs6000 -;; prologue code should have the equivilent change made so that there is -;; a TOC value to restore. (It currently uses the get_pool_size() check). - -(define_insn "nonlocal_goto_receiver" - [(unspec_volatile [(const_int 0)] 1)] - "TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size() != 0" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"\"; -}" - [(set_attr "type" "load")]) - -;; A function pointer under AIX is a pointer to a data area whose first word -;; contains the actual address of the function, whose second word contains a -;; pointer to its TOC, and whose third word contains a value to place in the -;; static chain register (r11). Note that if we load the static chain, our -;; "trampoline" need not have any executable code. -;; -;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address) -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX) -;; operands[3] is location to store the TOC -;; operands[4] is the TOC register -;; operands[5] is the static chain register -;; -;; We do not break this into separate insns, so that the scheduler will not try -;; to move the load of the new TOC before any loads from the TOC. - -(define_insn "call_indirect_aix32" - [(call (mem:SI (match_operand:SI 0 "register_operand" "b")) - (match_operand 1 "const_int_operand" "n")) - (use (match_operand 2 "const_int_operand" "n")) - (use (match_operand 3 "offsettable_addr_operand" "p")) - (use (match_operand 4 "register_operand" "r")) - (clobber (match_operand 5 "register_operand" "=r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=l"))] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)" - "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3" - [(set_attr "type" "load") - (set_attr "length" "28")]) - -(define_insn "call_indirect_aix64" - [(call (mem:SI (match_operand:DI 0 "register_operand" "b")) - (match_operand 1 "const_int_operand" "n")) - (use (match_operand 2 "const_int_operand" "n")) - (use (match_operand 3 "offsettable_addr_operand" "p")) - (use (match_operand 4 "register_operand" "r")) - (clobber (match_operand 5 "register_operand" "=r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=l"))] - "TARGET_64BIT && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)" - "std %4,%a3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%a3" - [(set_attr "type" "load") - (set_attr "length" "28")]) - -(define_insn "call_value_indirect_aix32" - [(set (match_operand 0 "register_operand" "fg") - (call (mem:SI (match_operand:SI 1 "register_operand" "b")) - (match_operand 2 "const_int_operand" "n"))) - (use (match_operand 3 "const_int_operand" "n")) - (use (match_operand 4 "offsettable_addr_operand" "p")) - (use (match_operand 5 "register_operand" "r")) - (clobber (match_operand 6 "register_operand" "=r")) - (clobber (match_scratch:SI 7 "=&r")) - (clobber (match_scratch:SI 8 "=l"))] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)" - "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4" - [(set_attr "type" "load") - (set_attr "length" "28")]) - -(define_insn "call_value_indirect_aix64" - [(set (match_operand 0 "register_operand" "fg") - (call (mem:SI (match_operand:DI 1 "register_operand" "b")) - (match_operand 2 "const_int_operand" "n"))) - (use (match_operand 3 "const_int_operand" "n")) - (use (match_operand 4 "offsettable_addr_operand" "p")) - (use (match_operand 5 "register_operand" "r")) - (clobber (match_operand 6 "register_operand" "=r")) - (clobber (match_scratch:SI 7 "=&r")) - (clobber (match_scratch:SI 8 "=l"))] - "TARGET_64BIT && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)" - "std %5,%a4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%a4" - [(set_attr "type" "load") - (set_attr "length" "28")]) - -;; A function pointer undef NT is a pointer to a data area whose first word -;; contains the actual address of the function, whose second word contains a -;; pointer to its TOC. The static chain is not stored under NT, which means -;; that we need a trampoline. -;; -;; operands[0] is an SImode pseudo in which we place the address of the function. -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT) -;; operands[3] is location to store the TOC -;; operands[4] is the TOC register -;; -;; We do not break this into separate insns, so that the scheduler will not try -;; to move the load of the new TOC before any loads from the TOC. - -(define_insn "call_indirect_nt" - [(call (mem:SI (match_operand:SI 0 "register_operand" "b")) - (match_operand 1 "const_int_operand" "n")) - (use (match_operand 2 "const_int_operand" "n")) - (use (match_operand 3 "offsettable_addr_operand" "p")) - (use (match_operand 4 "register_operand" "r")) - (clobber (match_scratch:SI 5 "=&r")) - (clobber (match_scratch:SI 6 "=l"))] - "DEFAULT_ABI == ABI_NT - && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)" - "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3" - [(set_attr "type" "load") - (set_attr "length" "24")]) - -(define_insn "call_value_indirect_nt" - [(set (match_operand 0 "register_operand" "fg") - (call (mem:SI (match_operand:SI 1 "register_operand" "b")) - (match_operand 2 "const_int_operand" "n"))) - (use (match_operand 3 "const_int_operand" "n")) - (use (match_operand 4 "offsettable_addr_operand" "p")) - (use (match_operand 5 "register_operand" "r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=l"))] - "DEFAULT_ABI == ABI_NT - && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)" - "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4" - [(set_attr "type" "load") - (set_attr "length" "24")]) - -;; A function pointer under System V is just a normal pointer -;; operands[0] is the function pointer -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1 - -(define_insn "call_indirect_sysv" - [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l")) - (match_operand 1 "const_int_operand" "n,n")) - (use (match_operand 2 "const_int_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return \"{brl|blrl}\"; -}" - [(set_attr "type" "jmpreg") - (set_attr "length" "4,8")]) - -(define_insn "call_value_indirect_sysv" - [(set (match_operand 0 "register_operand" "=fg,fg") - (call (mem:SI (match_operand:SI 1 "register_operand" "l,l")) - (match_operand 2 "const_int_operand" "n,n"))) - (use (match_operand 3 "const_int_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return \"{brl|blrl}\"; -}" - [(set_attr "type" "jmpreg") - (set_attr "length" "4,8")]) - -;; Now the definitions for the call and call_value insns -(define_expand "call" - [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (scratch:SI))])] - "" - " -{ - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT) - abort (); - - operands[0] = XEXP (operands[0], 0); - - /* Convert NT DLL imports into an indirect call. */ - if (GET_CODE (operands[0]) == SYMBOL_REF - && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0) - { - operands[0] = rs6000_dll_import_ref (operands[0]); - operands[2] = GEN_INT ((int)CALL_NORMAL); - } - - if (GET_CODE (operands[0]) != SYMBOL_REF - || (INTVAL (operands[2]) & CALL_LONG) != 0) - { - if (INTVAL (operands[2]) & CALL_LONG) - operands[0] = rs6000_longcall_ref (operands[0]); - - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS) - emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]), - operands[1], operands[2])); - else - { - rtx toc_reg = gen_rtx_REG (Pmode, 2); - rtx toc_addr = RS6000_SAVE_TOC; - - if (DEFAULT_ABI == ABI_AIX) - { - /* AIX function pointers are really pointers to a three word area */ - rtx static_chain = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); - emit_call_insn (TARGET_32BIT - ? gen_call_indirect_aix32 (force_reg (Pmode, operands[0]), - operands[1], operands[2], - toc_addr, toc_reg, static_chain) - : gen_call_indirect_aix64 (force_reg (Pmode, operands[0]), - operands[1], operands[2], - toc_addr, toc_reg, static_chain)); - } - else if (DEFAULT_ABI == ABI_NT) - { - /* NT function pointers are really pointers to a two word area */ - emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]), - operands[1], operands[2], - toc_addr, toc_reg)); - } - else - abort (); - } - DONE; - } -}") - -(define_expand "call_value" - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "address_operand" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (scratch:SI))])] - "" - " -{ - if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT) - abort (); - - operands[1] = XEXP (operands[1], 0); - - /* Convert NT DLL imports into an indirect call. */ - if (GET_CODE (operands[1]) == SYMBOL_REF - && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0) - { - operands[1] = rs6000_dll_import_ref (operands[1]); - operands[3] = GEN_INT ((int)CALL_NORMAL); - } - - if (GET_CODE (operands[1]) != SYMBOL_REF - || (INTVAL (operands[3]) & CALL_LONG) != 0) - { - if (INTVAL (operands[2]) & CALL_LONG) - operands[1] = rs6000_longcall_ref (operands[1]); - - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS) - emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1], - operands[2], operands[3])); - else - { - rtx toc_reg = gen_rtx_REG (Pmode, 2); - rtx toc_addr = RS6000_SAVE_TOC; - - if (DEFAULT_ABI == ABI_AIX) - { - /* AIX function pointers are really pointers to a three word area */ - rtx static_chain = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); - emit_call_insn (TARGET_32BIT - ? gen_call_value_indirect_aix32 (operands[0], - force_reg (Pmode, operands[1]), - operands[2], operands[3], - toc_addr, toc_reg, static_chain) - : gen_call_value_indirect_aix64 (operands[0], - force_reg (Pmode, operands[1]), - operands[2], operands[3], - toc_addr, toc_reg, static_chain)); - } - else if (DEFAULT_ABI == ABI_NT) - { - /* NT function pointers are really pointers to a two word area */ - emit_call_insn (gen_call_value_indirect_nt (operands[0], - force_reg (Pmode, operands[1]), - operands[2], operands[3], - toc_addr, toc_reg)); - } - else - abort (); - } - DONE; - } -}") - -;; Call to function in current module. No TOC pointer reload needed. -;; Operand2 is non-zero if we are using the V.4 calling sequence and -;; either the function was not prototyped, or it was prototyped as a -;; variable argument function. It is > 0 if FP registers were passed -;; and < 0 if they were not. - -(define_insn "*call_local32" - [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "(INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_local64" - [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*ret_call_local32" - [(set (match_operand 0 "" "=fg,fg") - (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "(INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - - -(define_insn "*ret_call_local64" - [(set (match_operand 0 "" "=fg,fg") - (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -;; Call to function which may be in another module. Restore the TOC -;; pointer (r2) after the call unless this is System V. -;; Operand2 is non-zero if we are using the V.4 calling sequence and -;; either the function was not prototyped, or it was prototyped as a -;; variable argument function. It is > 0 if FP registers were passed -;; and < 0 if they were not. - -(define_insn "*call_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s")) - (match_operand 1 "" "fg,fg")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - /* Indirect calls should go through call_indirect */ - if (GET_CODE (operands[0]) == REG) - abort (); - - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "8,12")]) - -(define_insn "*call_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "call_operand" "s,s")) - (match_operand 1 "" "fg,fg")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - /* Indirect calls should go through call_indirect */ - if (GET_CODE (operands[0]) == REG) - abort (); - - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "8,12")]) - -(define_insn "*call_nonlocal_sysv" - [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s")) - (match_operand 1 "" "fg,fg")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 3 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - /* Indirect calls should go through call_indirect */ - if (GET_CODE (operands[0]) == REG) - abort (); - - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*ret_call_nonlocal_aix32" - [(set (match_operand 0 "" "=fg,fg") - (call (mem:SI (match_operand:SI 1 "call_operand" "s,s")) - (match_operand 2 "" "fg,fg"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - /* This should be handled by call_value_indirect */ - if (GET_CODE (operands[1]) == REG) - abort (); - - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "8,12")]) - -(define_insn "*ret_call_nonlocal_aix64" - [(set (match_operand 0 "" "=fg,fg") - (call (mem:SI (match_operand:DI 1 "call_operand" "s,s")) - (match_operand 2 "" "fg,fg"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - /* This should be handled by call_value_indirect */ - if (GET_CODE (operands[1]) == REG) - abort (); - - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "8,12")]) - -(define_insn "*ret_call_nonlocal_sysv" - [(set (match_operand 0 "" "=fg,fg") - (call (mem:SI (match_operand:SI 1 "call_operand" "s,s")) - (match_operand 2 "" "fg,fg"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (match_scratch:SI 4 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - /* This should be handled by call_value_indirect */ - if (GET_CODE (operands[1]) == REG) - abort (); - - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -;; Call subroutine returning any type. -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "") - -;; V.4 specific code to initialize the PIC register - -(define_insn "init_v4_pic" - [(set (match_operand:SI 0 "register_operand" "=l") - (unspec [(const_int 0)] 7))] - "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS" - "bl _GLOBAL_OFFSET_TABLE_@local-4" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - - -;; Compare insns are next. Note that the RS/6000 has two types of compares, -;; signed & unsigned, and one type of branch. -;; -;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc -;; insns, and branches. We store the operands of compares until we see -;; how it is used. -(define_expand "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "gpc_reg_operand" "") - (match_operand:SI 1 "reg_or_short_operand" "")))] - "" - " -{ - /* Take care of the possibility that operands[1] might be negative but - this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 0) - operands[1] = force_reg (SImode, operands[1]); - - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 0; - DONE; -}") - -(define_expand "cmpdi" - [(set (cc0) - (compare (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "reg_or_short_operand" "")))] - "TARGET_POWERPC64" - " -{ - /* Take care of the possibility that operands[1] might be negative but - this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 0) - operands[1] = force_reg (DImode, operands[1]); - - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 0; - DONE; -}") - -(define_expand "cmpsf" - [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; - DONE; -}") - -(define_expand "cmpdf" - [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; - DONE; -}") - -(define_expand "beq" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (eq (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "bne" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (ne (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "blt" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (lt (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "bgt" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (gt (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "ble" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (le (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "bge" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (ge (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "bgtu" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (gtu (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "bltu" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (ltu (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "bgeu" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (geu (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "bleu" - [(set (match_dup 2) (match_dup 1)) - (set (pc) - (if_then_else (leu (match_dup 2) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -;; For SNE, we would prefer that the xor/abs sequence be used for integers. -;; For SEQ, likewise, except that comparisons with zero should be done -;; with an scc insns. However, due to the order that combine see the -;; resulting insns, we must, in fact, allow SEQ for integers. Fail in -;; the cases we don't want to handle. -(define_expand "seq" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (eq:SI (match_dup 2) (const_int 0)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "sne" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ne:SI (match_dup 2) (const_int 0)))] - "" - " -{ if (! rs6000_compare_fp_p) - FAIL; - - operands[1] = gen_rtx_COMPARE (CCFPmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCFPmode); -}") - -;; A > 0 is best done using the portable sequence, so fail in that case. -(define_expand "sgt" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gt:SI (match_dup 2) (const_int 0)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -;; A < 0 is best done in the portable way for A an integer. -(define_expand "slt" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (lt:SI (match_dup 2) (const_int 0)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "sge" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ge:SI (match_dup 2) (const_int 0)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -;; A <= 0 is best done the portable way for A an integer. -(define_expand "sle" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (le:SI (match_dup 2) (const_int 0)))] - "" - " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; - - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - operands[1] = gen_rtx_COMPARE (mode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (mode); -}") - -(define_expand "sgtu" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gtu:SI (match_dup 2) (const_int 0)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "sltu" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ltu:SI (match_dup 2) (const_int 0)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "sgeu" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (geu:SI (match_dup 2) (const_int 0)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "sleu" - [(set (match_dup 2) (match_dup 1)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (leu:SI (match_dup 2) (const_int 0)))] - "" - " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, - rs6000_compare_op0, rs6000_compare_op1); - operands[2] = gen_reg_rtx (CCUNSmode); -}") - -;; Here are the actual compare insns. -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "" - "{cmp%I2|cmpw%I2} %0,%1,%2" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")))] - "TARGET_POWERPC64" - "cmpd%I2 %0,%1,%2" - [(set_attr "type" "compare")]) - -;; If we are comparing a register for equality with a large constant, -;; we can do this with an XOR followed by a compare. But we need a scratch -;; register for the result of the XOR. - -(define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_short_cint_operand" ""))) - (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] - "find_single_use (operands[0], insn, 0) - && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ - || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)" - [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4))) - (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))] - " -{ - /* Get the constant we are comparing against, C, and see what it looks like - sign-extended to 16 bits. Then see what constant could be XOR'ed - with C to get the sign-extended value. */ - - int c = INTVAL (operands[2]); - int sextc = (c << 16) >> 16; - int xorv = c ^ sextc; - - operands[4] = GEN_INT (xorv); - operands[5] = GEN_INT (sextc); -}") - -(define_insn "" - [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_u_short_operand" "rI")))] - "" - "{cmpl%I2|cmplw%I2} %0,%1,%W2" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_u_short_operand" "rI")))] - "" - "cmpld%I2 %0,%1,%W2" - [(set_attr "type" "compare")]) - -;; The following two insns don't exist as single insns, but if we provide -;; them, we can swap an add and compare, which will enable us to overlap more -;; of the required delay between a compare and branch. We generate code for -;; them by splitting. - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "short_cint_operand" "i"))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] - "" - "#" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "u_short_cint_operand" "i"))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] - "" - "#" - [(set_attr "length" "8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "short_cint_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] - "" - [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) - -(define_split - [(set (match_operand:CCUNS 3 "cc_reg_operand" "") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "u_short_cint_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] - "" - [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) - -(define_insn "" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "fcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -;; Now we have the scc insns. We can do some combinations because of the -;; way the machine works. -;; -;; Note that this is probably faster if we can put an insn between the -;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most -;; cases the insns below which don't use an intermediate CR field will -;; be used instead. -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]))] - "" - "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (const_int 0))) - (set (match_operand:SI 3 "gpc_reg_operand" "=r") - (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "" - "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1" - [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "n")))] - "" - "* -{ - int is_bit = ccr_bit (operands[1], 1); - int put_bit = 31 - (INTVAL (operands[3]) & 31); - int count; - - if (is_bit >= put_bit) - count = is_bit - put_bit; - else - count = 32 - (put_bit - is_bit); - - operands[4] = GEN_INT (count); - operands[5] = GEN_INT (put_bit); - - return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; -}" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC - (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "n")) - (const_int 0))) - (set (match_operand:SI 4 "gpc_reg_operand" "=r") - (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) - (match_dup 3)))] - "" - "* -{ - int is_bit = ccr_bit (operands[1], 1); - int put_bit = 31 - (INTVAL (operands[3]) & 31); - int count; - - if (is_bit >= put_bit) - count = is_bit - put_bit; - else - count = 32 - (put_bit - is_bit); - - operands[5] = GEN_INT (count); - operands[6] = GEN_INT (put_bit); - - return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; -}" - [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) - -;; If we are comparing the result of two comparisons, this can be done -;; using creqv or crxor. - -(define_insn "" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") - (compare:CCEQ (match_operator 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (match_operator 3 "scc_comparison_operator" - [(match_operand 4 "cc_reg_operand" "y") - (const_int 0)])))] - "REGNO (operands[2]) != REGNO (operands[4])" - "* -{ - enum rtx_code code1, code2; - - code1 = GET_CODE (operands[1]); - code2 = GET_CODE (operands[3]); - - if ((code1 == EQ || code1 == LT || code1 == GT - || code1 == LTU || code1 == GTU - || (code1 != NE && GET_MODE (operands[2]) == CCFPmode)) - != - (code2 == EQ || code2 == LT || code2 == GT - || code2 == LTU || code2 == GTU - || (code2 != NE && GET_MODE (operands[4]) == CCFPmode))) - return \"%C1%C3crxor %E0,%j1,%j3\"; - else - return \"%C1%C3creqv %E0,%j1,%j3\"; -}" - [(set_attr "length" "12")]) - -;; There is a 3 cycle delay between consecutive mfcr instructions -;; so it is useful to combine 2 scc instructions to use only one mfcr. - -(define_peephole - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)])) - (set (match_operand:SI 3 "gpc_reg_operand" "=r") - (match_operator:SI 4 "scc_comparison_operator" - [(match_operand 5 "cc_reg_operand" "y") - (const_int 0)]))] - "REGNO (operands[2]) != REGNO (operands[5])" - "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" - [(set_attr "length" "20")]) - -;; There are some scc insns that can be done directly, without a compare. -;; These are faster because they don't involve the communications between -;; the FXU and branch units. In fact, we will be replacing all of the -;; integer scc insns here or in the portable methods in emit_store_flag. -;; -;; Also support (neg (scc ..)) since that construct is used to replace -;; branches, (plus (scc ..) ..) since that construct is common and -;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the -;; cases where it is no more expensive than (neg (scc ..)). - -;; Have reload force a constant into a register for the simple insns that -;; otherwise won't accept constants. We do this because it is faster than -;; the cmp/mfcr sequence we would otherwise generate. - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))) - (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))] - "" - "@ - xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 - {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1 - {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 - {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 - {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0" - [(set_attr "length" "12,8,12,12,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r") - (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I"))) - (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))] - "TARGET_POWERPC64" - "@ - xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0 - subfic %3,%1,0\;adde %0,%3,%1 - xori %0,%1,%b2\;subfic %3,%0,0\;adde %0,%3,%0 - xoris %0,%1,%u2\;subfic %3,%0,0\;adde %0,%3,%0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0" - [(set_attr "length" "12,8,12,12,12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") - (eq:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] - "" - "@ - xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1 - {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1\;cmpli %4,%0,0 - {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0\;cmpli %4,%0,0 - {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0\;cmpli %4,%0,0 - {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0\;cmpli %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") - (eq:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] - "TARGET_POWERPC64" - "@ - xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %3,%1,0\;adde. %0,%3,%1 - xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0 - xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 - xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %3,%1,0\;adde %0,%3,%1\;cmpli %4,%0,0 - xori %0,%1,%b2\;subfic %3,%0,0\;adde %0,%3,%0\;cmpli %4,%0,0 - xoris %0,%1,%u2\;subfic %3,%0,0\;adde %0,%3,%0\;cmpli %4,%0,0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0\;cmpli %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -;; We have insns of the form shown by the first define_insn below. If -;; there is something inside the comparison operation, we must split it. -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "" "") - (match_operand:SI 3 - "reg_or_cint_operand" "")]) - (match_operand:SI 4 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 5 "register_operand" ""))] - "! gpc_reg_operand (operands[2], SImode)" - [(set (match_dup 5) (match_dup 2)) - (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) - (match_dup 4)))]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") - (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] - "" - "@ - xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 - {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3 - {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 - {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3" - [(set_attr "length" "12,8,12,12,12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] - "" - "@ - xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 - {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3\;cmpli %0,%4,0 - {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3\;cmpli %0,%4,0 - {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %4,%3\;cmpli %0,%4,0 - {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %4,%3\;cmpli %0,%4,0 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") - (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] - "" - "@ - xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 - {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3\;cmpli %5,%0,0 - {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3\;cmpli %5,%0,0 - {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3\;cmpli %5,%0,0 - {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3\;cmpli %5,%0,0 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") - (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))] - "" - "@ - xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0 - {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "12,8,12,12,12")]) - -;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power, -;; since it nabs/sr is just as fast. -(define_insn "*ne0" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") - (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) - (const_int 31))) - (clobber (match_scratch:SI 2 "=&r"))] - "!TARGET_POWER" - "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) - (const_int 63))) - (clobber (match_scratch:DI 2 "=&r"))] - "TARGET_POWERPC64" - "addic %2,%1,-1\;subfe %0,%2,%1" - [(set_attr "length" "8")]) - -;; This is what (plus (ne X (const_int 0)) Y) looks like. -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (lshiftrt:SI - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) - (const_int 31)) - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 3 "=&r"))] - "" - "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (plus:DI (lshiftrt:DI - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) - (const_int 63)) - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:DI 3 "=&r"))] - "TARGET_POWERPC64" - "addic %3,%1,-1\;addze %0,%2" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (lshiftrt:SI - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))) - (const_int 31)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2 - {ai|addic} %3,%1,-1\;{aze|addze} %3,%2\;cmpli %0,%3,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (lshiftrt:DI - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))) - (const_int 63)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_POWERPC64" - "@ - addic %3,%1,-1\;addze. %3,%2 - addic %3,%1,-1\;addze. %3,%2\;cmpdi %0,%3,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (lshiftrt:SI - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))) - (const_int 31)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) - (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2 - {ai|addic} %3,%1,-1\;{aze|addze} %0,%2\;cmpli %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (lshiftrt:DI - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))) - (const_int 63)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) - (match_dup 2))) - (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_POWERPC64" - "@ - addic %3,%1,-1\;addze. %0,%2 - addic %3,%1,-1\;addze. %0,%2\;cmpdi %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O"))) - (clobber (match_scratch:SI 3 "=r,X"))] - "TARGET_POWER" - "@ - doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3 - {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (le:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,X,r,X"))] - "TARGET_POWER" - "@ - doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3 - {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31 - doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3\;cmpli %4,%0,0 - {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31\;cmpli %4,%0,0" - [(set_attr "type" "compare,delayed_compare,compare,compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O")) - (match_operand:SI 3 "gpc_reg_operand" "r,r"))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_POWER" - "@ - doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3 - doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %4,%3\;cmpli %0,%4,0 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_POWER" - "@ - doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3 - doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3\;cmpli %5,%0,0 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O"))))] - "TARGET_POWER" - "@ - doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "" - "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (leu:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 - {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0\;cmpli %3,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 4 "=&r"))] - "" - "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "" - "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 4 "=&r"))] - "" - "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %4,%3,%4\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "TARGET_POWER" - "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lt:SI (match_dup 1) (match_dup 2)))] - "TARGET_POWER" - "@ - doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31 - doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31\;cmpli %3,%0,0" - [(set_attr "type" "delayed_compare,compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 4 "=&r"))] - "TARGET_POWER" - "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3 - doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3 - doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "TARGET_POWER" - "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ltu:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0\;cmpli %3,%0,0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0\;cmpli %3,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P")) - (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I"))) - (clobber (match_scratch:SI 4 "=&r,r,&r,r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf|subfc} %4,%4,%3\;cmpli %0,%4,0 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf|subfc} %4,%4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf|subfc} %0,%4,%3\;cmpli %5,%0,0 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf|subfc} %0,%4,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))] - "" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))) - (clobber (match_scratch:SI 3 "=r"))] - "TARGET_POWER" - "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ge:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWER" - "@ - doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3 - doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3\;cmpli %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 4 "=&r"))] - "TARGET_POWER" - "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "TARGET_POWER" - "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "12")]) - -;; This is (and (neg (ge X (const_int 0))) Y). -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (neg:SI - (lshiftrt:SI - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (const_int 31))) - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 3 "=&r"))] - "" - "{srai|srawi} %3,%1,31\;andc %0,%2,%3" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (lshiftrt:SI - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 31))) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {srai|srawi} %3,%1,31\;andc. %3,%2,%3 - {srai|srawi} %3,%1,31\;andc %3,%2,%3\;cmpli %0,%3,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (lshiftrt:SI - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 31))) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1)) - (const_int 31))) - (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {srai|srawi} %3,%1,31\;andc. %0,%2,%3 - {srai|srawi} %3,%1,31\;andc %0,%2,%3\;cmpli %4,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "" - "@ - {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0 - {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (geu:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 - {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 - {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0\;cmpli %3,%0,0 - {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0\;cmpli %3,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r"))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3 - {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3 - {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3 - {sf|subfc} %4,%2,%1\;{aze|addze} %4,%3\;cmpli %0,%4,0 - {ai|addic} %4,%1,%n2\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3 - {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3 - {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3\;cmpli %5,%0,0 - {ai|addic} %4,%1,%n2\;{aze|addze} %4,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))))] - "" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0 - {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r"))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %4,%3,%4\;cmpli %0,%4,0 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4\;cmpli %5,%0,0 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0)))] - "" - "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (gt:SI (match_dup 1) (const_int 0)))] - "" - "@ - {sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31 - {sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31\;cmpli %2,%0,0" - [(set_attr "type" "delayed_compare,compare") - (set_attr "length" "12,8")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")))] - "TARGET_POWER" - "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (gt:SI (match_dup 1) (match_dup 2)))] - "TARGET_POWER" - "@ - doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31 - doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31\;cmpli %3,%0,0" - [(set_attr "type" "delayed_compare,compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 3 "=&r"))] - "" - "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2 - {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %3,%2\;cmpli %0,%3" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "" - "@ - {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2 - {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %3,%2\;cmpli %4,%3" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) - (match_operand:SI 3 "gpc_reg_operand" "r"))) - (clobber (match_scratch:SI 4 "=&r"))] - "TARGET_POWER" - "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3 - doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_POWER" - "@ - doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3 - doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0))))] - "" - "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r"))))] - "TARGET_POWER" - "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "" - "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (gtu:SI (match_dup 1) (match_dup 2)))] - "" - "@ - {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0\;cmpli %3,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r,rI")) - (match_operand:SI 3 "reg_or_short_operand" "r,r,I"))) - (clobber (match_scratch:SI 4 "=&r,&r,&r"))] - "" - "@ - {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" - [(set_attr "length" "8,12,12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3\;cmpli %0,%4,0 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3\;cmpli %0,%4,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) - -(define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "" - "@ - {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 - {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3\;cmpli %5,%0,0 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf|subfc} %0,%4,%3\;cmpli %5,%0,0" - [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "" - "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "8")]) - -;; Define both directions of branch and return. If we need a reload -;; register, we'd rather use CR0 since it is much easier to copy a -;; register CC value to there. - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "cc_reg_operand" "x,?y") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 8) - return \"%C1bc %t1,%j1,%l0\"; - else - return \"%C1bc %T1,%j1,%$+8\;b %l0\"; - -}" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "cc_reg_operand" "x,?y") - (const_int 0)]) - (return) - (pc)))] - "direct_return ()" - "{%C0bcr|%C0bclr} %t0,%j0" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "cc_reg_operand" "x,?y") - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (get_attr_length (insn) == 8) - return \"%C1bc %T1,%j1,%l0\"; - else - return \"%C1bc %t1,%j1,%$+8\;b %l0\"; -}" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "cc_reg_operand" "x,?y") - (const_int 0)]) - (pc) - (return)))] - "direct_return ()" - "{%C0bcr|%C0bclr} %T0,%j0" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -;; Unconditional branch and return. - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "b %l0" - [(set_attr "type" "branch")]) - -(define_insn "return" - [(return)] - "direct_return ()" - "{br|blr}" - [(set_attr "type" "jmpreg")]) - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))] - "" - "@ - bctr - {br|blr}" - [(set_attr "type" "jmpreg")]) - -(define_insn "" - [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))] - "TARGET_POWERPC64" - "@ - bctr - {br|blr}" - [(set_attr "type" "jmpreg")]) - -;; Table jump for switch statements: -(define_expand "tablejump" - [(use (match_operand 0 "" "")) - (use (label_ref (match_operand 1 "" "")))] - "" - " -{ - if (TARGET_32BIT) - emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); - else - emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); - DONE; -}") - -(define_expand "tablejumpsi" - [(set (match_dup 3) - (plus:SI (match_operand:SI 0 "" "") - (match_dup 2))) - (parallel [(set (pc) (match_dup 3)) - (use (label_ref (match_operand 1 "" "")))])] - "" - " -{ operands[0] = force_reg (SImode, operands[0]); - operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (VOIDmode, operands[1])); - operands[3] = gen_reg_rtx (SImode); -}") - -(define_expand "tablejumpdi" - [(set (match_dup 3) - (plus:DI (match_operand:DI 0 "" "") - (match_dup 2))) - (parallel [(set (pc) (match_dup 3)) - (use (label_ref (match_operand 1 "" "")))])] - "" - " -{ operands[0] = force_reg (DImode, operands[0]); - operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[1])); - operands[3] = gen_reg_rtx (DImode); -}") - -(define_insn "" - [(set (pc) - (match_operand:SI 0 "register_operand" "c,l")) - (use (label_ref (match_operand 1 "" "")))] - "" - "@ - bctr - {br|blr}" - [(set_attr "type" "jmpreg")]) - -(define_insn "" - [(set (pc) - (match_operand:DI 0 "register_operand" "c,l")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_POWERPC64" - "@ - bctr - {br|blr}" - [(set_attr "type" "jmpreg")]) - -(define_insn "nop" - [(const_int 0)] - "" - "{cror 0,0,0|nop}") - -;; Define the subtract-one-and-jump insns, starting with the template -;; so loop.c knows what to generate. - -(define_expand "decrement_and_branch_on_count" - [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1))) - (clobber (match_scratch:CC 2 "")) - (clobber (match_scratch:SI 3 ""))])] - "" - "") - -;; We need to be able to do this for any operand, including MEM, or we -;; will cause reload to blow up since we don't allow output reloads on -;; JUMP_INSNs. -;; In order that the length attribute is calculated correctly, the -;; label MUST be operand 0. - -(define_insn "" - [(set (pc) - (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "" - [(set (pc) - (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -;; Similar, but we can use GE since we have a REG_NONNEG. -(define_insn "" - [(set (pc) - (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&X")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "find_reg_note (insn, REG_NONNEG, 0)" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "" - [(set (pc) - (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&X")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "find_reg_note (insn, REG_NONNEG, 0)" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "" - [(set (pc) - (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "" - [(set (pc) - (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 8) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz %$+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:SI 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (compare:CC (plus:SI (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 0) - (plus:SI (match_dup 1) - (const_int -1)))]) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") - -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:SI 0 "general_operand" "") - (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:SI 4 ""))] - "reload_completed && ! gpc_reg_operand (operands[0], SImode)" - [(parallel [(set (match_dup 3) - (compare:CC (plus:SI (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 4) - (plus:SI (match_dup 1) - (const_int -1)))]) - (set (match_dup 0) - (match_dup 4)) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") - -(define_insn "trap" - [(trap_if (const_int 1) (const_int 0))] - "" - "{t 31,0,0|trap}") - -(define_expand "conditional_trap" - [(trap_if (match_operator 0 "trap_comparison_operator" - [(match_dup 2) (match_dup 3)]) - (match_operand 1 "const_int_operand" ""))] - "" - "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL; - operands[2] = rs6000_compare_op0; - operands[3] = rs6000_compare_op1;") - -(define_insn "" - [(trap_if (match_operator 0 "trap_comparison_operator" - [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")]) - (const_int 0))] - "" - "t%V0%I2 %1,%2") - - -;; CYGNUS LOCAL -- meissner/branch prediction -;; Branch prediction insns -(define_expand "expectsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (expect:SI (match_operand:SI 1 "nonmemory_operand" "") - (match_operand:SI 2 "immediate_operand" "")))] - "" - " -{ - if (CONSTANT_P (operands[1])) - { - emit_move_insn (operands[0], operands[1]); - DONE; - } -}") - -(define_insn "*expectsi3_internal" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r,r,r,r") - (expect:SI (match_operand:SI 1 "nonmemory_operand" "0,r,I,J,i") - (match_operand:SI 2 "immediate_operand" "n,n,n,n,n")))] - "" - "@ - # expect register %0 to be %2 - mr %0,%1\;# expect register %0 to be %2 - {lil|li} %0,%1 - {liu|lis} %0,%v1 - #" - [(set_attr "type" "integer") - (set_attr "length" "0,4,4,4,8")]) - -;; Split a load of a large constant into the appropriate two-insn -;; sequence. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (expect:SI (match_operand:SI 1 "const_int_operand" "") - (match_operand:SI 2 "immediate_operand" "")))] - "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 - && (INTVAL (operands[1]) & 0xffff) != 0" - [(set (match_dup 0) - (match_dup 3)) - (set (match_dup 0) - (ior:SI (match_dup 0) - (match_dup 4)))] - " -{ - operands[3] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) & 0xffff0000); - operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff); -}") - -(define_insn "*compare_expect1" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (expect:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "immediate_operand" "n")) - (match_operand:SI 3 "reg_or_short_operand" "rI")))] - "" - "{cmp%I3|cmpw%I3} %0,%1,%3\\t# expect register %1 to be %2" - [(set_attr "type" "compare")]) - -(define_insn "*compare_expect2" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (expect:SI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "immediate_operand" "n")) - (match_operand:DI 3 "reg_or_short_operand" "rI")))] - "TARGET_POWERPC64" - "cmpd%I3 %0,%1,%3\\t# expect register %1 to be %2" - [(set_attr "type" "compare")]) - -(define_insn "*branch_expect1" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(expect (match_operand 2 "cc_reg_operand" "x,?y") - (match_operand:SI 3 "immediate_operand" "n,n")) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 8) - return \"%C1bc%Q3 %t1,%j1,%l0\"; - else - return \"%C1bc%q3 %T1,%j1,%$+8\;b %l0\"; - -}" - [(set_attr "type" "branch")]) - -(define_insn "*branch_expect2" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(expect (match_operand 1 "cc_reg_operand" "x,?y") - (match_operand:SI 2 "immediate_operand" "n,n")) - (const_int 0)]) - (return) - (pc)))] - "direct_return ()" - "{%C0bcr|%C0bclr}%Q2 %t0,%j0" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*branch_expect3" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(expect (match_operand 2 "cc_reg_operand" "x,?y") - (match_operand:SI 3 "immediate_operand" "n,n")) - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (get_attr_length (insn) == 8) - return \"%C1bc%q3 %T1,%j1,%l0\"; - else - return \"%C1bc%Q3 %t1,%j1,%$+8\;b %l0\"; -}" - [(set_attr "type" "branch")]) - -(define_insn "*branch_expect4" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(expect (match_operand 1 "cc_reg_operand" "x,?y") - (match_operand:SI 2 "immediate_operand" "n,n")) - (const_int 0)]) - (pc) - (return)))] - "direct_return ()" - "{%C0bcr|%C0bclr}%q2 %T0,%j0" - [(set_attr "type" "branch") - (set_attr "length" "8")]) -;; END CYGNUS LOCAL -- meissner/branch prediction - -;; CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling - -;; The following is necessary for generation of RTL representation of -;; prologue and epilogue and subsequent instruction scheduling and -;; branch delay slot scheduling (if any). - -;; -;; .................... -;; -;; Function prologue/epilogue -;; -;; .................... -;; - -(define_expand "prologue" - [(const_int 1)] - "TARGET_SCHED_PROLOG" - " -{ - rs6000_expand_prologue (); - DONE; -}") - -;; At present, don't expand the epilogue, reorg.c will clobber the -;; return register in compiling gen_lowpart (emit-rtl.c). - -(define_expand "epilogue" - [(const_int 2)] - "TARGET_SCHED_EPILOG" - " -{ - rs6000_expand_epilogue (); - DONE; -}") - -(define_insn "movesi_from_cr" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) (reg:CC 72) - (reg:CC 73) (reg:CC 74) (reg:CC 75)] 101))] - "!TARGET_POWERPC64" - "mfcr %0") - -(define_insn "movedi_from_cr" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (unspec [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) (reg:CC 72) - (reg:CC 73) (reg:CC 74) (reg:CC 75)] 102))] - "TARGET_POWERPC64" - "mfcr %0") - -(define_insn "movesi_to_cr" - [(set (reg:CC 68) (unspec [(match_operand:SI 0 "gpc_reg_operand" "=r")] 113)) - (set (reg:CC 69) (unspec [(match_dup 0)] 114)) - (set (reg:CC 70) (unspec [(match_dup 0)] 115)) - (set (reg:CC 71) (unspec [(match_dup 0)] 116)) - (set (reg:CC 72) (unspec [(match_dup 0)] 117)) - (set (reg:CC 73) (unspec [(match_dup 0)] 118)) - (set (reg:CC 74) (unspec [(match_dup 0)] 119)) - (set (reg:CC 75) (unspec [(match_dup 0)] 120))] - "!TARGET_POWERPC64" - "mtcr %0") - -(define_insn "movedi_to_cr" - [(set (reg:CC 68) (unspec [(match_operand:DI 0 "gpc_reg_operand" "=r")] 123)) - (set (reg:CC 69) (unspec [(match_dup 0)] 124)) - (set (reg:CC 70) (unspec [(match_dup 0)] 125)) - (set (reg:CC 71) (unspec [(match_dup 0)] 126)) - (set (reg:CC 72) (unspec [(match_dup 0)] 127)) - (set (reg:CC 73) (unspec [(match_dup 0)] 128)) - (set (reg:CC 74) (unspec [(match_dup 0)] 129)) - (set (reg:CC 75) (unspec [(match_dup 0)] 130))] - "TARGET_POWERPC64" - "mtcr %0") - -(define_insn "loadsi_svr4_relocatable_toc" - [(set (reg:SI 30) (unspec [(pc)] 133)) - (set (pc) (unspec [(pc)] 143)) - (clobber (reg:SI 65)) - (clobber (match_operand:SI 0 "gpc_reg_operand" "r"))] - "" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"# end of toc load\"; -}") - -(define_insn "loaddi_svr4_relocatable_toc" - [(set (reg:DI 30) (unspec [(pc)] 153)) - (set (pc) (unspec [(pc)] 154)) - (clobber (reg:DI 65)) - (clobber (match_operand:DI 0 "gpc_reg_operand" "r"))] - "" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"# end of toc load\"; -}") - -(define_insn "loadsi_svr4_toc" - [(set (reg:SI 30) (unspec [(pc)] 134))] - "" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"# end of toc load\"; -}") - -(define_insn "loadsi_nonsvr4_toc" - [(set (reg:SI 30) (unspec [(pc)] 136)) - (clobber (match_operand:SI 0 "gpc_reg_operand" "r"))] - "" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"# end of toc load\"; -}") - -(define_insn "loaddi_nonsvr4_toc" - [(set (reg:DI 30) (unspec [(pc)] 137)) - (clobber (match_operand:DI 0 "gpc_reg_operand" "r"))] - "" - "* -{ - rs6000_output_load_toc_table (asm_out_file, 30, FALSE); - return \"# end of toc load\"; -}") - -;; END CYGNUS LOCAL -- vmakarov/prolog-epilog instruction scheduling diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h deleted file mode 100755 index bf14072..0000000 --- a/gcc/config/rs6000/rtems.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Definitions for rtems targeting a PowerPC using elf. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Contributed by Joel Sherrill (joel@OARcorp.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/eabi.h" - -/* Specify predefined symbols in preprocessor. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DPPC -Drtems -D__rtems__ \ - -Asystem(rtems) -Acpu(powerpc) -Amachine(powerpc)" - -/* Generate calls to memcpy, memcmp and memset. */ -#ifndef TARGET_MEM_FUNCTIONS -#define TARGET_MEM_FUNCTIONS -#endif - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "crt0.o%s" - -/* end of rs6000/rtems.h */ diff --git a/gcc/config/rs6000/sol-c0.c b/gcc/config/rs6000/sol-c0.c deleted file mode 100755 index bf935c3..0000000 --- a/gcc/config/rs6000/sol-c0.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Solaris PowerPC startfile. */ -/* Copyright (C) 1996 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -extern char **_environ; - -extern int atexit (void (*__func) (void)); -extern void __init (void) __attribute__ ((__longcall__)); -extern void __fini (void) __attribute__ ((__longcall__)); - -typedef void (*func_ptr) (void); -int (*__atexit)(func_ptr) = atexit; - -/* Exception handling */ -struct ex_shared1 { - void *prev; - void *next; - char *text_start; - char *range_start; - char *text_end; - char *range_end; -}; - -struct ex_shared { - void (*ex_register) (struct ex_shared1 *); - void (*ex_deregister) (struct ex_shared1 *); - struct ex_shared1 shared_info; -}; - -extern char _ex_text0[], _ex_text1[]; -extern char _ex_range0[], _ex_range1[]; -extern void _ex_register (struct ex_shared1 *); -extern void _ex_deregister (struct ex_shared1 *); -extern char _SDA_BASE_[]; -extern char _SDA2_BASE_[]; - -struct ex_shared shared __attribute__((section(".ex_shared"))) = { - _ex_register, - _ex_deregister, - { - (void *)0, - (void *)0, - _ex_text0, - _ex_range0, - _ex_text1, - _ex_range1 - } -}; - -static void -deregister (void) -{ - (* shared.ex_deregister) (&shared.shared_info); -} - -/* Start function. */ -void -_start(int argc, char *argv[], char *envp[], void *auxp, void (*termfunc)()) -{ - int ret; - int dummy = 0; - -#if 0 - /* Disable this for now, it causes an impossible reload. */ - /* Load up r13/r2 before we do anything else. */ - __asm__ volatile ("mr %%r13,%0;mr %%r2,%1" : "=r" (dummy) : "r" (&_SDA_BASE_[0]), "r" (&_SDA2_BASE_[0]), "r" (dummy)); -#endif - - _environ = envp + dummy; - - /* Register loader termination function (the || dummy is to make sure the above asm - is not optimized away). */ - if (termfunc) - atexit (termfunc); - - /* Register exception handler if needed */ - if (shared.ex_register) - (* shared.ex_register) (&shared.shared_info); - - if (shared.ex_deregister) - atexit (deregister); - - /* Call any global constructors and destructors. */ - __init (); - - atexit (__fini); - - /* Call the main program now */ - ret = main (argc, argv, envp, auxp); - - /* Return to the os */ - exit (ret); -} - -/* Provide a dummy __eabi in case main got compiled without -mcall-solaris. */ -void -__eabi () -{ -} diff --git a/gcc/config/rs6000/sol-ci.asm b/gcc/config/rs6000/sol-ci.asm deleted file mode 100755 index d0eced3..0000000 --- a/gcc/config/rs6000/sol-ci.asm +++ /dev/null @@ -1,104 +0,0 @@ -# crti.s for solaris - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled starting points for the .got* and other -# special sections. It is linked in first before other modules. - - .file "scrti.s" - .ident "GNU C scrti.s" - -# Start of .text - .section ".text" - .globl _ex_text0 -_ex_text0: - -# Exception range - .section ".exception_ranges","aw" - .globl _ex_range0 -_ex_range0: - -# List of C++ constructors - .section ".ctors","aw" - .globl __CTOR_LIST__ - .type __CTOR_LIST__,@object -__CTOR_LIST__: - -# List of C++ destructors - .section ".dtors","aw" - .globl __DTOR_LIST__ - .type __DTOR_LIST__,@object -__DTOR_LIST__: - -# Head of __init function used for static constructors in Solaris - .section ".init","ax" - .align 2 - .globl __init - .type __init,@function -__init: stwu %r1,-16(%r1) - mflr %r0 - stw %r31,12(%r1) - stw %r0,16(%r1) - - bl _GLOBAL_OFFSET_TABLE_-4 # get the GOT address - mflr %r31 - -# lwz %r3,_ex_shared0@got(%r31) -# lwz %r4,-8(%r3) # _ex_register or 0 -# cmpi %cr0,%r4,0 -# beq .Lno_reg -# mtlr %r4 -# blrl -#.Lno_reg: - -# Head of __fini function used for static destructors in Solaris - .section ".fini","ax" - .align 2 - .globl __fini - .type __fini,@function -__fini: stwu %r1,-16(%r1) - mflr %r0 - stw %r31,12(%r1) - stw %r0,16(%r1) - - bl _GLOBAL_OFFSET_TABLE_-4 # get the GOT address - mflr %r31 - -# _environ and its evil twin environ, pointing to the environment - .section ".sdata","aw" - .align 2 - .globl _environ - .space 4 - .weak environ - .set environ,_environ diff --git a/gcc/config/rs6000/sol-cn.asm b/gcc/config/rs6000/sol-cn.asm deleted file mode 100755 index 2bc992e..0000000 --- a/gcc/config/rs6000/sol-cn.asm +++ /dev/null @@ -1,82 +0,0 @@ -# crtn.s for solaris - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled ending points for the .got* and other -# special sections. It is linked in last after other modules. - - .file "scrtn.s" - .ident "GNU C scrtn.s" - -# Default versions of exception handling register/deregister - .weak _ex_register - .weak _ex_deregister - .set _ex_register,0 - .set _ex_deregister,0 - -# End list of C++ constructors - .section ".ctors","aw" - .globl __CTOR_END__ - .type __CTOR_END__,@object -__CTOR_END__: - -# End list of C++ destructors - .section ".dtors","aw" - .globl __DTOR_END__ - .type __DTOR_END__,@object -__DTOR_END__: - - .section ".text" - .globl _ex_text1 -_ex_text1: - - .section ".exception_ranges","aw" - .globl _ex_range1 -_ex_range1: - -# Tail of __init used for static constructors in Solaris - .section ".init","ax" - lwz %r0,16(%r1) - lwz %r31,12(%r1) - mtlr %r0 - addi %r1,%r1,16 - blr - -# Tail of __fini used for static destructors in Solaris - .section ".fini","ax" - lwz %r0,16(%r1) - lwz %r31,12(%r1) - mtlr %r0 - addi %r1,%r1,16 - blr diff --git a/gcc/config/rs6000/sol2.h b/gcc/config/rs6000/sol2.h deleted file mode 100755 index 0f1b13b..0000000 --- a/gcc/config/rs6000/sol2.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 running AIX version 3.1. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Contributed by David Reese (Dave.Reese@East.Sun.COM) - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/sysv4le.h" - -/* Default ABI to use */ -#undef RS6000_ABI_NAME -#define RS6000_ABI_NAME "solaris" - -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC "-le -s" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | \ - MASK_NEW_MNEMONICS | \ - MASK_LITTLE_ENDIAN | \ - MASK_REGNAMES) - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_solaris)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_solaris)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_solaris)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_solaris)" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ -%(cpp_sysv) %(cpp_endian) %(cpp_cpu) \ -%{mmvme: %(cpp_os_mvme) } \ -%{msim: %(cpp_os_sim) } \ -%{mcall-linux: %(cpp_os_linux) } \ -%{mcall-solaris: %(cpp_os_solaris) } \ -%{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}" - -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_solaris)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_solaris)" - -#undef CPP_ENDIAN_LITTLE_SPEC -#define CPP_ENDIAN_LITTLE_SPEC CPP_ENDIAN_SOLARIS_SPEC - -/* Don't turn -B into -L if the argument specifies a relative file name. */ -#undef RELATIVE_PREFIX_NOT_LINKDIR - -#define DEFAULT_PCC_STRUCT_RETURN 0 - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC Solaris)"); - - -/* Macros to check register numbers against specific register classes. */ - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - - -#if 0 -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ -do { \ - fprintf ((FILE), "\t%s\t", ".lcomm"); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \ -} while (0) -#endif - -/* Like block addresses, stabs line numbers are relative to the - current function. */ - -/* use .stabd instead of .stabn */ - -#define ASM_STABN_OP ".stabd" - -#undef ASM_OUTPUT_SOURCE_LINE -#define ASM_OUTPUT_SOURCE_LINE(file, line) \ -do \ - { \ - static int sym_lineno = 1; \ - char *_p; \ - fprintf (file, "\t.stabd 68,0,%d,.LM%d-", \ - line, sym_lineno); \ - STRIP_NAME_ENCODING (_p, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \ - assemble_name (file, _p); \ - fprintf (file, "\n.LM%d:\n", sym_lineno); \ - sym_lineno += 1; \ - } \ -while (0) - -/* This is how to output an assembler line defining a `double' constant. */ - -#undef ASM_OUTPUT_DOUBLE -#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \ - t[0] & 0xffffffff, t[1] & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \ - fprintf (FILE, "\t.double %s\n", str); \ - } \ - } - -/* This is how to output an assembler line defining a `float' constant. */ - -#undef ASM_OUTPUT_FLOAT -#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t.float %s\n", str); \ - } \ - } - - -/* Sun-ppc assembler does not permit '.' in some symbol names. - Use 'name_.labelno' instead. */ -#undef ASM_FORMAT_PRIVATE_NAME -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s_.%d", (NAME), (LABELNO))) - - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mcall-solaris" } - -#define STDC_0_IN_SYSTEM_HEADERS diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h deleted file mode 100755 index c0564c3..0000000 --- a/gcc/config/rs6000/sysv4.h +++ /dev/null @@ -1,1770 +0,0 @@ -/* Target definitions for GNU compiler for PowerPC running System V.4 - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Small data support types */ -enum rs6000_sdata_type { - SDATA_NONE, /* no small data support */ - SDATA_DATA, /* just put data in .sbss/.sdata, don't use relocs */ - SDATA_SYSV, /* Use r13 to point to .sdata/.sbss */ - SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2 */ -}; - -extern enum rs6000_sdata_type rs6000_sdata; - -/* V.4/eabi switches */ -#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */ -#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */ -#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */ -#define MASK_EABI 0x08000000 /* Adhere to eabi, not System V spec */ -#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */ -#define MASK_REGNAMES 0x02000000 /* use alternate register names. */ -#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */ -/* CYGNUS LOCAL vmakarov */ -#define MASK_NO_BITFIELD_WORD 0x00400000 /* Bitfields cannot cross word boundaries */ -/* END CYGNUS LOCAL */ - -#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE) -#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN) -#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE) -#define TARGET_EABI (target_flags & MASK_EABI) -/* CYGNUS LOCAL vmakarov */ -#define TARGET_NO_BITFIELD_WORD (target_flags & MASK_NO_BITFIELD_WORD) -/* END CYGNUS LOCAL */ -#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN) -#define TARGET_REGNAMES (target_flags & MASK_REGNAMES) -#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE) -#define TARGET_TOC ((target_flags & MASK_64BIT) \ - || ((target_flags & (MASK_RELOCATABLE \ - | MASK_MINIMAL_TOC)) \ - && flag_pic > 1) \ - || DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_NT) - -#define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE) -#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) -#define TARGET_NO_PROTOTYPE (! TARGET_PROTOTYPE) -#define TARGET_NO_TOC (! TARGET_TOC) -#define TARGET_NO_EABI (! TARGET_EABI) -/* CYGNUS LOCAL vmakarov */ -#define TARGET_BITFIELD_WORD (! TARGET_NO_BITFIELD_WORD) -/* END CYGNUS LOCAL */ - -/* Pseudo target to indicate whether the object format is ELF - (to get around not having conditional compilation in the md file) */ -#define TARGET_ELF 1 - -/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just - the same as -mminimal-toc. */ -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - { "bit-align", -MASK_NO_BITFIELD_TYPE }, \ - { "no-bit-align", MASK_NO_BITFIELD_TYPE }, \ - { "strict-align", MASK_STRICT_ALIGN }, \ - { "no-strict-align", -MASK_STRICT_ALIGN }, \ - { "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ - { "no-relocatable", -MASK_RELOCATABLE }, \ - { "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ - { "no-relocatable-lib", -MASK_RELOCATABLE }, \ - { "little-endian", MASK_LITTLE_ENDIAN }, \ - { "little", MASK_LITTLE_ENDIAN }, \ - { "big-endian", -MASK_LITTLE_ENDIAN }, \ - { "big", -MASK_LITTLE_ENDIAN }, \ - { "no-toc", 0 }, \ - { "toc", MASK_MINIMAL_TOC }, \ - { "full-toc", MASK_MINIMAL_TOC }, \ - { "prototype", MASK_PROTOTYPE }, \ - { "no-prototype", -MASK_PROTOTYPE }, \ - { "no-traceback", 0 }, \ - { "eabi", MASK_EABI }, \ - { "no-eabi", -MASK_EABI }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "bit-word", -MASK_NO_BITFIELD_WORD }, \ - { "no-bit-word", MASK_NO_BITFIELD_WORD }, \ -/* END CYGNUS LOCAL */ \ - { "regnames", MASK_REGNAMES }, \ - { "no-regnames", -MASK_REGNAMES }, \ - { "sdata", 0 }, \ - { "no-sdata", 0 }, \ - { "sim", 0 }, \ - { "ads", 0 }, \ - { "yellowknife", 0 }, \ - { "mvme", 0 }, \ - { "emb", 0 }, \ - { "solaris-cclib", 0 }, \ - { "shlib", 0 }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "vxworks", 0 }, \ -/* END CYGNUS LOCAL */ \ - EXTRA_SUBTARGET_SWITCHES \ - { "newlib", 0 }, - -/* This is meant to be redefined in the host dependent files */ -#define EXTRA_SUBTARGET_SWITCHES - -/* Default ABI to use */ -#define RS6000_ABI_NAME "sysv" - -/* Strings provided by SUBTARGET_OPTIONS */ -extern char *rs6000_abi_name; -extern char *rs6000_sdata_name; - -#define SUBTARGET_OPTIONS \ - { "call-", &rs6000_abi_name}, \ - { "sdata=", &rs6000_sdata_name} - -/* Max # of bytes for variables to automatically be put into the .sdata - or .sdata2 sections. */ -extern int g_switch_value; /* value of the -G xx switch */ -extern int g_switch_set; /* whether -G xx was passed. */ - -#ifndef SDATA_DEFAULT_SIZE -#define SDATA_DEFAULT_SIZE 8 -#endif - -/* Sometimes certain combinations of command options do not make sense - on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (!g_switch_set) \ - g_switch_value = SDATA_DEFAULT_SIZE; \ - \ - if (!strcmp (rs6000_abi_name, "sysv")) \ - rs6000_current_abi = ABI_V4; \ - else if (!strcmp (rs6000_abi_name, "sysv-noeabi")) \ - { \ - rs6000_current_abi = ABI_V4; \ - target_flags &= ~ MASK_EABI; \ - } \ - else if (!strcmp (rs6000_abi_name, "sysv-eabi") \ - || !strcmp (rs6000_abi_name, "eabi")) \ - { \ - rs6000_current_abi = ABI_V4; \ - target_flags |= MASK_EABI; \ - } \ - else if (!strcmp (rs6000_abi_name, "aix")) \ - { \ - rs6000_current_abi = ABI_AIX_NODESC; \ - target_flags |= MASK_EABI; \ - } \ - else if (!strcmp (rs6000_abi_name, "aixdesc")) \ - rs6000_current_abi = ABI_AIX; \ - else if (!strcmp (rs6000_abi_name, "nt")) \ - rs6000_current_abi = ABI_NT; \ - else if (!strcmp (rs6000_abi_name, "linux")) \ - rs6000_current_abi = ABI_V4; \ - else if (!strcmp (rs6000_abi_name, "solaris")) \ - rs6000_current_abi = ABI_SOLARIS; \ -/* CYGNUS LOCAL vmakarov */ \ - else if (!strcmp (rs6000_abi_name, "i960-old")) \ - { \ - rs6000_current_abi = ABI_V4; \ - target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI \ - | MASK_NO_BITFIELD_WORD); \ - target_flags &= ~MASK_STRICT_ALIGN; \ - } \ -/* END CYGNUS LOCAL */ \ - else \ - { \ - rs6000_current_abi = ABI_V4; \ - error ("Bad value for -mcall-%s", rs6000_abi_name); \ - } \ - \ - if (rs6000_sdata_name) \ - { \ - if (!strcmp (rs6000_sdata_name, "none")) \ - rs6000_sdata = SDATA_NONE; \ - else if (!strcmp (rs6000_sdata_name, "data")) \ - rs6000_sdata = SDATA_DATA; \ - else if (!strcmp (rs6000_sdata_name, "default")) \ - rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \ - else if (!strcmp (rs6000_sdata_name, "sysv")) \ - rs6000_sdata = SDATA_SYSV; \ - else if (!strcmp (rs6000_sdata_name, "eabi")) \ - rs6000_sdata = SDATA_EABI; \ - else \ - error ("Bad value for -msdata=%s", rs6000_sdata_name); \ - } \ - else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \ - { \ - rs6000_sdata = SDATA_DATA; \ - rs6000_sdata_name = "data"; \ - } \ - else \ - { \ - rs6000_sdata = SDATA_NONE; \ - rs6000_sdata_name = "none"; \ - } \ - \ - if (TARGET_RELOCATABLE && \ - (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \ - { \ - rs6000_sdata = SDATA_DATA; \ - error ("-mrelocatable and -msdata=%s are incompatible.", \ - rs6000_sdata_name); \ - } \ - \ - else if (flag_pic && \ - (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \ - { \ - rs6000_sdata = SDATA_DATA; \ - error ("-f%s and -msdata=%s are incompatible.", \ - (flag_pic > 1) ? "PIC" : "pic", \ - rs6000_sdata_name); \ - } \ - \ - if (rs6000_sdata != SDATA_NONE && DEFAULT_ABI != ABI_V4 \ - && DEFAULT_ABI != ABI_SOLARIS) \ - { \ - rs6000_sdata = SDATA_NONE; \ - error ("-msdata=%s and -mcall-%s are incompatible.", \ - rs6000_sdata_name, rs6000_abi_name); \ - } \ - \ - if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \ - { \ - target_flags |= MASK_MINIMAL_TOC; \ - error ("-mrelocatable and -mno-minimal-toc are incompatible."); \ - } \ - \ - if (TARGET_RELOCATABLE && \ - (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \ - { \ - target_flags &= ~MASK_RELOCATABLE; \ - error ("-mrelocatable and -mcall-%s are incompatible.", \ - rs6000_abi_name); \ - } \ - \ - if (flag_pic > 1 && \ - (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \ - { \ - flag_pic = 0; \ - error ("-fPIC and -mcall-%s are incompatible.", \ - rs6000_abi_name); \ - } \ - \ - if (rs6000_current_abi == ABI_AIX && TARGET_LITTLE_ENDIAN) \ - { \ - target_flags &= ~MASK_LITTLE_ENDIAN; \ - error ("-mcall-aixdesc must be big endian"); \ - } \ - \ - if (rs6000_current_abi == ABI_NT && TARGET_BIG_ENDIAN) \ - { \ - target_flags |= MASK_LITTLE_ENDIAN; \ - error ("-mcall-nt must be little endian"); \ - } \ - \ - /* Treat -fPIC the same as -mrelocatable */ \ - if (flag_pic > 1) \ - target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \ - \ - else if (TARGET_RELOCATABLE) \ - flag_pic = 2; \ - \ -} while (0) - -/* Default ABI to compile code for */ -#define DEFAULT_ABI rs6000_current_abi - -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#define ASM_DEFAULT_SPEC "-mppc" - -#include "rs6000/rs6000.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC601 - -/* System V.4 uses register 13 as a pointer to the small data area, - so it is not available to the normal user. */ - -#undef FIXED_R13 -#define FIXED_R13 1 - -/* System V.4 passes the first 8 floating arguments in registers, - instead of the first 13 like AIX does. */ -#undef FP_ARG_MAX_REG -#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) \ - ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) - -/* Size of the V.4 varargs area if needed */ -#undef RS6000_VARARGS_AREA -#define RS6000_VARARGS_AREA ((rs6000_sysv_varargs_p) ? RS6000_VARARGS_SIZE : 0) - -/* Override default big endianism */ -#undef BYTES_BIG_ENDIAN -#undef WORDS_BIG_ENDIAN -#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) -#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) - -/* Define this to set the endianness to use in libgcc2.c, which can - not depend on target_flags. */ -#if !defined(_LITTLE_ENDIAN) && !defined(__sun__) -#define LIBGCC2_WORDS_BIG_ENDIAN 1 -#else -#define LIBGCC2_WORDS_BIG_ENDIAN 0 -#endif - -/* Size of the outgoing register save area */ -#undef RS6000_REG_SAVE -#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_AIX_NODESC) \ - ? (TARGET_64BIT ? 64 : 32) \ - : 0) - -/* Size of the fixed area on the stack. For AIX, use the standard 6 word - area, otherwise use 2 words to store back chain & LR. */ -#undef RS6000_SAVE_AREA -#define RS6000_SAVE_AREA \ - (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8) << (TARGET_64BIT ? 1 : 0)) - -/* Define cutoff for using external functions to save floating point. - Currently on V.4, always use inline stores */ -#undef FP_SAVE_INLINE -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) - -/* Don't generate XCOFF debugging information. */ - -#undef XCOFF_DEBUGGING_INFO - -/* Don't use the COFF object file format. */ - -#undef OBJECT_FORMAT_COFF - -/* Don't bother to output .extern pseudo-ops. They are not needed by - ELF assemblers. */ - -#undef ASM_OUTPUT_EXTERNAL - -/* Put jump tables in read-only memory, rather than in .text. */ -#undef JUMP_TABLES_IN_TEXT_SECTION -#define JUMP_TABLES_IN_TEXT_SECTION 0 - -/* Disable AIX-ism that disables turning -B into -L if the argument specifies a - relative file name. This breaks setting GCC_EXEC_PREFIX to D:\path under - Windows. */ -#undef RELATIVE_PREFIX_NOT_LINKDIR - -/* Undefine some things which are defined by the generic svr4.h. */ - -#undef ASM_FILE_END -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#undef READONLY_DATA_SECTION -#undef SELECT_SECTION -#undef ASM_DECLARE_FUNCTION_NAME -#undef ASM_OUTPUT_CONSTRUCTOR -#undef ASM_OUTPUT_DESTRUCTOR - -/* Use the regular svr4 definitions. */ - -#include "svr4.h" - -/* Prefix and suffix to use to saving floating point */ -#undef SAVE_FP_PREFIX -#undef SAVE_FP_SUFFIX -#define SAVE_FP_PREFIX "_savefpr_" -#define SAVE_FP_SUFFIX "_l" - -/* Prefix and suffix to use to restoring floating point */ -#undef RESTORE_FP_PREFIX -#undef RESTORE_FP_SUFFIX -#define RESTORE_FP_PREFIX "_restfpr_" -#define RESTORE_FP_SUFFIX "_l" - -/* Type used for ptrdiff_t, as a string used in a declaration. */ -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ - -/* Variables to set wchar_t size/type */ -extern char *rs6000_wchar_type; -extern int rs6000_wchar_type_size; - -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE rs6000_wchar_type - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE rs6000_wchar_type_size - -/* Tell the preprocessor the maximum size of wchar_t. */ -#undef MAX_WCHAR_TYPE_SIZE -#define MAX_WCHAR_TYPE_SIZE INT_TYPE_SIZE - -/* Tell cccp we'll set up __WCHAR_TYPE__ */ -#undef NO_BUILTIN_WCHAR_TYPE -#define NO_BUILTIN_WCHAR_TYPE 1 - -/* CYGNUS LOCAL vmakarov */ -#else -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -#endif -/* END CYGNUS LOCAL */ - -/* Make int foo : 8 not cause structures to be aligned to an int boundary */ - -#undef PCC_BITFIELD_TYPE_MATTERS -#define PCC_BITFIELD_TYPE_MATTERS (TARGET_BITFIELD_TYPE) - -/* CYGNUS LOCAL vmakarov */ -#undef BITFIELD_NBYTES_LIMITED -#define BITFIELD_NBYTES_LIMITED (TARGET_NO_BITFIELD_WORD) -/* END CYGNUS LOCAL */ - -/* Define this macro to be the value 1 if instructions will fail to - work if given data not on the nominal alignment. If instructions - will merely go slower in that case, define this macro as 0. */ -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN) - -/* Alignment in bits of the stack boundary. Note, in order to allow building - one set of libraries with -mno-eabi instead of eabi libraries and non-eabi - versions, just use 64 as the stack boundary. */ -#undef STACK_BOUNDARY -#define STACK_BOUNDARY 64 - -/* Real stack boundary as mandated by the appropriate ABI */ -#define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128) - -/* No data type wants to be aligned rounder than this. */ -#undef BIGGEST_ALIGNMENT -#define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128) - -#undef BIGGEST_FIELD_ALIGNMENT -#undef ADJUST_FIELD_ALIGN -#undef ROUND_TYPE_ALIGN - -/* Use ELF style section commands. */ - -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP "\t.section\t\".text\"" - -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP "\t.section\t\".data\"" - -#undef BSS_SECTION_ASM_OP -#define BSS_SECTION_ASM_OP "\t.section\t\".bss\"" - -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\"" - -#undef FINI_SECTION_ASM_OP -#define FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\"" - -#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\"" - -/* Put PC relative got entries in .got2 */ -#define MINIMAL_TOC_SECTION_ASM_OP \ - ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"") - -/* Put relocatable data in .data, not .rodata so initialized pointers can be updated */ -#undef CONST_SECTION_ASM_OP -#define CONST_SECTION_ASM_OP \ - ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".data\"\t# .rodata" : "\t.section\t\".rodata\"") - - -#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\"" -#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\"" -#define SBSS_SECTION_ASM_OP \ - ((DEFAULT_ABI == ABI_SOLARIS) ? "\t.section\t\".sbss\",\"aw\"" : "\t.section\t\".sbss\",\"aw\",@nobits") - - -/* Besides the usual ELF sections, we need a toc section. */ -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss, in_init, in_fini - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION \ - TOC_SECTION_FUNCTION \ - SDATA_SECTION_FUNCTION \ - SDATA2_SECTION_FUNCTION \ - SBSS_SECTION_FUNCTION \ - INIT_SECTION_FUNCTION \ - FINI_SECTION_FUNCTION - -extern void toc_section (), sdata_section (), sdata2_section (); -extern void sbss_section (); - -#define TOC_SECTION_FUNCTION \ -void \ -toc_section () \ -{ \ - if (in_section != in_toc) \ - { \ - in_section = in_toc; \ - if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ - && TARGET_MINIMAL_TOC \ - && !TARGET_RELOCATABLE) \ - { \ - if (! toc_initialized) \ - { \ - toc_initialized = 1; \ - fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LCTOC", 0); \ - fprintf (asm_out_file, "\t.tc "); \ - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); \ - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \ - fprintf (asm_out_file, "\n"); \ - \ - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \ - fprintf (asm_out_file, " = .+32768\n"); \ - } \ - else \ - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ - } \ - else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ - && !TARGET_RELOCATABLE) \ - fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \ - else \ - { \ - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ - if (! toc_initialized) \ - { \ - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \ - fprintf (asm_out_file, " = .+32768\n"); \ - toc_initialized = 1; \ - } \ - } \ - } \ -} - -#define SDATA_SECTION_FUNCTION \ -void \ -sdata_section () \ -{ \ - if (in_section != in_sdata) \ - { \ - in_section = in_sdata; \ - fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \ - } \ -} - -#define SDATA2_SECTION_FUNCTION \ -void \ -sdata2_section () \ -{ \ - if (in_section != in_sdata2) \ - { \ - in_section = in_sdata2; \ - fprintf (asm_out_file, "%s\n", SDATA2_SECTION_ASM_OP); \ - } \ -} - -#define SBSS_SECTION_FUNCTION \ -void \ -sbss_section () \ -{ \ - if (in_section != in_sbss) \ - { \ - in_section = in_sbss; \ - fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \ - } \ -} - -#define INIT_SECTION_FUNCTION \ -void \ -init_section () \ -{ \ - if (in_section != in_init) \ - { \ - in_section = in_init; \ - fprintf (asm_out_file, "%s\n", INIT_SECTION_ASM_OP); \ - } \ -} - -#define FINI_SECTION_FUNCTION \ -void \ -fini_section () \ -{ \ - if (in_section != in_fini) \ - { \ - in_section = in_fini; \ - fprintf (asm_out_file, "%s\n", FINI_SECTION_ASM_OP); \ - } \ -} - -/* A C statement or statements to switch to the appropriate section - for output of RTX in mode MODE. You can assume that RTX is some - kind of constant in RTL. The argument MODE is redundant except in - the case of a `const_int' rtx. Select the section by calling - `text_section' or one of the alternatives for other sections. - - Do not define this macro if you put all constants in the read-only - data section. */ - -extern void rs6000_select_rtx_section (), rs6000_select_section (); - -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X) - -/* A C statement or statements to switch to the appropriate - section for output of DECL. DECL is either a `VAR_DECL' node - or a constant of some sort. RELOC indicates whether forming - the initial value of DECL requires link-time relocations. */ - -#undef SELECT_SECTION -#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC) - -/* Return non-zero if this entry is to be written into the constant pool - in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST - containing one of them. If -mfp-in-toc (the default), we also do - this for floating-point constants. We actually can only do this - if the FP formats of the target and host machines are the same, but - we can't check that since not every file that uses - GO_IF_LEGITIMATE_ADDRESS_P includes real.h. - - Unlike AIX, we don't key off of -mminimal-toc, but instead do not - allow floating point constants in the TOC if -mrelocatable. */ - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (!TARGET_NO_FP_IN_TOC \ - && !TARGET_RELOCATABLE \ - && GET_CODE (X) == CONST_DOUBLE \ - && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - && BITS_PER_WORD == HOST_BITS_PER_INT))) - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -extern int rs6000_pic_labelno; - -/* CYGNUS LOCAL vmakarov */ -#undef USER_LABEL_PREFIX -/* END CYGNUS LOCAL */ - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - char *orig_name; \ - char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \ - STRIP_NAME_ENCODING (orig_name, NAME); \ - \ - if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag)) \ - { \ - char buf[256], *buf_ptr; \ - \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno); \ - \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); \ - STRIP_NAME_ENCODING (buf_ptr, buf); \ - fprintf (FILE, "\t%s %s-", init_ptr, buf_ptr); \ - \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); \ - fprintf (FILE, "%s\n", buf_ptr); \ - } \ - \ - asm_fprintf (FILE, "\t%s\t %U%s,", TYPE_ASM_OP, orig_name); /* CYGNUS LOCAL vmakarov: asm_fprintf */ \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - \ - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ - { \ - char *desc_name = orig_name; \ - \ - while (*desc_name == '.') \ - desc_name++; \ - \ - if (TREE_PUBLIC (DECL)) \ - fprintf (FILE, "\t.globl %s\n", desc_name); \ - \ - fprintf (FILE, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ - fprintf (FILE, "%s:\n", desc_name); \ - fprintf (FILE, "\t%s %s\n", init_ptr, orig_name); \ - fprintf (FILE, "\t%s _GLOBAL_OFFSET_TABLE_\n", init_ptr); \ - if (DEFAULT_ABI == ABI_AIX) \ - fprintf (FILE, "\t%s 0\n", init_ptr); \ - fprintf (FILE, "\t.previous\n"); \ - } \ - asm_fprintf (FILE, "%U%s:\n", orig_name); /* CYGNUS LOCAL vmakarov: asm_fprintf */ \ - } while (0) - -/* How to renumber registers for dbx and gdb. */ - -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) - -/* CYGNUS LOCAL vmakarov */ -/* If defined, C string expressions to be used for the `%R', `%L', - `%U', and `%I' options of `asm_fprintf' (see `final.c'). These - are useful when a single `md' file must support multiple assembler - formats. In that case, the various `tm.h' files can define these - macros differently. */ - -#ifndef REGISTER_PREFIX -#define REGISTER_PREFIX "" -#endif - -#ifndef LOCAL_LABEL_PREFIX -#define LOCAL_LABEL_PREFIX "." -#endif - -#ifndef USER_LABEL_PREFIX -#define USER_LABEL_PREFIX "" -#endif - -#ifndef IMMEDIATE_PREFIX -#define IMMEDIATE_PREFIX "" -#endif -/* END CYGNUS LOCAL */ - -/* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL. */ - -#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - asm_fprintf (FILE, "%L%s", PREFIX) /* CYGNUS LOCAL vmakarov: asm_fprintf */ - -/* This is how to allocate empty space in some section. Use .space - instead of .zero because the Solaris PowerPC assembler doesn't - like it, and gas accepts either syntax. */ - -#undef SKIP_ASM_OP -#define SKIP_ASM_OP ".space" - -/* This says how to output assembler code to declare an - uninitialized internal linkage data object. Under SVR4, - the linker seems to want the alignment of data objects - to depend on their types. We do exactly that here. */ - -#ifndef LOCAL_ASM_OP -#define LOCAL_ASM_OP ".local" -#endif - -#ifndef LCOMM_ASM_OP -#define LCOMM_ASM_OP ".lcomm" -#endif - -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ -do { \ - if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \ - && (SIZE) <= g_switch_value) \ - { \ - sbss_section (); \ - ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - ASM_OUTPUT_SKIP (FILE, SIZE); \ - if (!flag_inhibit_size_directive && (SIZE) > 0) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", SIZE); \ - } \ - } \ - else \ - { \ - fprintf (FILE, "\t%s\t", LCOMM_ASM_OP); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \ - } \ -} while (0) - -/* Describe how to emit uninitialized external linkage items */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ -do { \ - ASM_GLOBALIZE_LABEL (FILE, NAME); \ - ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ -} while (0) - -/* Switch Recognition by gcc.c. Add -G xx support */ - -#undef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) \ - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ - || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \ - || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \ - || (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'G') - -/* Output .file. */ -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -do { \ - output_file_directive ((FILE), main_input_filename); \ - rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ -} while (0) - - -/* This is how to output an assembler line defining an `int' constant. - For -mrelocatable, we mark all addresses that need to be fixed up - in the .fixup section. */ -#undef ASM_OUTPUT_INT -#define ASM_OUTPUT_INT(FILE,VALUE) \ -do { \ - static int recurse = 0; \ - if ((TARGET_RELOCATABLE || flag_pic) \ - && in_section != in_toc \ - && in_section != in_text \ - && in_section != in_ctors \ - && in_section != in_dtors \ - && !recurse \ - && GET_CODE (VALUE) != CONST_INT \ - && GET_CODE (VALUE) != CONST_DOUBLE \ - && CONSTANT_P (VALUE)) \ - { \ - static int labelno = 0; \ - char buf[256], *p; \ - \ - recurse = 1; \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", labelno++); \ - STRIP_NAME_ENCODING (p, buf); \ - fprintf (FILE, "%s:\n", p); \ - fprintf (FILE, "\t.long ("); \ - output_addr_const (FILE, (VALUE)); \ - fprintf (FILE, ")@fixup\n"); \ - fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n"); \ - ASM_OUTPUT_ALIGN (FILE, 2); \ - fprintf (FILE, "\t.long\t%s\n", p); \ - fprintf (FILE, "\t.previous\n"); \ - recurse = 0; \ - } \ - /* Remove initial .'s to turn a -mcall-aixdesc or -mcall-nt function \ - address into the address of the descriptor, not the function \ - itself. */ \ - else if (GET_CODE (VALUE) == SYMBOL_REF \ - && XSTR (VALUE, 0)[0] == '.' \ - && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)) \ - { \ - char *name = XSTR (VALUE, 0); \ - while (*name == '.') \ - name++; \ - \ - fprintf (FILE, "\t.long %s\n", name); \ - } \ - else \ - { \ - fprintf (FILE, "\t.long "); \ - output_addr_const (FILE, (VALUE)); \ - fprintf (FILE, "\n"); \ - } \ -} while (0) - -/* This is the end of what might become sysv4.h. */ - -/* Allow stabs and dwarf, for now, make stabs the default debugging type, - not dwarf since G++ doesn't support dwarf. */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -#define DBX_DEBUGGING_INFO -#define DWARF_DEBUGGING_INFO - -/* If we are referencing a function that is static or is known to be - in this file, make the SYMBOL_REF special. We can use this to indicate - that we can branch to this function without emitting a no-op after the - call. For real AIX and NT calling sequences, we also replace the - function name with the real name (1 or 2 leading .'s), rather than - the function descriptor name. This saves a lot of overriding code - to readd the prefixes. */ - -#undef ENCODE_SECTION_INFO -#define ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL) - -extern void rs6000_encode_section_info (); - -/* This macro gets just the user-specified name - out of the string in a SYMBOL_REF. Discard - a leading * or @. */ -#undef STRIP_NAME_ENCODING -#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ -do { \ - char *_name = SYMBOL_NAME; \ - while (*_name == '*' || *_name == '@') \ - _name++; \ - (VAR) = _name; \ -} while (0) - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ -do { \ - char *_name = NAME; \ - while (*_name == '*' || *_name == '@') \ - _name++; \ - asm_fprintf (FILE, "%U%s", _name); /* CYGNUS LOCAL vmakarov: asm_fprintf */ \ -} while (0) - -/* - * Switch into a generic section. - * - * We make the section read-only and executable for a function decl, - * read-only for a const data decl, and writable for a non-const data decl. - * - * If the section has already been defined, we must not - * emit the attributes here. The SVR4 assembler does not - * recognize section redefinitions. - * If DECL is NULL, no attributes are emitted. - * - * Note, Solaris as doesn't like @nobits, and gas can handle .sbss without - * needing @nobits. - */ - -#undef ASM_OUTPUT_SECTION_NAME -#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ -do { \ - static struct section_info \ - { \ - struct section_info *next; \ - char *name; \ - enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \ - } *sections; \ - struct section_info *s; \ - char *mode; \ - enum sect_enum type; \ - \ - for (s = sections; s; s = s->next) \ - if (!strcmp (NAME, s->name)) \ - break; \ - \ - if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \ - type = SECT_EXEC, mode = "ax"; \ - else if (DECL && DECL_READONLY_SECTION (DECL, RELOC) && !TARGET_RELOCATABLE && !flag_pic) \ - type = SECT_RO, mode = "a"; \ - else \ - type = SECT_RW, mode = "aw"; \ - \ - if (s == 0) \ - { \ - s = (struct section_info *) xmalloc (sizeof (struct section_info)); \ - s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \ - strcpy (s->name, NAME); \ - s->type = type; \ - s->next = sections; \ - sections = s; \ - fprintf (FILE, "\t.section\t\"%s\",\"%s\"\n", NAME, mode); \ - } \ - else \ - { \ - if (DECL && s->type != type) \ - error_with_decl (DECL, "%s causes a section type conflict"); \ - \ - fprintf (FILE, "\t.section\t\"%s\"\n", NAME); \ - } \ -} while (0) - -#undef ASM_OUTPUT_CONSTRUCTOR -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - if (DEFAULT_ABI != ABI_SOLARIS) \ - { \ - ctors_section (); \ - fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ - assemble_name (FILE, NAME); \ - } \ - else \ - { \ - init_section (); \ - fputs ("\tbl ", FILE); \ - assemble_name (FILE, NAME); \ - } \ - fputs ("\n", FILE); \ - } while (0) - -/* A C statement (sans semicolon) to output an element in the table of - global destructors. */ -#undef ASM_OUTPUT_DESTRUCTOR -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - if (DEFAULT_ABI != ABI_SOLARIS) \ - { \ - dtors_section (); \ - fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ - assemble_name (FILE, NAME); \ - } \ - else \ - { \ - fini_section (); \ - fputs ("\tbl ", FILE); \ - assemble_name (FILE, NAME); \ - } \ - fputs ("\n", FILE); \ - } while (0) - -/* But, to make this work, we have to output the stabs for the function - name *first*... */ - -#define DBX_FUNCTION_FIRST - -/* This is the end of what might become sysv4dbx.h. */ - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)"); - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ - "-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)" - -/* Pass various options to the assembler */ -#undef ASM_SPEC -#define ASM_SPEC "%(asm_cpu) \ -%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \ -%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \ -%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \ -%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \ -%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-solaris: -mlittle -msolaris} \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: -mlittle} \ - %{end-cygnus-local: } \ - %{mcall-linux: -mbig} }}}}" - -#ifndef CC1_ENDIAN_BIG_SPEC -#define CC1_ENDIAN_BIG_SPEC "" -#endif - -#ifndef CC1_ENDIAN_LITTLE_SPEC -#define CC1_ENDIAN_LITTLE_SPEC "\ -%{!mstrict-align: %{!mno-strict-align: \ - %{cygnus-local-vmakarov: } \ - %{!mcall-i960-old: \ - %{end-cygnus-local: } \ - -mstrict-align \ - %{cygnus-local-vmakarov: } \ - } \ - %{end-cygnus-local: } \ -}}" -#endif - -#ifndef CC1_ENDIAN_DEFAULT_SPEC -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)" -#endif - -#undef CC1_SPEC -/* Pass -G xxx to the compiler and set correct endian mode */ -#define CC1_SPEC "%{G*} \ -%{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \ -%{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-nt: -mlittle %(cc1_endian_little) } \ - %{mcall-aixdesc: -mbig %(cc1_endian_big) } \ - %{mcall-solaris: -mlittle %(cc1_endian_little) } \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: -mlittle %(cc1_endian_little) } \ - %{end-cygnus-local: } \ - %{mcall-linux: -mbig %(cc1_endian_big) }} \ - %{!mcall-nt: %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \ - %{cygnus-local-vmakarov: } \ - %{!mcall-i960-old: \ - %{end-cygnus-local: } \ - %(cc1_endian_default) \ - %{cygnus-local-vmakarov: } \ - } \ - %{end-cygnus-local: } \ - }}}} \ -}}} \ -%{mcall-solaris: -mregnames } \ -%{mno-sdata: -msdata=none } \ -%{meabi: %{!mcall-*: -mcall-sysv }} \ -%{!meabi: %{!mno-eabi: \ - %{mrelocatable: -meabi } \ - %{mcall-solaris: -mno-eabi } \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: -meabi } \ - %{end-cygnus-local: } \ - %{mcall-linux: -mno-eabi }}} \ -%{msdata: -msdata=default} \ -%{mno-sdata: -msdata=none}" - -/* Don't put -Y P,<path> for cross compilers */ -#undef LINK_PATH_SPEC -#ifndef CROSS_COMPILE -#define LINK_PATH_SPEC "\ -%{!R*:%{L*:-R %*}} \ -%{!nostdlib: %{!YP,*: \ - %{compat-bsd: \ - %{p:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ - %{!p:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}} \ - %{!R*: %{!L*: -R /usr/ucblib}} \ - %{!compat-bsd: \ - %{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ - %{!p:-Y P,/usr/ccs/lib:/usr/lib}}}}" - -#else -#define LINK_PATH_SPEC "" -#endif - -/* Default starting address if specified */ -#ifndef LINK_START_SPEC -#define LINK_START_SPEC "\ -%{mads: %(link_start_ads) } \ -%{myellowknife: %(link_start_yellowknife) } \ -%{mmvme: %(link_start_mvme) } \ -%{msim: %(link_start_sim) } \ -%{mcall-linux: %(link_start_linux) } \ -%{mcall-solaris: %(link_start_solaris) } \ -%{cygnus-local-vmakarov: } \ -%{mvxworks: %(link_start_vxworks) } \ -%{end-cygnus-local: } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris:\ -%{cygnus-local-vmakarov: } \ - %{!mvxworks: \ -%{end-cygnus-local: } \ - %(link_start_default) \ -%{cygnus-local-vmakarov: } \ - } \ -%{end-cygnus-local: } \ -}}}}}}" -#endif - -#ifndef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "" -#endif - -#undef LINK_SPEC -/* CYGNUS LOCAL jlemke (mpc860) */ -#define LINK_SPEC "\ -%{h*} %{v:-V} %{G*} \ -%{Wl,*:%*} %{YP,*} %{R*} \ -%{Qy:} %{!Qn:-Qy} \ -%(link_shlib) \ -%{!Ttext*: %(link_start) } \ -%(link_target) \ -%{mmpc860c0*:--mpc860c0%*} \ -%(link_os)" -/* END CYGNUS LOCAL */ - -/* For now, turn off shared libraries by default. */ -#ifndef SHARED_LIB_SUPPORT -#define NO_SHARED_LIB_SUPPORT -#endif - -#undef LINK_SHLIB_SPEC -#ifndef NO_SHARED_LIB_SUPPORT -/* Shared libraries are default. */ -#define LINK_SHLIB_SPEC "\ -%{!static: %(link_path) %{!R*:%{L*:-R %*}}} \ -%{mshlib: } \ -%{static:-dn -Bstatic} \ -%{shared:-G -dy -z text} \ -%{symbolic:-Bsymbolic -G -dy -z text}" - -#else -/* Shared libraries are not default. */ -#define LINK_SHLIB_SPEC "\ -%{mshlib: %(link_path) } \ -%{!mshlib: %{!shared: %{!symbolic: -dn -Bstatic}}} \ -%{static: } \ -%{shared:-G -dy -z text %(link_path) } \ -%{symbolic:-Bsymbolic -G -dy -z text %(link_path) }" -#endif - -/* Override the default target of the linker. */ -#undef LINK_TARGET_SPEC -#define LINK_TARGET_SPEC "\ -%{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: -oformat elf32-powerpcle} \ - %{end-cygnus-local: } \ - %{mcall-solaris: -oformat elf32-powerpcle} \ - %{mcall-linux: -oformat elf32-powerpc}}}}}" - -/* Any specific OS flags */ -#ifndef LINK_OS_SPEC -#define LINK_OS_SPEC "\ -%{mads: %(link_os_ads) } \ -%{myellowknife: %(link_os_yellowknife) } \ -%{mmvme: %(link_os_mvme) } \ -%{msim: %(link_os_sim) } \ -%{mcall-linux: %(link_os_linux) } \ -%{mcall-solaris: %(link_os_solaris) } \ -%{cygnus-local-vmakarov: } \ -%{mvxworks: %(link_os_vxworks) } \ -%{end-cygnus-local: } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris:\ -%{cygnus-local-vmakarov: } \ - %{!mvxworks: \ -%{end-cygnus-local: } \ - %(link_os_default) \ -%{cygnus-local-vmakarov: } \ - } \ -%{end-cygnus-local: } \ -}}}}}}" -#endif - -#ifndef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "" -#endif - -#undef CPP_SYSV_SPEC -#define CPP_SYSV_SPEC \ -"%{mrelocatable*: -D_RELOCATABLE} \ -%{fpic: -D__PIC__=1 -D__pic__=1} \ -%{fPIC: -D__PIC__=2 -D__pic__=2} \ -%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \ -%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \ -%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \ -%{msoft-float: -D_SOFT_FLOAT} \ -%{cygnus-local-vmakarov: } \ -%{!msoft-float: %{!mhard-float: \ - %{mcpu=401: -D_SOFT_FLOAT} \ - %{mcpu=403: -D_SOFT_FLOAT} \ - %{mcpu=ec603e: -D_SOFT_FLOAT} \ - %{mcpu=801: -D_SOFT_FLOAT} \ - %{mcpu=821: -D_SOFT_FLOAT} \ - %{mcpu=823: -D_SOFT_FLOAT} \ - %{mcpu=860: -D_SOFT_FLOAT} \ - %{!mcpu*: %(cpp_float_default) }}} \ -%{end-cygnus-local: }" - -/* CYGNUS LOCAL vmakarov */ -/* Whether floating point is disabled by default */ -#undef CPP_FLOAT_DEFAULT_SPEC -#define CPP_FLOAT_DEFAULT_SPEC "" - -/* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a - header file. For VxWorks, don't define either _{BIG,LITTLE}_ENDIAN - for the same reason. */ -/* END CYGNUS LOCAL */ -#undef CPP_SYSV_DEFAULT_SPEC -#define CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV" - -#ifndef CPP_ENDIAN_BIG_SPEC -#define CPP_ENDIAN_BIG_SPEC "\ -%{cygnus-local-vmakarov: } \ -%{!mcall-solaris: %{!mvxworks: -D_BIG_ENDIAN }} \ -%{end-cygnus-local: } \ --D__BIG_ENDIAN__ -Amachine(bigendian)" -#endif - -#ifndef CPP_ENDIAN_LITTLE_SPEC -#define CPP_ENDIAN_LITTLE_SPEC "\ -%{cygnus-local-vmakarov: } \ -%{!mcall-solaris: %{!mvxworks: -D_LITTLE_ENDIAN }} \ -%{end-cygnus-local: } \ --D__LITTLE_ENDIAN__ -Amachine(littleendian)" -#endif - -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ -#ifndef CPP_ENDIAN_SOLARIS_SPEC -#define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" -#endif -/* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file. */ -/* CYGNUS LOCAL vmakarov */ -#endif -/* END CYGNUS LOCAL */ - -#undef CPP_ENDIAN_SPEC -#define CPP_ENDIAN_SPEC \ -"%{mlittle: %(cpp_endian_little) } \ -%{mlittle-endian: %(cpp_endian_little) } \ -%{mbig: %(cpp_endian_big) } \ -%{mbig-endian: %(cpp_endian_big) } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-solaris: %(cpp_endian_little) } %{cygnus-local-cpp-endian-little: }\ - %{mcall-nt: %(cpp_endian_little) } \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: %(cpp_endian_little) } \ - %{end-cygnus-local: } \ - %{mcall-linux: %(cpp_endian_big) } \ - %{mcall-aixdesc: %(cpp_endian_big) } \ - %{!mcall-solaris: %{!mcall-linux: %{!mcall-nt: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}}" - -#undef CPP_ENDIAN_DEFAULT_SPEC -#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_big)" - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %{msoft-float: -D_SOFT_FLOAT} \ -%(cpp_sysv) %(cpp_endian) %(cpp_cpu) \ -%{mads: %(cpp_os_ads) } \ -%{myellowknife: %(cpp_os_yellowknife) } \ -%{mmvme: %(cpp_os_mvme) } \ -%{msim: %(cpp_os_sim) } \ -%{mcall-linux: %(cpp_os_linux) } \ -%{mcall-solaris: %(cpp_os_solaris) } \ -%{cygnus-local-vmakarov: } \ -%{mvxworks: %(cpp_os_vxworks) } \ -%{end-cygnus-local: } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris:\ -%{cygnus-local-vmakarov: } \ -%{!mvxworks: \ -%{end-cygnus-local: } \ - %(cpp_os_default) \ - } \ -%{end-cygnus-local: } \ -}}}}}}" - -#ifndef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "" -#endif - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "\ -%{mads: %(startfile_ads) } \ -%{myellowknife: %(startfile_yellowknife) } \ -%{mmvme: %(startfile_mvme) } \ -%{msim: %(startfile_sim) } \ -%{mcall-linux: %(startfile_linux) } \ -%{mcall-solaris: %(startfile_solaris) } \ -%{cygnus-local-vmakarov: } \ -%{mvxworks: %(startfile_vxworks) } \ -%{end-cygnus-local: } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris:\ -%{cygnus-local-vmakarov: } \ -%{!mvxworks: \ -%{end-cygnus-local: } \ - %(startfile_default) \ -%{cygnus-local-vmakarov: } \ - } \ -%{end-cygnus-local: } \ -}}}}}}" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "" - -#undef LIB_SPEC -#define LIB_SPEC "\ -%{mads: %(lib_ads) } \ -%{myellowknife: %(lib_yellowknife) } \ -%{mmvme: %(lib_mvme) } \ -%{msim: %(lib_sim) } \ -%{mcall-linux: %(lib_linux) } \ -%{mcall-solaris: %(lib_solaris) } \ -%{cygnus-local-vmakarov: } \ -%{mvxworks: %(lib_vxworks) } \ -%{end-cygnus-local: } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris:\ -%{cygnus-local-vmakarov: } \ -%{!mvxworks: \ -%{end-cygnus-local: } \ - %(lib_default) \ -%{cygnus-local-vmakarov: } \ - }\ -%{end-cygnus-local: } \ -}}}}}}" - -#undef LIBGCC_SPEC -#define LIBGCC_SPEC "libgcc.a%s" - -#ifndef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "" -#endif - -#undef ENDFILE_SPEC - -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ -#define ENDFILE_SPEC "\ -%{mads: ecrtn.o%s} \ -%{myellowknife: ecrtn.o%s} \ -%{mmvme: ecrtn.o%s} \ -%{msim: ecrtn.o%s} \ -%{mcall-linux: %(endfile_linux) } \ -%{mcall-solaris: scrtn.o%s} \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(endfile_default) }}}}}}" - -/* CYGNUS LOCAL vmakarov */ -#endif - -#define ENDFILE_SPEC "\ -%{mads: %(endfile_ads) } \ -%{myellowknife: %(endfile_yellowknife) } \ -%{mmvme: %(endfile_mvme) } \ -%{msim: %(endfile_sim) } \ -%{mcall-linux: %(endfile_linux) } \ -%{mcall-solaris: %(endfile_solarils) } \ -%{mvxworks: %(endfile_vxworks) } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %{!mvxworks: %(endfile_default) }}}}}}}" -/* END CYGNUS LOCAL */ - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "" - -/* Motorola ADS support. */ -#ifndef LIB_ADS_SPEC -#define LIB_ADS_SPEC "--start-group -lads -lc --end-group" -#endif - -#ifndef STARTFILE_ADS_SPEC -#define STARTFILE_ADS_SPEC "ecrti.o%s crt0.o%s" -#endif - -#ifndef ENDFILE_ADS_SPEC -#define ENDFILE_ADS_SPEC "ecrtn.o%s" -#endif - -#ifndef LINK_START_ADS_SPEC -#define LINK_START_ADS_SPEC "-T ads.ld%s" -#endif - -#ifndef LINK_OS_ADS_SPEC -#define LINK_OS_ADS_SPEC "" -#endif - -#ifndef CPP_OS_ADS_SPEC -#define CPP_OS_ADS_SPEC "" -#endif - -/* Motorola Yellowknife support. */ -#ifndef LIB_YELLOWKNIFE_SPEC -#define LIB_YELLOWKNIFE_SPEC "--start-group -lyk -lc --end-group" -#endif - -#ifndef STARTFILE_YELLOWKNIFE_SPEC -#define STARTFILE_YELLOWKNIFE_SPEC "ecrti.o%s crt0.o%s" -#endif - -#ifndef ENDFILE_YELLOWKNIFE_SPEC -#define ENDFILE_YELLOWKNIFE_SPEC "ecrtn.o%s" -#endif - -#ifndef LINK_START_YELLOWKNIFE_SPEC -#define LINK_START_YELLOWKNIFE_SPEC "-T yellowknife.ld%s" -#endif - -#ifndef LINK_OS_YELLOWKNIFE_SPEC -#define LINK_OS_YELLOWKNIFE_SPEC "" -#endif - -#ifndef CPP_OS_YELLOWKNIFE_SPEC -#define CPP_OS_YELLOWKNIFE_SPEC "" -#endif - -/* Motorola MVME support. */ -#ifndef LIB_MVME_SPEC -#define LIB_MVME_SPEC "--start-group -lmvme -lc --end-group" -#endif - -#ifndef STARTFILE_MVME_SPEC -#define STARTFILE_MVME_SPEC "ecrti.o%s crt0.o%s" -#endif - -#ifndef ENDFILE_MVME_SPEC -#define ENDFILE_MVME_SPEC "ecrtn.o%s" -#endif - -#ifndef LINK_START_MVME_SPEC -#define LINK_START_MVME_SPEC "%{!Wl,-T*: %{!T*: -Ttext 0x40000}}" -#endif - -#ifndef LINK_OS_MVME_SPEC -#define LINK_OS_MVME_SPEC "" -#endif - -#ifndef CPP_OS_MVME_SPEC -#define CPP_OS_MVME_SPEC "" -#endif - -/* PowerPC simulator based on netbsd system calls support. */ -#ifndef LIB_SIM_SPEC -#define LIB_SIM_SPEC "--start-group -lsim -lc --end-group" -#endif - -#ifndef STARTFILE_SIM_SPEC -#define STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s" -#endif - -#ifndef ENDFILE_SIM_SPEC -#define ENDFILE_SIM_SPEC "ecrtn.o%s" -#endif - -#ifndef LINK_START_SIM_SPEC -#define LINK_START_SIM_SPEC "-Ttext 0x10000074" -#endif - -#ifndef LINK_OS_SIM_SPEC -#define LINK_OS_SIM_SPEC "" -#endif - -#ifndef CPP_OS_SIM_SPEC -#define CPP_OS_SIM_SPEC "" -#endif - -/* GNU/Linux support. */ -#ifndef LIB_LINUX_SPEC -#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } %{!mnewlib: -lc }" -#endif - -#ifndef STARTFILE_LINUX_SPEC -#define STARTFILE_LINUX_SPEC "\ -%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \ -%{mnewlib: ecrti.o%s} \ -%{!mnewlib: crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" -#endif - -#ifndef ENDFILE_LINUX_SPEC -#define ENDFILE_LINUX_SPEC "\ -%{mnewlib: ecrtn.o%s} \ -%{!mnewlib: %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s}" -#endif - -#ifndef LINK_START_LINUX_SPEC -#define LINK_START_LINUX_SPEC "-Ttext 0x400074" -#endif - -#ifndef LINK_OS_LINUX_SPEC -#define LINK_OS_LINUX_SPEC "" -#endif - -#ifndef CPP_OS_LINUX_SPEC -#define CPP_OS_LINUX_SPEC "-D__unix__ -D__linux__ \ -%{!ansi: -Dunix -Dlinux } \ --Asystem(unix) -Asystem(linux)" -#endif - -#ifndef CPP_OS_LINUX_SPEC -#define CPP_OS_LINUX_SPEC "" -#endif - -/* Solaris support. */ -/* For Solaris, Gcc automatically adds in one of the files - /usr/ccs/lib/values-Xc.o, /usr/ccs/lib/values-Xa.o, or - /usr/ccs/lib/values-Xt.o for each final link step (depending upon the other - gcc options selected, such as -traditional and -ansi). These files each - contain one (initialized) copy of a special variable called `_lib_version'. - Each one of these files has `_lib_version' initialized to a different (enum) - value. The SVR4 library routines query the value of `_lib_version' at run - to decide how they should behave. Specifically, they decide (based upon the - value of `_lib_version') if they will act in a strictly ANSI conforming - manner or not. */ - -#ifndef LIB_SOLARIS_SPEC -#define LIB_SOLARIS_SPEC "\ -%{mnewlib: --start-group -lsolaris -lc --end-group } \ -%{!mnewlib: \ - %{ansi:values-Xc.o%s} \ - %{!ansi: \ - %{traditional:values-Xt.o%s} \ - %{!traditional:values-Xa.o%s}} \ - %{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \ - %{solaris-cclib: /opt/SUNWspro/SC4.0/lib/libabi.a} \ - %{!shared: %{!symbolic: -lc }}}" -#endif - -#ifndef STARTFILE_SOLARIS_SPEC -#define STARTFILE_SOLARIS_SPEC "\ -%{!msolaris-cclib: scrti.o%s scrt0.o%s} \ -%{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crti.o%s /opt/SUNWspro/SC4.0/lib/crt1.o%s}" -#endif - -#ifndef ENDFILE_SOLARIS_SPEC -#define ENDFILE_SOLARIS_SPEC "\ -%{!msolaris-cclib: scrtn.o%s} \ -%{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crtn.o%s}" -#endif - -#ifndef LINK_START_SOLARIS_SPEC -#ifdef CROSS_COMPILER -#define LINK_START_SOLARIS_SPEC "-Ttext 0x2000074" -#else -#define LINK_START_SOLARIS_SPEC "" -#endif -#endif - -#ifndef LINK_OS_SOLARIS_SPEC -#define LINK_OS_SOLARIS_SPEC "" -#endif - -#ifndef CPP_OS_SOLARIS_SPEC -#define CPP_OS_SOLARIS_SPEC "-D__ppc -D__sun__=1 -D__unix__ -D__svr4__ -D__SVR4__ \ -%{!ansi: -Dsun=1 -Dunix -DSVR4 -D__EXTENSIONS__ } \ --Amachine(prep)" -#endif - -/* CYGNUS LOCAL vmakarov */ -/* VxWorks support. */ -/* VxWorks does all the library stuff itself. */ -#ifndef LIB_VXWORKS_SPEC -#define LIB_VXWORKS_SPEC "" -#endif - -/* Because it uses ld -r, vxworks has no start/end files, nor starting address. */ -#ifndef STARTFILE_VXWORKS_SPEC -#define STARTFILE_VXWORKS_SPEC "" -#endif - -#ifndef ENDFILE_VXWORKS_SPEC -#define ENDFILE_VXWORKS_SPEC "" -#endif - -#ifndef LINK_START_VXWORKS_SPEC -#define LINK_START_VXWORKS_SPEC "" -#endif - -#ifndef LINK_OS_VXWORKS_SPEC -#define LINK_OS_VXWORKS_SPEC "-r" -#endif - -#ifndef CPP_OS_VXWORKS_SPEC -#define CPP_OS_VXWORKS_SPEC "\ --DCPU_FAMILY=PPC \ -%{!mcpu*: \ - %{mpowerpc*: -DCPU=PPC603} \ - %{!mno-powerpc: -DCPU=PPC603}} \ -%{mcpu=powerpc: -DCPU=PPC603} \ -%{mcpu=401: -DCPU=PPC403} \ -%{mcpu=403: -DCPU=PPC403} \ -%{mcpu=601: -DCPU=PPC601} \ -%{mcpu=602: -DCPU=PPC603} \ -%{mcpu=603: -DCPU=PPC603} \ -%{mcpu=603e: -DCPU=PPC603} \ -%{mcpu=ec603e: -DCPU=PPC603} \ -%{mcpu=604: -DCPU=PPC604} \ -%{mcpu=604e: -DCPU=PPC604} \ -%{mcpu=620: -DCPU=PPC604} \ -%{mcpu=801: -DCPU=PPC603} \ -%{mcpu=821: -DCPU=PPC603} \ -%{mcpu=823: -DCPU=PPC603} \ -%{mcpu=860: -DCPU=PPC603}" - -#endif -/* END CYGNUS LOCAL */ - -/* Define any extra SPECS that the compiler needs to generate. */ -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ - { "lib_ads", LIB_ADS_SPEC }, \ - { "lib_yellowknife", LIB_YELLOWKNIFE_SPEC }, \ - { "lib_mvme", LIB_MVME_SPEC }, \ - { "lib_sim", LIB_SIM_SPEC }, \ - { "lib_linux", LIB_LINUX_SPEC }, \ - { "lib_solaris", LIB_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "lib_vxworks", LIB_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "lib_default", LIB_DEFAULT_SPEC }, \ - { "startfile_ads", STARTFILE_ADS_SPEC }, \ - { "startfile_yellowknife", STARTFILE_YELLOWKNIFE_SPEC }, \ - { "startfile_mvme", STARTFILE_MVME_SPEC }, \ - { "startfile_sim", STARTFILE_SIM_SPEC }, \ - { "startfile_linux", STARTFILE_LINUX_SPEC }, \ - { "startfile_solaris", STARTFILE_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "startfile_vxworks", STARTFILE_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "startfile_default", STARTFILE_DEFAULT_SPEC }, \ - { "endfile_ads", ENDFILE_ADS_SPEC }, \ - { "endfile_yellowknife", ENDFILE_YELLOWKNIFE_SPEC }, \ - { "endfile_mvme", ENDFILE_MVME_SPEC }, \ - { "endfile_sim", ENDFILE_SIM_SPEC }, \ - { "endfile_linux", ENDFILE_LINUX_SPEC }, \ - { "endfile_solaris", ENDFILE_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "endfile_vxworks", ENDFILE_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "endfile_default", ENDFILE_DEFAULT_SPEC }, \ - { "link_path", LINK_PATH_SPEC }, \ - { "link_shlib", LINK_SHLIB_SPEC }, \ - { "link_target", LINK_TARGET_SPEC }, \ - { "link_start", LINK_START_SPEC }, \ - { "link_start_ads", LINK_START_ADS_SPEC }, \ - { "link_start_yellowknife", LINK_START_YELLOWKNIFE_SPEC }, \ - { "link_start_mvme", LINK_START_MVME_SPEC }, \ - { "link_start_sim", LINK_START_SIM_SPEC }, \ - { "link_start_linux", LINK_START_LINUX_SPEC }, \ - { "link_start_solaris", LINK_START_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "link_start_vxworks", LINK_START_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "link_start_default", LINK_START_DEFAULT_SPEC }, \ - { "link_os", LINK_OS_SPEC }, \ - { "link_os_ads", LINK_OS_ADS_SPEC }, \ - { "link_os_yellowknife", LINK_OS_YELLOWKNIFE_SPEC }, \ - { "link_os_mvme", LINK_OS_MVME_SPEC }, \ - { "link_os_sim", LINK_OS_SIM_SPEC }, \ - { "link_os_linux", LINK_OS_LINUX_SPEC }, \ - { "link_os_solaris", LINK_OS_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "link_os_vxworks", LINK_OS_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "link_os_default", LINK_OS_DEFAULT_SPEC }, \ - { "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \ - { "cc1_endian_little", CC1_ENDIAN_LITTLE_SPEC }, \ - { "cc1_endian_default", CC1_ENDIAN_DEFAULT_SPEC }, \ - { "cpp_endian_big", CPP_ENDIAN_BIG_SPEC }, \ - { "cpp_endian_little", CPP_ENDIAN_LITTLE_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \ - { "cpp_float_default", CPP_FLOAT_DEFAULT_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "cpp_os_ads", CPP_OS_ADS_SPEC }, \ - { "cpp_os_yellowknife", CPP_OS_YELLOWKNIFE_SPEC }, \ - { "cpp_os_mvme", CPP_OS_MVME_SPEC }, \ - { "cpp_os_sim", CPP_OS_SIM_SPEC }, \ - { "cpp_os_linux", CPP_OS_LINUX_SPEC }, \ - { "cpp_os_solaris", CPP_OS_SOLARIS_SPEC }, \ -/* CYGNUS LOCAL vmakarov */ \ - { "cpp_os_vxworks", CPP_OS_VXWORKS_SPEC }, \ -/* END CYGNUS LOCAL */ \ - { "cpp_os_default", CPP_OS_DEFAULT_SPEC }, - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" } - -/* Define this macro if the code for function profiling should come - before the function prologue. Normally, the profiling code comes - after. */ -#define PROFILE_BEFORE_PROLOGUE 1 - -/* Function name to call to do profiling. */ -#undef RS6000_MCOUNT -#define RS6000_MCOUNT "_mcount" diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h deleted file mode 100755 index d444a1a..0000000 --- a/gcc/config/rs6000/sysv4le.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Target definitions for GNU compiler for a little endian PowerPC - running System V.4 - Copyright (C) 1995, 1998 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "rs6000/sysv4.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN) - -#undef CPP_ENDIAN_DEFAULT_SPEC -#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_little)" - -#undef CC1_ENDIAN_DEFAULT_SPEC -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)" - -#undef LINK_TARGET_SPEC -#define LINK_TARGET_SPEC "\ -%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{cygnus-local-vmakarov: } \ - %{mcall-i960-old: -oformat elf32-powerpcle} \ - %{end-cygnus-local: } \ - %{mcall-solaris: -oformat elf32-powerpcle} \ - %{mcall-linux: -oformat elf32-powerpc}}}}}" - -/* Define this macro as a C expression for the initializer of an - array of string to tell the driver program which options are - defaults for this target and thus do not need to be handled - specially when using `MULTILIB_OPTIONS'. - - Do not define this macro if `MULTILIB_OPTIONS' is not defined in - the target makefile fragment or if none of the options listed in - `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" } diff --git a/gcc/config/rs6000/t-aix43 b/gcc/config/rs6000/t-aix43 deleted file mode 100755 index 56ddb45..0000000 --- a/gcc/config/rs6000/t-aix43 +++ /dev/null @@ -1,48 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point and all of the -# different processor models - -MULTILIB_OPTIONS = msoft-float \ - mcpu=common/mcpu=power/mcpu=powerpc/maix64 - -MULTILIB_DIRNAMES = soft-float \ - common power powerpc aix64 - -MULTILIB_MATCHES = msoft-float=mcpu?403 \ - maix64=maix64 \ - mcpu?power=mpower \ - mcpu?power=mrios1 \ - mcpu?power=mcpu?rios1 \ - mcpu?power=mcpu?rsc \ - mcpu?power=mcpu?rsc1 \ - mcpu?power=mpower2 \ - mcpu?power=mrios2 \ - mcpu?power=mcpu=rios2 \ - mcpu?powerpc=mcpu?601 \ - mcpu?powerpc=mcpu?602 \ - mcpu?powerpc=mcpu?603 \ - mcpu?powerpc=mcpu?603e \ - mcpu?powerpc=mcpu?604 \ - mcpu?powerpc=mcpu?620 \ - mcpu?powerpc=mcpu?403 \ - mcpu?powerpc=mpowerpc \ - mcpu?powerpc=mpowerpc-gpopt \ - mcpu?powerpc=mpowerpc-gfxopt - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib - diff --git a/gcc/config/rs6000/t-beos b/gcc/config/rs6000/t-beos deleted file mode 100755 index 1436108..0000000 --- a/gcc/config/rs6000/t-beos +++ /dev/null @@ -1,51 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point - -MULTILIB_OPTIONS = msoft-float mcpu=common -MULTILIB_DIRNAMES = soft-float common - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib - -# This is probably the correct define, to override the Makefile -# default, but using it causes more problems than it solves. -# -# Using it will cause fixincludes to try and fix some of the -# mwcc header files, which it seems to do a poor job of. On -# the other hand, not using it will only cause the gcc version -# of limits.h to lack the header and trailer parts that are -# tacked on to it when there is a limits.h in the system header -# dir. -# -# For now it is probably better to change the rule for -# LIMITS_H_TEST to explicitly look for the BeOS limits.h. -# If the gcc limits.h is not set up to #include_next the -# BeOS limits.h, then some things will go undefined, like -# PATH_MAX. - -#SYSTEM_HEADER_DIR=/boot/develop/headers/posix -# Test to see whether <limits.h> exists in the system header files. -LIMITS_H_TEST = [ -f /boot/develop/headers/posix/limits.h ] - -# Aix 3.2.x needs milli.exp for -mcpu=common -EXTRA_PARTS = milli.exp -milli.exp: $(srcdir)/config/rs6000/milli.exp - rm -f milli.exp - cp $(srcdir)/config/rs6000/milli.exp ./milli.exp - -# Don't use collect. -USE_COLLECT2 = diff --git a/gcc/config/rs6000/t-newas b/gcc/config/rs6000/t-newas deleted file mode 100755 index 823b03b..0000000 --- a/gcc/config/rs6000/t-newas +++ /dev/null @@ -1,52 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point and all of the -# different processor models - -MULTILIB_OPTIONS = msoft-float \ - mcpu=common/mcpu=power/mcpu=powerpc - -MULTILIB_DIRNAMES = soft-float \ - common power powerpc - -MULTILIB_MATCHES = msoft-float=mcpu?403 \ - mcpu?power=mpower \ - mcpu?power=mrios1 \ - mcpu?power=mcpu?rios1 \ - mcpu?power=mcpu?rsc \ - mcpu?power=mcpu?rsc1 \ - mcpu?power=mpower2 \ - mcpu?power=mrios2 \ - mcpu?power=mcpu=rios2 \ - mcpu?powerpc=mcpu?601 \ - mcpu?powerpc=mcpu?602 \ - mcpu?powerpc=mcpu?603 \ - mcpu?powerpc=mcpu?603e \ - mcpu?powerpc=mcpu?604 \ - mcpu?powerpc=mcpu?620 \ - mcpu?powerpc=mcpu?403 \ - mcpu?powerpc=mpowerpc \ - mcpu?powerpc=mpowerpc-gpopt \ - mcpu?powerpc=mpowerpc-gfxopt - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib - -# Aix 3.2.x needs milli.exp for -mcpu=common -EXTRA_PARTS = milli.exp -milli.exp: $(srcdir)/config/rs6000/milli.exp - rm -f milli.exp - cp $(srcdir)/config/rs6000/milli.exp ./milli.exp diff --git a/gcc/config/rs6000/t-ppc b/gcc/config/rs6000/t-ppc deleted file mode 100755 index 8143488..0000000 --- a/gcc/config/rs6000/t-ppc +++ /dev/null @@ -1,12 +0,0 @@ -# PowerPC support without gas - -# Build libgcc.a with different options. If no gas support, don't build -# explicit little endian or big endian libraries, since it depends on the -# -mbig/-mlittle switches passed to gas. The -mrelocatable support also needs -# -mrelocatable passed to gas, so don't use it either. - -MULTILIB_OPTIONS = msoft-float -MULTILIB_DIRNAMES = nof -MULTILIB_EXCEPTIONS = -MULTILIB_EXTRA_OPTS = mstrict-align -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} diff --git a/gcc/config/rs6000/t-ppccomm b/gcc/config/rs6000/t-ppccomm deleted file mode 100755 index 9ed1690..0000000 --- a/gcc/config/rs6000/t-ppccomm +++ /dev/null @@ -1,79 +0,0 @@ -# Common support for PowerPC eabi, System V targets. - -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c eabi.S eabi-ctors.c tramp.S - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -eabi.S: $(srcdir)/config/rs6000/eabi.asm - cat $(srcdir)/config/rs6000/eabi.asm > eabi.S - -eabi-ctors.c: $(srcdir)/config/rs6000/eabi-ctors.c - cat $(srcdir)/config/rs6000/eabi-ctors.c > eabi-ctors.c - -tramp.S: $(srcdir)/config/rs6000/tramp.asm - cat $(srcdir)/config/rs6000/tramp.asm > tramp.S - -# Switch synonyms -MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \ - msoft-float=mcpu?403 \ - msoft-float=mcpu?ec603e \ - msoft-float=mcpu?801 \ - msoft-float=mcpu?821 \ - msoft-float=mcpu?823 \ - msoft-float=mcpu?860 -MULTILIB_MATCHES_ENDIAN = mlittle=mlittle-endian mbig=mbig-endian -MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib -EXTRA_MULTILIB_PARTS = ecrti$(objext) ecrtn$(objext) scrt0$(objext) scrti$(objext) scrtn$(objext) - -# We build {e,s}crti.o, {e,s}crtn.o, and scrt0.o which serve to add begin and -# end labels to all of the special sections used when we link using gcc. - -# Assemble startup files. -ecrti.S: $(srcdir)/config/rs6000/eabi-ci.asm - cat $(srcdir)/config/rs6000/eabi-ci.asm >ecrti.S - -ecrtn.S: $(srcdir)/config/rs6000/eabi-cn.asm - cat $(srcdir)/config/rs6000/eabi-cn.asm >ecrtn.S - -scrti.S: $(srcdir)/config/rs6000/sol-ci.asm - cat $(srcdir)/config/rs6000/sol-ci.asm >scrti.S - -scrtn.S: $(srcdir)/config/rs6000/sol-cn.asm - cat $(srcdir)/config/rs6000/sol-cn.asm >scrtn.S - -scrt0.c: $(srcdir)/config/rs6000/sol-c0.c - cat $(srcdir)/config/rs6000/sol-c0.c >scrt0.c - -# Build multiple copies of ?crt{i,n}.o, one for each target switch. -$(T)ecrti$(objext): ecrti.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrti.S -o $(T)ecrti$(objext) - -$(T)ecrtn$(objext): ecrtn.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrtn.S -o $(T)ecrtn$(objext) - -$(T)scrti$(objext): scrti.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrti.S -o $(T)scrti$(objext) - -$(T)scrtn$(objext): scrtn.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrtn.S -o $(T)scrtn$(objext) - -$(T)scrt0$(objext): scrt0.c - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c scrt0.c -o $(T)scrt0$(objext) - -# It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata. -CRTSTUFF_T_CFLAGS = -msdata=none -CRTSTUFF_T_CFLAGS_S = -fpic -msdata=none diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas deleted file mode 100755 index ce4c469..0000000 --- a/gcc/config/rs6000/t-ppcgas +++ /dev/null @@ -1,22 +0,0 @@ -# PowerPC embedded support with gas. -# Build libgcc.a with different options. - -MULTILIB_OPTIONS = msoft-float \ - mlittle/mbig \ - mcall-sysv/mcall-aix/mcall-linux/mcall-i960-old \ - fleading-underscore # CYGNUS local vmakarov: mcall-i960-old and fleading-underscore - -MULTILIB_DIRNAMES = nof \ - le be \ - cs ca lin o960 \ - uns # CYGNUS local vmakarov: o960 and uns - -MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align -MULTILIB_EXCEPTIONS = *mbig/*mcall-linux* \ - *mlittle/*mcall-linux* \ - *msoft-float/*mcall-linux* \ - *mbig/*mcall-i960-old* # CYGNUS local vmakarov - -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ - ${MULTILIB_MATCHES_ENDIAN} \ - ${MULTILIB_MATCHES_SYSV} diff --git a/gcc/config/rs6000/t-ppcos b/gcc/config/rs6000/t-ppcos deleted file mode 100755 index 480665a..0000000 --- a/gcc/config/rs6000/t-ppcos +++ /dev/null @@ -1,12 +0,0 @@ -# Target config file for a System V based system (Solaris, GNU/Linux, Netbsd) -# with gas. - -# Build libgcc.a with different options. With gas, build pic libraries -# as well no floating point -MULTILIB_OPTIONS = msoft-float fPIC -MULTILIB_DIRNAMES = nof pic -MULTILIB_EXCEPTIONS = -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ - fPIC=mrelocatable-lib \ - fPIC=mrelocatable \ - fPIC=fpic diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000 deleted file mode 100755 index 4c659a6..0000000 --- a/gcc/config/rs6000/t-rs6000 +++ /dev/null @@ -1,22 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point - -MULTILIB_OPTIONS = msoft-float -MULTILIB_DIRNAMES = soft-float - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/rs6000/t-vxworks b/gcc/config/rs6000/t-vxworks deleted file mode 100755 index df4f856..0000000 --- a/gcc/config/rs6000/t-vxworks +++ /dev/null @@ -1,3 +0,0 @@ -# Inhibit building libc routines under VxWorks for now - -TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc diff --git a/gcc/config/rs6000/t-winnt b/gcc/config/rs6000/t-winnt deleted file mode 100755 index f58aefe..0000000 --- a/gcc/config/rs6000/t-winnt +++ /dev/null @@ -1,35 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -EXTRA_PARTS = crti.o crtn.o - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c ntstack.S - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -ntstack.S: $(srcdir)/config/rs6000/ntstack.asm - cat $(srcdir)/config/rs6000/ntstack.asm > ntstack.S - -# For NT we build crti.o and crtn.o which serve to add begin and -# end labels for the static constructors and destructors. - -# Assemble startup files. -crti.s: $(srcdir)/config/rs6000/nt-ci.asm - cat $(srcdir)/config/rs6000/nt-ci.asm >crti.s - -crtn.s: $(srcdir)/config/rs6000/nt-cn.asm - cat $(srcdir)/config/rs6000/nt-cn.asm >crtn.s - -crti.o: crti.s - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crti.o crti.s - -crtn.o: crtn.s - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtn.o crtn.s diff --git a/gcc/config/rs6000/t-xnewas b/gcc/config/rs6000/t-xnewas deleted file mode 100755 index 285f825..0000000 --- a/gcc/config/rs6000/t-xnewas +++ /dev/null @@ -1,58 +0,0 @@ -# Same as t-newas, except don't build libgcc1-test. This is because -# the compiler emits code to call external functions to save the -# arguments that are in libc, but since libgcc1-test is linked without -# libc, they will show up as errors. -LIBGCC1_TEST = - -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point and all of the -# different processor models - -MULTILIB_OPTIONS = msoft-float \ - mcpu=common/mcpu=power/mcpu=powerpc - -MULTILIB_DIRNAMES = soft-float \ - common power powerpc - -MULTILIB_MATCHES = msoft-float=mcpu?403 \ - mcpu?power=mpower \ - mcpu?power=mrios1 \ - mcpu?power=mcpu?rios1 \ - mcpu?power=mcpu?rsc \ - mcpu?power=mcpu?rsc1 \ - mcpu?power=mpower2 \ - mcpu?power=mrios2 \ - mcpu?power=mcpu=rios2 \ - mcpu?powerpc=mcpu?601 \ - mcpu?powerpc=mcpu?602 \ - mcpu?powerpc=mcpu?603 \ - mcpu?powerpc=mcpu?603e \ - mcpu?powerpc=mcpu?604 \ - mcpu?powerpc=mcpu?620 \ - mcpu?powerpc=mcpu?403 \ - mcpu?powerpc=mpowerpc \ - mcpu?powerpc=mpowerpc-gpopt \ - mcpu?powerpc=mpowerpc-gfxopt - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib - -# Aix 3.2.x needs milli.exp for -mcpu=common -EXTRA_PARTS = milli.exp -milli.exp: $(srcdir)/config/rs6000/milli.exp - rm -f milli.exp - cp $(srcdir)/config/rs6000/milli.exp ./milli.exp diff --git a/gcc/config/rs6000/t-xrs6000 b/gcc/config/rs6000/t-xrs6000 deleted file mode 100755 index f5d34d6..0000000 --- a/gcc/config/rs6000/t-xrs6000 +++ /dev/null @@ -1,28 +0,0 @@ -# Same as t-rs6000, except don't build libgcc1-test. This is because -# the compiler emits code to call external functions to save the -# arguments that are in libc, but since libgcc1-test is linked without -# libc, they will show up as errors. -LIBGCC1_TEST = - -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -# Build the libraries for both hard and soft floating point - -MULTILIB_OPTIONS = msoft-float -MULTILIB_DIRNAMES = soft-float - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/rs6000/tramp.asm b/gcc/config/rs6000/tramp.asm deleted file mode 100755 index 47ab7d6..0000000 --- a/gcc/config/rs6000/tramp.asm +++ /dev/null @@ -1,120 +0,0 @@ -/* Special support for trampolines - * - * Copyright (C) 1996, 1997 Free Software Foundation, Inc. - * Written By Michael Meissner - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * In addition to the permissions in the GNU General Public License, the - * Free Software Foundation gives you unlimited permission to link the - * compiled version of this file with other programs, and to distribute - * those programs without any restriction coming from the use of this - * file. (The General Public License restrictions do apply in other - * respects; for example, they cover modification of the file, and - * distribution when not linked into another program.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * As a special exception, if you link this library with files - * compiled with GCC to produce an executable, this does not cause - * the resulting executable to be covered by the GNU General Public License. - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - */ - -/* Set up trampolines */ - - .file "tramp.asm" - .section ".text" - #include "ppc-asm.h" - - .globl __trampoline_initial - .type __trampoline_initial,@object - .align 2 -__trampoline_initial: - mflr r0 - bl 1f -.Lfunc = .-__trampoline_initial - .long 0 /* will be replaced with function address */ -.Lchain = .-__trampoline_initial - .long 0 /* will be replaced with static chain */ -1: mflr r11 - mtlr r0 - lwz r0,0(r11) /* function address */ - lwz r11,4(r11) /* static chain */ - mtctr r0 - bctr - -__trampoline_size = .-__trampoline_initial - .size __trampoline_initial,__trampoline_size - - .section ".got2","aw" -.LCTOC1 = .+32768 -.Ltramp = .-.LCTOC1 - .long __trampoline_initial-4 - - .section ".text" -.LCL0: - .long .LCTOC1-.LCF0 - -/* R3 = stack address to store trampoline */ -/* R4 = length of trampoline area */ -/* R5 = function address */ -/* R6 = static chain */ - -FUNC_START(__trampoline_setup) - mflr r0 /* save return address */ - bl .LCF0 /* load up __trampoline_initial into r7 */ -.LCF0: - mflr r11 - lwz r12,(.LCL0-.LCF0)(r11) - add r11,r12,r11 - lwz r7,.Ltramp(r11) /* trampoline address -4 */ - - li r8,__trampoline_size /* verify that the trampoline is big enough */ - cmpw cr1,r8,r4 - srwi r4,r4,2 /* # words to move */ - addi r9,r3,-4 /* adjust pointer for lwzu */ - mtctr r4 - blt cr1,.Labort - - mtlr r0 - - /* Copy the instructions to the stack */ -.Lmove: - lwzu r10,4(r7) - stwu r10,4(r9) - bdnz .Lmove - - /* Store correct function and static chain */ - stw r5,.Lfunc(r3) - stw r6,.Lchain(r3) - - /* Now flush both caches */ - mtctr r4 -.Lcache: - icbi 0,r3 - dcbf 0,r3 - addi r3,r3,4 - bdnz .Lcache - - /* Finally synchronize things & return */ - sync - isync - blr - -.Labort: - bl abort -FUNC_END(__trampoline_setup) -/* END CYGNUS LOCAL -- waiting for FSF sources to be restored/meissner */ diff --git a/gcc/config/rs6000/vxppc.h b/gcc/config/rs6000/vxppc.h deleted file mode 100755 index 83b2348..0000000 --- a/gcc/config/rs6000/vxppc.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Definitions of target machine for GNU compiler. Vxworks PowerPC version. - Copyright (C) 1996, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file just exists to give specs for the PowerPC running on VxWorks. */ - -#include "rs6000/sysv4.h" - -/* CYGNUS LOCAL vmakarov */ -#if 0 -/* END CYGNUS LOCAL */ -/* ??? This file redefines CPP_SPEC which is wrong. It should instead define - one of the extra specs that gets included in CPP_SPEC. For instance, - CPP_OS_DEFAULT_SPEC. The mrelocatable line was copied from CPP_SYSV_SPEC. - There is probably other stuff missing. */ - -#undef CPP_SPEC -#define CPP_SPEC "\ -%{posix: -D_POSIX_SOURCE} \ -%{mrelocatable*: -D_RELOCATABLE} \ -%{!mcpu*: \ - %{mpowerpc*: -D_ARCH_PPC -DCPU=PPC603} \ - %{!mno-powerpc: -D_ARCH_PPC -DCPU=PPC603}} \ -%{mcpu=powerpc: -D_ARCH_PPC -DCPU=PPC603} \ -%{mcpu=403: -D_ARCH_PPC -DCPU=PPC403} \ -%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR -DCPU=PPC601} \ -%{mcpu=603: -D_ARCH_PPC -DCPU=PPC603} \ -%{mcpu=604: -D_ARCH_PPC -DCPU=PPC604}" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "\ --D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \ --Acpu(powerpc) -Amachine(powerpc)" - -/* VxWorks does all the library stuff itself. */ - -#undef LIB_SPEC -#define LIB_SPEC "" - -/* VxWorks uses object files, not loadable images. make linker just - combine objects. */ - -#undef LINK_SPEC -#define LINK_SPEC "-r" - -/* VxWorks provides the functionality of crt0.o and friends itself. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "" - -/* CYGNUS LOCAL vmakarov */ -#endif - -/* Reset defaults */ -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_vxworks)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "\ --D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \ --Acpu(powerpc) -Amachine(powerpc)" - -/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */ -#undef CPP_ENDIAN_BIG_SPEC -#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)" - -#undef CPP_ENDIAN_LITTLE_SPEC -#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" -/* END CYGNUS LOCAL */ - -/* We use stabs-in-elf for debugging */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/gcc/config/rs6000/vxppcle.h b/gcc/config/rs6000/vxppcle.h deleted file mode 100755 index fadec99..0000000 --- a/gcc/config/rs6000/vxppcle.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Definitions of target machine for GNU compiler. Vxworks PowerPC version. - Copyright (C) 1996, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file just exists to give specs for the PowerPC running on VxWorks. */ - -#include "rs6000/sysv4le.h" - -/* Reset defaults */ -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_vxworks)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "\ --D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \ --Acpu(powerpc) -Amachine(powerpc)" - -/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */ -#undef CPP_ENDIAN_BIG_SPEC -#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)" - -#undef CPP_ENDIAN_LITTLE_SPEC -#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" - -/* We use stabs-in-elf for debugging */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h deleted file mode 100755 index 742a5e8..0000000 --- a/gcc/config/rs6000/win-nt.h +++ /dev/null @@ -1,481 +0,0 @@ -/* Definitions of target machine for GNU compiler, for PowerPC - running Windows/NT. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Say this is Windows/NT for the other config files. */ -#define WINDOWS_NT 1 -#define COFF_WITH_PE 1 - -/* Default ABI to compile code for */ -#define DEFAULT_ABI ABI_NT - -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#define ASM_DEFAULT_SPEC "-mppc" - -/* Pseudo target that we can test in the md file. */ -#define TARGET_WINDOWS_NT 1 - -#include "rs6000/rs6000.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWERPC - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DWIN32 -D_WIN32 \ - -DWINNT -D__STDC__=0 -DALMOST_STDC \ - -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)" - -#if 0 -#include "winnt/win-nt.h" -#endif - -#undef LIB_SPEC -#define LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \ - USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \ - %{!mwindows:-subsystem console -e mainCRTStartup} \ - %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \ - %{v}" - -#undef LINK_SPEC -#define LINK_SPEC "%{v:-V}" - -/* Allow switches specified in LIB_SPEC, but don't do anything with them - in the compiler. */ -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - { "windows", 0 }, \ - { "crtmt", 0 }, - -#undef XCOFF_DEBUGGING_INFO - -/* this is pure coff, not xcoff */ -#define SDB_DEBUGGING_INFO -#define DBX_DEBUGGING_INFO - -#undef SDB_DELIM -#define SDB_DELIM ";" - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -/* NT always runs little endian */ -#undef BYTES_BIG_ENDIAN -#define BYTES_BIG_ENDIAN 0 - -#undef WORDS_BIG_ENDIAN -#define WORDS_BIG_ENDIAN 0 - -/* Define cutoff for using external functions to save floating point. - Currently on NT, always use inline stores */ -#undef FP_SAVE_INLINE -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) - -/* Note, little endian systems trap on unaligned addresses, so never - turn off strict alignment in that case. */ - -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT 1 - -/* Align stack to 16 byte boundaries */ -#undef STACK_BOUNDARY -#define STACK_BOUNDARY 128 - -/* No data type wants to be aligned rounder than this. */ -#undef BIGGEST_ALIGNMENT -#define BIGGEST_ALIGNMENT 128 - -/* NT aligns internal doubles in structures on dword boundaries. */ -#undef BIGGEST_FIELD_ALIGNMENT -#define BIGGEST_FIELD_ALIGNMENT 64 - -#undef ADJUST_FIELD_ALIGN -#undef ROUND_TYPE_ALIGN - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC PE)"); - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC) - -/* Address to save the TOC register */ -#undef RS6000_SAVE_TOC -#define RS6000_SAVE_TOC plus_constant (virtual_incoming_args_rtx, -RS6000_SAVE_AREA - 8) - -/* Windows NT specifies that r13 is reserved to the OS, so it is not available - to the normal user. */ - -#undef FIXED_R13 -#define FIXED_R13 1 - -/* This says how to output an assembler line - to define a global common symbol. */ - -#undef ASM_OUTPUT_ALIGNED_COMMON -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \ - do { fputs ("\t.comm \t", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - if ( (SIZE) > 4) \ - fprintf ((FILE), ",%d,%d\n", (SIZE), 3); \ - else \ - fprintf( (FILE), ",%d\n", (SIZE)); \ - } while (0) - -#undef ASM_OUTPUT_ALIGNED_LOCAL - -/* This says how to output an assembler line - to define a global common symbol. */ - -#undef ASM_OUTPUT_COMMON -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ - do { fputs ("\t.comm \t", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%d\n", (SIZE)); } while (0) - -/* This says how to output an assembler line - to define an aligned local common symbol. */ - -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ -do { \ - bss_section (); \ - ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - ASM_OUTPUT_SKIP (FILE, SIZE); \ -} while (0) - -/* Describe how to emit uninitialized external linkage items */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ -do { \ - ASM_GLOBALIZE_LABEL (FILE, NAME); \ - ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ -} while (0) - -/* This says out to put a global symbol in the BSS section */ -#undef ASM_OUTPUT_ALIGNED_BSS -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ - asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) - - -/* Stuff to force fit us into the Motorola PPC assembler */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -do { \ - output_file_directive ((FILE), main_input_filename); \ - rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ - data_section (); \ -} while (0) - -#undef ASM_FILE_END - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ -{ \ - tree exception_args; \ - int i; \ - \ - if (TREE_PUBLIC (DECL)) \ - { \ - fprintf (FILE, "\t.globl .."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - \ - fprintf (FILE, "\n#\tFunction: '.."); \ - assemble_name (FILE, NAME); \ - fputs ("'\n", FILE); \ - fputs ("#\tText in section: <default>\n\n", FILE); \ - fputs ("#\tSetup MS Structured-Exception-Handling\n", FILE); \ - fputs ("\t.pdata\n", FILE); \ - fputs ("\t.align 2\n", FILE); \ - fputs ("\t.ualong ..", FILE); \ - assemble_name (FILE, NAME); \ - fputs (",", FILE); \ - assemble_name (FILE, NAME); \ - fputs (".e,", FILE); \ - exception_args = lookup_attribute ("exception", \ - TYPE_ATTRIBUTES (TREE_TYPE (DECL))); \ - \ - if (exception_args) \ - exception_args = TREE_VALUE (exception_args); \ - \ - for (i = 0; i < 2; i++) \ - { \ - if (!exception_args) \ - fputs ("0,", FILE); \ - else \ - { \ - tree field = TREE_VALUE (exception_args); \ - exception_args = TREE_PURPOSE (exception_args); \ - if (TREE_CODE (field) == STRING_CST) \ - fprintf (FILE, "%.*s,", TREE_STRING_LENGTH (field), \ - TREE_STRING_POINTER (field)); \ - else if (TREE_CODE (field) == IDENTIFIER_NODE) \ - fprintf (FILE, "%.*s,", IDENTIFIER_LENGTH (field), \ - IDENTIFIER_POINTER (field)); \ - else \ - abort (); \ - } \ - } \ - \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ".b\n\n"); \ - fprintf (FILE, "#\tSwitch to the relocation section\n"); \ - fprintf (FILE, "\t.reldata\n"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n"); \ - fprintf (FILE, "\t.ualong .."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",.toc\n"); \ - \ - if (lookup_attribute ("dllexport", \ - TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \ - { \ - fprintf (FILE, "\t.globl __imp_"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n__imp_"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n\t.ulong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - \ - fprintf (FILE, "\t.section .text\n\t.align 2\n.."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n"); \ - fprintf (FILE, "\t.function\t.."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ -} - -/* This is how to output an assembler line defining a `double' constant. */ - -#undef ASM_OUTPUT_DOUBLE -#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t.ualong 0x%lx\n\t.long 0x%lx\n", \ - t[0] & 0xffffffff, t[1] & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \ - fprintf (FILE, "\t.double %s\n", str); \ - } \ - } - -/* This is how to output an assembler line defining a `float' constant. */ - -#undef ASM_OUTPUT_FLOAT -#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.ualong 0x%lx\n", t & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t.float %s\n", str); \ - } \ - } - -/* Output before instructions. */ -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP "\t.text" - -/* Output before writable data. */ -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP "\t.data" - -/* Output to the bss section. */ -#undef BSS_SECTION_ASM_OP -#define BSS_SECTION_ASM_OP "\t.section .bss" - -/* Define the extra sections we need. We define a dummy TOC section, - plus sections to hold the list of static constructors (.ctors) and - destructors (.dtors). */ - -#undef READONLY_DATA_SECTION -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_toc, in_ctors, in_dtors - -/* Define the routines to implement these extra sections. */ - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION \ - TOC_SECTION_FUNCTION \ - -#define TOC_SECTION_FUNCTION \ -void \ -toc_section () \ -{ \ -} - -#define CTORS_SECTION_ASM_OP ".section\t.ctors" -#define CTORS_SECTION_FUNCTION \ -void \ -ctors_section () \ -{ \ - if (in_section != in_ctors) \ - { \ - fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ - in_section = in_ctors; \ - } \ -} - -#define DTORS_SECTION_ASM_OP ".section\t.dtors" -#define DTORS_SECTION_FUNCTION \ -void \ -dtors_section () \ -{ \ - if (in_section != in_dtors) \ - { \ - fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ - in_section = in_dtors; \ - } \ -} - -#undef SELECT_SECTION -#undef SELECT_RTX_SECTION - -/* Make sure __main gets called */ -#define INVOKE__main 1 - -/* A C statement (sans semicolon) to output an element in the table of - global constructors. */ -#undef ASM_OUTPUT_CONSTRUCTOR -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctors_section (); \ - fprintf (FILE, "\t.ualong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* A C statement (sans semicolon) to output an element in the table of - global destructors. */ -#undef ASM_OUTPUT_DESTRUCTOR -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtors_section (); \ - fprintf (FILE, "\t.ualong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - - -/* Text to write out after a CALL that may be replaced by glue code by - the loader. The motorola asm demands that, for dll support, a .znop - be issued after a bl instruction, and the symbol on the .znop is the - symbol on the bl instruction */ - -#undef RS6000_CALL_GLUE -#define RS6000_CALL_GLUE "nop #\tFIXME: only works for non-dll calls." - -#define RS6000_CALL_GLUE2 ".znop " - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY - -/* Output something to declare an external symbol to the assembler. Most - assemblers don't need this. */ - -#undef ASM_OUTPUT_EXTERNAL - -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ \ - char *_name; \ - rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - _name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - XSTR (_symref, 0) = _name; \ - } \ - else \ - _name = XSTR (_symref, 0); \ - \ - if (DECL_FUNCTION_CODE (DECL) == 0) \ - { \ - fputs ("\t.extern ", FILE); \ - assemble_name (FILE, _name); \ - putc ('\n', FILE); \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - { \ - fputs ("\t.extern ..", FILE); \ - assemble_name (FILE, _name); \ - putc ('\n', FILE); \ - } \ - } \ -} - -/* Similar, but for libcall. We only have to worry about the function name, - not that of the descriptor. */ - -#undef ASM_OUTPUT_EXTERNAL_LIBCALL - -#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ -{ fprintf (FILE, "\t.extern .."); \ - assemble_name (FILE, XSTR (FUN, 0)); \ - fprintf (FILE, "\n"); \ -} - -/* The prefix to add to user-visible assembler symbols. */ - -#define USER_LABEL_PREFIX ".." - -/* Eliminate AIX style constant pool processing */ -#undef LEGITIMATE_CONSTANT_POOL_BASE_P -#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) 0 - -#undef LEGITIMATE_CONSTANT_POOL_ADDRESS_P -#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) 0 - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY - -#undef ASM_IDENTIFY_GCC -#define ASM_IDENTIFY_GCC(x) - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - The trampoline should set the static chain pointer to value placed - into the trampoline and should branch to the specified routine. */ -#define TRAMPOLINE_TEMPLATE(FILE) rs6000_trampoline_template (FILE) diff --git a/gcc/config/rs6000/x-aix31 b/gcc/config/rs6000/x-aix31 deleted file mode 100755 index 9f171fc..0000000 --- a/gcc/config/rs6000/x-aix31 +++ /dev/null @@ -1,9 +0,0 @@ -# configuration for IBM rs6000 running aix -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# For some reason, we need -lm for cc1. -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lm -lld diff --git a/gcc/config/rs6000/x-aix41 b/gcc/config/rs6000/x-aix41 deleted file mode 100755 index 69c666b..0000000 --- a/gcc/config/rs6000/x-aix41 +++ /dev/null @@ -1,12 +0,0 @@ -# configuration for IBM RS/6000 running AIX 4.1+ - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lld - -# f771 and cc1plus overflow the AIX TOC -BOOT_LDFLAGS=-Wl,-bbigtoc diff --git a/gcc/config/rs6000/x-aix43 b/gcc/config/rs6000/x-aix43 deleted file mode 100755 index 072d925..0000000 --- a/gcc/config/rs6000/x-aix43 +++ /dev/null @@ -1,15 +0,0 @@ -# configuration for IBM RS/6000 running AIX 4.3+ - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lld - -# f771 and cc1plus overflow the AIX TOC -BOOT_LDFLAGS=-Wl,-bbigtoc - -# Both 32-bit and 64-bit objects in archives -AR_FOR_TARGET=ar -X32_64 diff --git a/gcc/config/rs6000/x-beos b/gcc/config/rs6000/x-beos deleted file mode 100755 index 37b8cca..0000000 --- a/gcc/config/rs6000/x-beos +++ /dev/null @@ -1,9 +0,0 @@ -# configuration for BeOS -INSTALL=install -c - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o -# Use it regardless of whether we are compiling with gcc or not. -USE_ALLOCA= `echo "${ALLOCA}"` -USE_HOST_ALLOCA= `echo ${HOST_PREFIX}${HOST_ALLOCA}` -SUBDIR_USE_ALLOCA = `if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi` diff --git a/gcc/config/rs6000/x-cygwin b/gcc/config/rs6000/x-cygwin deleted file mode 100755 index 5e796a0..0000000 --- a/gcc/config/rs6000/x-cygwin +++ /dev/null @@ -1,4 +0,0 @@ -# Don't run fixproto -STMP_FIXPROTO = -# Don't need collect2 -USE_COLLECT2 = diff --git a/gcc/config/rs6000/x-lynx b/gcc/config/rs6000/x-lynx deleted file mode 100755 index a1a2a73..0000000 --- a/gcc/config/rs6000/x-lynx +++ /dev/null @@ -1,14 +0,0 @@ -# /bin/cc is hopelessly broken, so we must use /bin/gcc instead. -CC = $(OLDCC) -OLDCC = /bin/gcc - -# /bin/sh is too buggy, so use /bin/bash instead. -SHELL = /bin/bash - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# configuration for IBM rs6000 running lynx - -# For some reason, we need -lm for cc1. -CLIB=-lm diff --git a/gcc/config/rs6000/x-mach b/gcc/config/rs6000/x-mach deleted file mode 100755 index 64f39a5..0000000 --- a/gcc/config/rs6000/x-mach +++ /dev/null @@ -1,7 +0,0 @@ -# configuration for IBM rs6000 running MACH - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# For some reason, we need -lm for cc1. -CLIB=-lm diff --git a/gcc/config/rs6000/x-rs6000 b/gcc/config/rs6000/x-rs6000 deleted file mode 100755 index 0d8f311..0000000 --- a/gcc/config/rs6000/x-rs6000 +++ /dev/null @@ -1,9 +0,0 @@ -# configuration for IBM rs6000 running aix - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lld diff --git a/gcc/config/rs6000/x-sysv4 b/gcc/config/rs6000/x-sysv4 deleted file mode 100755 index 2a661e3..0000000 --- a/gcc/config/rs6000/x-sysv4 +++ /dev/null @@ -1,2 +0,0 @@ -X_CFLAGS=-DSVR4 -ALLOCA=alloca.o diff --git a/gcc/config/rs6000/xm-beos.h b/gcc/config/rs6000/xm-beos.h deleted file mode 100755 index 681aa73..0000000 --- a/gcc/config/rs6000/xm-beos.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Configuration for GNU C-compiler for BeOS host. - Copyright (C) 1997 Free Software Foundation, Inc. - Contributed by Fred Fish (fnf@cygnus.com), based on xm-rs6000.h - by Richard Kenner (kenner@vlsi1.ultra.nyu.edu). - - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* #defines that need visibility everywhere. */ - -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ - -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -#define HOST_WORDS_BIG_ENDIAN - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ - -#include "tm.h" - -/* Arguments to use with `exit'. */ - -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* Use the C alloca and use only int bitfields. */ - -#define USE_C_ALLOCA -extern void *alloca (); -#define ONLY_INT_FIELDS - -/* use ANSI/SYSV style byte manipulation routines instead of BSD ones */ - -#undef bcopy -#define bcopy(s,d,n) memmove((d),(s),(n)) -#undef bzero -#define bzero(d,n) memset((d),0,(n)) -#undef bcmp -#define bcmp(l,r,n) memcmp((l),(r),(n)) -#undef index -#define index strchr -#undef rindex -#define rindex strrchr - -/* BeOS is closer to USG than BSD */ - -#define USG - -/* Define various things that the BeOS host has. */ - -#define HAVE_VPRINTF -#define HAVE_PUTENV -#define HAVE_ATEXIT -#define HAVE_RENAME - -#define STDC_HEADERS 1 - -/* STANDARD_INCLUDE_DIR is the equivalent of "/usr/include" on UNIX. */ - -#define STANDARD_INCLUDE_DIR "/boot/develop/headers/posix" - -/* SYSTEM_INCLUDE_DIR is the location for system specific, non-POSIX headers. */ - -#define SYSTEM_INCLUDE_DIR "/boot/develop/headers/be" - diff --git a/gcc/config/rs6000/xm-cygwin.h b/gcc/config/rs6000/xm-cygwin.h deleted file mode 100755 index ca54831..0000000 --- a/gcc/config/rs6000/xm-cygwin.h +++ /dev/null @@ -1 +0,0 @@ -#define EXECUTABLE_SUFFIX ".exe" diff --git a/gcc/config/rs6000/xm-lynx.h b/gcc/config/rs6000/xm-lynx.h deleted file mode 100755 index 1c093c2..0000000 --- a/gcc/config/rs6000/xm-lynx.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Configuration for GNU C-compiler for rs6000 platforms running LynxOS. - Copyright (C) 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include <xm-lynx.h> - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -#define HOST_WORDS_BIG_ENDIAN 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ - -#include "tm.h" diff --git a/gcc/config/rs6000/xm-mach.h b/gcc/config/rs6000/xm-mach.h deleted file mode 100755 index 2d4ee5d..0000000 --- a/gcc/config/rs6000/xm-mach.h +++ /dev/null @@ -1,2 +0,0 @@ -#undef USG -#undef COLLECT_EXPORT_LIST diff --git a/gcc/config/rs6000/xm-rs6000.h b/gcc/config/rs6000/xm-rs6000.h deleted file mode 100755 index 1ad9da9..0000000 --- a/gcc/config/rs6000/xm-rs6000.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Configuration for GNU C-compiler for IBM RS/6000 running AIX in 32-bit mode. - Copyright (C) 1990, 1993, 1995, 1998 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -#define HOST_WORDS_BIG_ENDIAN - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If not compiled with GNU C, use the C alloca and use only int bitfields. */ -#ifndef __GNUC__ -#define USE_C_ALLOCA -#if __STDC__ -extern void *alloca (); -#else -extern char *alloca (); -#endif -#define ONLY_INT_FIELDS -#endif - -/* AIX is a flavor of System V */ -#define USG - -/* Big buffers improve performance. */ -#define IO_BUFFER_SIZE (0x8000 - 4096) - -#ifndef CROSS_COMPILE -/* The AIX linker will discard static constructors in object files before - collect has a chance to see them, so scan the object files directly. */ -#define COLLECT_EXPORT_LIST -#endif diff --git a/gcc/config/rs6000/xm-sysv4.h b/gcc/config/rs6000/xm-sysv4.h deleted file mode 100755 index cf56eb4..0000000 --- a/gcc/config/rs6000/xm-sysv4.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Configuration for GNU C-compiler for PowerPC running System V.4. - Copyright (C) 1995, 1998 Free Software Foundation, Inc. - - Cloned from sparc/xm-sysv4.h by Michael Meissner (meissner@cygnus.com). - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#if 0 -#define HOST_BITS_PER_LONGLONG 64 -#endif - -/* Doubles are stored in memory with the high order word first. This - matters when cross-compiling. */ -#define HOST_WORDS_BIG_ENDIAN 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -#ifdef __linux__ -#include "xm-linux.h" -#endif - -/* if not compiled with GNU C, use the C alloca and use only int bitfields. */ -#ifndef __GNUC__ -#define USE_C_ALLOCA -#ifdef __STDC__ -extern void *alloca (); -#else -extern char *alloca (); -#endif -#undef ONLY_INT_FIELDS -#define ONLY_INT_FIELDS -#endif - -#ifdef __PPC__ -#ifndef __STDC__ -extern char *malloc (), *realloc (), *calloc (); -#else -extern void *malloc (), *realloc (), *calloc (); -#endif -extern void free (); -#endif |