Commit a260abc9 by David Edelsohn Committed by David Edelsohn

tree.c (get_inner_array_type): New function.

Thu Jun  4 14:35:27 1998  David Edelsohn  <edelsohn@mhpcc.edu>
	* tree.c (get_inner_array_type): New function.
	* tree.h (get_inner_array_type): Prototype.
	* expr.h (STACK_SAVEAREA_MODE): New macro.
	* expr.c (expand_builtin_setjmp): Initialize sa_mode using
	STACK_SAVEAREA_MODE.
	(expand_builtin_longjmp): Likewise.
	* explow.c (emit_stack_save): Likewise.
	(allocate_dynamic_stack_space): Use Pmode not insn_operand_mode.
	* rs6000/aix41.h (ASM_CPU_SPEC): Define relative to ASM_DEFAULT_SPEC.
	(CPP_CPU_SPEC): Define relative to CPU_DEFAULT_SPEC.
	* rs6000/aix43.h: New file.
	* rs6000/t-aix43: New file.
	* rs6000/x-aix41: New file.
	* rs6000/x-aix43: New file.
	* configure.in (rs6000-ibm-aix*): Use them.
	* rs6000/powerpc.h: Delete.
	* rs6000/sysv4.h: Move necessary powerpc.h definitions to here.
	* rs6000/netware.h: and here.
	* rs6000/win-nt.h: and here.
	* rs6000/rs6000.c (processor_target_table, 620): Do not affect
	MASK_POWERPC64.
	(rs6000_override_options): Ignore flag_pic for AIX.
	(rs6000_immed_double_const): Delete.
	(u_short_cint_operand): Don't assume 32-bit CONST_INT.
	(reg_or_u_short_operand): Don't assume 32-bit CONST_INT.
	(num_insns_constant): mask64_operand() is 2 insns.
	(logical_operand): Don't assume 32-bit CONST_INT.
	(non_logical_cint_operand): Don't assume 32-bit CONST_INT.
	(easy_fp_constant): Any CONST_DOUBLE_HIGH is okay for 64-bit.
	(mask_constant): HOST_WIDE_INT parameter.
	(non_and_cint_operand): Delete.
	(mask64_operand): New function.
	(and64_operand): New function.
	(function_arg_advance): DImode arguments do not need special
	alignment when 64-bit.
	(function_arg): Likewise.
	(setup_incoming_varargs): Reverse reg_size assignment.
	(print_operand): HOST_WIDE_INT second parameter.
	(print_operand, 'B'): New case.
	(print_operand, 'M'): Fix typo in lossage string.
	(print_operandm 'S'): New case.
	(rs6000_stack_info): Reverse reg_size assignment.  Use total_raw_size
	to compute AIX push_p.  Use reg_size to compute {cr,lr}_save_offset.
	(rs6000_output_load_toc_table): Reverse init_ptr assignment.  Use
	TARGET_64BIT not TARGET_POWERPC64.  Convert fprintf to fputs.
	Load GOT highpart, don't add it.  Add lowpart with {cal|la}.
	(rs6000_allocate_stack_space): Use {cal|la}.
	(output_epilog): Use {cal|la}
	(output_function_profiler): Add call glue to mcount call.
	Load GOT highpart, don't add it.  Add lowpart with {cal|la}.
	* rs6000/rs6000.h (TARGET_SWITCHES): Add powerpc64.
	(STACK_BOUNDARY): Depend on TARGET_32BIT.
	(ADJUST_FIELD_ALIGN): Calculate array alignment using innermost type.
	(CONST_OK_FOR_LETTER_P): Don't assume 32-bit CONST_INT.
	(EXTRA_CONSTRAINTS): Remove NT 'S' and 'T'.  Replace 'S' with
	64-bit mask operand.
	(RS6000_SAVE_TOC): Depend on TARGET_32BIT.
	(STACK_SAVEAREA_MODE): New macro.
	(LEGITIMATE_CONSTANT_P): DImode okay for 64bit.
	(LEGITIMIZE_RELOAD_ADDRESS): New macro.
	(RTX_COSTS, AND/IOR/XOR): Reflect current machine description.
	(ASM_FILE_START): Emit 64-bit ABI directive.
	(ASM_DECLARE_FUNCTION_NAME): Align CSECT on doubleword in 64-bit mode.
	(ASM_OUTPUT_SPECIAL_POOL_ENTRY): DImode okay for 64-bit.
	(PREDICATE_CODES): Add "and64_operand" and "mask64_operand".
	Delete "non_and_cint_operand".  "input_operand" includes CONST_DOUBLE.
	* rs6000/rs6000.md (iorsi3, xorsi3): Use HOST_WIDE_INT for mask.
	Restore define_splits.
	(floatsidf2, floatunssidf2): Remove !TARGET_POWERPC64 final constraint.
	(floatsidf2_internal, floatunssidf2_internal2): Likewise.
	Do not specify base register operand mode.
	(floatsidf2_loadaddr): Do not specify base register operand mode.
	(floatsidf2_store1, floatsidf2_store2): Operand 1 must be base
	register; do not specify mode.  Remove !TARGET_POWERPC64 final
	constraint.
	(floatsidf2_load): Do not specify base register operand mode.  Remove
	!TARGET_POWERPC64 final constraint.
	(fix_truncdfsi2_internal, fix_truncdfsi2_{store,load}): Do not specify
	base register operand mode.
	(adddi3): Split large constants early.
	(absdi3): Shift by 63, not 31.
	(*mulsidi3_ppc64): New pattern.
	(rotldi3): Add masking combiner patterns.
	(anddi3): Add rldic{r,l} masking.  Remove split of large constants
	because PPC insns zero-extend.
	(iordi3, xordi3): Split large constants early.
	(movsi matcher): Remove S and T constraints.
	(movsf const_double): create SImode constant from TARGET_DOUBLE.
	(movdf_hardfloat32): Add default abort() case.
	(movdf easy_fp_const): create DImode constant from TARGET_DOUBLE.
	(movdi): Remove 64-bit constant generator.  Try to convert
	CONST_DOUBLE to CONST_INT.  Handle TOC memory constants.
	(movdi_32): Add default abort() case.
	(movdi_64): Add numerous ways to split 64-bit constants.
	Make catch-all define_split more optimal and never FAIL.
	(movti_ppc64): Add default abort() case.
	(allocate_stack): Remove operand modes.  Use Pmode.
	(restore_stack_block): Remove operand modes.  Generate Pmode
	temporary.
	(save_stack_nonlocal, restore_stack_nonlocal):  Generate Pmode
	temporary.  Save area is double Pmode.
	(call_indirect_aix64, call_value_indirect_aix64): New patterns.
	(call, call_value): Do not specify address operand mode.  Choose
	appropriate AIX ABI.
	(*call_local64, *ret_call_local64): New patterns.
	(*call_nonlocal_aix64, *ret_call_nonlocal_aix64): New patterns.
	(*ret_call_nonlocal_aix32): Use call_value_indirect for REG.
	(compare): Materialize DImode truthvalues.

From-SVN: r20229
parent a66c6fe2
Thu Jun 4 14:35:27 1998 David Edelsohn <edelsohn@mhpcc.edu>
* tree.c (get_inner_array_type): New function.
* tree.h (get_inner_array_type): Prototype.
* expr.h (STACK_SAVEAREA_MODE): New macro.
* expr.c (expand_builtin_setjmp): Initialize sa_mode using
STACK_SAVEAREA_MODE.
(expand_builtin_longjmp): Likewise.
* explow.c (emit_stack_save): Likewise.
(allocate_dynamic_stack_space): Use Pmode not insn_operand_mode.
* rs6000/aix41.h (ASM_CPU_SPEC): Define relative to ASM_DEFAULT_SPEC.
(CPP_CPU_SPEC): Define relative to CPU_DEFAULT_SPEC.
* rs6000/aix43.h: New file.
* rs6000/t-aix43: New file.
* rs6000/x-aix41: New file.
* rs6000/x-aix43: New file.
* configure.in (rs6000-ibm-aix*): Use them.
* rs6000/powerpc.h: Delete.
* rs6000/sysv4.h: Move necessary powerpc.h definitions to here.
* rs6000/netware.h: and here.
* rs6000/win-nt.h: and here.
* rs6000/rs6000.c (processor_target_table, 620): Do not affect
MASK_POWERPC64.
(rs6000_override_options): Ignore flag_pic for AIX.
(rs6000_immed_double_const): Delete.
(u_short_cint_operand): Don't assume 32-bit CONST_INT.
(reg_or_u_short_operand): Don't assume 32-bit CONST_INT.
(num_insns_constant): mask64_operand() is 2 insns.
(logical_operand): Don't assume 32-bit CONST_INT.
(non_logical_cint_operand): Don't assume 32-bit CONST_INT.
(easy_fp_constant): Any CONST_DOUBLE_HIGH is okay for 64-bit.
(mask_constant): HOST_WIDE_INT parameter.
(non_and_cint_operand): Delete.
(mask64_operand): New function.
(and64_operand): New function.
(function_arg_advance): DImode arguments do not need special
alignment when 64-bit.
(function_arg): Likewise.
(setup_incoming_varargs): Reverse reg_size assignment.
(print_operand): HOST_WIDE_INT second parameter.
(print_operand, 'B'): New case.
(print_operand, 'M'): Fix typo in lossage string.
(print_operandm 'S'): New case.
(rs6000_stack_info): Reverse reg_size assignment. Use total_raw_size
to compute AIX push_p. Use reg_size to compute {cr,lr}_save_offset.
(rs6000_output_load_toc_table): Reverse init_ptr assignment. Use
TARGET_64BIT not TARGET_POWERPC64. Convert fprintf to fputs.
Load GOT highpart, don't add it. Add lowpart with {cal|la}.
(rs6000_allocate_stack_space): Use {cal|la}.
(output_epilog): Use {cal|la}
(output_function_profiler): Add call glue to mcount call.
Load GOT highpart, don't add it. Add lowpart with {cal|la}.
* rs6000/rs6000.h (TARGET_SWITCHES): Add powerpc64.
(STACK_BOUNDARY): Depend on TARGET_32BIT.
(ADJUST_FIELD_ALIGN): Calculate array alignment using innermost type.
(CONST_OK_FOR_LETTER_P): Don't assume 32-bit CONST_INT.
(EXTRA_CONSTRAINTS): Remove NT 'S' and 'T'. Replace 'S' with
64-bit mask operand.
(RS6000_SAVE_TOC): Depend on TARGET_32BIT.
(STACK_SAVEAREA_MODE): New macro.
(LEGITIMATE_CONSTANT_P): DImode okay for 64bit.
(LEGITIMIZE_RELOAD_ADDRESS): New macro.
(RTX_COSTS, AND/IOR/XOR): Reflect current machine description.
(ASM_FILE_START): Emit 64-bit ABI directive.
(ASM_DECLARE_FUNCTION_NAME): Align CSECT on doubleword in 64-bit mode.
(ASM_OUTPUT_SPECIAL_POOL_ENTRY): DImode okay for 64-bit.
(PREDICATE_CODES): Add "and64_operand" and "mask64_operand".
Delete "non_and_cint_operand". "input_operand" includes CONST_DOUBLE.
* rs6000/rs6000.md (iorsi3, xorsi3): Use HOST_WIDE_INT for mask.
Restore define_splits.
(floatsidf2, floatunssidf2): Remove !TARGET_POWERPC64 final constraint.
(floatsidf2_internal, floatunssidf2_internal2): Likewise.
Do not specify base register operand mode.
(floatsidf2_loadaddr): Do not specify base register operand mode.
(floatsidf2_store1, floatsidf2_store2): Operand 1 must be base
register; do not specify mode. Remove !TARGET_POWERPC64 final
constraint.
(floatsidf2_load): Do not specify base register operand mode. Remove
!TARGET_POWERPC64 final constraint.
(fix_truncdfsi2_internal, fix_truncdfsi2_{store,load}): Do not specify
base register operand mode.
(adddi3): Split large constants early.
(absdi3): Shift by 63, not 31.
(*mulsidi3_ppc64): New pattern.
(rotldi3): Add masking combiner patterns.
(anddi3): Add rldic{r,l} masking. Remove split of large constants
because PPC insns zero-extend.
(iordi3, xordi3): Split large constants early.
(movsi matcher): Remove S and T constraints.
(movsf const_double): create SImode constant from TARGET_DOUBLE.
(movdf_hardfloat32): Add default abort() case.
(movdf easy_fp_const): create DImode constant from TARGET_DOUBLE.
(movdi): Remove 64-bit constant generator. Try to convert
CONST_DOUBLE to CONST_INT. Handle TOC memory constants.
(movdi_32): Add default abort() case.
(movdi_64): Add numerous ways to split 64-bit constants.
Make catch-all define_split more optimal and never FAIL.
(movti_ppc64): Add default abort() case.
(allocate_stack): Remove operand modes. Use Pmode.
(restore_stack_block): Remove operand modes. Generate Pmode
temporary.
(save_stack_nonlocal, restore_stack_nonlocal): Generate Pmode
temporary. Save area is double Pmode.
(call_indirect_aix64, call_value_indirect_aix64): New patterns.
(call, call_value): Do not specify address operand mode. Choose
appropriate AIX ABI.
(*call_local64, *ret_call_local64): New patterns.
(*call_nonlocal_aix64, *ret_call_nonlocal_aix64): New patterns.
(*ret_call_nonlocal_aix32): Use call_value_indirect for REG.
(compare): Materialize DImode truthvalues.
Thu Jun 4 01:26:57 1998 Craig Burley <burley@gnu.org> Thu Jun 4 01:26:57 1998 Craig Burley <burley@gnu.org>
* expr.c (safe_from_p): Avoid combinatorial explosion * expr.c (safe_from_p): Avoid combinatorial explosion
......
/* Definitions of target machine for GNU compiler, /* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX version 4.1. for IBM RS/6000 POWER running AIX version 4.1.
Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@npac.syr.edu). Contributed by David Edelsohn (edelsohn@npac.syr.edu).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -38,15 +38,13 @@ Boston, MA 02111-1307, USA. */ ...@@ -38,15 +38,13 @@ Boston, MA 02111-1307, USA. */
/* Common ASM definitions used by ASM_SPEC amonst the various targets /* Common ASM definitions used by ASM_SPEC amonst the various targets
for handling -mcpu=xxx switches. */ for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC #undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \ #define ASM_CPU_SPEC \
"%{!mcpu*: \ "%{!mcpu*: \
%{mpower: %{!mpower2: -mpwr}} \ %{mpower: %{!mpower2: -mpwr}} \
%{mpower2: -mpwr2} \ %{mpower2: -mpwr2} \
%{mpowerpc*: -mppc} \ %{mpowerpc*: -mppc} \
%{mno-power: %{!mpowerpc*: -mcom}} \ %{!mpower*: %{!mpowerpc*: %(asm_default)}}} \
%{!mno-power: %{!mpower2: %(asm_default)}}} \
%{mcpu=common: -mcom} \ %{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \ %{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \ %{mcpu=power2: -mpwr2} \
...@@ -67,6 +65,9 @@ Boston, MA 02111-1307, USA. */ ...@@ -67,6 +65,9 @@ Boston, MA 02111-1307, USA. */
%{mcpu=821: -mppc} \ %{mcpu=821: -mppc} \
%{mcpu=860: -mppc}" %{mcpu=860: -mppc}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
#undef CPP_PREDEFINES #undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 \ #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 \
-Asystem(unix) -Asystem(aix)" -Asystem(unix) -Asystem(aix)"
...@@ -77,12 +78,38 @@ Boston, MA 02111-1307, USA. */ ...@@ -77,12 +78,38 @@ Boston, MA 02111-1307, USA. */
%{mthreads: -D_THREAD_SAFE}\ %{mthreads: -D_THREAD_SAFE}\
%(cpp_cpu)" %(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 #undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_COM" #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_NEW_MNEMONICS #define TARGET_DEFAULT MASK_NEW_MNEMONICS
......
/* 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 \
-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"
/* Core target definitions for GNU compiler /* Core target definitions for GNU compiler
for IBM RS/6000 PowerPC running NetWare for IBM RS/6000 PowerPC running NetWare
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support. Contributed by Cygnus Support.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -21,7 +21,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -21,7 +21,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define TARGET_AIX 0 #define TARGET_AIX 0
#include "rs6000/powerpc.h" #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. */ /* Don't generate XCOFF debugging information. */
......
/* 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; \
} \
}
/* Subroutines used for code generation on IBM RS/6000. /* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. Copyright (C) 1991, 93-7, 1998 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC. This file is part of GNU CC.
...@@ -226,7 +226,7 @@ rs6000_override_options (default_cpu) ...@@ -226,7 +226,7 @@ rs6000_override_options (default_cpu)
POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
{"620", PROCESSOR_PPC620, {"620", PROCESSOR_PPC620,
MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, POWER_MASKS | MASK_PPC_GPOPT},
{"801", PROCESSOR_MPCCORE, {"801", PROCESSOR_MPCCORE,
MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
...@@ -304,6 +304,13 @@ rs6000_override_options (default_cpu) ...@@ -304,6 +304,13 @@ rs6000_override_options (default_cpu)
} }
} }
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 */ /* Set debug flags */
if (rs6000_debug_name) if (rs6000_debug_name)
{ {
...@@ -388,22 +395,6 @@ rs6000_float_const (string, mode) ...@@ -388,22 +395,6 @@ rs6000_float_const (string, mode)
REAL_VALUE_TYPE value = REAL_VALUE_ATOF (string, mode); REAL_VALUE_TYPE value = REAL_VALUE_ATOF (string, mode);
return immed_real_const_1 (value, mode); return immed_real_const_1 (value, mode);
} }
/* Create a CONST_DOUBLE like immed_double_const, except reverse the
two parts of the constant if the target is little endian. */
struct rtx_def *
rs6000_immed_double_const (i0, i1, mode)
HOST_WIDE_INT i0, i1;
enum machine_mode mode;
{
if (! WORDS_BIG_ENDIAN)
return immed_double_const (i1, i0, mode);
return immed_double_const (i0, i1, mode);
}
/* Return non-zero if this function is known to have a null epilogue. */ /* Return non-zero if this function is known to have a null epilogue. */
...@@ -492,7 +483,8 @@ u_short_cint_operand (op, mode) ...@@ -492,7 +483,8 @@ u_short_cint_operand (op, mode)
register rtx op; register rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0); return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0);
} }
/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */ /* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
...@@ -569,7 +561,7 @@ reg_or_u_short_operand (op, mode) ...@@ -569,7 +561,7 @@ reg_or_u_short_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
if (GET_CODE (op) == CONST_INT if (GET_CODE (op) == CONST_INT
&& (INTVAL (op) & 0xffff0000) == 0) && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0)
return 1; return 1;
return gpc_reg_operand (op, mode); return gpc_reg_operand (op, mode);
...@@ -706,6 +698,9 @@ num_insns_constant (op, mode) ...@@ -706,6 +698,9 @@ num_insns_constant (op, mode)
&& ((low & 0x80000000) != 0)) && ((low & 0x80000000) != 0))
return num_insns_constant_wide (low); return num_insns_constant_wide (low);
else if (mask64_operand (op, mode))
return 2;
else if (low == 0) else if (low == 0)
return num_insns_constant_wide (high) + 1; return num_insns_constant_wide (high) + 1;
...@@ -770,8 +765,10 @@ easy_fp_constant (op, mode) ...@@ -770,8 +765,10 @@ easy_fp_constant (op, mode)
return num_insns_constant_wide (l) == 1; return num_insns_constant_wide (l) == 1;
} }
else if (mode == DImode && TARGET_32BIT) else if (mode == DImode)
return num_insns_constant (op, DImode) == 2; return ((TARGET_64BIT
&& GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
|| (num_insns_constant (op, DImode) <= 2));
else else
abort (); abort ();
...@@ -861,7 +858,7 @@ logical_operand (op, mode) ...@@ -861,7 +858,7 @@ logical_operand (op, mode)
{ {
return (gpc_reg_operand (op, mode) return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT || (GET_CODE (op) == CONST_INT
&& ((INTVAL (op) & 0xffff0000) == 0 && ((INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0
|| (INTVAL (op) & 0xffff) == 0))); || (INTVAL (op) & 0xffff) == 0)));
} }
...@@ -874,7 +871,7 @@ non_logical_cint_operand (op, mode) ...@@ -874,7 +871,7 @@ non_logical_cint_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (GET_CODE (op) == CONST_INT return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) & 0xffff0000) != 0 && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0
&& (INTVAL (op) & 0xffff) != 0); && (INTVAL (op) & 0xffff) != 0);
} }
...@@ -885,7 +882,7 @@ non_logical_cint_operand (op, mode) ...@@ -885,7 +882,7 @@ non_logical_cint_operand (op, mode)
int int
mask_constant (c) mask_constant (c)
register int c; register HOST_WIDE_INT c;
{ {
int i; int i;
int last_bit_value; int last_bit_value;
...@@ -913,27 +910,105 @@ mask_operand (op, mode) ...@@ -913,27 +910,105 @@ mask_operand (op, mode)
return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op)); return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op));
} }
/* Return 1 if the operand is either a non-special register or a /* Return 1 if the operand is a constant that is a PowerPC64 mask.
constant that can be used as the operand of an RS/6000 logical AND insn. */ 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 int
and_operand (op, mode) 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_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_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_INT == 32
&& high == 0
#endif
)
|| (low == ~0
#if HOST_BITS_PER_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_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; register rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
return (logical_operand (op, mode) return (logical_operand (op, mode)
|| mask_operand (op, mode)); || mask64_operand (op, mode));
} }
/* Return 1 if the operand is a constant but not a valid operand for an AND /* Return 1 if the operand is either a non-special register or a
insn. */ constant that can be used as the operand of an RS/6000 logical AND insn. */
int int
non_and_cint_operand (op, mode) and_operand (op, mode)
register rtx op; register rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
return GET_CODE (op) == CONST_INT && ! and_operand (op, mode); return (logical_operand (op, mode)
|| mask_operand (op, mode));
} }
/* Return 1 if the operand is a general register or memory operand. */ /* Return 1 if the operand is a general register or memory operand. */
...@@ -1240,7 +1315,8 @@ function_arg_advance (cum, mode, type, named) ...@@ -1240,7 +1315,8 @@ function_arg_advance (cum, mode, type, named)
tree type; tree type;
int named; int named;
{ {
int align = ((cum->words & 1) != 0 && function_arg_boundary (mode, type) == 64) ? 1 : 0; int align = (TARGET_32BIT && (cum->words & 1) != 0
&& function_arg_boundary (mode, type) == 64) ? 1 : 0;
cum->words += align; cum->words += align;
cum->nargs_prototype--; cum->nargs_prototype--;
...@@ -1313,7 +1389,8 @@ function_arg (cum, mode, type, named) ...@@ -1313,7 +1389,8 @@ function_arg (cum, mode, type, named)
tree type; tree type;
int named; int named;
{ {
int align = ((cum->words & 1) != 0 && function_arg_boundary (mode, type) == 64) ? 1 : 0; int align = (TARGET_32BIT && (cum->words & 1) != 0
&& function_arg_boundary (mode, type) == 64) ? 1 : 0;
int align_words = cum->words + align; int align_words = cum->words + align;
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
...@@ -1489,7 +1566,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) ...@@ -1489,7 +1566,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
{ {
rtx save_area = virtual_incoming_args_rtx; rtx save_area = virtual_incoming_args_rtx;
int reg_size = (TARGET_64BIT) ? 8 : 4; int reg_size = TARGET_32BIT ? 4 : 8;
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, fprintf (stderr,
...@@ -2395,7 +2472,7 @@ print_operand (file, x, code) ...@@ -2395,7 +2472,7 @@ print_operand (file, x, code)
char code; char code;
{ {
int i; int i;
int val; HOST_WIDE_INT val;
/* These macros test for integers and extract the low-order bits. */ /* These macros test for integers and extract the low-order bits. */
#define INT_P(X) \ #define INT_P(X) \
...@@ -2443,6 +2520,11 @@ print_operand (file, x, code) ...@@ -2443,6 +2520,11 @@ print_operand (file, x, code)
fprintf (file, "%d", INT_LOWPART (x) & 0xffff); fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
return; 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);
case 'C': case 'C':
/* This is an optional cror needed for LE or GE floating-point /* This is an optional cror needed for LE or GE floating-point
comparisons. Otherwise write nothing. */ comparisons. Otherwise write nothing. */
...@@ -2619,7 +2701,7 @@ print_operand (file, x, code) ...@@ -2619,7 +2701,7 @@ print_operand (file, x, code)
if (((val >>= 1) & 1) == 0) if (((val >>= 1) & 1) == 0)
break; break;
/* If we ended in ...01, I would be 0. The correct value is 31, so /* If we ended in ...01, i would be 0. The correct value is 31, so
we want 31 - i. */ we want 31 - i. */
fprintf (file, "%d", 31 - i); fprintf (file, "%d", 31 - i);
return; return;
...@@ -2627,7 +2709,7 @@ print_operand (file, x, code) ...@@ -2627,7 +2709,7 @@ print_operand (file, x, code)
case 'M': case 'M':
/* ME value for a mask operand. */ /* ME value for a mask operand. */
if (! mask_operand (x, VOIDmode)) if (! mask_operand (x, VOIDmode))
output_operand_lossage ("invalid %%m value"); output_operand_lossage ("invalid %%M value");
val = INT_LOWPART (x); val = INT_LOWPART (x);
...@@ -2645,7 +2727,7 @@ print_operand (file, x, code) ...@@ -2645,7 +2727,7 @@ print_operand (file, x, code)
if ((val >>= 1) & 1) if ((val >>= 1) & 1)
break; break;
/* If we had ....10, I would be 0. The result should be /* If we had ....10, i would be 0. The result should be
30, so we need 30 - i. */ 30, so we need 30 - i. */
fprintf (file, "%d", 30 - i); fprintf (file, "%d", 30 - i);
return; return;
...@@ -2711,6 +2793,72 @@ print_operand (file, x, code) ...@@ -2711,6 +2793,72 @@ print_operand (file, x, code)
fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31); fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);
return; 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 */
{
if (val == 1)
i = 0;
else
for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
if (!((val >>= 1) & 1))
break;
#if HOST_BITS_PER_INT == 32
if (GET_CODE (x) == CONST_DOUBLE && i == 32)
{
val = CONST_DOUBLE_HIGH (x);
if (val == 0)
--i;
else if (val == 1)
;
else
for (i = 33; i < 64; i++)
if (!((val >>= 1) & 1))
break;
}
#endif
fprintf (file, "%d", 63 - i);
return;
}
else /* Clear Right */
{
val = (GET_CODE (x) == CONST_INT ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
if (val == (-1 << (HOST_BITS_PER_WIDE_INT-1)))
i = 0;
else
for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
if ((val <<= 1) < 0)
break;
#if HOST_BITS_PER_INT == 32
if (GET_CODE (x) == CONST_DOUBLE && i == 32)
{
val = CONST_DOUBLE_LOW (x);
if (val == 0)
--i;
else if (val == (-1 << (HOST_BITS_PER_WIDE_INT-1)))
;
else
for (i = 33; i < 64; i++)
if ((val <<= 1) < 0)
break;
}
#endif
fprintf (file, "%d", i);
return;
}
case 't': case 't':
/* Write 12 if this jump operation will branch if true, 4 otherwise. /* Write 12 if this jump operation will branch if true, 4 otherwise.
All floating-point operations except NE branch true and integer All floating-point operations except NE branch true and integer
...@@ -3006,23 +3154,23 @@ rs6000_makes_calls () ...@@ -3006,23 +3154,23 @@ rs6000_makes_calls ()
sequence and the V.4 calling sequence. sequence and the V.4 calling sequence.
AIX stack frames look like: AIX stack frames look like:
32-bit 64-bit
SP----> +---------------------------------------+ SP----> +---------------------------------------+
| back chain to caller | 0 | back chain to caller | 0 0
+---------------------------------------+ +---------------------------------------+
| saved CR | 4 | saved CR | 4 8 (8-11)
+---------------------------------------+ +---------------------------------------+
| saved LR | 8 | saved LR | 8 16
+---------------------------------------+ +---------------------------------------+
| reserved for compilers | 12 | reserved for compilers | 12 24
+---------------------------------------+ +---------------------------------------+
| reserved for binders | 16 | reserved for binders | 16 32
+---------------------------------------+ +---------------------------------------+
| saved TOC pointer | 20 | saved TOC pointer | 20 40
+---------------------------------------+ +---------------------------------------+
| Parameter save area (P) | 24 | Parameter save area (P) | 24 48
+---------------------------------------+ +---------------------------------------+
| Alloca space (A) | 24+P | Alloca space (A) | 24+P etc.
+---------------------------------------+ +---------------------------------------+
| Local variable space (L) | 24+P+A | Local variable space (L) | 24+P+A
+---------------------------------------+ +---------------------------------------+
...@@ -3115,7 +3263,7 @@ rs6000_stack_info () ...@@ -3115,7 +3263,7 @@ rs6000_stack_info ()
{ {
static rs6000_stack_t info, zero_info; static rs6000_stack_t info, zero_info;
rs6000_stack_t *info_ptr = &info; rs6000_stack_t *info_ptr = &info;
int reg_size = TARGET_64BIT ? 8 : 4; int reg_size = TARGET_32BIT ? 4 : 8;
enum rs6000_abi abi; enum rs6000_abi abi;
int total_raw_size; int total_raw_size;
...@@ -3257,7 +3405,7 @@ rs6000_stack_info () ...@@ -3257,7 +3405,7 @@ rs6000_stack_info ()
else else
info_ptr->push_p = (frame_pointer_needed info_ptr->push_p = (frame_pointer_needed
|| write_symbols != NO_DEBUG || write_symbols != NO_DEBUG
|| ((info_ptr->total_size - info_ptr->fixed_size) || ((total_raw_size - info_ptr->fixed_size)
> (TARGET_32BIT ? 220 : 296))); > (TARGET_32BIT ? 220 : 296)));
/* Calculate the offsets */ /* Calculate the offsets */
...@@ -3272,8 +3420,8 @@ rs6000_stack_info () ...@@ -3272,8 +3420,8 @@ rs6000_stack_info ()
info_ptr->fp_save_offset = - info_ptr->fp_size; 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->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->main_save_offset = info_ptr->gp_save_offset - info_ptr->main_size;
info_ptr->cr_save_offset = 4; info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
info_ptr->lr_save_offset = 8; info_ptr->lr_save_offset = 2*reg_size;
break; break;
case ABI_V4: case ABI_V4:
...@@ -3287,13 +3435,13 @@ rs6000_stack_info () ...@@ -3287,13 +3435,13 @@ rs6000_stack_info ()
break; break;
case ABI_NT: case ABI_NT:
info_ptr->lr_save_offset = -4; info_ptr->lr_save_offset = -reg_size;
info_ptr->toc_save_offset = info_ptr->lr_save_offset - info_ptr->lr_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->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->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; 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) if (info_ptr->fp_size && ((- info_ptr->fp_save_offset) % 8) != 0)
info_ptr->fp_save_offset -= 4; info_ptr->fp_save_offset -= reg_size;
info_ptr->main_save_offset = info_ptr->fp_save_offset - info_ptr->main_size; info_ptr->main_save_offset = info_ptr->fp_save_offset - info_ptr->main_size;
break; break;
...@@ -3303,9 +3451,9 @@ rs6000_stack_info () ...@@ -3303,9 +3451,9 @@ rs6000_stack_info ()
{ {
info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size; info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size;
rs6000_fpmem_size = info_ptr->fpmem_size; rs6000_fpmem_size = info_ptr->fpmem_size;
rs6000_fpmem_offset = info_ptr->push_p rs6000_fpmem_offset = (info_ptr->push_p
? info_ptr->total_size + info_ptr->fpmem_offset ? info_ptr->total_size + info_ptr->fpmem_offset
: info_ptr->fpmem_offset; : info_ptr->fpmem_offset);
} }
else else
info_ptr->fpmem_offset = 0; info_ptr->fpmem_offset = 0;
...@@ -3491,7 +3639,7 @@ rs6000_output_load_toc_table (file, reg) ...@@ -3491,7 +3639,7 @@ rs6000_output_load_toc_table (file, reg)
address before loading. */ address before loading. */
if (rs6000_pic_func_labelno != rs6000_pic_labelno) if (rs6000_pic_func_labelno != rs6000_pic_labelno)
{ {
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; char *init_ptr = TARGET_32BIT ? ".long" : ".quad";
char *buf_ptr; char *buf_ptr;
ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno); ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno);
...@@ -3508,26 +3656,14 @@ rs6000_output_load_toc_table (file, reg) ...@@ -3508,26 +3656,14 @@ rs6000_output_load_toc_table (file, reg)
fprintf (file, "\tmflr %s\n", reg_names[reg]); fprintf (file, "\tmflr %s\n", reg_names[reg]);
if (rs6000_pic_func_labelno != rs6000_pic_labelno) if (rs6000_pic_func_labelno != rs6000_pic_labelno)
{ asm_fprintf(file, "\t{cal|la} %s,%d(%s)\n", reg_names[reg],
if (TARGET_POWERPC64) (TARGET_32BIT ? 4 : 8), reg_names[reg]);
fprintf (file, "\taddi %s,%s,8\n", reg_names[reg], reg_names[reg]);
else if (TARGET_NEW_MNEMONICS)
fprintf (file, "\taddi %s,%s,4\n", reg_names[reg], reg_names[reg]);
else
fprintf (file, "\tcal %s,4(%s)\n", reg_names[reg], reg_names[reg]);
}
if (TARGET_POWERPC64) asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s,(" : "\tld %s,(",
fprintf (file, "\tld"); reg_names[0]);
else if (TARGET_NEW_MNEMONICS)
fprintf (file, "\tlwz");
else
fprintf (file, "\tl");
fprintf (file, " %s,(", reg_names[0]);
ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
assemble_name (file, buf); assemble_name (file, buf);
fprintf (file, "-"); fputs ("-", file);
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
assemble_name (file, buf); assemble_name (file, buf);
fprintf (file, ")(%s)\n", reg_names[reg]); fprintf (file, ")(%s)\n", reg_names[reg]);
...@@ -3538,21 +3674,12 @@ rs6000_output_load_toc_table (file, reg) ...@@ -3538,21 +3674,12 @@ rs6000_output_load_toc_table (file, reg)
else if (!TARGET_64BIT) else if (!TARGET_64BIT)
{ {
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
asm_fprintf (file, "\t{cau|addis} %s,%s,", reg_names[reg], reg_names[0]); asm_fprintf (file, "\t{liu|lis} %s,", reg_names[reg]);
assemble_name (file, buf); assemble_name (file, buf);
asm_fprintf (file, "@ha\n"); asm_fprintf (file, "@ha\n");
if (TARGET_NEW_MNEMONICS) asm_fprintf (file, "\t{cal|la} %s,", reg_names[reg]);
{ assemble_name (file, buf);
asm_fprintf (file, "\taddi %s,%s,", reg_names[reg], reg_names[reg]); asm_fprintf (file, "@l(%s)\n", reg_names[reg]);
assemble_name (file, buf);
asm_fprintf (file, "@l\n");
}
else
{
asm_fprintf (file, "\tcal %s,", reg_names[reg]);
assemble_name (file, buf);
asm_fprintf (file, "@l(%s)\n", reg_names[reg]);
}
} }
else else
abort (); abort ();
...@@ -3599,12 +3726,8 @@ rs6000_allocate_stack_space (file, size, copy_r12) ...@@ -3599,12 +3726,8 @@ rs6000_allocate_stack_space (file, size, copy_r12)
{ {
fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
if (size < 32767) if (size < 32767)
{ fprintf (file, "\t{cal|la} %s,%d(%s)\n",
if (TARGET_NEW_MNEMONICS) reg_names[1], neg_size, reg_names[1]);
fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], neg_size);
else
fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], neg_size, reg_names[1]);
}
else else
{ {
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
...@@ -3912,10 +4035,9 @@ output_epilog (file, size) ...@@ -3912,10 +4035,9 @@ output_epilog (file, size)
{ {
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
sp_offset = info->total_size; sp_offset = info->total_size;
else if (TARGET_NEW_MNEMONICS)
asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size);
else else
asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], info->total_size, reg_names[1]); 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. */ /* Get the old lr if we saved it. */
...@@ -3967,12 +4089,8 @@ output_epilog (file, size) ...@@ -3967,12 +4089,8 @@ output_epilog (file, size)
/* If this is V.4, unwind the stack pointer after all of the loads have been done */ /* If this is V.4, unwind the stack pointer after all of the loads have been done */
if (sp_offset) if (sp_offset)
{ asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n",
if (TARGET_NEW_MNEMONICS) reg_names[1], sp_offset, reg_names[1]);
asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], sp_offset);
else
asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], sp_offset, reg_names[1]);
}
else if (sp_reg != 1) else if (sp_reg != 1)
asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]); asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]);
...@@ -4521,25 +4639,15 @@ output_function_profiler (file, labelno) ...@@ -4521,25 +4639,15 @@ output_function_profiler (file, labelno)
fputs ("\n\t.previous\n", file); fputs ("\n\t.previous\n", file);
} }
#endif #endif
else if (TARGET_NEW_MNEMONICS)
{
fprintf (file, "\taddis %s,%s,", reg_names[11], reg_names[11]);
assemble_name (file, buf);
fprintf (file, "@ha\n");
fprintf (file, "\tstw %s,4(%s)\n", reg_names[0], reg_names[1]);
fprintf (file, "\taddi %s,%s,", reg_names[0], reg_names[11]);
assemble_name (file, buf);
fputs ("@l\n", file);
}
else else
{ {
fprintf (file, "\tcau %s,%s,", reg_names[11], reg_names[11]); asm_fprintf (file, "\t{liu|lis} %s,", reg_names[11]);
assemble_name (file, buf); assemble_name (file, buf);
fprintf (file, "@ha\n"); asm_fprintf (file, "@ha\n");
fprintf (file, "\tst %s,4(%s)\n", reg_names[0], reg_names[1]); asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]);
fprintf (file, "\tcal %s,", reg_names[11]); asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
assemble_name (file, buf); assemble_name (file, buf);
fprintf (file, "@l(%s)\n", reg_names[11]); asm_fprintf (file, "@l(%s)\n", reg_names[11]);
} }
fprintf (file, "\tbl %s\n", RS6000_MCOUNT); fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
...@@ -4585,7 +4693,8 @@ output_function_profiler (file, labelno) ...@@ -4585,7 +4693,8 @@ output_function_profiler (file, labelno)
ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno); ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno);
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]); asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]);
assemble_name (file, buf); assemble_name (file, buf);
asm_fprintf (file, "(%s)\n\tbl %s\n", reg_names[2], RS6000_MCOUNT); asm_fprintf (file, "(%s)\n\tbl %s\n\t%s\n",
reg_names[2], RS6000_MCOUNT, RS6000_CALL_GLUE);
/* Restore parameter registers. */ /* Restore parameter registers. */
...@@ -5058,7 +5167,7 @@ rs6000_select_section (decl, reloc) ...@@ -5058,7 +5167,7 @@ rs6000_select_section (decl, reloc)
call. For real AIX and NT calling sequences, we also replace 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 function name with the real name (1 or 2 leading .'s), rather than
the function descriptor name. This saves a lot of overriding code the function descriptor name. This saves a lot of overriding code
to readd the prefixes. */ to read the prefixes. */
void void
rs6000_encode_section_info (decl) rs6000_encode_section_info (decl)
......
/* Definitions of target machine for GNU compiler, for IBM RS/6000. /* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. Copyright (C) 1992, 93-7, 1998 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC. This file is part of GNU CC.
...@@ -351,6 +351,8 @@ extern int target_flags; ...@@ -351,6 +351,8 @@ extern int target_flags;
{"no-powerpc-gpopt", - MASK_PPC_GPOPT}, \ {"no-powerpc-gpopt", - MASK_PPC_GPOPT}, \
{"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT}, \ {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT}, \
{"no-powerpc-gfxopt", - MASK_PPC_GFXOPT}, \ {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT}, \
{"powerpc64", MASK_POWERPC64}, \
{"no-powerpc64", - MASK_POWERPC64}, \
{"new-mnemonics", MASK_NEW_MNEMONICS}, \ {"new-mnemonics", MASK_NEW_MNEMONICS}, \
{"old-mnemonics", -MASK_NEW_MNEMONICS}, \ {"old-mnemonics", -MASK_NEW_MNEMONICS}, \
{"full-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC \ {"full-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC \
...@@ -577,7 +579,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -577,7 +579,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64) #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */ /* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY 64 #define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */ /* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32 #define FUNCTION_BOUNDARY 32
...@@ -587,7 +589,10 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -587,7 +589,10 @@ extern int rs6000_debug_arg; /* debug argument handling */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
(DECL_MODE (FIELD) != DFmode ? (COMPUTED) : MIN ((COMPUTED), 32)) (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. */ /* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32 #define EMPTY_FIELD_BOUNDARY 32
...@@ -737,8 +742,8 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -737,8 +742,8 @@ extern int rs6000_debug_arg; /* debug argument handling */
This is ordinarily the length in words of a value 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. but can be less for certain modes in special long registers.
On RS/6000, ordinary registers hold 32 bits worth; POWER and PowerPC GPRs hold 32 bits worth;
a single floating point register holds 64 bits worth. */ PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
#define HARD_REGNO_NREGS(REGNO, MODE) \ #define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO) \ (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO) \
...@@ -1042,7 +1047,7 @@ enum reg_class ...@@ -1042,7 +1047,7 @@ enum reg_class
#define CONST_OK_FOR_LETTER_P(VALUE, C) \ #define CONST_OK_FOR_LETTER_P(VALUE, C) \
( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \ ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
: (C) == 'J' ? ((VALUE) & 0xffff) == 0 \ : (C) == 'J' ? ((VALUE) & 0xffff) == 0 \
: (C) == 'K' ? ((VALUE) & 0xffff0000) == 0 \ : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \
: (C) == 'L' ? mask_constant (VALUE) \ : (C) == 'L' ? mask_constant (VALUE) \
: (C) == 'M' ? (VALUE) > 31 \ : (C) == 'M' ? (VALUE) > 31 \
: (C) == 'N' ? exact_log2 (VALUE) >= 0 \ : (C) == 'N' ? exact_log2 (VALUE) >= 0 \
...@@ -1068,15 +1073,13 @@ enum reg_class ...@@ -1068,15 +1073,13 @@ enum reg_class
'Q' means that is a memory operand that is just an offset from a reg. 'Q' means that is a memory operand that is just an offset from a reg.
'R' is for AIX TOC entries. 'R' is for AIX TOC entries.
'S' is for Windows NT SYMBOL_REFs 'S' is a constant that can be placed into a 64-bit mask operand
'T' is for Windows NT LABEL_REFs.
'U' is for V.4 small data references. */ 'U' is for V.4 small data references. */
#define EXTRA_CONSTRAINT(OP, C) \ #define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \ ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
: (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \ : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
: (C) == 'S' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == SYMBOL_REF)\ : (C) == 'S' ? mask64_operand (OP, VOIDmode) \
: (C) == 'T' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == LABEL_REF) \
: (C) == 'U' ? ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \ : (C) == 'U' ? ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
&& small_data_operand (OP, GET_MODE (OP))) \ && small_data_operand (OP, GET_MODE (OP))) \
: 0) : 0)
...@@ -1201,7 +1204,7 @@ typedef struct rs6000_stack { ...@@ -1201,7 +1204,7 @@ typedef struct rs6000_stack {
#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48) #define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48)
/* Address to save the TOC register */ /* Address to save the TOC register */
#define RS6000_SAVE_TOC plus_constant (stack_pointer_rtx, 20) #define RS6000_SAVE_TOC plus_constant (stack_pointer_rtx, (TARGET_32BIT ? 20 : 40))
/* Offset & size for fpmem stack locations used for converting between /* Offset & size for fpmem stack locations used for converting between
float and integral types. */ float and integral types. */
...@@ -1320,6 +1323,11 @@ extern int rs6000_sysv_varargs_p; ...@@ -1320,6 +1323,11 @@ extern int rs6000_sysv_varargs_p;
(TYPE_MODE (TYPE) == BLKmode \ (TYPE_MODE (TYPE) == BLKmode \
&& (DEFAULT_ABI != ABI_SOLARIS || int_size_in_bytes (TYPE) > 8)) && (DEFAULT_ABI != ABI_SOLARIS || int_size_in_bytes (TYPE) > 8))
/* Mode of stack savearea.
NONLOCAL needs twice Pmode to maintain both backchain and SP. */
#define STACK_SAVEAREA_MODE(LEVEL) \
(LEVEL == SAVE_NONLOCAL ? (TARGET_32BIT ? DImode : TImode) : Pmode)
/* Minimum and maximum general purpose registers used to hold arguments. */ /* Minimum and maximum general purpose registers used to hold arguments. */
#define GP_ARG_MIN_REG 3 #define GP_ARG_MIN_REG 3
#define GP_ARG_MAX_REG 10 #define GP_ARG_MAX_REG 10
...@@ -1723,6 +1731,7 @@ typedef struct rs6000_args ...@@ -1723,6 +1731,7 @@ typedef struct rs6000_args
#define LEGITIMATE_CONSTANT_P(X) \ #define LEGITIMATE_CONSTANT_P(X) \
(GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \ (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \
|| (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
|| easy_fp_constant (X, GET_MODE (X))) || easy_fp_constant (X, GET_MODE (X)))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
...@@ -1777,7 +1786,7 @@ typedef struct rs6000_args ...@@ -1777,7 +1786,7 @@ typedef struct rs6000_args
&& CONSTANT_POOL_ADDRESS_P (X) \ && CONSTANT_POOL_ADDRESS_P (X) \
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X))) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))
/* TARGET_64BIT TOC64 guaranteed to have 64 bit alignment. */ /* AIX64 guaranteed to have 64 bit TOC alignment. */
#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \ #define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
(LEGITIMATE_CONSTANT_POOL_BASE_P (X) \ (LEGITIMATE_CONSTANT_POOL_BASE_P (X) \
|| (TARGET_TOC \ || (TARGET_TOC \
...@@ -1916,6 +1925,46 @@ typedef struct rs6000_args ...@@ -1916,6 +1925,46 @@ typedef struct rs6000_args
} \ } \
} }
/* 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 { \
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) /* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. has an effect that depends on the machine mode it is used for.
...@@ -2053,10 +2102,9 @@ typedef struct rs6000_args ...@@ -2053,10 +2102,9 @@ typedef struct rs6000_args
#define OBJECT_FORMAT_COFF #define OBJECT_FORMAT_COFF
/* Define the magic numbers that we recognize as COFF. /* Define the magic numbers that we recognize as COFF.
AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit executables, but collect2.c AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c
does not include these files in the right order to conditionally define does not include files in the correct order to conditionally define
the value in the macro. */ the symbolic name in this macro. */
#define MY_ISCOFF(magic) \ #define MY_ISCOFF(magic) \
((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \ ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
|| (magic) == U802TOCMAGIC || (magic) == 0757) || (magic) == U802TOCMAGIC || (magic) == 0757)
...@@ -2086,7 +2134,6 @@ typedef struct rs6000_args ...@@ -2086,7 +2134,6 @@ typedef struct rs6000_args
#define Pmode (TARGET_32BIT ? SImode : DImode) #define Pmode (TARGET_32BIT ? SImode : DImode)
/* Mode of a function address in a call instruction (for indexing purposes). /* Mode of a function address in a call instruction (for indexing purposes).
Doesn't matter on RS/6000. */ Doesn't matter on RS/6000. */
#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode) #define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode)
...@@ -2131,17 +2178,17 @@ typedef struct rs6000_args ...@@ -2131,17 +2178,17 @@ typedef struct rs6000_args
#define RTX_COSTS(X,CODE,OUTER_CODE) \ #define RTX_COSTS(X,CODE,OUTER_CODE) \
case PLUS: \ case PLUS: \
return ((GET_CODE (XEXP (X, 1)) == CONST_INT \ return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
&& (unsigned HOST_WIDE_INT) ((INTVAL (XEXP (X, 1)) \ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) \
+ 0x8000) >= 0x10000)) \ + 0x8000) >= 0x10000) \
&& (INTVAL (XEXP (X, 1)) & 0xffff != 0)) \
? COSTS_N_INSNS (2) \ ? COSTS_N_INSNS (2) \
: COSTS_N_INSNS (1)); \ : COSTS_N_INSNS (1)); \
case AND: \ case AND: \
return ((non_and_cint_operand (XEXP (X, 1), SImode)) \
? COSTS_N_INSNS (2) \
: COSTS_N_INSNS (1)); \
case IOR: \ case IOR: \
case XOR: \ case XOR: \
return ((non_logical_cint_operand (XEXP (X, 1), SImode)) \ 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 (2) \
: COSTS_N_INSNS (1)); \ : COSTS_N_INSNS (1)); \
case MULT: \ case MULT: \
...@@ -2307,6 +2354,8 @@ extern int rs6000_trunc_used; ...@@ -2307,6 +2354,8 @@ extern int rs6000_trunc_used;
main_input_filename, ".ro_"); \ main_input_filename, ".ro_"); \
\ \
output_file_directive (FILE, main_input_filename); \ output_file_directive (FILE, main_input_filename); \
if (TARGET_64BIT) \
fputs ("\t.machine\t\"ppc64\"\n", FILE); \
toc_section (); \ toc_section (); \
if (write_symbols != NO_DEBUG) \ if (write_symbols != NO_DEBUG) \
private_data_section (); \ private_data_section (); \
...@@ -2469,10 +2518,10 @@ extern int toc_initialized; ...@@ -2469,10 +2518,10 @@ extern int toc_initialized;
} \ } \
fputs (".csect ", FILE); \ fputs (".csect ", FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs ("[DS]\n", FILE); \ fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (":\n", FILE); \ fputs (":\n", FILE); \
fputs ((TARGET_32BIT) ? "\t.long ." : "\t.llong .", FILE); \ fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (", TOC[tc0], 0\n", FILE); \ fputs (", TOC[tc0], 0\n", FILE); \
fputs (".csect .text[PR]\n.", FILE); \ fputs (".csect .text[PR]\n.", FILE); \
...@@ -2498,8 +2547,11 @@ extern int toc_initialized; ...@@ -2498,8 +2547,11 @@ extern int toc_initialized;
|| GET_CODE (X) == LABEL_REF \ || GET_CODE (X) == LABEL_REF \
|| (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \ || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \
&& GET_CODE (X) == CONST_DOUBLE \ && GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
|| (TARGET_POWERPC64 && GET_MODE (X) == DImode)))))
#if 0
&& BITS_PER_WORD == HOST_BITS_PER_INT))) && BITS_PER_WORD == HOST_BITS_PER_INT)))
#endif
/* Select section for constant in constant pool. /* Select section for constant in constant pool.
...@@ -2949,7 +3001,7 @@ do { \ ...@@ -2949,7 +3001,7 @@ do { \
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do { char buf[100]; \ do { char buf[100]; \
fputs ((TARGET_32BIT) ? "\t.long " : "\t.llong ", FILE); \ fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \
ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \
assemble_name (FILE, buf); \ assemble_name (FILE, buf); \
putc ('\n', FILE); \ putc ('\n', FILE); \
...@@ -2959,7 +3011,7 @@ do { \ ...@@ -2959,7 +3011,7 @@ do { \
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)\ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)\
do { char buf[100]; \ do { char buf[100]; \
fputs ((TARGET_32BIT) ? "\t.long " : "\t.llong ", FILE); \ fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE); \
ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \
assemble_name (FILE, buf); \ assemble_name (FILE, buf); \
putc ('-', FILE); \ putc ('-', FILE); \
...@@ -3061,15 +3113,16 @@ do { \ ...@@ -3061,15 +3113,16 @@ do { \
{"add_operand", {SUBREG, REG, CONST_INT}}, \ {"add_operand", {SUBREG, REG, CONST_INT}}, \
{"non_add_cint_operand", {CONST_INT}}, \ {"non_add_cint_operand", {CONST_INT}}, \
{"and_operand", {SUBREG, REG, CONST_INT}}, \ {"and_operand", {SUBREG, REG, CONST_INT}}, \
{"non_and_cint_operand", {CONST_INT}}, \ {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \ {"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"non_logical_cint_operand", {CONST_INT}}, \ {"non_logical_cint_operand", {CONST_INT}}, \
{"mask_operand", {CONST_INT}}, \ {"mask_operand", {CONST_INT}}, \
{"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \
{"count_register_operand", {REG}}, \ {"count_register_operand", {REG}}, \
{"fpmem_operand", {REG}}, \ {"fpmem_operand", {REG}}, \
{"call_operand", {SYMBOL_REF, REG}}, \ {"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \ {"current_file_function_operand", {SYMBOL_REF}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT, SYMBOL_REF}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT, CONST_DOUBLE, SYMBOL_REF}}, \
{"load_multiple_operation", {PARALLEL}}, \ {"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \ {"store_multiple_operation", {PARALLEL}}, \
{"branch_comparison_operator", {EQ, NE, LE, LT, GE, \ {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \
...@@ -3098,7 +3151,6 @@ extern void output_options (); ...@@ -3098,7 +3151,6 @@ extern void output_options ();
extern void rs6000_override_options (); extern void rs6000_override_options ();
extern void rs6000_file_start (); extern void rs6000_file_start ();
extern struct rtx_def *rs6000_float_const (); extern struct rtx_def *rs6000_float_const ();
extern struct rtx_def *rs6000_immed_double_const ();
extern struct rtx_def *rs6000_got_register (); extern struct rtx_def *rs6000_got_register ();
extern int direct_return (); extern int direct_return ();
extern int get_issue_rate (); extern int get_issue_rate ();
...@@ -3123,13 +3175,13 @@ extern int add_operand (); ...@@ -3123,13 +3175,13 @@ extern int add_operand ();
extern int non_add_cint_operand (); extern int non_add_cint_operand ();
extern int non_logical_cint_operand (); extern int non_logical_cint_operand ();
extern int logical_operand (); extern int logical_operand ();
extern int non_logical_operand ();
extern int mask_constant (); extern int mask_constant ();
extern int mask_operand (); extern int mask_operand ();
extern int mask64_operand ();
extern int and64_operand ();
extern int and_operand (); extern int and_operand ();
extern int count_register_operand (); extern int count_register_operand ();
extern int fpmem_operand (); extern int fpmem_operand ();
extern int non_and_cint_operand ();
extern int reg_or_mem_operand (); extern int reg_or_mem_operand ();
extern int lwa_operand (); extern int lwa_operand ();
extern int call_operand (); extern int call_operand ();
......
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
;; Copyright (C) 1990, 91-96, 1997, 1998 Free Software Foundation, Inc. ;; Copyright (C) 1990, 91-97, 1998 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;; This file is part of GNU CC. ;; This file is part of GNU CC.
...@@ -1761,8 +1761,9 @@ ...@@ -1761,8 +1761,9 @@
|| rtx_equal_p (operands[0], operands[1])) || rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (SImode)); ? operands[0] : gen_reg_rtx (SImode));
emit_insn (gen_iorsi3 (tmp, operands[1], GEN_INT (value & 0xffff0000))); emit_insn (gen_iorsi3 (tmp, operands[1],
emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0x0000ffff))); GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE; DONE;
} }
}") }")
...@@ -1799,6 +1800,22 @@ ...@@ -1799,6 +1800,22 @@
"or. %0,%1,%2" "or. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
;; 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" (define_expand "xorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "") [(set (match_operand:SI 0 "gpc_reg_operand" "")
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "") (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
...@@ -1814,8 +1831,9 @@ ...@@ -1814,8 +1831,9 @@
|| rtx_equal_p (operands[0], operands[1])) || rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (SImode)); ? operands[0] : gen_reg_rtx (SImode));
emit_insn (gen_xorsi3 (tmp, operands[1], GEN_INT (value & 0xffff0000))); emit_insn (gen_xorsi3 (tmp, operands[1],
emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0x0000ffff))); GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE; DONE;
} }
}") }")
...@@ -1852,14 +1870,30 @@ ...@@ -1852,14 +1870,30 @@
"xor. %0,%1,%2" "xor. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*eqv_internal1" ;; 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") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
(match_operand:SI 2 "gpc_reg_operand" "r"))))] (match_operand:SI 2 "gpc_reg_operand" "r"))))]
"" ""
"eqv %0,%1,%2") "eqv %0,%1,%2")
(define_insn "*eqv_internal2" (define_insn "*eqvsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
(match_operand:SI 2 "gpc_reg_operand" "r"))) (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -1869,7 +1903,7 @@ ...@@ -1869,7 +1903,7 @@
"eqv. %3,%1,%2" "eqv. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*eqv_internal3" (define_insn "*eqvsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
(match_operand:SI 2 "gpc_reg_operand" "r"))) (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -1880,14 +1914,14 @@ ...@@ -1880,14 +1914,14 @@
"eqv. %0,%1,%2" "eqv. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*andc_internal1" (define_insn "*andcsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")))] (match_operand:SI 2 "gpc_reg_operand" "r")))]
"" ""
"andc %0,%2,%1") "andc %0,%2,%1")
(define_insn "*andc_internal2" (define_insn "*andcsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 2 "gpc_reg_operand" "r"))
...@@ -1897,7 +1931,7 @@ ...@@ -1897,7 +1931,7 @@
"andc. %3,%2,%1" "andc. %3,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*andc_internal3" (define_insn "*andcsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 2 "gpc_reg_operand" "r"))
...@@ -1908,14 +1942,14 @@ ...@@ -1908,14 +1942,14 @@
"andc. %0,%2,%1" "andc. %0,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*iorc_internal1" (define_insn "*iorcsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")))] (match_operand:SI 2 "gpc_reg_operand" "r")))]
"" ""
"orc %0,%2,%1") "orc %0,%2,%1")
(define_insn "*iorc_internal2" (define_insn "*iorcsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 2 "gpc_reg_operand" "r"))
...@@ -1925,7 +1959,7 @@ ...@@ -1925,7 +1959,7 @@
"orc. %3,%2,%1" "orc. %3,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*iorc_internal3" (define_insn "*iorcsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 2 "gpc_reg_operand" "r"))
...@@ -1936,14 +1970,14 @@ ...@@ -1936,14 +1970,14 @@
"orc. %0,%2,%1" "orc. %0,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*nand_internal1" (define_insn "*nandsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ior:SI (not:SI (match_operand:SI 1 "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"))))] (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
"" ""
"nand %0,%1,%2") "nand %0,%1,%2")
(define_insn "*nand_internal2" (define_insn "*nandsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -1953,7 +1987,7 @@ ...@@ -1953,7 +1987,7 @@
"nand. %3,%1,%2" "nand. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*nand_internal3" (define_insn "*nandsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -1964,14 +1998,14 @@ ...@@ -1964,14 +1998,14 @@
"nand. %0,%1,%2" "nand. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*nor_internal1" (define_insn "*norsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (not:SI (match_operand:SI 1 "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"))))] (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
"" ""
"nor %0,%1,%2") "nor %0,%1,%2")
(define_insn "*nor_internal2" (define_insn "*norsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -1981,7 +2015,7 @@ ...@@ -1981,7 +2015,7 @@
"nor. %3,%1,%2" "nor. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "*nor_internal3" (define_insn "*norsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
...@@ -2384,7 +2418,7 @@ ...@@ -2384,7 +2418,7 @@
"" ""
"{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
(define_insn "" (define_insn "*rotlsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_cint_operand" "ri")) (match_operand:SI 2 "reg_or_cint_operand" "ri"))
...@@ -2394,7 +2428,7 @@ ...@@ -2394,7 +2428,7 @@
"{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff" "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_cint_operand" "ri")) (match_operand:SI 2 "reg_or_cint_operand" "ri"))
...@@ -2405,7 +2439,7 @@ ...@@ -2405,7 +2439,7 @@
"{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff" "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal4"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(and:SI (rotate:SI (match_operand:SI 1 "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 2 "reg_or_cint_operand" "ri"))
...@@ -2413,7 +2447,7 @@ ...@@ -2413,7 +2447,7 @@
"" ""
"{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
(define_insn "" (define_insn "*rotlsi3_internal5"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (and:SI (compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
...@@ -2425,7 +2459,7 @@ ...@@ -2425,7 +2459,7 @@
"{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3" "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal6"
[(set (match_operand:CC 4 "cc_reg_operand" "=x") [(set (match_operand:CC 4 "cc_reg_operand" "=x")
(compare:CC (and:SI (compare:CC (and:SI
(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
...@@ -2438,7 +2472,7 @@ ...@@ -2438,7 +2472,7 @@
"{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3" "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal7"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI (zero_extend:SI
(subreg:QI (subreg:QI
...@@ -2447,7 +2481,7 @@ ...@@ -2447,7 +2481,7 @@
"" ""
"{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff") "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
(define_insn "" (define_insn "*rotlsi3_internal8"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (zero_extend:SI (compare:CC (zero_extend:SI
(subreg:QI (subreg:QI
...@@ -2459,7 +2493,7 @@ ...@@ -2459,7 +2493,7 @@
"{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff" "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal9"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (zero_extend:SI (compare:CC (zero_extend:SI
(subreg:QI (subreg:QI
...@@ -2472,7 +2506,7 @@ ...@@ -2472,7 +2506,7 @@
"{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff" "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal10"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(zero_extend:SI (zero_extend:SI
(subreg:HI (subreg:HI
...@@ -2481,7 +2515,7 @@ ...@@ -2481,7 +2515,7 @@
"" ""
"{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
(define_insn "" (define_insn "*rotlsi3_internal11"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (zero_extend:SI (compare:CC (zero_extend:SI
(subreg:HI (subreg:HI
...@@ -2493,7 +2527,7 @@ ...@@ -2493,7 +2527,7 @@
"{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff" "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotlsi3_internal12"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (zero_extend:SI (compare:CC (zero_extend:SI
(subreg:HI (subreg:HI
...@@ -3580,7 +3614,7 @@ ...@@ -3580,7 +3614,7 @@
(clobber (match_dup 4)) (clobber (match_dup 4))
(clobber (match_dup 5)) (clobber (match_dup 5))
(clobber (reg:DF 76))])] (clobber (reg:DF 76))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
" "
{ {
operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[2] = force_reg (SImode, GEN_INT (0x43300000));
...@@ -3595,9 +3629,9 @@ ...@@ -3595,9 +3629,9 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f")) (use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (match_operand:SI 5 "gpc_reg_operand" "=b")) (clobber (match_operand 5 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"#" "#"
[(set_attr "length" "24")]) [(set_attr "length" "24")])
...@@ -3607,9 +3641,9 @@ ...@@ -3607,9 +3641,9 @@
(use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:SI 2 "gpc_reg_operand" ""))
(use (match_operand:DF 3 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" ""))
(clobber (match_operand:SI 4 "gpc_reg_operand" "")) (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
(clobber (match_operand:SI 5 "gpc_reg_operand" "")) (clobber (match_operand 5 "gpc_reg_operand" ""))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
[(set (match_dup 4) [(set (match_dup 4)
(xor:SI (match_dup 1) (xor:SI (match_dup 1)
(match_dup 6))) (match_dup 6)))
...@@ -3641,7 +3675,7 @@ ...@@ -3641,7 +3675,7 @@
(use (match_dup 3)) (use (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
(clobber (reg:DF 76))])] (clobber (reg:DF 76))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
" "
{ {
operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[2] = force_reg (SImode, GEN_INT (0x43300000));
...@@ -3654,9 +3688,9 @@ ...@@ -3654,9 +3688,9 @@
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f")) (use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=b")) (clobber (match_operand 4 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"#" "#"
[(set_attr "length" "20")]) [(set_attr "length" "20")])
...@@ -3665,9 +3699,9 @@ ...@@ -3665,9 +3699,9 @@
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
(use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:SI 2 "gpc_reg_operand" ""))
(use (match_operand:DF 3 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" ""))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=b")) (clobber (match_operand 4 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
[(set (match_dup 4) [(set (match_dup 4)
(unspec [(const_int 0)] 11)) (unspec [(const_int 0)] 11))
(set (match_dup 5) (set (match_dup 5)
...@@ -3687,7 +3721,7 @@ ...@@ -3687,7 +3721,7 @@
;; Load up scratch register with base address + offset if needed ;; Load up scratch register with base address + offset if needed
(define_insn "*floatsidf2_loadaddr" (define_insn "*floatsidf2_loadaddr"
[(set (match_operand:SI 0 "gpc_reg_operand" "=b") [(set (match_operand 0 "gpc_reg_operand" "=b")
(unspec [(const_int 0)] 11))] (unspec [(const_int 0)] 11))]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"* "*
...@@ -3709,8 +3743,8 @@ ...@@ -3709,8 +3743,8 @@
(define_insn "*floatsidf2_store1" (define_insn "*floatsidf2_store1"
[(set (reg:DF 76) [(set (reg:DF 76)
(unspec [(match_operand:SI 0 "gpc_reg_operand" "r") (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
(match_operand:SI 1 "gpc_reg_operand" "r")] 12))] (match_operand 1 "gpc_reg_operand" "b")] 12))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"* "*
{ {
rtx indx; rtx indx;
...@@ -3735,9 +3769,9 @@ ...@@ -3735,9 +3769,9 @@
(define_insn "*floatsidf2_store2" (define_insn "*floatsidf2_store2"
[(set (reg:DF 76) [(set (reg:DF 76)
(unspec [(match_operand:SI 0 "gpc_reg_operand" "r") (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
(match_operand:SI 1 "gpc_reg_operand" "r") (match_operand 1 "gpc_reg_operand" "b")
(reg:DF 76)] 13))] (reg:DF 76)] 13))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"* "*
{ {
rtx indx; rtx indx;
...@@ -3762,8 +3796,8 @@ ...@@ -3762,8 +3796,8 @@
(define_insn "*floatsidf2_load" (define_insn "*floatsidf2_load"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f") [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec [(reg:DF 76) (unspec [(reg:DF 76)
(match_operand:SI 1 "gpc_reg_operand" "b")] 14))] (match_operand 1 "gpc_reg_operand" "b")] 14))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"* "*
{ {
rtx indx; rtx indx;
...@@ -3811,7 +3845,7 @@ ...@@ -3811,7 +3845,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
(clobber (match_operand:SI 3 "gpc_reg_operand" "=b")) (clobber (match_operand 3 "gpc_reg_operand" "=b"))
(clobber (reg:DI 76))] (clobber (reg:DI 76))]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"#" "#"
...@@ -3821,7 +3855,7 @@ ...@@ -3821,7 +3855,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "") [(set (match_operand:SI 0 "gpc_reg_operand" "")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "")) (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:SI 3 "gpc_reg_operand" "")) (clobber (match_operand 3 "gpc_reg_operand" ""))
(clobber (reg:DI 76))] (clobber (reg:DI 76))]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
[(set (match_dup 2) [(set (match_dup 2)
...@@ -3836,17 +3870,10 @@ ...@@ -3836,17 +3870,10 @@
(match_dup 3)] 16))] (match_dup 3)] 16))]
"operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);") "operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);")
(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 "*fix_truncdfsi2_store" (define_insn "*fix_truncdfsi2_store"
[(set (reg:DI 76) [(set (reg:DI 76)
(unspec [(match_operand:DI 0 "gpc_reg_operand" "f") (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
(match_operand:SI 1 "gpc_reg_operand" "b")] 15))] (match_operand 1 "gpc_reg_operand" "b")] 15))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"* "*
{ {
...@@ -3872,7 +3899,7 @@ ...@@ -3872,7 +3899,7 @@
(define_insn "*fix_truncdfsi2_load" (define_insn "*fix_truncdfsi2_load"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec [(reg:DI 76) (unspec [(reg:DI 76)
(match_operand:SI 1 "gpc_reg_operand" "b")] 16))] (match_operand 1 "gpc_reg_operand" "b")] 16))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"* "*
{ {
...@@ -3940,6 +3967,13 @@ ...@@ -3940,6 +3967,13 @@
rs6000_trunc_used = 1; 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" (define_insn "floatdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f") [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))] (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
...@@ -4286,18 +4320,39 @@ ...@@ -4286,18 +4320,39 @@
(define_expand "adddi3" (define_expand "adddi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (match_operand:DI 1 "gpc_reg_operand" "") (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "add_operand" "")))] (match_operand:DI 2 "reg_or_cint_operand" "")))]
"" ""
" "
{ {
if (! TARGET_POWERPC64 && non_short_cint_operand (operands[2], DImode)) if (! TARGET_POWERPC64)
FAIL; {
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 ;; Discourage ai/addic because of carry but provide it in an alternative
;; allowing register zero as source. ;; allowing register zero as source.
(define_insn "" (define_insn "*adddi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r") [(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") (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
(match_operand:DI 2 "add_operand" "r,I,I,J")))] (match_operand:DI 2 "add_operand" "r,I,I,J")))]
...@@ -4308,7 +4363,7 @@ ...@@ -4308,7 +4363,7 @@
addic %0,%1,%2 addic %0,%1,%2
addis %0,%1,%v2") addis %0,%1,%v2")
(define_insn "" (define_insn "*adddi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x") [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
(compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "reg_or_short_operand" "r,I")) (match_operand:DI 2 "reg_or_short_operand" "r,I"))
...@@ -4320,7 +4375,7 @@ ...@@ -4320,7 +4375,7 @@
addic. %3,%1,%2" addic. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*adddi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x") [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
(compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "reg_or_short_operand" "r,I")) (match_operand:DI 2 "reg_or_short_operand" "r,I"))
...@@ -4431,7 +4486,7 @@ ...@@ -4431,7 +4486,7 @@
(abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
(clobber (match_scratch:DI 2 "=&r,&r"))] (clobber (match_scratch:DI 2 "=&r,&r"))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0" "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%2,%0"
[(set_attr "length" "12")]) [(set_attr "length" "12")])
(define_split (define_split
...@@ -4439,7 +4494,7 @@ ...@@ -4439,7 +4494,7 @@
(abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
(clobber (match_scratch:DI 2 "=&r,&r"))] (clobber (match_scratch:DI 2 "=&r,&r"))]
"TARGET_POWERPC64 && reload_completed" "TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31))) [(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) (xor:DI (match_dup 2) (match_dup 1)))
(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))] (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
"") "")
...@@ -4449,7 +4504,7 @@ ...@@ -4449,7 +4504,7 @@
(neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
(clobber (match_scratch:DI 2 "=&r,&r"))] (clobber (match_scratch:DI 2 "=&r,&r"))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2" "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%0,%2"
[(set_attr "length" "12")]) [(set_attr "length" "12")])
(define_split (define_split
...@@ -4457,7 +4512,7 @@ ...@@ -4457,7 +4512,7 @@
(neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
(clobber (match_scratch:DI 2 "=&r,&r"))] (clobber (match_scratch:DI 2 "=&r,&r"))]
"TARGET_POWERPC64 && reload_completed" "TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31))) [(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) (xor:DI (match_dup 2) (match_dup 1)))
(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
"") "")
...@@ -4508,6 +4563,14 @@ ...@@ -4508,6 +4563,14 @@
"mulld %0,%1,%2" "mulld %0,%1,%2"
[(set_attr "type" "imul")]) [(set_attr "type" "imul")])
(define_insn "*mulsidi3_ppc64"
[(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_POWERPC64"
"mulld %0,%1,%2"
[(set_attr "type" "imul")])
(define_insn "smuldi3_highpart" (define_insn "smuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI (truncate:DI
...@@ -4603,7 +4666,7 @@ ...@@ -4603,7 +4666,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(div:DI (match_operand:DI 1 "gpc_reg_operand" "r") (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "gpc_reg_operand" "r")))] (match_operand:DI 2 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"divd %0,%1,%2" "divd %0,%1,%2"
[(set_attr "type" "idiv")]) [(set_attr "type" "idiv")])
...@@ -4623,7 +4686,7 @@ ...@@ -4623,7 +4686,7 @@
"TARGET_POWERPC64" "TARGET_POWERPC64"
"rld%I2cl %0,%1,%H2,0") "rld%I2cl %0,%1,%H2,0")
(define_insn "" (define_insn "*rotldi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_cint_operand" "ri")) (match_operand:DI 2 "reg_or_cint_operand" "ri"))
...@@ -4633,7 +4696,7 @@ ...@@ -4633,7 +4696,7 @@
"rld%I2cl. %3,%1,%H2,0" "rld%I2cl. %3,%1,%H2,0"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "" (define_insn "*rotldi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_cint_operand" "ri")) (match_operand:DI 2 "reg_or_cint_operand" "ri"))
...@@ -4644,6 +4707,141 @@ ...@@ -4644,6 +4707,141 @@
"rld%I2cl. %0,%1,%H2,0" "rld%I2cl. %0,%1,%H2,0"
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(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")
(compare:CC (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"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r"))]
"TARGET_POWERPC64"
"rld%I2c%B3. %4,%1,%H2,%S3"
[(set_attr "type" "delayed_compare")])
(define_insn "*rotldi3_internal6"
[(set (match_operand:CC 4 "cc_reg_operand" "=x")
(compare:CC (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"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=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")])
(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")
(compare:CC (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))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r"))]
"TARGET_POWERPC64"
"rld%I2cl. %3,%1,%H2,56"
[(set_attr "type" "delayed_compare")])
(define_insn "*rotldi3_internal9"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (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))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=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")])
(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")
(compare:CC (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))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r"))]
"TARGET_POWERPC64"
"rld%I2cl. %3,%1,%H2,48"
[(set_attr "type" "delayed_compare")])
(define_insn "*rotldi3_internal12"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (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))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=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")])
(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")
(compare:CC (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))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r"))]
"TARGET_POWERPC64"
"rld%I2cl. %3,%1,%H2,32"
[(set_attr "type" "delayed_compare")])
(define_insn "*rotldi3_internal15"
[(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (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))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=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")])
(define_expand "ashldi3" (define_expand "ashldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
...@@ -4784,84 +4982,69 @@ ...@@ -4784,84 +4982,69 @@
[(set_attr "type" "delayed_compare")]) [(set_attr "type" "delayed_compare")])
(define_insn "anddi3" (define_insn "anddi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:DI 2 "and_operand" "?r,K,J"))) (match_operand:DI 2 "and64_operand" "?r,S,K,J")))
(clobber (match_scratch:CC 3 "=X,x,x"))] (clobber (match_scratch:CC 3 "=X,X,x,x"))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"@ "@
and %0,%1,%2 and %0,%1,%2
rldic%B2 %0,%1,0,%S2
andi. %0,%1,%b2 andi. %0,%1,%b2
andis. %0,%1,%u2") andis. %0,%1,%u2")
(define_insn "" (define_insn "*anddi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x") [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:DI 2 "and_operand" "r,K,J")) (match_operand:DI 2 "and64_operand" "r,K,J,S"))
(const_int 0))) (const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r"))] (clobber (match_scratch:DI 3 "=r,r,r,r"))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"@ "@
and. %3,%1,%2 and. %3,%1,%2
andi. %3,%1,%b2 andi. %3,%1,%b2
andis. %3,%1,%u2" andis. %3,%1,%u2
[(set_attr "type" "compare,compare,compare")]) rldic%B2. %3,%1,0,%S2"
[(set_attr "type" "compare,compare,compare,delayed_compare")])
(define_insn "" (define_insn "*anddi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x") [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
(match_operand:DI 2 "and_operand" "r,K,J")) (match_operand:DI 2 "and64_operand" "r,K,J,S"))
(const_int 0))) (const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(and:DI (match_dup 1) (match_dup 2)))] (and:DI (match_dup 1) (match_dup 2)))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"@ "@
and. %0,%1,%2 and. %0,%1,%2
andi. %0,%1,%b2 andi. %0,%1,%b2
andis. %0,%1,%u2" andis. %0,%1,%u2
[(set_attr "type" "compare,compare,compare")]) rldic%B2. %3,%1,0,%S2"
[(set_attr "type" "compare,compare,compare,delayed_compare")])
;; Take a AND with a constant that cannot be done in a single insn and try to
;; split it into two insns. This does not verify that the insns are valid
;; since this need not be done as combine will do it.
(define_split (define_expand "iordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(and:DI (match_operand:DI 1 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "non_and_cint_operand" "")))] (match_operand:DI 2 "reg_or_cint_operand" "")))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
" "
{ {
int maskval = INTVAL (operands[2]); if (GET_CODE (operands[2]) == CONST_INT
int i, transitions, last_bit_value; && !logical_operand (operands[2], DImode))
int orig = maskval, first_c = maskval, second_c;
/* We know that MASKVAL must have more than 2 bit-transitions. Start at
the low-order bit and count for the third transition. When we get there,
make a first mask that has everything to the left of that position
a one. Then make the second mask to turn off whatever else is needed. */
for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
{ {
if (((maskval >>= 1) & 1) != last_bit_value) HOST_WIDE_INT value = INTVAL (operands[2]);
last_bit_value ^= 1, transitions++; rtx tmp = ((reload_in_progress || reload_completed
|| rtx_equal_p (operands[0], operands[1]))
? operands[0] : gen_reg_rtx (DImode));
if (transitions > 2) emit_insn (gen_iordi3 (tmp, operands[1],
{ GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
first_c |= (~0) << i; emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
break; DONE;
}
} }
second_c = orig | ~ first_c;
operands[3] = GEN_INT (first_c);
operands[4] = GEN_INT (second_c);
}") }")
(define_insn "iordi3" (define_insn "*iordi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
(ior:DI (match_operand:DI 1 "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")))] (match_operand:DI 2 "logical_operand" "r,K,J")))]
...@@ -4871,7 +5054,7 @@ ...@@ -4871,7 +5054,7 @@
ori %0,%1,%b2 ori %0,%1,%b2
oris %0,%1,%u2") oris %0,%1,%u2")
(define_insn "" (define_insn "*iordi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -4881,7 +5064,7 @@ ...@@ -4881,7 +5064,7 @@
"or. %3,%1,%2" "or. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*iordi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -4908,7 +5091,29 @@ ...@@ -4908,7 +5091,29 @@
operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
}") }")
(define_insn "xordi3" (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") [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
(xor:DI (match_operand:DI 1 "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")))] (match_operand:DI 2 "logical_operand" "r,K,J")))]
...@@ -4918,7 +5123,7 @@ ...@@ -4918,7 +5123,7 @@
xori %0,%1,%b2 xori %0,%1,%b2
xoris %0,%1,%u2") xoris %0,%1,%u2")
(define_insn "" (define_insn "*xordi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -4928,7 +5133,7 @@ ...@@ -4928,7 +5133,7 @@
"xor. %3,%1,%2" "xor. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*xordi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -4944,25 +5149,25 @@ ...@@ -4944,25 +5149,25 @@
(define_split (define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:DI 2 "non_logical_cint_operand" "")))] (match_operand:DI 2 "non_logical_cint_operand" "")))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
[(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3))) [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))] (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
" "
{ {
operands[3] = GEN_INT (INTVAL (operands[2]) & 0xffff0000); operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
}") }")
(define_insn "" (define_insn "*eqvdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r"))))] (match_operand:DI 2 "gpc_reg_operand" "r"))))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"eqv %0,%1,%2") "eqv %0,%1,%2")
(define_insn "" (define_insn "*eqvdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r"))) (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -4972,7 +5177,7 @@ ...@@ -4972,7 +5177,7 @@
"eqv. %3,%1,%2" "eqv. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*eqvdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r"))) (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -4983,14 +5188,14 @@ ...@@ -4983,14 +5188,14 @@
"eqv. %0,%1,%2" "eqv. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*andcdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")))] (match_operand:DI 2 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"andc %0,%2,%1") "andc %0,%2,%1")
(define_insn "" (define_insn "*andcdi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -5000,7 +5205,7 @@ ...@@ -5000,7 +5205,7 @@
"andc. %3,%2,%1" "andc. %3,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*andcdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -5011,14 +5216,14 @@ ...@@ -5011,14 +5216,14 @@
"andc. %0,%2,%1" "andc. %0,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*iorcdi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")))] (match_operand:DI 2 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"orc %0,%2,%1") "orc %0,%2,%1")
(define_insn "" (define_insn "*iorcdi3_inernal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -5028,7 +5233,7 @@ ...@@ -5028,7 +5233,7 @@
"orc. %3,%2,%1" "orc. %3,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*iorcdi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r"))
...@@ -5039,14 +5244,14 @@ ...@@ -5039,14 +5244,14 @@
"orc. %0,%2,%1" "orc. %0,%2,%1"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*nanddi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(ior:DI (not:DI (match_operand:DI 1 "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"))))] (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"nand %0,%1,%2") "nand %0,%1,%2")
(define_insn "" (define_insn "*nanddi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -5056,7 +5261,7 @@ ...@@ -5056,7 +5261,7 @@
"nand. %3,%1,%2" "nand. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*nanddi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -5067,14 +5272,14 @@ ...@@ -5067,14 +5272,14 @@
"nand. %0,%1,%2" "nand. %0,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*nordi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "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"))))] (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"nor %0,%1,%2") "nor %0,%1,%2")
(define_insn "" (define_insn "*nordi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -5084,7 +5289,7 @@ ...@@ -5084,7 +5289,7 @@
"nor. %3,%1,%2" "nor. %3,%1,%2"
[(set_attr "type" "compare")]) [(set_attr "type" "compare")])
(define_insn "" (define_insn "*nordi3_internal3"
[(set (match_operand:CC 3 "cc_reg_operand" "=x") [(set (match_operand:CC 3 "cc_reg_operand" "=x")
(compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
...@@ -5312,14 +5517,12 @@ ...@@ -5312,14 +5517,12 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h") [(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,S,T,U,m,r,I,J,n,R,*h,r,r,0"))] (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[0], SImode)
|| gpc_reg_operand (operands[1], SImode)" || gpc_reg_operand (operands[1], SImode)"
"@ "@
mr %0,%1 mr %0,%1
{l|lwz} %0,[toc]%1(2)
{l|lwz} %0,[toc]%l1(2)
{cal|la} %0,%a1 {cal|la} %0,%a1
{l%U1%X1|lwz%U1%X1} %0,%1 {l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0 {st%U0%X0|stw%U0%X0} %1,%0
...@@ -5331,8 +5534,8 @@ ...@@ -5331,8 +5534,8 @@
mt%0 %1 mt%0 %1
mt%0 %1 mt%0 %1
cror 0,0,0" cror 0,0,0"
[(set_attr "type" "*,load,load,*,load,store,*,*,*,*,*,*,mtjmpr,*") [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*")
(set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")]) (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 ;; Split a load of a large constant into the appropriate two-insn
;; sequence. ;; sequence.
...@@ -5567,7 +5770,7 @@ ...@@ -5567,7 +5770,7 @@
(define_split (define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "") [(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operand:SF 1 "const_double_operand" ""))] (match_operand:SF 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed "! TARGET_POWERPC64 && reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG || (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG && GET_CODE (SUBREG_REG (operands[0])) == REG
...@@ -5585,6 +5788,27 @@ ...@@ -5585,6 +5788,27 @@
operands[3] = GEN_INT(l); operands[3] = GEN_INT(l);
}") }")
(define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operand:SF 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 3))]
"
{
long l;
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
operands[2] = gen_lowpart (SImode, operands[0]);
operands[3] = GEN_INT(l);
}")
(define_insn "*movsf_hardfloat" (define_insn "*movsf_hardfloat"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,!r,!r") [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,!r,!r")
(match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))] (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
...@@ -5656,7 +5880,7 @@ ...@@ -5656,7 +5880,7 @@
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "const_int_operand" ""))] (match_operand:DF 1 "const_int_operand" ""))]
"TARGET_32BIT && reload_completed "! TARGET_POWERPC64 && reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG || (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG && GET_CODE (SUBREG_REG (operands[0])) == REG
...@@ -5674,7 +5898,7 @@ ...@@ -5674,7 +5898,7 @@
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "const_double_operand" ""))] (match_operand:DF 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed "! TARGET_POWERPC64 && reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG || (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG && GET_CODE (SUBREG_REG (operands[0])) == REG
...@@ -5699,14 +5923,25 @@ ...@@ -5699,14 +5923,25 @@
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "easy_fp_constant" ""))] (match_operand:DF 1 "easy_fp_constant" ""))]
"TARGET_64BIT && reload_completed "TARGET_POWERPC64 && reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG || (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG && GET_CODE (SUBREG_REG (operands[0])) == REG
&& REGNO (SUBREG_REG (operands[0])) <= 31))" && REGNO (SUBREG_REG (operands[0])) <= 31))"
[(set (match_dup 2) (subreg:DI (match_dup 1) 0))] [(set (match_dup 2) (match_dup 3))]
" "
{ operands[2] = gen_lowpart (DImode, operands[0]); }") {
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, ;; Don't have reload use general registers to load a constant. First,
;; it might not work if the output operand has is the equivalent of ;; it might not work if the output operand has is the equivalent of
...@@ -5724,6 +5959,8 @@ ...@@ -5724,6 +5959,8 @@
{ {
switch (which_alternative) switch (which_alternative)
{ {
default:
abort();
case 0: case 0:
/* We normally copy the low-numbered register first. However, if /* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of the first register operand 0 is the same as the second register of
...@@ -5769,6 +6006,8 @@ ...@@ -5769,6 +6006,8 @@
{ {
switch (which_alternative) switch (which_alternative)
{ {
default:
abort();
case 0: case 0:
/* We normally copy the low-numbered register first. However, if /* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of the first register operand 0 is the same as the second register of
...@@ -5844,77 +6083,74 @@ ...@@ -5844,77 +6083,74 @@
if (GET_CODE (operands[0]) != REG) if (GET_CODE (operands[0]) != REG)
operands[1] = force_reg (DImode, operands[1]); operands[1] = force_reg (DImode, operands[1]);
if (TARGET_64BIT /* Convert a move of a CONST_DOUBLE into a CONST_INT
&& (GET_CODE (operands[1]) == CONST_DOUBLE only if sign-extended lower-half for 32-bit host. */
|| GET_CODE (operands[1]) == CONST_INT)) if (GET_CODE (operands[1]) == CONST_DOUBLE
{
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 #if HOST_BITS_PER_WIDE_INT == 32
{ && ((CONST_DOUBLE_HIGH (operands[1]) == 0
low = INTVAL (operands[1]); && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
high = (low < 0) ? ~0 : 0; || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff
} && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
#else
{
low = INTVAL (operands[1]) & 0xffffffff;
high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
}
#endif #endif
)
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
if (high) if (TARGET_64BIT
{ && CONSTANT_P (operands[1])
emit_move_insn (operands[0], GEN_INT (high)); #if HOST_BITS_PER_WIDE_INT == 32
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32))); && GET_CODE (operands[1]) != CONST_INT
if (low) #endif
{ && ! easy_fp_constant (operands[1], DImode)
HOST_WIDE_INT low_low = low & 0xffff; && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff); {
if (low_high) /* Emit a USE operation so that the constant isn't deleted if
emit_insn (gen_iordi3 (operands[0], operands[0], expensive optimizations are turned on because nobody
GEN_INT (low_high))); references it. This should only be done for operands that
if (low_low) contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
emit_insn (gen_iordi3 (operands[0], operands[0], This should not be done for operands that contain LABEL_REFs.
GEN_INT (low_low))); For now, we just handle the obvious case. */
} if (GET_CODE (operands[1]) != LABEL_REF)
DONE; emit_insn (gen_rtx (USE, VOIDmode, operands[1]));
}
}
/* Stores between FPR and any non-FPR registers must go through a /* If we are to limit the number of things we put in the TOC and
temporary stack slot. */ 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);
if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG emit_insn (gen_adddi3 (operands[0], force_reg (DImode, sym), other));
&& ((FP_REGNO_P (REGNO (operands[0])) DONE;
&& ! FP_REGNO_P (REGNO (operands[1]))) }
|| (FP_REGNO_P (REGNO (operands[1]))
&& ! FP_REGNO_P (REGNO (operands[0])))))
{
rtx stack_slot = assign_stack_temp (DImode, 8, 0);
emit_move_insn (stack_slot, operands[1]); operands[1] = force_const_mem (DImode, operands[1]);
emit_move_insn (operands[0], stack_slot); if (! memory_address_p (DImode, XEXP (operands[1], 0))
DONE; && ! reload_in_progress)
operands[1] = change_address (operands[1], DImode,
XEXP (operands[1], 0));
} }
}") }")
(define_insn "*movdi_32" (define_insn "*movdi_32"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r") [(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"))] (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
"TARGET_32BIT "! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode) && (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))" || gpc_reg_operand (operands[1], DImode))"
"* "*
{ {
switch (which_alternative) switch (which_alternative)
{ {
default:
abort();
case 0: case 0:
/* We normally copy the low-numbered register first. However, if /* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of the first register operand 0 is the same as the second register of
...@@ -5955,7 +6191,7 @@ ...@@ -5955,7 +6191,7 @@
(define_split (define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_int_operand" ""))] (match_operand:DI 1 "const_int_operand" ""))]
"TARGET_32BIT && reload_completed" "! TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2) (match_dup 4)) [(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 1))] (set (match_dup 3) (match_dup 1))]
" "
...@@ -5968,7 +6204,7 @@ ...@@ -5968,7 +6204,7 @@
(define_split (define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))] (match_operand:DI 1 "const_double_operand" ""))]
"TARGET_32BIT && reload_completed" "! TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2) (match_dup 4)) [(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))] (set (match_dup 3) (match_dup 5))]
" "
...@@ -5982,7 +6218,7 @@ ...@@ -5982,7 +6218,7 @@
(define_insn "*movdi_64" (define_insn "*movdi_64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") [(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"))] (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
"TARGET_64BIT "TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode) && (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))" || gpc_reg_operand (operands[1], DImode))"
"@ "@
...@@ -6002,28 +6238,111 @@ ...@@ -6002,28 +6238,111 @@
[(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*") [(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")]) (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate five-instruction (define_insn ""
;; sequence. The expansion in movdi tries to perform the minimum number of [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
;; steps, but here we have to handle anything in a constant number of insns. (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 (define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "") [(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))] (match_operand:DI 1 "const_double_operand" ""))]
"TARGET_64BIT && num_insns_constant (operands[1], DImode) > 1" "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) [(set (match_dup 0)
(match_dup 2)) (match_dup 2))
(set (match_dup 0) (set (match_dup 0)
(ior:DI (match_dup 0) (ior:DI (match_dup 0)
(match_dup 3))) (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) (set (match_dup 0)
(ashift:DI (match_dup 0) (ashift:DI (match_dup 0)
(const_int 32))) (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) (set (match_dup 0)
(ior:DI (match_dup 0) (and:DI (rotate:DI (match_dup 0)
(match_dup 4))) (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) (set (match_dup 0)
(ior:DI (match_dup 0) (ior:DI (match_dup 0)
(match_dup 5)))] (match_dup 3)))]
" "
{ {
HOST_WIDE_INT low; HOST_WIDE_INT low;
...@@ -6047,14 +6366,8 @@ ...@@ -6047,14 +6366,8 @@
} }
#endif #endif
if ((high + 0x8000) < 0x10000 operands[2] = GEN_INT (high);
&& ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0)) operands[3] = GEN_INT (low);
FAIL;
operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff));
operands[3] = GEN_INT (high & 0xffff);
operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff));
operands[5] = GEN_INT (low & 0xffff);
}") }")
(define_insn "" (define_insn ""
...@@ -6097,7 +6410,7 @@ ...@@ -6097,7 +6410,7 @@
;; while the 2nd alternative would not. We put memory cases first so they ;; 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 ;; are preferred. Otherwise, we'd try to reload the output instead of
;; giving the SCRATCH mq. ;; giving the SCRATCH mq.
(define_insn "" (define_insn "*movti_power"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r") [(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")) (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
...@@ -6151,7 +6464,7 @@ ...@@ -6151,7 +6464,7 @@
[(set_attr "type" "store,store,*,load,load") [(set_attr "type" "store,store,*,load,load")
(set_attr "length" "*,16,16,*,16")]) (set_attr "length" "*,16,16,*,16")])
(define_insn "" (define_insn "*movti_string"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r") [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,m")) (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
(clobber (match_scratch:SI 2 "=X,X,X"))] (clobber (match_scratch:SI 2 "=X,X,X"))]
...@@ -6196,7 +6509,7 @@ ...@@ -6196,7 +6509,7 @@
[(set_attr "type" "store,*,load") [(set_attr "type" "store,*,load")
(set_attr "length" "16,16,16")]) (set_attr "length" "16,16,16")])
(define_insn "" (define_insn "*movti_ppc64"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
(match_operand:TI 1 "input_operand" "r,m,r"))] (match_operand:TI 1 "input_operand" "r,m,r"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
...@@ -6205,6 +6518,8 @@ ...@@ -6205,6 +6518,8 @@
{ {
switch (which_alternative) switch (which_alternative)
{ {
default:
abort();
case 0: case 0:
/* We normally copy the low-numbered register first. However, if /* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of the first register operand 0 is the same as the second register of
...@@ -6919,10 +7234,10 @@ ...@@ -6919,10 +7234,10 @@
;; We move the back-chain and decrement the stack pointer. ;; We move the back-chain and decrement the stack pointer.
(define_expand "allocate_stack" (define_expand "allocate_stack"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand 0 "register_operand" "=r")
(minus:SI (reg:SI 1) (match_operand:SI 1 "reg_or_short_operand" ""))) (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
(set (reg:SI 1) (set (reg 1)
(minus:SI (reg:SI 1) (match_dup 1)))] (minus (reg 1) (match_dup 1)))]
"" ""
" "
{ rtx chain = gen_reg_rtx (Pmode); { rtx chain = gen_reg_rtx (Pmode);
...@@ -6937,9 +7252,9 @@ ...@@ -6937,9 +7252,9 @@
if (DEFAULT_ABI == ABI_NT if (DEFAULT_ABI == ABI_NT
&& (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096)) && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096))
{ {
rtx tmp = gen_reg_rtx (SImode); rtx tmp = gen_reg_rtx (Pmode);
emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"), emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
tmp, 0, SImode, 1, operands[1], Pmode); tmp, 0, Pmode, 1, operands[1], Pmode);
emit_insn (gen_set_sp (tmp)); emit_insn (gen_set_sp (tmp));
emit_move_insn (operands[0], tmp); emit_move_insn (operands[0], tmp);
DONE; DONE;
...@@ -6966,9 +7281,7 @@ ...@@ -6966,9 +7281,7 @@
{ {
emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3)) emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
(stack_pointer_rtx, stack_pointer_rtx, neg_op0)); (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
emit_move_insn (gen_rtx (MEM, (TARGET_32BIT) ? SImode : DImode, emit_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx), chain);
stack_pointer_rtx),
chain);
} }
emit_move_insn (operands[0], virtual_stack_dynamic_rtx); emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
...@@ -7005,40 +7318,44 @@ ...@@ -7005,40 +7318,44 @@
"") "")
(define_expand "restore_stack_block" (define_expand "restore_stack_block"
[(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" ""))) [(set (match_dup 2) (mem (match_operand 0 "register_operand" "")))
(set (match_dup 0) (match_operand:SI 1 "register_operand" "")) (set (match_dup 0) (match_operand 1 "register_operand" ""))
(set (mem:SI (match_dup 0)) (match_dup 2))] (set (mem (match_dup 0)) (match_dup 2))]
"" ""
" "
{ operands[2] = gen_reg_rtx (SImode); }") { operands[2] = gen_reg_rtx (Pmode); }")
(define_expand "save_stack_nonlocal" (define_expand "save_stack_nonlocal"
[(match_operand:DI 0 "memory_operand" "") [(match_operand 0 "memory_operand" "")
(match_operand:SI 1 "register_operand" "")] (match_operand 1 "register_operand" "")]
"" ""
" "
{ {
rtx temp = gen_reg_rtx (SImode); rtx temp = gen_reg_rtx (Pmode);
/* Copy the backchain to the first word, sp to the second. */ /* Copy the backchain to the first word, sp to the second. */
emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1])); emit_move_insn (temp, gen_rtx (MEM, Pmode, operands[1]));
emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp); emit_move_insn (operand_subword (operands[0], 0, 0, (TARGET_32BIT ? DImode : TImode)),
emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]); temp);
emit_move_insn (operand_subword (operands[0], 1, 0, (TARGET_32BIT ? DImode : TImode)),
operands[1]);
DONE; DONE;
}") }")
(define_expand "restore_stack_nonlocal" (define_expand "restore_stack_nonlocal"
[(match_operand:SI 0 "register_operand" "") [(match_operand 0 "register_operand" "")
(match_operand:DI 1 "memory_operand" "")] (match_operand 1 "memory_operand" "")]
"" ""
" "
{ {
rtx temp = gen_reg_rtx (SImode); rtx temp = gen_reg_rtx (Pmode);
/* Restore the backchain from the first word, sp from the second. */ /* Restore the backchain from the first word, sp from the second. */
emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode)); emit_move_insn (temp,
emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode)); operand_subword (operands[1], 0, 0, (TARGET_32BIT ? DImode : TImode)));
emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp); 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; DONE;
}") }")
...@@ -7070,7 +7387,7 @@ ...@@ -7070,7 +7387,7 @@
;; We do not break this into separate insns, so that the scheduler will not try ;; 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. ;; to move the load of the new TOC before any loads from the TOC.
(define_insn "call_indirect_aix" (define_insn "call_indirect_aix32"
[(call (mem:SI (match_operand:SI 0 "register_operand" "b")) [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
(match_operand 1 "const_int_operand" "n")) (match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "n")) (use (match_operand 2 "const_int_operand" "n"))
...@@ -7085,7 +7402,22 @@ ...@@ -7085,7 +7402,22 @@
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "28")]) (set_attr "length" "28")])
(define_insn "call_value_indirect_aix" (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)"
"stw %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") [(set (match_operand 0 "register_operand" "fg")
(call (mem:SI (match_operand:SI 1 "register_operand" "b")) (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
(match_operand 2 "const_int_operand" "n"))) (match_operand 2 "const_int_operand" "n")))
...@@ -7097,7 +7429,23 @@ ...@@ -7097,7 +7429,23 @@
(clobber (match_scratch:SI 8 "=l"))] (clobber (match_scratch:SI 8 "=l"))]
"DEFAULT_ABI == ABI_AIX "DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)" && (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" "{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)"
"stw %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 "type" "load")
(set_attr "length" "28")]) (set_attr "length" "28")])
...@@ -7190,7 +7538,7 @@ ...@@ -7190,7 +7538,7 @@
;; Now the definitions for the call and call_value insns ;; Now the definitions for the call and call_value insns
(define_expand "call" (define_expand "call"
[(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" "")) [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(use (match_operand 2 "" "")) (use (match_operand 2 "" ""))
(clobber (scratch:SI))])] (clobber (scratch:SI))])]
...@@ -7228,9 +7576,13 @@ ...@@ -7228,9 +7576,13 @@
{ {
/* AIX function pointers are really pointers to a three word area */ /* AIX function pointers are really pointers to a three word area */
rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM); rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]), emit_call_insn (TARGET_32BIT
operands[1], operands[2], ? gen_call_indirect_aix32 (force_reg (Pmode, operands[0]),
toc_addr, toc_reg, static_chain)); 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) else if (DEFAULT_ABI == ABI_NT)
{ {
...@@ -7248,7 +7600,7 @@ ...@@ -7248,7 +7600,7 @@
(define_expand "call_value" (define_expand "call_value"
[(parallel [(set (match_operand 0 "" "") [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "address_operand" "")) (call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(use (match_operand 3 "" "")) (use (match_operand 3 "" ""))
(clobber (scratch:SI))])] (clobber (scratch:SI))])]
...@@ -7286,10 +7638,15 @@ ...@@ -7286,10 +7638,15 @@
{ {
/* AIX function pointers are really pointers to a three word area */ /* AIX function pointers are really pointers to a three word area */
rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM); rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
emit_call_insn (gen_call_value_indirect_aix (operands[0], emit_call_insn (TARGET_32BIT
force_reg (Pmode, operands[1]), ? gen_call_value_indirect_aix32 (operands[0],
operands[2], operands[3], force_reg (Pmode, operands[1]),
toc_addr, toc_reg, static_chain)); 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) else if (DEFAULT_ABI == ABI_NT)
{ {
...@@ -7312,7 +7669,7 @@ ...@@ -7312,7 +7669,7 @@
;; variable argument function. It is > 0 if FP registers were passed ;; variable argument function. It is > 0 if FP registers were passed
;; and < 0 if they were not. ;; and < 0 if they were not.
(define_insn "" (define_insn "*call_local32"
[(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g")) (match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 2 "immediate_operand" "O,n"))
...@@ -7331,6 +7688,66 @@ ...@@ -7331,6 +7688,66 @@
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "4,8")]) (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 ;; Call to function which may be in another module. Restore the TOC
;; pointer (r2) after the call unless this is System V. ;; pointer (r2) after the call unless this is System V.
;; Operand2 is non-zero if we are using the V.4 calling sequence and ;; Operand2 is non-zero if we are using the V.4 calling sequence and
...@@ -7338,7 +7755,7 @@ ...@@ -7338,7 +7755,7 @@
;; variable argument function. It is > 0 if FP registers were passed ;; variable argument function. It is > 0 if FP registers were passed
;; and < 0 if they were not. ;; and < 0 if they were not.
(define_insn "" (define_insn "*call_nonlocal_aix32"
[(call (mem:SI (match_operand:SI 0 "call_operand" "s,s")) [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
(match_operand 1 "" "fg,fg")) (match_operand 1 "" "fg,fg"))
(use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 2 "immediate_operand" "O,n"))
...@@ -7362,7 +7779,31 @@ ...@@ -7362,7 +7779,31 @@
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "8,12")]) (set_attr "length" "8,12")])
(define_insn "" (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")) [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
(match_operand 1 "" "fg,fg")) (match_operand 1 "" "fg,fg"))
(use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 2 "immediate_operand" "O,n"))
...@@ -7386,33 +7827,38 @@ ...@@ -7386,33 +7827,38 @@
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "4,8")]) (set_attr "length" "4,8")])
(define_insn "" (define_insn "*ret_call_nonlocal_aix32"
[(set (match_operand 0 "" "=fg,fg") [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
(match_operand 2 "" "g,g"))) (match_operand 2 "" "fg,fg")))
(use (match_operand:SI 3 "immediate_operand" "O,n")) (use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))] (clobber (match_scratch:SI 4 "=l,l"))]
"(INTVAL (operands[3]) & CALL_LONG) == 0" "(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) if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
output_asm_insn (\"crxor 6,6,6\", operands); output_asm_insn (\"crxor 6,6,6\", operands);
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands); output_asm_insn (\"creqv 6,6,6\", operands);
return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
}" }"
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "4,8")]) (set_attr "length" "8,12")])
(define_insn "" (define_insn "*ret_call_nonlocal_aix64"
[(set (match_operand 0 "" "=fg,fg") [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "s,s")) (call (mem:SI (match_operand:DI 1 "call_operand" "s,s"))
(match_operand 2 "" "fg,fg"))) (match_operand 2 "" "fg,fg")))
(use (match_operand:SI 3 "immediate_operand" "O,n")) (use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))] (clobber (match_scratch:SI 4 "=l,l"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
&& (INTVAL (operands[3]) & CALL_LONG) == 0" && (INTVAL (operands[3]) & CALL_LONG) == 0"
"* "*
{ {
...@@ -7431,7 +7877,7 @@ ...@@ -7431,7 +7877,7 @@
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "8,12")]) (set_attr "length" "8,12")])
(define_insn "" (define_insn "*ret_call_nonlocal_sysv"
[(set (match_operand 0 "" "=fg,fg") [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "s,s")) (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
(match_operand 2 "" "fg,fg"))) (match_operand 2 "" "fg,fg")))
...@@ -8139,6 +8585,20 @@ ...@@ -8139,6 +8585,20 @@
[(set_attr "length" "12,8,12,12,12")]) [(set_attr "length" "12,8,12,12,12")])
(define_insn "" (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") [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
(compare:CC (compare:CC
(eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
...@@ -8157,6 +8617,25 @@ ...@@ -8157,6 +8617,25 @@
[(set_attr "type" "compare") [(set_attr "type" "compare")
(set_attr "length" "12,8,12,12,12")]) (set_attr "length" "12,8,12,12,12")])
(define_insn ""
[(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
(compare:CC
(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"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
(eq:DI (match_dup 1) (match_dup 2)))
(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 "type" "compare")
(set_attr "length" "12,8,12,12,12")])
;; We have insns of the form shown by the first define_insn below. If ;; 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. ;; there is something inside the comparison operation, we must split it.
(define_split (define_split
...@@ -8251,6 +8730,15 @@ ...@@ -8251,6 +8730,15 @@
"{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
[(set_attr "length" "8")]) [(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. ;; This is what (plus (ne X (const_int 0)) Y) looks like.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
...@@ -8264,6 +8752,17 @@ ...@@ -8264,6 +8752,17 @@
[(set_attr "length" "8")]) [(set_attr "length" "8")])
(define_insn "" (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") [(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC (compare:CC
(plus:SI (lshiftrt:SI (plus:SI (lshiftrt:SI
...@@ -8278,6 +8777,20 @@ ...@@ -8278,6 +8777,20 @@
(set_attr "length" "8")]) (set_attr "length" "8")])
(define_insn "" (define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
(compare:CC
(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"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=&r"))]
"TARGET_POWERPC64"
"addic %3,%1,-1\;addze. %3,%2"
[(set_attr "type" "compare")
(set_attr "length" "8")])
(define_insn ""
[(set (match_operand:CC 4 "cc_reg_operand" "=x") [(set (match_operand:CC 4 "cc_reg_operand" "=x")
(compare:CC (compare:CC
(plus:SI (lshiftrt:SI (plus:SI (lshiftrt:SI
...@@ -8295,6 +8808,23 @@ ...@@ -8295,6 +8808,23 @@
(set_attr "length" "8")]) (set_attr "length" "8")])
(define_insn "" (define_insn ""
[(set (match_operand:CC 4 "cc_reg_operand" "=x")
(compare:CC
(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"))
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
(clobber (match_scratch:DI 3 "=&r"))]
"TARGET_POWERPC64"
"addic %3,%1,-1\;addze. %0,%2"
[(set_attr "type" "compare")
(set_attr "length" "8")])
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(le:SI (match_operand:SI 1 "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"))) (match_operand:SI 2 "reg_or_short_operand" "r,O")))
......
...@@ -266,7 +266,17 @@ do { \ ...@@ -266,7 +266,17 @@ do { \
/* Default ABI to compile code for */ /* Default ABI to compile code for */
#define DEFAULT_ABI rs6000_current_abi #define DEFAULT_ABI rs6000_current_abi
#include "rs6000/powerpc.h" #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, /* System V.4 uses register 13 as a pointer to the small data area,
so it is not available to the normal user. */ so it is not available to the normal user. */
......
# 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
/* Definitions of target machine for GNU compiler, for PowerPC /* Definitions of target machine for GNU compiler, for PowerPC
running Windows/NT. running Windows/NT.
Copyright (C) 1995, 1996 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support. Contributed by Cygnus Support.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -27,12 +27,21 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,12 +27,21 @@ Boston, MA 02111-1307, USA. */
/* Default ABI to compile code for */ /* Default ABI to compile code for */
#define DEFAULT_ABI ABI_NT #define DEFAULT_ABI ABI_NT
#include "rs6000/powerpc.h" #define CPP_DEFAULT_SPEC "-D_ARCH_PPC"
#define ASM_DEFAULT_SPEC "-mppc"
/* Pseudo target that we can test in the md file. */ /* Pseudo target that we can test in the md file. */
#undef TARGET_WINDOWS_NT
#define TARGET_WINDOWS_NT 1 #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 #undef CPP_PREDEFINES
#define CPP_PREDEFINES "-DWIN32 -D_WIN32 \ #define CPP_PREDEFINES "-DWIN32 -D_WIN32 \
-DWINNT -D__STDC__=0 -DALMOST_STDC \ -DWINNT -D__STDC__=0 -DALMOST_STDC \
...@@ -71,9 +80,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -71,9 +80,6 @@ Boston, MA 02111-1307, USA. */
#undef PREFERRED_DEBUGGING_TYPE #undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#undef PROCESSOR_DEFAULT
#define PROCESSOR_DEFAULT PROCESSOR_POWERPC
/* NT always runs little endian */ /* NT always runs little endian */
#undef BYTES_BIG_ENDIAN #undef BYTES_BIG_ENDIAN
#define BYTES_BIG_ENDIAN 0 #define BYTES_BIG_ENDIAN 0
...@@ -113,9 +119,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -113,9 +119,6 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC) #define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)
#undef PROCESSOR_DEFAULT
#define PROCESSOR_DEFAULT PROCESSOR_PPC601
/* Address to save the TOC register */ /* Address to save the TOC register */
#undef RS6000_SAVE_TOC #undef RS6000_SAVE_TOC
#define RS6000_SAVE_TOC plus_constant (virtual_incoming_args_rtx, -RS6000_SAVE_AREA - 8) #define RS6000_SAVE_TOC plus_constant (virtual_incoming_args_rtx, -RS6000_SAVE_AREA - 8)
...@@ -162,7 +165,7 @@ do { \ ...@@ -162,7 +165,7 @@ do { \
ASM_OUTPUT_SKIP (FILE, SIZE); \ ASM_OUTPUT_SKIP (FILE, SIZE); \
} while (0) } while (0)
/* Describe how to emit unitialized external linkage items */ /* Describe how to emit uninitialized external linkage items */
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \ do { \
ASM_GLOBALIZE_LABEL (FILE, NAME); \ ASM_GLOBALIZE_LABEL (FILE, NAME); \
......
# 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
# 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=ar -X32_64
...@@ -2443,7 +2443,7 @@ for machine in $build $host $target; do ...@@ -2443,7 +2443,7 @@ for machine in $build $host $target; do
fi fi
use_collect2=yes use_collect2=yes
;; ;;
rs6000-ibm-aix[[456789]].* | powerpc-ibm-aix[[456789]].*) rs6000-ibm-aix4.[[12]].* | powerpc-ibm-aix4.[[12]].*)
tm_file=rs6000/aix41.h tm_file=rs6000/aix41.h
if [[ x$host != x$target ]] if [[ x$host != x$target ]]
then then
...@@ -2451,7 +2451,29 @@ for machine in $build $host $target; do ...@@ -2451,7 +2451,29 @@ for machine in $build $host $target; do
else else
tmake_file=rs6000/t-newas tmake_file=rs6000/t-newas
fi fi
xmake_file=rs6000/x-aix31 xmake_file=rs6000/x-aix41
use_collect2=yes
;;
rs6000-ibm-aix4.[[3456789]].* | powerpc-ibm-aix4.[[3456789]].*)
tm_file=rs6000/aix43.h
if [[ x$host != x$target ]]
then
tmake_file=rs6000/t-xaix43
else
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
use_collect2=yes
;;
rs6000-ibm-aix[[56789]].* | powerpc-ibm-aix[[56789]].*)
tm_file=rs6000/aix43.h
if [[ x$host != x$target ]]
then
tmake_file=rs6000/t-xaix43
else
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
use_collect2=yes use_collect2=yes
;; ;;
rs6000-ibm-aix*) rs6000-ibm-aix*)
......
...@@ -867,7 +867,7 @@ emit_stack_save (save_level, psave, after) ...@@ -867,7 +867,7 @@ emit_stack_save (save_level, psave, after)
rtx sa = *psave; rtx sa = *psave;
/* The default is that we use a move insn and save in a Pmode object. */ /* The default is that we use a move insn and save in a Pmode object. */
rtx (*fcn) () = gen_move_insn; rtx (*fcn) () = gen_move_insn;
enum machine_mode mode = Pmode; enum machine_mode mode = STACK_SAVEAREA_MODE (save_level);
/* See if this machine has anything special to do for this kind of save. */ /* See if this machine has anything special to do for this kind of save. */
switch (save_level) switch (save_level)
...@@ -875,28 +875,19 @@ emit_stack_save (save_level, psave, after) ...@@ -875,28 +875,19 @@ emit_stack_save (save_level, psave, after)
#ifdef HAVE_save_stack_block #ifdef HAVE_save_stack_block
case SAVE_BLOCK: case SAVE_BLOCK:
if (HAVE_save_stack_block) if (HAVE_save_stack_block)
{ fcn = gen_save_stack_block;
fcn = gen_save_stack_block;
mode = insn_operand_mode[CODE_FOR_save_stack_block][0];
}
break; break;
#endif #endif
#ifdef HAVE_save_stack_function #ifdef HAVE_save_stack_function
case SAVE_FUNCTION: case SAVE_FUNCTION:
if (HAVE_save_stack_function) if (HAVE_save_stack_function)
{ fcn = gen_save_stack_function;
fcn = gen_save_stack_function;
mode = insn_operand_mode[CODE_FOR_save_stack_function][0];
}
break; break;
#endif #endif
#ifdef HAVE_save_stack_nonlocal #ifdef HAVE_save_stack_nonlocal
case SAVE_NONLOCAL: case SAVE_NONLOCAL:
if (HAVE_save_stack_nonlocal) if (HAVE_save_stack_nonlocal)
{ fcn = gen_save_stack_nonlocal;
fcn = gen_save_stack_nonlocal;
mode = insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0];
}
break; break;
#endif #endif
default: default:
...@@ -975,7 +966,6 @@ emit_stack_restore (save_level, sa, after) ...@@ -975,7 +966,6 @@ emit_stack_restore (save_level, sa, after)
break; break;
#endif #endif
#ifdef HAVE_restore_stack_nonlocal #ifdef HAVE_restore_stack_nonlocal
case SAVE_NONLOCAL: case SAVE_NONLOCAL:
if (HAVE_restore_stack_nonlocal) if (HAVE_restore_stack_nonlocal)
fcn = gen_restore_stack_nonlocal; fcn = gen_restore_stack_nonlocal;
...@@ -1243,18 +1233,15 @@ allocate_dynamic_stack_space (size, target, known_align) ...@@ -1243,18 +1233,15 @@ allocate_dynamic_stack_space (size, target, known_align)
#ifdef HAVE_allocate_stack #ifdef HAVE_allocate_stack
if (HAVE_allocate_stack) if (HAVE_allocate_stack)
{ {
enum machine_mode mode;
if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0] if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]
&& ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]) && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0])
(target, Pmode))) (target, Pmode)))
target = copy_to_mode_reg (Pmode, target); target = copy_to_mode_reg (Pmode, target);
mode = insn_operand_mode[(int) CODE_FOR_allocate_stack][1]; size = convert_modes (Pmode, ptr_mode, size, 1);
size = convert_modes (mode, ptr_mode, size, 1);
if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][1] if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][1]
&& ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][1]) && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][1])
(size, mode))) (size, Pmode)))
size = copy_to_mode_reg (mode, size); size = copy_to_mode_reg (Pmode, size);
emit_insn (gen_allocate_stack (target, size)); emit_insn (gen_allocate_stack (target, size));
} }
......
...@@ -7771,7 +7771,8 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) ...@@ -7771,7 +7771,8 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
rtx first_label, next_label; rtx first_label, next_label;
{ {
rtx lab1 = gen_label_rtx (); rtx lab1 = gen_label_rtx ();
enum machine_mode sa_mode = Pmode, value_mode; enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
enum machine_mode value_mode;
rtx stack_save; rtx stack_save;
value_mode = TYPE_MODE (integer_type_node); value_mode = TYPE_MODE (integer_type_node);
...@@ -7803,11 +7804,6 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) ...@@ -7803,11 +7804,6 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
GET_MODE_SIZE (Pmode)))), GET_MODE_SIZE (Pmode)))),
gen_rtx_LABEL_REF (Pmode, lab1)); gen_rtx_LABEL_REF (Pmode, lab1));
#ifdef HAVE_save_stack_nonlocal
if (HAVE_save_stack_nonlocal)
sa_mode = insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0];
#endif
stack_save = gen_rtx_MEM (sa_mode, stack_save = gen_rtx_MEM (sa_mode,
plus_constant (buf_addr, plus_constant (buf_addr,
2 * GET_MODE_SIZE (Pmode))); 2 * GET_MODE_SIZE (Pmode)));
...@@ -7899,7 +7895,7 @@ expand_builtin_longjmp (buf_addr, value) ...@@ -7899,7 +7895,7 @@ expand_builtin_longjmp (buf_addr, value)
rtx buf_addr, value; rtx buf_addr, value;
{ {
rtx fp, lab, stack; rtx fp, lab, stack;
enum machine_mode sa_mode; enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
#ifdef POINTERS_EXTEND_UNSIGNED #ifdef POINTERS_EXTEND_UNSIGNED
buf_addr = convert_memory_address (Pmode, buf_addr); buf_addr = convert_memory_address (Pmode, buf_addr);
...@@ -7942,14 +7938,6 @@ expand_builtin_longjmp (buf_addr, value) ...@@ -7942,14 +7938,6 @@ expand_builtin_longjmp (buf_addr, value)
lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr, lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
GET_MODE_SIZE (Pmode))); GET_MODE_SIZE (Pmode)));
#ifdef HAVE_save_stack_nonlocal
sa_mode = (HAVE_save_stack_nonlocal
? insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0]
: Pmode);
#else
sa_mode = Pmode;
#endif
stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr, stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
2 * GET_MODE_SIZE (Pmode))); 2 * GET_MODE_SIZE (Pmode)));
......
...@@ -245,6 +245,13 @@ enum direction {none, upward, downward}; /* Value has this type. */ ...@@ -245,6 +245,13 @@ enum direction {none, upward, downward}; /* Value has this type. */
#define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode) #define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode)
#endif #endif
/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
Normally move_insn, so Pmode stack pointer. */
#ifndef STACK_SAVEAREA_MODE
#define STACK_SAVEAREA_MODE(LEVEL) Pmode
#endif
/* Provide default values for the macros controlling stack checking. */ /* Provide default values for the macros controlling stack checking. */
#ifndef STACK_CHECK_BUILTIN #ifndef STACK_CHECK_BUILTIN
......
...@@ -4242,6 +4242,21 @@ build_array_type (elt_type, index_type) ...@@ -4242,6 +4242,21 @@ build_array_type (elt_type, index_type)
return t; return t;
} }
/* Return the TYPE of the elements comprising
the innermost dimension of ARRAY. */
tree
get_inner_array_type (array)
tree array;
{
tree type = TREE_TYPE (array);
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
return type;
}
/* Construct, lay out and return /* Construct, lay out and return
the type of functions returning type VALUE_TYPE the type of functions returning type VALUE_TYPE
given arguments of types ARG_TYPES. given arguments of types ARG_TYPES.
......
...@@ -1393,6 +1393,7 @@ extern int tree_int_cst_equal PROTO((tree, tree)); ...@@ -1393,6 +1393,7 @@ extern int tree_int_cst_equal PROTO((tree, tree));
extern int tree_int_cst_lt PROTO((tree, tree)); extern int tree_int_cst_lt PROTO((tree, tree));
extern int tree_int_cst_sgn PROTO((tree)); extern int tree_int_cst_sgn PROTO((tree));
extern int index_type_equal PROTO((tree, tree)); extern int index_type_equal PROTO((tree, tree));
extern tree get_inner_array_type PROTO((tree));
/* From expmed.c. Since rtl.h is included after tree.h, we can't /* From expmed.c. Since rtl.h is included after tree.h, we can't
put the prototype here. Rtl.h does declare the prototype if put the prototype here. Rtl.h does declare the prototype if
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment