From: Geoff Keating Date: Thu, 16 Mar 2000 03:16:41 +0000 (+0000) Subject: See the ChangeLog on the branch for more details. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9ebbca7d736ea66eabef6263a4317458bc2676ac;p=gcc.git See the ChangeLog on the branch for more details. * configure.in: Merge in changes from newppc-branch. * configure: Regenerate. * config/rs6000/*: Merge in changes from newppc-branch. Also correct copyright notices. From-SVN: r32575 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c16f4b6ceb3..5b521c38f6d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2000-03-15 Geoff Keating + + See the ChangeLog on the branch for more details. + + * configure.in: Merge in changes from newppc-branch. + * configure: Regenerate. + * config/rs6000/*: Merge in changes from newppc-branch. + Also correct copyright notices. + Wed Mar 15 15:43:38 2000 Jeffrey A Law (law@cygnus.com) * acconfig.h (HAVE_GAS_WEAK): New define. diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h new file mode 100644 index 00000000000..9f2b996b74c --- /dev/null +++ b/gcc/config/rs6000/aix.h @@ -0,0 +1,544 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX. + Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Yes! We are AIX! */ +#define DEFAULT_ABI ABI_AIX +#define TARGET_OBJECT_FORMAT OBJECT_XCOFF + +/* The RS/6000 uses the XCOFF format. */ + +#define XCOFF_DEBUGGING_INFO + +/* Define if the object format being used is COFF or a superset. */ +#define OBJECT_FORMAT_COFF + +/* Define the magic numbers that we recognize as COFF. + + AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c + does not include files in the correct order to conditionally define + the symbolic name in this macro. + + The AIX linker accepts import/export files as object files, + so accept "#!" (0x2321) magic number. */ +#define MY_ISCOFF(magic) \ + ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \ + || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0x2321) + +/* This is the only version of nm that collect2 can work with. */ +#define REAL_NM_FILE_NAME "/usr/ucb/nm" + +/* We don't have GAS for the RS/6000 yet, so don't write out special + .stabs in cc1plus. */ + +#define FASCIST_ASSEMBLER + +/* AIX does not have any init/fini or ctor/dtor sections, so create + static constructors and destructors as normal functions. */ +/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */ +/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */ + +/* The prefix to add to user-visible assembler symbols. */ +#define USER_LABEL_PREFIX "." + +/* Don't turn -B into -L if the argument specifies a relative file name. */ +#define RELATIVE_PREFIX_NOT_LINKDIR + +/* Names to predefine in the preprocessor for this target machine. */ + +#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \ +-Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" + +/* Tell the assembler to assume that all undefined names are external. + + Don't do this until the fixed IBM assembler is more generally available. + When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL, + ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no + longer be needed. Also, the extern declaration of mcount in ASM_FILE_START + will no longer be needed. */ + +/* #define ASM_SPEC "-u %(asm_cpu)" */ + +/* Default location of syscalls.exp under AIX */ +#ifndef CROSS_COMPILE +#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp" +#else +#define LINK_SYSCALLS_SPEC "" +#endif + +/* Default location of libg.exp under AIX */ +#ifndef CROSS_COMPILE +#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp" +#else +#define LINK_LIBG_SPEC "" +#endif + +/* Define the options for the binder: Start text at 512, align all segments + to 512 bytes, and warn if there is text relocation. + + The -bhalt:4 option supposedly changes the level at which ld will abort, + but it also suppresses warnings about multiply defined symbols and is + used by the AIX cc command. So we use it here. + + -bnodelcsect undoes a poor choice of default relating to multiply-defined + csects. See AIX documentation for more information about this. + + -bM:SRE tells the linker that the output file is Shared REusable. Note + that to actually build a shared library you will also need to specify an + export list with the -Wl,-bE option. */ + +#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ +%{static:-bnso %(link_syscalls) } \ +%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" + +/* Profiled library versions are used by linking with special directories. */ +#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ +%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" + +/* Define the extra sections we need. We define three: one is the read-only + data section which is used for constants. This is a csect whose name is + derived from the name of the input file. The second is for initialized + global variables. This is a csect whose name is that of the variable. + The third is the TOC. */ + +#define EXTRA_SECTIONS \ + read_only_data, private_data, read_only_private_data, toc, bss + +/* Define the routines to implement these extra sections. + BIGGEST_ALIGNMENT is 64, so align the sections that much. */ + +#define EXTRA_SECTION_FUNCTIONS \ + \ +void \ +read_only_data_section () \ +{ \ + if (in_section != read_only_data) \ + { \ + fprintf (asm_out_file, "\t.csect %s[RO],3\n", \ + xcoff_read_only_section_name); \ + in_section = read_only_data; \ + } \ +} \ + \ +void \ +private_data_section () \ +{ \ + if (in_section != private_data) \ + { \ + fprintf (asm_out_file, "\t.csect %s[RW],3\n", \ + xcoff_private_data_section_name); \ + in_section = private_data; \ + } \ +} \ + \ +void \ +read_only_private_data_section () \ +{ \ + if (in_section != read_only_private_data) \ + { \ + fprintf (asm_out_file, "\t.csect %s[RO],3\n", \ + xcoff_private_data_section_name); \ + in_section = read_only_private_data; \ + } \ +} \ + \ +void \ +toc_section () \ +{ \ + if (TARGET_MINIMAL_TOC) \ + { \ + /* toc_section is always called at least once from ASM_FILE_START, \ + so this is guaranteed to always be defined once and only once \ + in each file. */ \ + if (! toc_initialized) \ + { \ + fputs ("\t.toc\nLCTOC..1:\n", asm_out_file); \ + fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \ + toc_initialized = 1; \ + } \ + \ + if (in_section != toc) \ + fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n", \ + (TARGET_32BIT ? "" : ",3")); \ + } \ + else \ + { \ + if (in_section != toc) \ + fputs ("\t.toc\n", asm_out_file); \ + } \ + in_section = toc; \ +} + +/* Define the name of our readonly data section. */ + +#define READONLY_DATA_SECTION read_only_data_section + +/* Select the section for an initialized data object. + + On the RS/6000, we have a special section for all variables except those + that are static. */ + +#define SELECT_SECTION(EXP,RELOC) \ +{ \ + if ((TREE_CODE (EXP) == STRING_CST \ + && ! flag_writable_strings) \ + || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd' \ + && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \ + && DECL_INITIAL (EXP) \ + && (DECL_INITIAL (EXP) == error_mark_node \ + || TREE_CONSTANT (DECL_INITIAL (EXP))) \ + && ! (RELOC))) \ + { \ + if (TREE_PUBLIC (EXP)) \ + read_only_data_section (); \ + else \ + read_only_private_data_section (); \ + } \ + else \ + { \ + if (TREE_PUBLIC (EXP)) \ + data_section (); \ + else \ + private_data_section (); \ + } \ +} + +/* Select section for constant in constant pool. + + On RS/6000, all constants are in the private read-only data area. + However, if this is being placed in the TOC it must be output as a + toc entry. */ + +#define SELECT_RTX_SECTION(MODE, X) \ +{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ + toc_section (); \ + else \ + read_only_private_data_section (); \ +} + +/* Indicate that jump tables go in the text section. */ + +#define JUMP_TABLES_IN_TEXT_SECTION 1 + +/* Enable AIX XL compiler calling convention breakage compatibility. */ +#undef TARGET_XL_CALL +#define MASK_XL_CALL 0x40000000 +#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + {"xl-call", MASK_XL_CALL, \ + "Always pass floating-point arguments in memory" }, \ + {"no-xl-call", - MASK_XL_CALL, \ + "Don't always pass floating-point arguments in memory" }, \ + SUBSUBTARGET_SWITCHES +#define SUBSUBTARGET_SWITCHES + +/* Define any extra SPECS that the compiler needs to generate. */ +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "link_syscalls", LINK_SYSCALLS_SPEC }, \ + { "link_libg", LINK_LIBG_SPEC } + +/* FP save and restore routines. */ +#define SAVE_FP_PREFIX "._savef" +#define SAVE_FP_SUFFIX "" +#define RESTORE_FP_PREFIX "._restf" +#define RESTORE_FP_SUFFIX "" + +/* Define cutoff for using external functions to save floating point. */ +#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) + +/* Function name to call to do profiling. */ +#define RS6000_MCOUNT ".__mcount" + +/* AIX always has a TOC. */ +#define TARGET_NO_TOC 0 +#define TARGET_TOC 1 + +/* AIX allows r13 to be used. */ +#define FIXED_R13 0 + +/* This outputs NAME to FILE up to the first null or '['. */ + +#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ + { \ + const char *_p; \ + \ + STRIP_NAME_ENCODING (_p, (NAME)); \ + assemble_name ((FILE), _p); \ + } + +/* This is how to output the definition of a user-level label named NAME, + such as the label on a static function or variable NAME. */ + +#define ASM_OUTPUT_LABEL(FILE,NAME) \ + do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0) + +/* This is how to output a command to make the user-level label named NAME + defined for reference from other files. */ + +#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ + do { fputs ("\t.globl ", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0) + +/* Remove any trailing [DS] or the like from the symbol name. */ + +#define STRIP_NAME_ENCODING(VAR,NAME) \ + do \ + { \ + const char *_name = (NAME); \ + size_t _len; \ + if (*_name == '*') \ + _name++; \ + _len = strlen (_name); \ + if (_name[_len - 1] != ']') \ + (VAR) = _name; \ + else \ + { \ + char *_new_name = (char *) alloca (_len + 1); \ + strcpy (_new_name, _name); \ + _new_name[_len - 4] = '\0'; \ + (VAR) = _new_name; \ + } \ + } \ + while (0) + +/* Output at beginning of assembler file. + + Initialize the section names for the RS/6000 at this point. + + Specify filename, including full path, to assembler. + + We want to go into the TOC section so at least one .toc will be emitted. + Also, in order to output proper .bs/.es pairs, we need at least one static + [RW] section emitted. + + We then switch back to text to force the gcc2_compiled. label and the space + allocated after it (when profiling) into the text section. + + Finally, declare mcount when profiling to make the assembler happy. */ + +#define ASM_FILE_START(FILE) \ +{ \ + rs6000_gen_section_name (&xcoff_bss_section_name, \ + main_input_filename, ".bss_"); \ + rs6000_gen_section_name (&xcoff_private_data_section_name, \ + main_input_filename, ".rw_"); \ + rs6000_gen_section_name (&xcoff_read_only_section_name, \ + main_input_filename, ".ro_"); \ + \ + fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename); \ + if (TARGET_64BIT) \ + fputs ("\t.machine\t\"ppc64\"\n", FILE); \ + toc_section (); \ + if (write_symbols != NO_DEBUG) \ + private_data_section (); \ + text_section (); \ + if (profile_flag) \ + fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT); \ + rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ +} + +/* Output at end of assembler file. + + On the RS/6000, referencing data should automatically pull in text. */ + +#define ASM_FILE_END(FILE) \ +{ \ + text_section (); \ + fputs ("_section_.text:\n", FILE); \ + data_section (); \ + fputs (TARGET_32BIT \ + ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \ +} + +/* This macro produces the initial definition of a function name. + On the RS/6000, we need to place an extra '.' in the function name and + output the function descriptor. + + The csect for the function will have already been created by the + `text_section' call previously done. We do have to go back to that + csect, however. + + The third and fourth parameters to the .function pseudo-op (16 and 044) + are placeholders which no longer have any use. */ + +#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ +{ if (TREE_PUBLIC (DECL)) \ + { \ + fputs ("\t.globl .", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + putc ('\n', FILE); \ + } \ + else \ + { \ + fputs ("\t.lglobl .", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + putc ('\n', FILE); \ + } \ + fputs ("\t.csect ", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + fputs (":\n", FILE); \ + fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + fputs (", TOC[tc0], 0\n", FILE); \ + fputs (TARGET_32BIT \ + ? "\t.csect .text[PR]\n." : "\t.csect .text[PR],3\n.", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, NAME); \ + fputs (":\n", FILE); \ + if (write_symbols == XCOFF_DEBUG) \ + xcoffout_declare_function (FILE, DECL, NAME); \ +} + +/* This is how to output a reference to a user-level label named NAME. + `assemble_name' uses this. */ + +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + fputs (NAME, FILE) + +/* This says how to output an external. */ + +#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; \ + } \ +} + +/* This is how to output an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. */ + +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ + fprintf (FILE, "%s..%d:\n", PREFIX, NUM) + +/* This is how to output an internal label prefix. rs6000.c uses this + when generating traceback tables. */ + +#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ + fprintf (FILE, "%s..", PREFIX) + +/* This is how to output a label for a jump table. Arguments are the same as + for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is + passed. */ + +#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \ +{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); } + +/* This is how to store into the string LABEL + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ + sprintf (LABEL, "*%s..%d", PREFIX, NUM) + +/* This is how to output an assembler line to define N characters starting + at P to FILE. */ + +#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N)) + +/* This is how to advance the location counter by SIZE bytes. */ + +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t.space %d\n", (SIZE)) + +/* This says how to output an assembler line + to define a global common symbol. */ + +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \ + do { fputs (".comm ", (FILE)); \ + RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ + if ( (SIZE) > 4) \ + fprintf ((FILE), ",%d,3\n", (SIZE)); \ + else \ + fprintf( (FILE), ",%d\n", (SIZE)); \ + } while (0) + +/* These are various definitions for DWARF output. They could just + use '.long' or '.word', but that aligns to a 4-byte boundary which + is not what is required. So we define a million macros... */ + +#define ASM_OUTPUT_DWARF_ADDR_VAR(FILE, LABEL, LENGTH) \ + do { fprintf ((FILE), "\t.vbyte\t%d,", LENGTH); \ + assemble_name (FILE, LABEL); \ + } while (0) + +#define ASM_OUTPUT_DWARF_DELTA_VAR(FILE, LABEL1, LABEL2, LENGTH) \ + do { fprintf ((FILE), "\t.vbyte\t%d,", LENGTH); \ + assemble_name (FILE, LABEL1); \ + fprintf (FILE, "-"); \ + assemble_name (FILE, LABEL2); \ + } while (0) + +#define ASM_OUTPUT_DWARF_DELTA2(FILE, LABEL1, LABEL2) \ + ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, 2) + +#define ASM_OUTPUT_DWARF_DELTA4(FILE, LABEL1, LABEL2) \ + ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, 4) + +#define ASM_OUTPUT_DWARF_DELTA(FILE, LABEL1, LABEL2) \ + ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, DWARF_OFFSET_SIZE) + +#define ASM_OUTPUT_DWARF_ADDR_DELTA(FILE, LABEL1, LABEL2) \ + ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, \ + POINTER_SIZE / BITS_PER_UNIT) + +#define ASM_OUTPUT_DWARF_ADDR(FILE, LABEL) \ + ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, POINTER_SIZE / BITS_PER_UNIT) + +#define ASM_OUTPUT_DWARF_DATA4(FILE, VALUE) \ + fprintf ((FILE), "\t.vbyte\t4,0x%x", (unsigned) (VALUE)) + +#define ASM_OUTPUT_DWARF_DATA2(FILE, VALUE) \ + fprintf ((FILE), "\t.vbyte\t2,0x%x", (unsigned) (VALUE)) + +#define ASM_OUTPUT_DWARF_OFFSET4(FILE, LABEL) \ + ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, 4) + +#define ASM_OUTPUT_DWARF_OFFSET(FILE, LABEL) \ + ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, DWARF_OFFSET_SIZE) + +/* dwarf2out keys off this, but we don't have to have a real definition. */ +#define UNALIGNED_INT_ASM_OP bite_me + +/* Output before instructions. + Text section for 64-bit target may contain 64-bit address jump table. */ +#define TEXT_SECTION_ASM_OP (TARGET_32BIT \ + ? "\t.csect .text[PR]" : "\t.csect .text[PR],3") + +/* Output before writable data. + Align entire section to BIGGEST_ALIGNMENT. */ +#define DATA_SECTION_ASM_OP "\t.csect .data[RW],3" + +/* __throw will restore its own return address to be the same as the + return address of the function that the throw is being made to. + This is unfortunate, because we want to check the original + return address to see if we need to restore the TOC. + So we have to squirrel it away with this. */ +#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init () + diff --git a/gcc/config/rs6000/aix31.h b/gcc/config/rs6000/aix31.h index 46bd03c38fb..34d3628e8bd 100644 --- a/gcc/config/rs6000/aix31.h +++ b/gcc/config/rs6000/aix31.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000 running AIX version 3.1. - Copyright (C) 1993,1997 Free Software Foundation, Inc. + Copyright (C) 1993,1997, 2000 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) This file is part of GNU CC. @@ -22,6 +22,45 @@ Boston, MA 02111-1307, USA. */ #include "rs6000/rs6000.h" +#include "rs6000/aix.h" + +/* Output something to declare an external symbol to the assembler. Most + assemblers don't need this. + + If we haven't already, add "[RW]" (or "[DS]" for a function) to the + name. Normally we write this out along with the name. In the few cases + where we can't, it gets stripped off. */ + +#undef ASM_OUTPUT_EXTERNAL +#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ +{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ + if ((TREE_CODE (DECL) == VAR_DECL \ + || TREE_CODE (DECL) == FUNCTION_DECL) \ + && (NAME)[strlen (NAME) - 1] != ']') \ + { \ + char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ + strcpy (_name, XSTR (_symref, 0)); \ + strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ + XSTR (_symref, 0) = _name; \ + } \ + fputs ("\t.extern ", FILE); \ + assemble_name (FILE, XSTR (_symref, 0)); \ + if (TREE_CODE (DECL) == FUNCTION_DECL) \ + { \ + fputs ("\n\t.extern .", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0)); \ + } \ + putc ('\n', FILE); \ +} + +/* Similar, but for libcall. We only have to worry about the function name, + not that of the descriptor. */ + +#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ +{ fputs ("\t.extern .", FILE); \ + assemble_name (FILE, XSTR (FUN, 0)); \ + putc ('\n', FILE); \ +} /* AIX 3.2 defined _AIX32, but older versions do not. */ #undef CPP_PREDEFINES diff --git a/gcc/config/rs6000/aix3newas.h b/gcc/config/rs6000/aix3newas.h index 9659794d7c8..f2b938661ca 100644 --- a/gcc/config/rs6000/aix3newas.h +++ b/gcc/config/rs6000/aix3newas.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX version 3.x with the fixed assembler. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Contributed by Jason Merrill (jason@cygnus.com). This file is part of GNU CC. @@ -21,15 +21,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, - #include "rs6000/rs6000.h" +#include "rs6000/aix.h" /* Tell the assembler to assume that all undefined names are external. */ @@ -68,21 +61,3 @@ Boston, MA 02111-1307, USA. */ %{mcpu=common: milli.exp%s} \ %{shared:-bM:SRE}" #endif - -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} diff --git a/gcc/config/rs6000/aix41.h b/gcc/config/rs6000/aix41.h index e4a731cea53..7ab7eedc12d 100644 --- a/gcc/config/rs6000/aix41.h +++ b/gcc/config/rs6000/aix41.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX version 4.1. - Copyright (C) 1994, 1995, 1996, 1998, 1998, 1999 + Copyright (C) 1994, 95, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by David Edelsohn (edelsohn@gnu.org). @@ -22,51 +22,19 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Enable AIX XL compiler calling convention breakage compatibility. */ -#define MASK_XL_CALL 0x40000000 -#define TARGET_XL_CALL (target_flags & MASK_XL_CALL) -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - {"xl-call", MASK_XL_CALL}, \ - {"no-xl-call", - MASK_XL_CALL}, \ - {"threads", 0}, \ - {"pe", 0}, - #include "rs6000/rs6000.h" +#include "rs6000/aix.h" + +#undef SUBSUBTARGET_SWITCHES +#define SUBSUBTARGET_SWITCHES \ + {"threads", 0, \ + "Use the thread library and reentrant C library" }, \ + {"pe", 0, \ + "Support message passing with the Parallel Environment" }, #undef ASM_SPEC #define ASM_SPEC "-u %(asm_cpu)" -/* Common ASM definitions used by ASM_SPEC amonst the various targets - for handling -mcpu=xxx switches. */ -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -mpwr}} \ - %{mpower2: -mpwr2} \ - %{mpowerpc*: -mppc} \ - %{!mpower*: %{!mpowerpc*: %(asm_default)}}} \ -%{mcpu=common: -mcom} \ -%{mcpu=power: -mpwr} \ -%{mcpu=power2: -mpwr2} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rios: -mpwr} \ -%{mcpu=rios1: -mpwr} \ -%{mcpu=rios2: -mpwr2} \ -%{mcpu=rsc: -mpwr} \ -%{mcpu=rsc1: -mpwr} \ -%{mcpu=403: -mppc} \ -%{mcpu=505: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -mppc} \ -%{mcpu=821: -mppc} \ -%{mcpu=860: -mppc}" - #undef ASM_DEFAULT_SPEC #define ASM_DEFAULT_SPEC "-mcom" @@ -80,35 +48,6 @@ Boston, MA 02111-1307, USA. */ %{mthreads: -D_THREAD_SAFE}\ %(cpp_cpu)" -/* Common CPP definitions used by CPP_SPEC among the various targets - for handling -mcpu=xxx switches. */ -#undef CPP_CPU_SPEC -#define CPP_CPU_SPEC \ -"%{!mcpu*: \ - %{mpower: %{!mpower2: -D_ARCH_PWR}} \ - %{mpower2: -D_ARCH_PWR2} \ - %{mpowerpc*: -D_ARCH_PPC} \ - %{!mpower*: %{!mpowerpc*: %(cpp_default)}}} \ -%{mcpu=common: -D_ARCH_COM} \ -%{mcpu=power: -D_ARCH_PWR} \ -%{mcpu=power2: -D_ARCH_PWR2} \ -%{mcpu=powerpc: -D_ARCH_PPC} \ -%{mcpu=rios: -D_ARCH_PWR} \ -%{mcpu=rios1: -D_ARCH_PWR} \ -%{mcpu=rios2: -D_ARCH_PWR2} \ -%{mcpu=rsc: -D_ARCH_PWR} \ -%{mcpu=rsc1: -D_ARCH_PWR} \ -%{mcpu=403: -D_ARCH_PPC} \ -%{mcpu=505: -D_ARCH_PPC} \ -%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \ -%{mcpu=602: -D_ARCH_PPC} \ -%{mcpu=603: -D_ARCH_PPC} \ -%{mcpu=603e: -D_ARCH_PPC} \ -%{mcpu=604: -D_ARCH_PPC} \ -%{mcpu=620: -D_ARCH_PPC} \ -%{mcpu=821: -D_ARCH_PPC} \ -%{mcpu=860: -D_ARCH_PPC}" - #undef CPP_DEFAULT_SPEC #define CPP_DEFAULT_SPEC "-D_ARCH_COM" @@ -130,24 +69,6 @@ Boston, MA 02111-1307, USA. */ #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}}\ diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h index 8b0c6fb6b05..3822c0a2aa3 100644 --- a/gcc/config/rs6000/aix43.h +++ b/gcc/config/rs6000/aix43.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX version 4.3. - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by David Edelsohn (edelsohn@gnu.org). This file is part of GNU CC. @@ -21,17 +21,20 @@ 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}, +#include "rs6000/rs6000.h" +#include "rs6000/aix.h" + +/* AIX 4.3 and above support 64-bit executables. */ +#undef SUBSUBTARGET_SWITCHES +#define SUBSUBTARGET_SWITCHES \ + {"aix64", MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC, \ + "Compile for 64-bit pointers" }, \ + {"aix32", - (MASK_64BIT | MASK_POWERPC64), \ + "Compile for 32-bit pointers" }, \ + {"threads", 0, \ + "Use the thread library and reentrant C library" }, \ + {"pe", 0, \ + "Support message passing with the Parallel Environment" }, /* Sometimes certain combinations of command options do not make sense on a particular target machine. You can define a macro @@ -57,8 +60,6 @@ do { \ } \ } while (0); -#include "rs6000/rs6000.h" - #undef ASM_SPEC #define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)" @@ -161,24 +162,6 @@ do { \ #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}\ @@ -214,7 +197,6 @@ do { \ #undef RS6000_CALL_GLUE #define RS6000_CALL_GLUE "{cror 31,31,31|nop}" -#if 0 /* AIX 4.2 and above provides initialization and finalization function support from linker command line. */ #undef HAS_INIT_SECTION @@ -222,4 +204,3 @@ do { \ #undef LD_INIT_SWITCH #define LD_INIT_SWITCH "-binitfini" -#endif diff --git a/gcc/config/rs6000/beos.h b/gcc/config/rs6000/beos.h index 851601ff2b8..6643691af76 100644 --- a/gcc/config/rs6000/beos.h +++ b/gcc/config/rs6000/beos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for BeOS. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2000 Free Software Foundation, Inc. Contributed by Fred Fish (fnf@cygnus.com), based on aix41.h from David Edelsohn (edelsohn@npac.syr.edu). @@ -21,6 +21,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "rs6000/rs6000.h" +#include "rs6000/aix.h" + /* Enable AIX XL compiler calling convention breakage compatibility. */ #define MASK_XL_CALL 0x40000000 #define TARGET_XL_CALL (target_flags & MASK_XL_CALL) @@ -31,8 +34,6 @@ Boston, MA 02111-1307, USA. */ {"threads", 0}, \ {"pe", 0}, -#include "rs6000/rs6000.h" - #undef ASM_SPEC #define ASM_SPEC "-u %(asm_cpu)" @@ -79,24 +80,6 @@ Boston, MA 02111-1307, USA. */ #undef MULTILIB_DEFAULTS #define MULTILIB_DEFAULTS { "mcpu=powerpc" } -/* These are not necessary when we pass -u to the assembler, and undefining - them saves a great deal of space in object files. */ - -#undef ASM_OUTPUT_EXTERNAL -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ -} - /* These empty definitions get rid of the attempt to link in crt0.o and any libraries like libc.a. On BeOS the ld executable is actually a linker front end that first runs diff --git a/gcc/config/rs6000/cygwin.h b/gcc/config/rs6000/cygwin.h deleted file mode 100644 index 0ed448b2124..00000000000 --- a/gcc/config/rs6000/cygwin.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Operating system specific defines to be used when targeting GCC for - hosting on Windows NT 3.x, using the Cygnus API - - This is different to the winnt.h file, since that is used - to build GCC for use with a windows style library and tool - set, winnt.h uses the Microsoft tools to do that. - - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Ugly hack */ -#include "rs6000/win-nt.h" - - -#ifdef CPP_PREDEFINES -#undef CPP_PREDEFINES -#endif - -#define CPP_PREDEFINES "-D_WIN32 -DWINNT -D__CYGWIN__ -D__CYGWIN32__ -DPOSIX \ - -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)" - -#undef CPP_SPEC -#define CPP_SPEC "-remap %{posix: -D_POSIX_SOURCE} %(cpp_cpu)" - -/* We have to dynamic link to get to the system DLLs. All of libc, libm and - the Unix stuff is in cygwin.dll. The import library is called - 'libcygwin.a'. For Windows applications, include more libraries, but - always include kernel32. We'd like to specific subsystem windows to - ld, but that doesn't work just yet. */ - -#undef LIB_SPEC -#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32" - -#undef LINK_SPEC -#define LINK_SPEC "%{v:-V}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "crti%O%s crt0%O%s" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtn%O%s" - -#define PTRDIFF_TYPE "int" -#define WCHAR_UNSIGNED 1 -#define WCHAR_TYPE_SIZE 16 -#define WCHAR_TYPE "short unsigned int" - -#define DBX_DEBUGGING_INFO -#undef SDB_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/gcc/config/rs6000/eabi-ci.asm b/gcc/config/rs6000/eabi-ci.asm index 6b753ca1239..40fc98ef566 100644 --- a/gcc/config/rs6000/eabi-ci.asm +++ b/gcc/config/rs6000/eabi-ci.asm @@ -1,6 +1,6 @@ # crti.s for eabi -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996, 2000 Free Software Foundation, Inc. # Written By Michael Meissner # # This file is free software; you can redistribute it and/or modify it @@ -102,6 +102,11 @@ __SBSS2_START__: .type __EXCEPT_START__,@object __EXCEPT_START__: + .section ".eh_frame","aw" + .globl __EH_FRAME_BEGIN__ + .type __EH_FRAME_BEGIN__,@object +__EH_FRAME_BEGIN__: + # Head of __init function used for static constructors in Solaris .section ".init","ax" .align 2 diff --git a/gcc/config/rs6000/eabi-cn.asm b/gcc/config/rs6000/eabi-cn.asm index 06e895638dc..d62e2faff92 100644 --- a/gcc/config/rs6000/eabi-cn.asm +++ b/gcc/config/rs6000/eabi-cn.asm @@ -1,6 +1,6 @@ # crtn.s for eabi -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996, 2000 Free Software Foundation, Inc. # Written By Michael Meissner # # This file is free software; you can redistribute it and/or modify it @@ -94,6 +94,12 @@ __SBSS2_END__: .type __EXCEPT_END__,@object __EXCEPT_END__: + .section ".eh_frame","aw" + .globl __EH_FRAME_END__ + .type __EH_FRAME_END__,@object +__EH_FRAME_END__: + .long 0 + # Tail of __init used for static constructors in Solaris .section ".init","ax" lwz 0,12(1) diff --git a/gcc/config/rs6000/eabi-ctors.c b/gcc/config/rs6000/eabi-ctors.c index 2ff3c1abc61..9785a112a6d 100644 --- a/gcc/config/rs6000/eabi-ctors.c +++ b/gcc/config/rs6000/eabi-ctors.c @@ -1,7 +1,7 @@ /* Stripped down support to run global constructors and destructors on embedded PowerPC systems. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2000 Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@cygnus.com). This file is part of GNU CC. @@ -28,65 +28,77 @@ Boston, MA 02111-1307, USA. */ This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ +#include "tm.h" +#include "defaults.h" +#include +#include "frame.h" +#include "gbl-ctors.h" -/* Declare a pointer to void function type. */ - -typedef void (*func_ptr) (void); +/* FIXME: This file should share code with all the other + constructor/destructor implementations in crtstuff.c and libgcc2.c. */ /* Declare the set of symbols use as begin and end markers for the lists of global object constructors and global object destructors. */ -extern func_ptr __CTOR_LIST__[]; -extern func_ptr __CTOR_END__ []; -extern func_ptr __DTOR_LIST__[]; -extern func_ptr __DTOR_END__ []; +extern func_ptr __CTOR_LIST__[] asm ("__CTOR_LIST__"); +extern func_ptr __CTOR_END__ [] asm ("__CTOR_END__"); +extern func_ptr __DTOR_LIST__[] asm ("__DTOR_LIST__"); +extern func_ptr __DTOR_END__ [] asm ("__DTOR_END__"); +extern unsigned char __EH_FRAME_BEGIN__[] asm ("__EH_FRAME_BEGIN__"); extern void __do_global_ctors (void); -extern void __do_global_dtors (void); extern void __init (), __fini (); -/* The Solaris linker seems to incorrectly relocate PC relative relocations - to a different section (ie, calls to __init, __fini), so avoid it by - using a function pointer. */ -static void (*init_ptr) (void) = __init; -static void (*fini_ptr) (void) = __fini; - void (*__atexit)(func_ptr); /* Call all global constructors */ void __do_global_ctors (void) { - func_ptr *ptr = &__CTOR_END__[0] - 1; - func_ptr *start = &__CTOR_LIST__[0]; + func_ptr *p = __CTOR_END__ - 1; - if (__atexit) - __atexit (__do_global_dtors); +#ifdef EH_FRAME_SECTION + { + static struct object object; + __register_frame_info (__EH_FRAME_BEGIN__, &object); + } +#endif /* Call the constructors collected in the .ctors section. */ - for ( ; ptr >= start; ptr--) - if (*ptr) - (*ptr)(); + for ( ; p >= __CTOR_LIST__; p--) + if (*p) + (*p)(); + + if (__atexit) + __atexit (__do_global_dtors); /* Call the initialization function in the .init section. */ - (*init_ptr) (); + __init (); } /* Call all global destructors */ void __do_global_dtors (void) { - func_ptr *ptr = &__DTOR_LIST__[0]; - func_ptr *end = &__DTOR_END__[0]; + static func_ptr *p = __DTOR_LIST__ + 1; + static int completed = 0; - /* Call the termination function in the .fini section. */ - (*fini_ptr) (); + if (completed) + return; - /* Call the destructors collected in the .dtors section. Run - the destructors in reverse order. */ - for ( ; ptr < end; ptr++) - if (*ptr) - (*ptr)(); + /* Call the termination function in the .fini section. */ + __fini (); + + while (p < __DTOR_END__) + { + p++; + (*(p-1)) (); + } + +#ifdef EH_FRAME_SECTION_ASM_OP + if (__deregister_frame_info) + __deregister_frame_info (__EH_FRAME_BEGIN__); +#endif + completed = 1; } - diff --git a/gcc/config/rs6000/eabi.h b/gcc/config/rs6000/eabi.h index 1c225ea35dc..5293a076cce 100644 --- a/gcc/config/rs6000/eabi.h +++ b/gcc/config/rs6000/eabi.h @@ -1,6 +1,6 @@ /* Core target definitions for GNU compiler for IBM RS/6000 PowerPC targeted to embedded ELF systems. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GNU CC. @@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */ /* Invoke an initializer function to set up the GOT */ #define NAME__MAIN "__eabi" +#define INVOKE__main #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)"); diff --git a/gcc/config/rs6000/lynx.h b/gcc/config/rs6000/lynx.h index e2fe6339fe4..5257be5dcd9 100644 --- a/gcc/config/rs6000/lynx.h +++ b/gcc/config/rs6000/lynx.h @@ -1,5 +1,5 @@ /* Definitions for Rs6000 running LynxOS. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com) This file is part of GNU CC. @@ -96,7 +96,6 @@ do { \ #undef OBJECT_FORMAT_ROSE #undef MD_EXEC_PREFIX #undef REAL_LD_FILE_NAME -#undef REAL_NM_FILE_NAME #undef REAL_STRIP_FILE_NAME /* LynxOS doesn't have mcount. */ diff --git a/gcc/config/rs6000/netware.h b/gcc/config/rs6000/netware.h index 61133b9b1ee..622b972aa19 100644 --- a/gcc/config/rs6000/netware.h +++ b/gcc/config/rs6000/netware.h @@ -1,6 +1,6 @@ /* Core target definitions for GNU compiler for IBM RS/6000 PowerPC running NetWare - Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1996, 1998, 2000 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GNU CC. @@ -34,24 +34,11 @@ Boston, MA 02111-1307, USA. */ #undef PROCESSOR_DEFAULT #define PROCESSOR_DEFAULT PROCESSOR_PPC601 -/* Don't generate XCOFF debugging information. */ - -#undef XCOFF_DEBUGGING_INFO - -/* Don't use the COFF object file format. */ - -#undef OBJECT_FORMAT_COFF - /* The XCOFF support uses weird symbol suffixes, which we don't want for ELF. */ #undef STRIP_NAME_ENCODING -/* Don't bother to output .extern pseudo-ops. They are not needed by - ELF assemblers. */ - -#undef ASM_OUTPUT_EXTERNAL - /* Undefine some things which are defined by the generic svr4.h. */ #undef ASM_FILE_END diff --git a/gcc/config/rs6000/nt-ci.asm b/gcc/config/rs6000/nt-ci.asm deleted file mode 100644 index 67ca9564abf..00000000000 --- a/gcc/config/rs6000/nt-ci.asm +++ /dev/null @@ -1,48 +0,0 @@ -# crti.s for Windows NT - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled starting points for the static constructors -# and destructors. It is linked in first before other modules. - - .file "crti.s" - .ident "GNU C crti.s" - - .section .ctors,"w" - .globl __CTOR_LIST__ -__CTOR_LIST__: - - .section .dtors,"w" - .globl __DTOR_LIST__ -__DTOR_LIST__: diff --git a/gcc/config/rs6000/nt-cn.asm b/gcc/config/rs6000/nt-cn.asm deleted file mode 100644 index dd6daf29b2e..00000000000 --- a/gcc/config/rs6000/nt-cn.asm +++ /dev/null @@ -1,48 +0,0 @@ -# crtn.s for Windows NT - -# Copyright (C) 1996 Free Software Foundation, Inc. -# Written By Michael Meissner -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# In addition to the permissions in the GNU General Public License, the -# Free Software Foundation gives you unlimited permission to link the -# compiled version of this file with other programs, and to distribute -# those programs without any restriction coming from the use of this -# file. (The General Public License restrictions do apply in other -# respects; for example, they cover modification of the file, and -# distribution when not linked into another program.) -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# As a special exception, if you link this library with files -# compiled with GCC to produce an executable, this does not cause -# the resulting executable to be covered by the GNU General Public License. -# This exception does not however invalidate any other reasons why -# the executable file might be covered by the GNU General Public License. -# - -# This file just supplies labeled ending points for the static constructors -# and destructors. It is linked in last after other modules. - - .file "crtn.s" - .ident "GNU C crtn.s" - - .section .ctors,"w" - .globl __CTOR_END__ -__CTOR_END__: - - .section .dtors,"w" - .globl __DTOR_END__ -__DTOR_END__: diff --git a/gcc/config/rs6000/ntstack.asm b/gcc/config/rs6000/ntstack.asm deleted file mode 100644 index aa4179e7a79..00000000000 --- a/gcc/config/rs6000/ntstack.asm +++ /dev/null @@ -1,42 +0,0 @@ -# Allocate stack for NT, inserting stack probes every 4k pages - - .file "ntstack.asm" - -# Setup MS Structured-Exception-Handling - .pdata - .align 2 - .ualong ..__allocate_stack,__allocate_stack.e,0,0,__allocate_stack.b - -# Switch to the relocation section - .reldata - .globl __allocate_stack - .globl ..__allocate_stack -__allocate_stack: - .ualong ..__allocate_stack,.toc - - .text - .align 2 -..__allocate_stack: - .function ..__allocate_stack -__allocate_stack.b: - addi 3,3,15 # round up to 16 byte alignment - lwz 0,0(1) # old stack link - rlwinm 3,3,0,0,28 - srawi. 4,3,12 # get # of pages to check - neg 3,3 # negate so we can use stwux - bgt- 0,.Lcheck - stwux 0,1,3 # small request, just decrement and return - blr - -.Lcheck: - mtctr 4 # number of pages to check - mr 5,1 # tmp pointer -.Lloop: - lwzu 6,-4096(5) # touch the page - bdnz+ .Lloop # and loop back - - stwux 0,1,3 # update stack pointer - blr - -__allocate_stack.e: -FE_MOT_RESVD..__allocate_stack: diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h new file mode 100644 index 00000000000..c63360705a7 --- /dev/null +++ b/gcc/config/rs6000/rs6000-protos.h @@ -0,0 +1,162 @@ +/* Definitions of target machine for GNU compiler, for IBM RS/6000. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Declare functions in rs6000.c */ + +#ifdef RTX_CODE + +#ifdef TREE_CODE +extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int)); +extern void rs6000_va_start PARAMS ((int, tree, rtx)); +#endif /* TREE_CODE */ + +extern struct rtx_def *rs6000_got_register PARAMS ((rtx)); +extern struct rtx_def *find_addr_reg PARAMS ((rtx)); +extern int any_operand PARAMS ((rtx, enum machine_mode)); +extern int short_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int u_short_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int non_short_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int gpc_reg_operand PARAMS ((rtx, enum machine_mode)); +extern int cc_reg_operand PARAMS ((rtx, enum machine_mode)); +extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_short_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_u_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int got_operand PARAMS ((rtx, enum machine_mode)); +extern int got_no_const_operand PARAMS ((rtx, enum machine_mode)); +extern int num_insns_constant PARAMS ((rtx, enum machine_mode)); +extern int easy_fp_constant PARAMS ((rtx, enum machine_mode)); +extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode)); +extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode)); +extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode)); +extern int add_operand PARAMS ((rtx, enum machine_mode)); +extern int non_add_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int non_logical_u_cint_operand PARAMS ((rtx, enum machine_mode)); +extern int logical_operand PARAMS ((rtx, enum machine_mode)); +extern int logical_u_operand PARAMS ((rtx, enum machine_mode)); +extern int mask_operand PARAMS ((rtx, enum machine_mode)); +extern int mask64_operand PARAMS ((rtx, enum machine_mode)); +extern int and64_operand PARAMS ((rtx, enum machine_mode)); +extern int and_operand PARAMS ((rtx, enum machine_mode)); +extern int count_register_operand PARAMS ((rtx, enum machine_mode)); +extern int xer_operand PARAMS ((rtx, enum machine_mode)); +extern int reg_or_mem_operand PARAMS ((rtx, enum machine_mode)); +extern int lwa_operand PARAMS ((rtx, enum machine_mode)); +extern int call_operand PARAMS ((rtx, enum machine_mode)); +extern int current_file_function_operand PARAMS ((rtx, enum machine_mode)); +extern int input_operand PARAMS ((rtx, enum machine_mode)); +extern int small_data_operand PARAMS ((rtx, enum machine_mode)); +extern int constant_pool_expr_p PARAMS ((rtx)); +extern int toc_relative_expr_p PARAMS ((rtx)); +extern int expand_block_move PARAMS ((rtx[])); +extern int load_multiple_operation PARAMS ((rtx, enum machine_mode)); +extern int store_multiple_operation PARAMS ((rtx, enum machine_mode)); +extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode)); +extern int scc_comparison_operator PARAMS ((rtx, enum machine_mode)); +extern int trap_comparison_operator PARAMS ((rtx, enum machine_mode)); +extern int includes_lshift_p PARAMS ((rtx, rtx)); +extern int includes_rshift_p PARAMS ((rtx, rtx)); +extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx)); +extern int addrs_ok_for_quad_peep PARAMS ((rtx, rtx)); +extern enum reg_class secondary_reload_class PARAMS ((enum reg_class, + enum machine_mode, rtx)); +extern int ccr_bit PARAMS ((rtx, int)); +extern void print_operand PARAMS ((FILE *, rtx, int)); +extern void print_operand_address PARAMS ((FILE *, rtx)); +extern void output_toc PARAMS ((FILE *, rtx, int)); +extern int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int)); +extern int rs6000_adjust_priority PARAMS ((rtx, int)); +extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx)); +extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx)); +extern void rs6000_fatal_bad_address PARAMS ((rtx)); +extern int stmw_operation PARAMS ((rtx, enum machine_mode)); +extern int mtcrf_operation PARAMS ((rtx, enum machine_mode)); +extern int lmw_operation PARAMS ((rtx, enum machine_mode)); +extern struct rtx_def *create_TOC_reference PARAMS ((rtx)); +extern void rs6000_emit_eh_toc_restore PARAMS ((rtx)); +extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode)); +extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx)); +#endif /* RTX_CODE */ + +#ifdef TREE_CODE +extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, + tree, int)); +extern int function_arg_boundary PARAMS ((enum machine_mode, tree)); +extern struct rtx_def *function_arg PARAMS ((CUMULATIVE_ARGS *, + enum machine_mode, tree, int)); +extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *, + enum machine_mode, tree, int)); +extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *, + enum machine_mode, + tree, int)); +extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *, + enum machine_mode, tree, + int *, int)); +extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree)); +extern void output_mi_thunk PARAMS ((FILE *, tree, int, tree)); +extern int rs6000_comp_type_attributes PARAMS ((tree, tree)); +extern int rs6000_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree)); +extern int rs6000_valid_type_attribute_p PARAMS ((tree, tree, tree, tree)); +extern void rs6000_set_default_type_attributes PARAMS ((tree)); +extern void rs6000_encode_section_info PARAMS ((tree)); +extern void rs6000_select_section PARAMS ((tree, int)); +#ifdef ARGS_SIZE_RTX +/* expr.h defines ARGS_SIZE_RTX and `enum direction' */ +extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree)); +#endif /* ARGS_SIZE_RTX */ +#endif /* TREE_CODE */ + +extern void optimization_options PARAMS ((int, int)); +extern void rs6000_override_options PARAMS ((const char *)); +extern void rs6000_file_start PARAMS ((FILE *, const char *)); +extern struct rtx_def *rs6000_float_const PARAMS ((const char *, + enum machine_mode)); +extern int direct_return PARAMS ((void)); +extern int get_issue_rate PARAMS ((void)); +extern union tree_node *rs6000_build_va_list PARAMS ((void)); +extern void rs6000_save_machine_status PARAMS ((struct function *)); +extern void rs6000_restore_machine_status PARAMS ((struct function *)); +extern void rs6000_init_expanders PARAMS ((void)); +extern int first_reg_to_save PARAMS ((void)); +extern int first_fp_reg_to_save PARAMS ((void)); +extern rs6000_stack_t *rs6000_stack_info PARAMS ((void)); +extern void output_prolog PARAMS ((FILE *, int)); +extern void output_epilog PARAMS ((FILE *, int)); +extern void output_ascii PARAMS ((FILE *, const char *, int)); +extern void rs6000_gen_section_name PARAMS ((char **, const char *, + const char *)); +extern void output_function_profiler PARAMS ((FILE *, int)); +extern int rs6000_trampoline_size PARAMS ((void)); +extern void toc_section PARAMS ((void)); +extern void sdata_section PARAMS ((void)); +extern void sdata2_section PARAMS ((void)); +extern void sbss_section PARAMS ((void)); +extern void private_data_section PARAMS ((void)); +extern int get_TOC_alias_set PARAMS ((void)); +extern int uses_TOC PARAMS ((void)); +extern void rs6000_emit_prologue PARAMS ((void)); +extern void rs6000_emit_load_toc_table PARAMS ((int)); +extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void)); +extern void rs6000_emit_epilogue PARAMS ((int)); +extern void debug_stack_info PARAMS ((rs6000_stack_t *)); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a408d7e5921..e7923587aa4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1,6 +1,6 @@ /* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -40,6 +40,8 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "toplev.h" #include "ggc.h" +#include "hashtab.h" +#include "tm_p.h" #ifndef TARGET_NO_PROTOTYPE #define TARGET_NO_PROTOTYPE 0 @@ -78,12 +80,11 @@ static int common_mode_defined; rtx rs6000_compare_op0, rs6000_compare_op1; int rs6000_compare_fp_p; -#ifdef USING_SVR4_H /* Label number of label created for -mrelocatable, to call to so we can get the address of the GOT section */ int rs6000_pic_labelno; -int rs6000_pic_func_labelno; +#ifdef USING_SVR4_H /* Which abi to adhere to */ const char *rs6000_abi_name = RS6000_ABI_NAME; @@ -92,6 +93,9 @@ enum rs6000_sdata_type rs6000_sdata = SDATA_DATA; /* Which small data model to use */ const char *rs6000_sdata_name = (char *)0; + +/* Counter for labels which are to be placed in .fixup. */ +int fixuplabelno = 0; #endif /* Whether a System V.4 varargs area was created. */ @@ -100,11 +104,6 @@ int rs6000_sysv_varargs_p; /* ABI enumeration available for subtarget to use. */ enum rs6000_abi rs6000_current_abi; -/* Offset & size for fpmem stack locations used for converting between - float and integral types. */ -int rs6000_fpmem_offset; -int rs6000_fpmem_size; - /* Debug flags */ const char *rs6000_debug_name; int rs6000_debug_stack; /* debug stack applications */ @@ -112,9 +111,23 @@ int rs6000_debug_arg; /* debug argument handling */ /* Flag to say the TOC is initialized */ int toc_initialized; +char toc_label_name[10]; -static void rs6000_add_gc_roots PARAMS ((void)); +/* Alias set for saves and restores from the rs6000 stack. */ +static int rs6000_sr_alias_set; +static void rs6000_add_gc_roots PARAMS ((void)); +static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT)); +static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx)); +static void rs6000_emit_stack_tie PARAMS ((void)); +static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx)); +static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int)); +static unsigned rs6000_hash_constant PARAMS ((rtx)); +static unsigned toc_hash_function PARAMS ((const void *)); +static int toc_hash_eq PARAMS ((const void *, const void *)); +static int toc_hash_mark_entry PARAMS ((void *, void *)); +static void toc_hash_mark_table PARAMS ((void *)); +static int constant_pool_expr_1 PARAMS ((rtx, int *, int *)); /* Default register names. */ char rs6000_reg_names[][8] = @@ -129,7 +142,7 @@ char rs6000_reg_names[][8] = "24", "25", "26", "27", "28", "29", "30", "31", "mq", "lr", "ctr","ap", "0", "1", "2", "3", "4", "5", "6", "7", - "fpmem" + "xer" }; #ifdef TARGET_REGNAMES @@ -145,7 +158,7 @@ static char alt_reg_names[][8] = "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31", "mq", "lr", "ctr", "ap", "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", - "fpmem" + "xer" }; #endif @@ -374,6 +387,12 @@ rs6000_override_options (default_cpu) /* Register global variables with the garbage collector. */ rs6000_add_gc_roots (); + + /* Allocate an alias set for register saves & restores from stack. */ + rs6000_sr_alias_set = new_alias_set (); + + if (TARGET_TOC) + ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1); } void @@ -496,24 +515,17 @@ count_register_operand(op, mode) return 0; } -/* Returns 1 if op is memory location for float/int conversions that masquerades - as a register. */ int -fpmem_operand(op, mode) +xer_operand(op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; { if (GET_CODE (op) != REG) return 0; - if (FPMEM_REGNO_P (REGNO (op))) + if (XER_REGNO_P (REGNO (op))) return 1; -#if 0 - if (REGNO (op) > FIRST_PSEUDO_REGISTER) - return 1; -#endif - return 0; } @@ -560,8 +572,9 @@ gpc_reg_operand (op, mode) { return (register_operand (op, mode) && (GET_CODE (op) != REG - || (REGNO (op) >= 67 && !FPMEM_REGNO_P (REGNO (op))) - || REGNO (op) < 64)); + || (REGNO (op) >= ARG_POINTER_REGNUM + && !XER_REGNO_P (REGNO (op))) + || REGNO (op) < MQ_REGNO)); } /* Returns 1 if OP is either a pseudo-register or a register denoting a @@ -641,6 +654,27 @@ reg_or_cint_operand (op, mode) || gpc_reg_operand (op, mode)); } +/* Return 1 is the operand is either a non-special register or ANY + 32-bit unsigned constant integer. */ + +int +reg_or_u_cint_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + return (gpc_reg_operand (op, mode) + || (GET_CODE (op) == CONST_INT +#if HOST_BITS_PER_WIDE_INT != 32 + && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32) +#endif + && INTVAL (op) > 0) +#if HOST_BITS_PER_WIDE_INT == 32 + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0) +#endif + ); +} + /* Return 1 if the operand is an operand that can be loaded via the GOT */ int @@ -685,10 +719,10 @@ num_insns_constant_wide (value) HOST_WIDE_INT low = value & 0xffffffff; HOST_WIDE_INT high = value >> 32; - if (high == 0 && (low & 0x80000000) == 0) + if (high == 0 && (low & 0x80000000u) == 0) return 2; - else if (high == -1 && (low & 0x80000000) != 0) + else if (high == -1 && (low & 0x80000000u) != 0) return 2; else if (! low) @@ -749,10 +783,10 @@ num_insns_constant (op, mode) else { - if (high == 0 && (low & 0x80000000) == 0) + if (high == 0 && (low & 0x80000000u) == 0) return num_insns_constant_wide (low); - else if (high == -1 && (low & 0x80000000) != 0) + else if (high == -1 && (low & 0x80000000u) != 0) return num_insns_constant_wide (low); else if (mask64_operand (op, mode)) @@ -917,10 +951,41 @@ logical_operand (op, mode) { return (gpc_reg_operand (op, mode) || (GET_CODE (op) == CONST_INT +#if HOST_BITS_PER_WIDE_INT != 32 + && INTVAL (op) > 0 + && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32) +#endif + && ((INTVAL (op) & GET_MODE_MASK (mode) + & (~ (HOST_WIDE_INT) 0xffff)) == 0 + || (INTVAL (op) & GET_MODE_MASK (mode) + & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0))); +} + +/* Return 1 if the operand is a non-special register or a 32-bit constant + that can be used as the operand of an OR or XOR insn on the RS/6000. */ + +int +logical_u_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + return (gpc_reg_operand (op, mode) + || (GET_CODE (op) == CONST_INT + && INTVAL (op) > 0 +#if HOST_BITS_PER_WIDE_INT != 32 + && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32) +#endif && ((INTVAL (op) & GET_MODE_MASK (mode) & (~ (HOST_WIDE_INT) 0xffff)) == 0 || (INTVAL (op) & GET_MODE_MASK (mode) - & (~ (HOST_WIDE_INT) 0xffff0000)) == 0))); + & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)) +#if HOST_BITS_PER_WIDE_INT == 32 + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && ((CONST_DOUBLE_LOW (op) + & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)) +#endif + ); } /* Return 1 if C is a constant that is not a logical operand (as @@ -932,10 +997,39 @@ non_logical_cint_operand (op, mode) enum machine_mode mode; { return (GET_CODE (op) == CONST_INT +#if HOST_BITS_PER_WIDE_INT != 32 + && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32) +#endif && (INTVAL (op) & GET_MODE_MASK (mode) & (~ (HOST_WIDE_INT) 0xffff)) != 0 && (INTVAL (op) & GET_MODE_MASK (mode) & - (~ (HOST_WIDE_INT) 0xffff0000)) != 0); + (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0); +} + +/* Return 1 if C is an unsigned 32-bit constant that is not a + logical operand (as above). */ + +int +non_logical_u_cint_operand (op, mode) + register rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + return ((GET_CODE (op) == CONST_INT + && INTVAL (op) > 0 +#if HOST_BITS_PER_WIDE_INT != 32 + && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32) +#endif + && (INTVAL (op) & GET_MODE_MASK (mode) + & (~ (HOST_WIDE_INT) 0xffff)) != 0 + && (INTVAL (op) & GET_MODE_MASK (mode) + & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0) +#if HOST_BITS_PER_WIDE_INT == 32 + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && (CONST_DOUBLE_LOW (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0 + && (CONST_DOUBLE_LOW (op) + & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0)); +#endif } /* Return 1 if C is a constant that can be encoded in a 32-bit mask on the @@ -1055,7 +1149,7 @@ and64_operand (op, mode) register rtx op; enum machine_mode mode; { - if (fixed_regs[68]) /* CR0 not available, don't do andi./andis. */ + if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */ return (gpc_reg_operand (op, mode) || mask64_operand (op, mode)); return (logical_operand (op, mode) || mask64_operand (op, mode)); @@ -1069,7 +1163,7 @@ and_operand (op, mode) register rtx op; enum machine_mode mode; { - if (fixed_regs[68]) /* CR0 not available, don't do andi./andis. */ + if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */ return (gpc_reg_operand (op, mode) || mask_operand (op, mode)); return (logical_operand (op, mode) || mask_operand (op, mode)); @@ -1182,10 +1276,8 @@ input_operand (op, mode) if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op)) return 1; - /* Windows NT allows SYMBOL_REFs and LABEL_REFs against the TOC - directly in the instruction stream */ - if (DEFAULT_ABI == ABI_NT - && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)) + /* A constant pool expression (relative to the TOC) is valid */ + if (TOC_RELATIVE_EXPR_P (op)) return 1; /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region @@ -1246,6 +1338,138 @@ small_data_operand (op, mode) return 0; #endif } + +static int +constant_pool_expr_1 (op, have_sym, have_toc) + rtx op; + int *have_sym; + int *have_toc; +{ + switch (GET_CODE(op)) + { + case SYMBOL_REF: + if (CONSTANT_POOL_ADDRESS_P (op)) + { + if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op))) + { + *have_sym = 1; + return 1; + } + else + return 0; + } + else if (! strcmp (XSTR (op, 0), toc_label_name)) + { + *have_toc = 1; + return 1; + } + else + return 0; + case PLUS: + case MINUS: + return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc) && + constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc); + case CONST: + return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc); + case CONST_INT: + return 1; + default: + return 0; + } +} + +int +constant_pool_expr_p (op) + rtx op; +{ + int have_sym = 0; + int have_toc = 0; + return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym; +} + +int +toc_relative_expr_p (op) + rtx op; +{ + int have_sym = 0; + int have_toc = 0; + return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc; +} + +/* Try machine-dependent ways of modifying an illegitimate address + to be legitimate. If we find one, return the new, valid address. + This is used from only one place: `memory_address' in explow.c. + + OLDX is the address as it was before break_out_memory_refs was called. + In some cases it is useful to look at this to decide what needs to be done. + + MODE is passed so that this macro can use GO_IF_LEGITIMATE_ADDRESS. + + It is always safe for this macro to do nothing. It exists to recognize + opportunities to optimize the output. + + On RS/6000, first check for the sum of a register with a constant + integer that is out of range. If so, generate code to add the + constant with the low-order 16 bits masked to the register and force + this result into another register (this can be done with `cau'). + Then generate an address of REG+(CONST&0xffff), allowing for the + possibility of bit 16 being a one. + + Then check for the sum of a register and something not constant, try to + load the other things into a register and return the sum. */ +rtx +rs6000_legitimize_address (x, oldx, mode) + rtx x; + rtx oldx ATTRIBUTE_UNUSED; + enum machine_mode mode; +{ + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == REG + && GET_CODE (XEXP (x, 1)) == CONST_INT + && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000) + { + HOST_WIDE_INT high_int, low_int; + rtx sum; + high_int = INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff); + low_int = INTVAL (XEXP (x, 1)) & 0xffff; + if (low_int & 0x8000) + high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16; + sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0), + GEN_INT (high_int)), 0); + return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); + } + else if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == REG + && GET_CODE (XEXP (x, 1)) != CONST_INT + && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode) + && (TARGET_POWERPC64 || mode != DImode) + && mode != TImode) + { + return gen_rtx_PLUS (Pmode, XEXP (x, 0), + force_reg (Pmode, force_operand (XEXP (x, 1), 0))); + } + else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic + && GET_CODE (x) != CONST_INT + && GET_CODE (x) != CONST_DOUBLE + && CONSTANT_P (x) + && (TARGET_HARD_FLOAT || mode != DFmode) + && mode != DImode + && mode != TImode) + { + rtx reg = gen_reg_rtx (Pmode); + emit_insn (gen_elf_high (reg, (x))); + return gen_rtx_LO_SUM (Pmode, reg, (x)); + } + else if (TARGET_TOC + && CONSTANT_POOL_EXPR_P (x) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x))) + { + return create_TOC_reference (x); + } + else + return NULL_RTX; +} + /* Initialize a variable CUM of type CUMULATIVE_ARGS @@ -1263,7 +1487,6 @@ init_cumulative_args (cum, fntype, libname, incoming) int incoming; { static CUMULATIVE_ARGS zero_cumulative; - enum rs6000_abi abi = DEFAULT_ABI; *cum = zero_cumulative; cum->words = 0; @@ -1285,14 +1508,8 @@ init_cumulative_args (cum, fntype, libname, incoming) cum->orig_nargs = cum->nargs_prototype; - /* Check for DLL import functions */ - if (abi == ABI_NT - && fntype - && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype))) - cum->call_cookie = CALL_NT_DLLIMPORT; - - /* Also check for longcall's */ - else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))) + /* Check for longcall's */ + if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))) cum->call_cookie = CALL_LONG; if (TARGET_DEBUG_ARG) @@ -1305,9 +1522,6 @@ init_cumulative_args (cum, fntype, libname, incoming) tree_code_name[ (int)TREE_CODE (ret_type) ]); } - if (cum->call_cookie & CALL_NT_DLLIMPORT) - fprintf (stderr, " dllimport,"); - if (cum->call_cookie & CALL_LONG) fprintf (stderr, " longcall,"); @@ -1325,48 +1539,40 @@ init_cumulative_args (cum, fntype, libname, incoming) For the AIX ABI structs are always stored left shifted in their argument slot. */ -int +enum direction function_arg_padding (mode, type) enum machine_mode mode; tree type; { if (type != 0 && AGGREGATE_TYPE_P (type)) - return (int)upward; + return upward; /* This is the default definition. */ return (! BYTES_BIG_ENDIAN - ? (int)upward + ? upward : ((mode == BLKmode ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT)) : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY) - ? (int)downward : (int)upward)); + ? downward : upward)); } /* If defined, a C expression that gives the alignment boundary, in bits, of an argument with the specified mode and type. If it is not defined, PARM_BOUNDARY is used for all arguments. - Windows NT wants anything >= 8 bytes to be double word aligned. - V.4 wants long longs to be double word aligned. */ int function_arg_boundary (mode, type) enum machine_mode mode; - tree type; + tree type ATTRIBUTE_UNUSED; { if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && (mode == DImode || mode == DFmode)) return 64; - - if (DEFAULT_ABI != ABI_NT || TARGET_64BIT) + else return PARM_BOUNDARY; - - if (mode != BLKmode) - return (GET_MODE_SIZE (mode)) >= 8 ? 64 : 32; - - return (int_size_in_bytes (type) >= 8) ? 64 : 32; } /* Update the data in CUM to advance over an argument @@ -1660,7 +1866,6 @@ function_arg_pass_by_reference (cum, mode, type, named) return 0; } - /* Perform any needed actions needed for a function that is receiving a variable number of arguments. @@ -1749,7 +1954,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) && next_cum.fregno <= FP_ARG_V4_MAX_REG) { int fregno = next_cum.fregno; - rtx cr1 = gen_rtx_REG (CCmode, 69); + rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO); rtx lab = gen_label_rtx (); int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8); @@ -1780,18 +1985,19 @@ tree rs6000_build_va_list () { tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl; - tree uchar_type_node; - /* Only SVR4 needs something special. */ + /* For AIX, prefer 'char *' because that's what the system + header files like. */ if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - return ptr_type_node; + return build_pointer_type (char_type_node); record = make_lang_type (RECORD_TYPE); type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record); - uchar_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"), uchar_type_node); - f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"), uchar_type_node); + f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"), + unsigned_char_type_node); + f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"), + unsigned_char_type_node); f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"), ptr_type_node); f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"), @@ -1891,9 +2097,48 @@ rs6000_va_arg (valist, type) int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale; rtx lab_false, lab_over, addr_rtx, r; - /* Only SVR4 needs something special. */ + /* For AIX, the rule is that structures are passed left-aligned in + their stack slot. However, GCC does not presently do this: + structures which are the same size as integer types are passed + right-aligned, as if they were in fact integers. This only + matters for structures of size 1 or 2, or 4 when TARGET_64BIT. */ if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - return std_expand_builtin_va_arg (valist, type); + { + HOST_WIDE_INT align, rounded_size; + enum machine_mode mode; + tree addr_tree; + + /* Compute the rounded size of the type. */ + align = PARM_BOUNDARY / BITS_PER_UNIT; + rounded_size = (((int_size_in_bytes (type) + align - 1) / align) + * align); + + addr_tree = valist; + + mode = TYPE_MODE (type); + if (mode != BLKmode) + { + HOST_WIDE_INT adj; + adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT; + if (rounded_size > align) + adj = rounded_size; + + addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, + build_int_2 (rounded_size - adj, 0)); + } + + addr_rtx = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); + addr_rtx = copy_to_reg (addr_rtx); + + /* Compute new value for AP. */ + t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, + build (PLUS_EXPR, TREE_TYPE (valist), valist, + build_int_2 (rounded_size, 0))); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + + return addr_rtx; + } f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); f_fpr = TREE_CHAIN (f_gpr); @@ -2431,6 +2676,215 @@ store_multiple_operation (op, mode) return 1; } + +/* Return 1 for an PARALLEL suitable for mtcrf. */ + +int +mtcrf_operation (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + int count = XVECLEN (op, 0); + int i; + int bitmap = 0; + rtx src_reg; + + /* Perform a quick check so we don't blow up below. */ + if (count < 2 + || GET_CODE (XVECEXP (op, 0, 0)) != USE + || GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) != CONST_INT + || GET_CODE (XVECEXP (op, 0, 1)) != SET + || GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != UNSPEC + || XVECLEN (SET_SRC (XVECEXP (op, 0, 1)), 0) != 2) + return 0; + src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 1)), 0, 0); + + if (GET_CODE (src_reg) != REG + || GET_MODE (src_reg) != SImode + || ! INT_REGNO_P (REGNO (src_reg))) + return 0; + + for (i = 1; i < count; i++) + { + rtx exp = XVECEXP (op, 0, i); + rtx unspec; + int maskval; + + if (GET_CODE (exp) != SET + || GET_CODE (SET_DEST (exp)) != REG + || GET_MODE (SET_DEST (exp)) != CCmode + || ! CR_REGNO_P (REGNO (SET_DEST (exp)))) + return 0; + unspec = SET_SRC (exp); + maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp))); + bitmap |= maskval; + + if (GET_CODE (unspec) != UNSPEC + || XINT (unspec, 1) != 20 + || XVECLEN (unspec, 0) != 2 + || XVECEXP (unspec, 0, 0) != src_reg + || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT + || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) + return 0; + } + return INTVAL (XEXP (XVECEXP (op, 0, 0), 0)) == bitmap; +} + +/* Return 1 for an PARALLEL suitable for lmw. */ + +int +lmw_operation (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + int count = XVECLEN (op, 0); + int dest_regno; + rtx src_addr; + int base_regno; + HOST_WIDE_INT offset; + int i; + + /* Perform a quick check so we don't blow up below. */ + if (count <= 1 + || GET_CODE (XVECEXP (op, 0, 0)) != SET + || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG + || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) + return 0; + + dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); + src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); + + if (dest_regno > 31 + || count != 32 - dest_regno) + return 0; + + if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr)) + { + offset = 0; + base_regno = REGNO (src_addr); + if (base_regno == 0) + return 0; + } + else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr)) + { + offset = INTVAL (XEXP (src_addr, 1)); + base_regno = REGNO (XEXP (src_addr, 0)); + } + else + return 0; + + for (i = 0; i < count; i++) + { + rtx elt = XVECEXP (op, 0, i); + rtx newaddr; + rtx addr_reg; + HOST_WIDE_INT newoffset; + + if (GET_CODE (elt) != SET + || GET_CODE (SET_DEST (elt)) != REG + || GET_MODE (SET_DEST (elt)) != SImode + || REGNO (SET_DEST (elt)) != dest_regno + i + || GET_CODE (SET_SRC (elt)) != MEM + || GET_MODE (SET_SRC (elt)) != SImode) + return 0; + newaddr = XEXP (SET_SRC (elt), 0); + if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr)) + { + newoffset = 0; + addr_reg = newaddr; + } + else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr)) + { + addr_reg = XEXP (newaddr, 0); + newoffset = INTVAL (XEXP (newaddr, 1)); + } + else + return 0; + if (REGNO (addr_reg) != base_regno + || newoffset != offset + 4 * i) + return 0; + } + + return 1; +} + +/* Return 1 for an PARALLEL suitable for stmw. */ + +int +stmw_operation (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + int count = XVECLEN (op, 0); + int src_regno; + rtx dest_addr; + int base_regno; + HOST_WIDE_INT offset; + int i; + + /* Perform a quick check so we don't blow up below. */ + if (count <= 1 + || GET_CODE (XVECEXP (op, 0, 0)) != SET + || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM + || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) + return 0; + + src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); + dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); + + if (src_regno > 31 + || count != 32 - src_regno) + return 0; + + if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr)) + { + offset = 0; + base_regno = REGNO (dest_addr); + if (base_regno == 0) + return 0; + } + else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr)) + { + offset = INTVAL (XEXP (dest_addr, 1)); + base_regno = REGNO (XEXP (dest_addr, 0)); + } + else + return 0; + + for (i = 0; i < count; i++) + { + rtx elt = XVECEXP (op, 0, i); + rtx newaddr; + rtx addr_reg; + HOST_WIDE_INT newoffset; + + if (GET_CODE (elt) != SET + || GET_CODE (SET_SRC (elt)) != REG + || GET_MODE (SET_SRC (elt)) != SImode + || REGNO (SET_SRC (elt)) != src_regno + i + || GET_CODE (SET_DEST (elt)) != MEM + || GET_MODE (SET_DEST (elt)) != SImode) + return 0; + newaddr = XEXP (SET_DEST (elt), 0); + if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr)) + { + newoffset = 0; + addr_reg = newaddr; + } + else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr)) + { + addr_reg = XEXP (newaddr, 0); + newoffset = INTVAL (XEXP (newaddr, 1)); + } + else + return 0; + if (REGNO (addr_reg) != base_regno + || newoffset != offset + 4 * i) + return 0; + } + + return 1; +} /* Return 1 if OP is a comparison operation that is valid for a branch insn. We only check the opcode against the mode of the CC value here. */ @@ -2691,13 +3145,20 @@ ccr_bit (op, scc_p) enum machine_mode cc_mode; int cc_regnum; int base_bit; + rtx reg; if (GET_RTX_CLASS (code) != '<') return -1; - cc_mode = GET_MODE (XEXP (op, 0)); - cc_regnum = REGNO (XEXP (op, 0)); - base_bit = 4 * (cc_regnum - 68); + reg = XEXP (op, 0); + + if (GET_CODE (reg) != REG + || ! CR_REGNO_P (REGNO (reg))) + abort (); + + cc_mode = GET_MODE (reg); + cc_regnum = REGNO (reg); + base_bit = 4 * (cc_regnum - CR0_REGNO); /* In CCEQmode cases we have made sure that the result is always in the third bit of the CR field. */ @@ -2746,39 +3207,14 @@ rs6000_got_register (value) return pic_offset_table_rtx; } - -/* Search for any occurrence of the GOT_TOC register marker that should - have been eliminated, but may have crept back in. - - This function could completely go away now (June 1999), but we leave it - in for a while until all the possible issues with the new -fpic handling - are resolved. */ - -void -rs6000_reorg (insn) - rtx insn; -{ - if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) - { - rtx got_reg = gen_rtx_REG (Pmode, 2); - for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn)) - if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' - && reg_mentioned_p (got_reg, PATTERN (insn))) - fatal_insn ("GOT/TOC register marker not removed:", PATTERN (insn)); - } -} - /* Define the structure for the machine field in struct function. */ struct machine_function { int sysv_varargs_p; - int save_toc_p; - int fpmem_size; - int fpmem_offset; }; -/* Functions to save and restore rs6000_fpmem_size. +/* Functions to save and restore sysv_varargs_p. These will be called, via pointer variables, from push_function_context and pop_function_context. */ @@ -2791,8 +3227,6 @@ rs6000_save_machine_status (p) p->machine = machine; machine->sysv_varargs_p = rs6000_sysv_varargs_p; - machine->fpmem_size = rs6000_fpmem_size; - machine->fpmem_offset = rs6000_fpmem_offset; } void @@ -2802,8 +3236,6 @@ rs6000_restore_machine_status (p) struct machine_function *machine = p->machine; rs6000_sysv_varargs_p = machine->sysv_varargs_p; - rs6000_fpmem_size = machine->fpmem_size; - rs6000_fpmem_offset = machine->fpmem_offset; free (machine); p->machine = (struct machine_function *)0; @@ -2814,10 +3246,8 @@ rs6000_restore_machine_status (p) void rs6000_init_expanders () { - /* Reset varargs and save TOC indicator */ + /* Reset varargs */ rs6000_sysv_varargs_p = 0; - rs6000_fpmem_size = 0; - rs6000_fpmem_offset = 0; /* Arrange to save and restore machine status around nested functions. */ save_machine_status = rs6000_save_machine_status; @@ -2839,7 +3269,7 @@ void print_operand (file, x, code) FILE *file; rtx x; - char code; + int code; { int i; HOST_WIDE_INT val; @@ -2860,11 +3290,6 @@ print_operand (file, x, code) asm_fprintf (file, RS6000_CALL_GLUE); return; - case '*': - /* Write the register number of the TOC register. */ - fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2 /* PIC_OFFSET_TABLE_REGNUM? */ ], file); - return; - case '$': /* Write out either a '.' or '$' for the current location, depending on whether this is Solaris or not. */ @@ -2902,7 +3327,7 @@ print_operand (file, x, code) if ((GET_CODE (x) == LE || GET_CODE (x) == GE) && GET_MODE (XEXP (x, 0)) == CCFPmode) { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); + int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO); fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, base_bit + 2, base_bit + (GET_CODE (x) == GE)); @@ -2916,7 +3341,7 @@ print_operand (file, x, code) if (GET_CODE (x) == LE || GET_CODE (x) == GE || GET_CODE (x) == LEU || GET_CODE (x) == GEU) { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); + int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO); fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, base_bit + 2, @@ -2925,7 +3350,7 @@ print_operand (file, x, code) else if (GET_CODE (x) == NE) { - int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); + int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO); fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3, base_bit + 2, base_bit + 2); @@ -2937,7 +3362,7 @@ print_operand (file, x, code) if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) output_operand_lossage ("invalid %%E value"); - fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3); + fprintf(file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 3); return; case 'f': @@ -2946,7 +3371,7 @@ print_operand (file, x, code) if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) output_operand_lossage ("invalid %%f value"); else - fprintf (file, "%d", 4 * (REGNO (x) - 68)); + fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO)); return; case 'F': @@ -2955,7 +3380,7 @@ print_operand (file, x, code) if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) output_operand_lossage ("invalid %%F value"); else - fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68)); + fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO)); return; case 'G': @@ -3022,6 +3447,27 @@ print_operand (file, x, code) fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x)); return; + case 'l': + /* X must be a symbolic constant on ELF. Write an + expression suitable for an 'addi' that adds in the low 16 + bits of the MEM. */ + if (GET_CODE (x) != CONST) + { + print_operand_address (file, x); + fputs ("@l", file); + } + else + { + if (GET_CODE (XEXP (x, 0)) != PLUS + || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) + || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) + output_operand_lossage ("invalid %%l value"); + print_operand_address (file, XEXP (XEXP (x, 0), 0)); + fputs ("@l", file); + print_operand (file, XEXP (XEXP (x, 0), 1), 0); + } + case 'L': /* Write second word of DImode or DFmode reference. Works on register or non-indexed memory only. */ @@ -3054,15 +3500,15 @@ print_operand (file, x, code) /* If the high bit is set and the low bit is not, the value is zero. If the high bit is zero, the value is the first 1 bit we find from the left. */ - if ((val & 0x80000000) && ((val & 1) == 0)) + if ((val & 0x80000000u) && ((val & 1) == 0)) { putc ('0', file); return; } - else if ((val & 0x80000000) == 0) + else if ((val & 0x80000000u) == 0) { for (i = 1; i < 32; i++) - if ((val <<= 1) & 0x80000000) + if ((val <<= 1) & 0x80000000u) break; fprintf (file, "%d", i); return; @@ -3089,7 +3535,7 @@ print_operand (file, x, code) /* If the low bit is set and the high bit is not, the value is 31. If the low bit is zero, the value is the first 1 bit we find from the right. */ - if ((val & 1) && ((val & 0x80000000) == 0)) + if ((val & 1) && ((val & 0x80000000u) == 0)) { fputs ("31", file); return; @@ -3109,7 +3555,7 @@ print_operand (file, x, code) /* Otherwise, look for the first 0 bit from the left. The result is its number minus 1. We know the high-order bit is one. */ for (i = 0; i < 32; i++) - if (((val <<= 1) & 0x80000000) == 0) + if (((val <<= 1) & 0x80000000u) == 0) break; fprintf (file, "%d", i); @@ -3155,7 +3601,7 @@ print_operand (file, x, code) if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) output_operand_lossage ("invalid %%R value"); else - fprintf (file, "%d", 128 >> (REGNO (x) - 68)); + fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO)); return; case 's': @@ -3399,13 +3845,13 @@ print_operand (file, x, code) case ABI_AIX_NODESC: case ABI_SOLARIS: break; - - case ABI_NT: - fputs ("..", file); - break; } } +#if TARGET_AIX RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); +#else + assemble_name (file, XSTR (x, 0)); +#endif return; case 'Z': @@ -3459,19 +3905,15 @@ print_operand_address (file, x) { if (GET_CODE (x) == REG) fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); - else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST || GET_CODE (x) == LABEL_REF) + else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST + || GET_CODE (x) == LABEL_REF) { output_addr_const (file, x); if (small_data_operand (x, GET_MODE (x))) fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, reg_names[SMALL_DATA_REG]); - -#ifdef TARGET_NO_TOC - else if (TARGET_NO_TOC) - ; -#endif - else - fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 /* PIC_OFFSET_TABLE_REGNUM? */ ]); + else if (TARGET_TOC) + abort(); } else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) { @@ -3495,6 +3937,28 @@ print_operand_address (file, x) fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); } #endif + else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x)) + { + if (TARGET_AIX) + { + rtx contains_minus = XEXP (x, 1); + rtx minus; + + /* Find the (minus (sym) (toc)) buried in X, and temporarily + turn it into (sym) for output_addr_const. */ + while (GET_CODE (XEXP (contains_minus, 0)) != MINUS) + contains_minus = XEXP (contains_minus, 0); + + minus = XEXP (contains_minus, 0); + XEXP (contains_minus, 0) = XEXP (minus, 0); + output_addr_const (file, XEXP (x, 1)); + XEXP (contains_minus, 0) = minus; + } + else + output_addr_const (file, XEXP (x, 1)); + + fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]); + } else abort (); } @@ -3577,27 +4041,6 @@ first_fp_reg_to_save () return first_reg; } - -/* Return non-zero if this function makes calls. */ - -int -rs6000_makes_calls () -{ - rtx insn; - - /* If we are profiling, we will be making a call to __mcount. - Under the System V ABI's, we store the LR directly, so - we don't need to do it here. */ - if (DEFAULT_ABI == ABI_AIX && profile_flag) - return 1; - - for (insn = get_insns (); insn; insn = next_insn (insn)) - if (GET_CODE (insn) == CALL_INSN) - return 1; - - return 0; -} - /* Calculate the stack information for the current function. This is complicated by having two separate calling sequences, the AIX calling @@ -3671,53 +4114,6 @@ rs6000_makes_calls () -mno-eabi libraries can be used with -meabi programs.) - A PowerPC Windows/NT frame looks like: - - SP----> +---------------------------------------+ - | back chain to caller | 0 - +---------------------------------------+ - | reserved | 4 - +---------------------------------------+ - | reserved | 8 - +---------------------------------------+ - | reserved | 12 - +---------------------------------------+ - | reserved | 16 - +---------------------------------------+ - | reserved | 20 - +---------------------------------------+ - | Parameter save area (P) | 24 - +---------------------------------------+ - | Alloca space (A) | 24+P - +---------------------------------------+ - | Local variable space (L) | 24+P+A - +---------------------------------------+ - | Float/int conversion temporary (X) | 24+P+A+L - +---------------------------------------+ - | Save area for FP registers (F) | 24+P+A+L+X - +---------------------------------------+ - | Possible alignment area (Y) | 24+P+A+L+X+F - +---------------------------------------+ - | Save area for GP registers (G) | 24+P+A+L+X+F+Y - +---------------------------------------+ - | Save area for CR (C) | 24+P+A+L+X+F+Y+G - +---------------------------------------+ - | Save area for TOC (T) | 24+P+A+L+X+F+Y+G+C - +---------------------------------------+ - | Save area for LR (R) | 24+P+A+L+X+F+Y+G+C+T - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - For NT, there is no specific order to save the registers, but in - order to support __builtin_return_address, the save area for the - link register needs to be in a known place, so we use -4 off of the - old SP. To support calls through pointers, we also allocate a - fixed slot to store the TOC, -8 off the old SP. - - The required alignment for NT is 16 bytes. - - The EABI configuration defaults to the V.4 layout, unless -mcall-aix is used, in which case the AIX layout is used. However, the stack alignment requirements may differ. If -mno-eabi is not @@ -3734,7 +4130,7 @@ rs6000_stack_info () { static rs6000_stack_t info, zero_info; rs6000_stack_t *info_ptr = &info; - int reg_size = TARGET_32BIT ? 4 : 8; + int reg_size = TARGET_POWERPC64 ? 8 : 4; enum rs6000_abi abi; int total_raw_size; @@ -3759,54 +4155,10 @@ rs6000_stack_info () info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); /* Does this function call anything? */ - info_ptr->calls_p = rs6000_makes_calls (); - - /* Allocate space to save the toc. */ - if (abi == ABI_NT && info_ptr->calls_p) - { - info_ptr->toc_save_p = 1; - info_ptr->toc_size = reg_size; - } - - /* Does this machine need the float/int conversion area? */ - info_ptr->fpmem_p = regs_ever_live[FPMEM_REGNUM]; - - /* If this is main and we need to call a function to set things up, - save main's arguments around the call. */ -#ifdef TARGET_EABI - if (TARGET_EABI) -#endif - { - if (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), - "main") - && DECL_CONTEXT (current_function_decl) == NULL_TREE) - { - info_ptr->main_p = 1; - -#ifdef NAME__MAIN - info_ptr->calls_p = 1; - - if (DECL_ARGUMENTS (current_function_decl)) - { - int i; - tree arg; - - info_ptr->main_save_p = 1; - info_ptr->main_size = 0; - - for ((i = 0), (arg = DECL_ARGUMENTS (current_function_decl)); - arg != NULL_TREE && i < 8; - (arg = TREE_CHAIN (arg)), i++) - { - info_ptr->main_size += reg_size; - } - } -#endif - } - } + info_ptr->calls_p = ! current_function_is_leaf; /* Determine if we need to save the link register */ - if (regs_ever_live[65] + if (regs_ever_live[LINK_REGISTER_REGNUM] || (DEFAULT_ABI == ABI_AIX && profile_flag) #ifdef TARGET_RELOCATABLE || (TARGET_RELOCATABLE && (get_pool_size () != 0)) @@ -3818,16 +4170,16 @@ rs6000_stack_info () || info_ptr->calls_p) { info_ptr->lr_save_p = 1; - regs_ever_live[65] = 1; - if (abi == ABI_NT) - info_ptr->lr_size = reg_size; + regs_ever_live[LINK_REGISTER_REGNUM] = 1; } - /* Determine if we need to save the condition code registers */ - if (regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72]) + /* Determine if we need to save the condition code registers. */ + if (regs_ever_live[CR2_REGNO] + || regs_ever_live[CR3_REGNO] + || regs_ever_live[CR4_REGNO]) { info_ptr->cr_save_p = 1; - if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS) + if (abi == ABI_V4 || abi == ABI_SOLARIS) info_ptr->cr_size = reg_size; } @@ -3837,13 +4189,11 @@ rs6000_stack_info () info_ptr->varargs_size = RS6000_VARARGS_AREA; info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8); info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size, 8); - info_ptr->fpmem_size = (info_ptr->fpmem_p) ? 8 : 0; info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size + info_ptr->gp_size + info_ptr->cr_size + info_ptr->lr_size - + info_ptr->toc_size - + info_ptr->main_size, 8); + + info_ptr->toc_size, 8); /* Calculate the offsets */ switch (abi) @@ -3856,7 +4206,6 @@ rs6000_stack_info () case ABI_AIX_NODESC: info_ptr->fp_save_offset = - info_ptr->fp_size; info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; - info_ptr->main_save_offset = info_ptr->gp_save_offset - info_ptr->main_size; info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */ info_ptr->lr_save_offset = 2*reg_size; break; @@ -3867,31 +4216,12 @@ rs6000_stack_info () info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size; info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size; - info_ptr->main_save_offset = info_ptr->toc_save_offset - info_ptr->main_size; info_ptr->lr_save_offset = reg_size; break; - - case ABI_NT: - info_ptr->lr_save_offset = -reg_size; - info_ptr->toc_save_offset = info_ptr->lr_save_offset - info_ptr->lr_size; - info_ptr->cr_save_offset = info_ptr->toc_save_offset - info_ptr->toc_size; - info_ptr->gp_save_offset = info_ptr->cr_save_offset - info_ptr->cr_size - info_ptr->gp_size + reg_size; - info_ptr->fp_save_offset = info_ptr->gp_save_offset - info_ptr->fp_size; - if (info_ptr->fp_size && ((- info_ptr->fp_save_offset) % 8) != 0) - info_ptr->fp_save_offset -= reg_size; - - info_ptr->main_save_offset = info_ptr->fp_save_offset - info_ptr->main_size; - break; } - /* Ensure that fpmem_offset will be aligned to an 8-byte boundary. */ - if (info_ptr->fpmem_p - && (info_ptr->main_save_offset - info_ptr->fpmem_size) % 8) - info_ptr->fpmem_size += reg_size; - total_raw_size = (info_ptr->vars_size + info_ptr->parm_size - + info_ptr->fpmem_size + info_ptr->save_size + info_ptr->varargs_size + info_ptr->fixed_size); @@ -3902,7 +4232,7 @@ rs6000_stack_info () For AIX we need to push the stack if a frame pointer is needed (because the stack might be dynamically adjusted), if we are debugging, if we - make calls, or if the sum of fp_save, gp_save, fpmem, and local variables + make calls, or if the sum of fp_save, gp_save, and local variables are more than the space needed to save all non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 + 18*8 = 288 (GPR13 reserved). @@ -3912,10 +4242,9 @@ rs6000_stack_info () if (info_ptr->calls_p) info_ptr->push_p = 1; - else if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS) + else if (abi == ABI_V4 || abi == ABI_SOLARIS) info_ptr->push_p = (total_raw_size > info_ptr->fixed_size - || (abi == ABI_NT ? info_ptr->lr_save_p - : info_ptr->calls_p)); + || info_ptr->calls_p); else info_ptr->push_p = (frame_pointer_needed @@ -3923,17 +4252,6 @@ rs6000_stack_info () || ((total_raw_size - info_ptr->fixed_size) > (TARGET_32BIT ? 220 : 288))); - if (info_ptr->fpmem_p) - { - info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size; - rs6000_fpmem_size = info_ptr->fpmem_size; - rs6000_fpmem_offset = (info_ptr->push_p - ? info_ptr->total_size + info_ptr->fpmem_offset - : info_ptr->fpmem_offset); - } - else - info_ptr->fpmem_offset = 0; - /* Zero offsets if we're not saving those registers */ if (info_ptr->fp_size == 0) info_ptr->fp_save_offset = 0; @@ -3950,9 +4268,6 @@ rs6000_stack_info () if (! info_ptr->toc_save_p) info_ptr->toc_save_offset = 0; - if (! info_ptr->main_save_p) - info_ptr->main_save_offset = 0; - return info_ptr; } @@ -3978,7 +4293,6 @@ debug_stack_info (info) case ABI_AIX_NODESC: abi_string = "AIX"; break; case ABI_V4: abi_string = "V.4"; break; case ABI_SOLARIS: abi_string = "Solaris"; break; - case ABI_NT: abi_string = "NT"; break; } fprintf (stderr, "\tABI = %5s\n", abi_string); @@ -4004,15 +4318,6 @@ debug_stack_info (info) if (info->calls_p) fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p); - if (info->main_p) - fprintf (stderr, "\tmain_p = %5d\n", info->main_p); - - if (info->main_save_p) - fprintf (stderr, "\tmain_save_p = %5d\n", info->main_save_p); - - if (info->fpmem_p) - fprintf (stderr, "\tfpmem_p = %5d\n", info->fpmem_p); - if (info->gp_save_offset) fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset); @@ -4031,12 +4336,6 @@ debug_stack_info (info) if (info->varargs_save_offset) fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset); - if (info->main_save_offset) - fprintf (stderr, "\tmain_save_offset = %5d\n", info->main_save_offset); - - if (info->fpmem_offset) - fprintf (stderr, "\tfpmem_offset = %5d\n", info->fpmem_offset); - if (info->total_size) fprintf (stderr, "\ttotal_size = %5d\n", info->total_size); @@ -4049,9 +4348,6 @@ debug_stack_info (info) if (info->parm_size) fprintf (stderr, "\tparm_size = %5d\n", info->parm_size); - if (info->fpmem_size) - fprintf (stderr, "\tfpmem_size = %5d\n", info->fpmem_size); - if (info->fixed_size) fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size); @@ -4070,9 +4366,6 @@ debug_stack_info (info) if (info->toc_size) fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size); - if (info->main_size) - fprintf (stderr, "\tmain_size = %5d\n", info->main_size); - if (info->save_size) fprintf (stderr, "\tsave_size = %5d\n", info->save_size); @@ -4082,104 +4375,303 @@ debug_stack_info (info) fprintf (stderr, "\n"); } -/* Write out an instruction to load the TOC_TABLE address into register 30. +/* Emit instructions needed to load the TOC register. This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is - a constant pool. */ + a constant pool; or for SVR4 -fpic. */ void -rs6000_output_load_toc_table (file, reg) - FILE *file; - int reg; +rs6000_emit_load_toc_table (fromprolog) + int fromprolog; { - char buf[256]; + rtx dest; + dest = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); -#ifdef USING_SVR4_H - if (TARGET_RELOCATABLE) + if (TARGET_ELF) { - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "\tbl "); - assemble_name (file, buf); - fprintf (file, "\n"); - - /* possibly create the toc section */ - if (! toc_initialized) + if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && flag_pic == 1) { - toc_section (); - function_section (current_function_decl); + rtx temp = (fromprolog + ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) + : gen_reg_rtx (Pmode)); + if (TARGET_32BIT) + emit_insn (gen_load_toc_v4_pic_si (temp)); + else + emit_insn (gen_load_toc_v4_pic_di (temp)); + emit_move_insn (dest, temp); } + else if (flag_pic == 2) + { + char buf[30]; + rtx tempLR = (fromprolog + ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) + : gen_reg_rtx (Pmode)); + rtx temp0 = (fromprolog + ? gen_rtx_REG (Pmode, 0) + : gen_reg_rtx (Pmode)); + rtx symF; + + /* possibly create the toc section */ + if (! toc_initialized) + { + toc_section (); + function_section (current_function_decl); + } + + if (fromprolog) + { + rtx symL; + + ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); + symF = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); - /* If not first call in this function, we need to put the - different between .LCTOC1 and the address we get to right - after the bl. It will mess up disassembling the instructions - but that can't be helped. We will later need to bias the - address before loading. */ - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - { - const char *init_ptr = TARGET_32BIT ? ".long" : ".quad"; - const char *buf_ptr; + ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); + symL = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); - ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno); + emit_insn (gen_load_toc_v4_PIC_1 (tempLR, symF)); + emit_move_insn (dest, tempLR); + emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF)); + } + else + { + rtx tocsym; + static int reload_toc_labelno = 0; + + tocsym = gen_rtx_SYMBOL_REF (Pmode, + ggc_alloc_string (toc_label_name, -1)); + ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++); + symF = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); + + emit_insn (gen_load_toc_v4_PIC_1b (tempLR, symF, tocsym)); + emit_move_insn (dest, tempLR); + emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest)); + } + emit_insn (gen_addsi3 (dest, temp0, dest)); + } + else if (flag_pic == 0 && TARGET_MINIMAL_TOC) + { + /* This is for AIX code running in non-PIC ELF. */ + char buf[30]; + rtx realsym; ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - STRIP_NAME_ENCODING (buf_ptr, buf); - fprintf (file, "\t%s %s-", init_ptr, buf_ptr); + realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); + + emit_insn (gen_elf_high (dest, realsym)); + emit_insn (gen_elf_low (dest, dest, realsym)); + } + else + abort(); + } + else + { + if (TARGET_32BIT) + emit_insn (gen_load_toc_aix_si (dest)); + else + emit_insn (gen_load_toc_aix_di (dest)); + } +} + +int +get_TOC_alias_set () +{ + static int set = -1; + if (set == -1) + set = new_alias_set (); + return set; +} + +/* This retuns nonzero if the current function uses the TOC. This is + determined by the presence of (unspec ... 7), which is generated by + the various load_toc_* patterns. */ +int +uses_TOC () +{ + rtx insn; - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - fprintf (file, "%s\n", buf_ptr); + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') + { + rtx pat = PATTERN (insn); + int i; + + if (GET_CODE(pat) == PARALLEL) + for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) + if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC + && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7) + return 1; } + return 0; +} - ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno); - fprintf (file, "\tmflr %s\n", reg_names[reg]); +rtx +create_TOC_reference(symbol) + rtx symbol; +{ + return gen_rtx_PLUS (Pmode, + gen_rtx_REG (Pmode, TOC_REGISTER), + gen_rtx_CONST (Pmode, + gen_rtx_MINUS (Pmode, symbol, + gen_rtx_SYMBOL_REF (Pmode, + ggc_alloc_string (toc_label_name, -1))))); +} - if (rs6000_pic_func_labelno != rs6000_pic_labelno) - asm_fprintf(file, "\t{cal|la} %s,%d(%s)\n", reg_names[reg], - (TARGET_32BIT ? 4 : 8), reg_names[reg]); +#if TARGET_AIX +/* __throw will restore its own return address to be the same as the + return address of the function that the throw is being made to. + This is unfortunate, because we want to check the original + return address to see if we need to restore the TOC. + So we have to squirrel it away here. + This is used only in compiling __throw and __rethrow. - asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s,(" : "\tld %s,(", - reg_names[0]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); - assemble_name (file, buf); - putc ('-', file); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - assemble_name (file, buf); - fprintf (file, ")(%s)\n", reg_names[reg]); - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", - reg_names[reg], reg_names[0], reg_names[reg]); - rs6000_pic_labelno++; - } - else if (! TARGET_64BIT) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - asm_fprintf (file, "\t{liu|lis} %s,", reg_names[reg]); - assemble_name (file, buf); - fputs ("@ha\n", file); - asm_fprintf (file, "\t{cal|la} %s,", reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "@l(%s)\n", reg_names[reg]); - } - else - abort (); + Most of this code should be removed by CSE. */ +static rtx insn_after_throw; -#else /* !USING_SVR4_H */ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0); - asm_fprintf (file, TARGET_32BIT ? "\t{l|lwz} %s," : "\tld %s,", - reg_names[reg]); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", reg_names[2]); -#endif /* USING_SVR4_H */ +/* This does the saving... */ +void +rs6000_aix_emit_builtin_unwind_init () +{ + rtx mem; + rtx stack_top = gen_reg_rtx (Pmode); + rtx opcode_addr = gen_reg_rtx (Pmode); + + insn_after_throw = gen_reg_rtx (SImode); + + mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx); + emit_move_insn (stack_top, mem); + + mem = gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, stack_top, + GEN_INT (2 * GET_MODE_SIZE (Pmode)))); + emit_move_insn (opcode_addr, mem); + emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr)); } +/* Emit insns to _restore_ the TOC register, at runtime (specifically in _eh.o). + Only used on AIX. + + The idea is that on AIX, function calls look like this: + bl somefunction-trampoline + lwz r2,20(sp) + + and later, + somefunction-trampoline: + stw r2,20(sp) + ... load function address in the count register ... + bctr + or like this, if the linker determines that this is not a cross-module call + and so the TOC need not be restored: + bl somefunction + nop + or like this, if the compiler could determine that this is not a + cross-module call: + bl somefunction + now, the tricky bit here is that register 2 is saved and restored + by the _linker_, so we can't readily generate debugging information + for it. So we need to go back up the call chain looking at the + insns at return addresses to see which calls saved the TOC register + and so see where it gets restored from. + + Oh, and all this gets done in RTL inside the eh_epilogue pattern, + just before the actual epilogue. + + On the bright side, this incurs no space or time overhead unless an + exception is thrown, except for the extra code in libgcc.a. + + The parameter STACKSIZE is a register containing (at runtime) + the amount to be popped off the stack in addition to the stack frame + of this routine (which will be __throw or __rethrow, and so is + guaranteed to have a stack frame). */ +void +rs6000_emit_eh_toc_restore (stacksize) + rtx stacksize; +{ + rtx top_of_stack; + rtx bottom_of_stack = gen_reg_rtx (Pmode); + rtx tocompare = gen_reg_rtx (SImode); + rtx opcode = gen_reg_rtx (SImode); + rtx opcode_addr = gen_reg_rtx (Pmode); + rtx mem; + rtx loop_start = gen_label_rtx (); + rtx no_toc_restore_needed = gen_label_rtx (); + rtx loop_exit = gen_label_rtx (); + + mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + emit_move_insn (bottom_of_stack, mem); + + top_of_stack = expand_binop (Pmode, add_optab, + bottom_of_stack, stacksize, + NULL_RTX, 1, OPTAB_WIDEN); + + emit_move_insn (tocompare, + GEN_INT (trunc_int_for_mode (TARGET_32BIT + ? 0x80410014 + : 0xE8410028, SImode))); + + if (insn_after_throw == NULL_RTX) + abort(); + emit_move_insn (opcode, insn_after_throw); + + emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG); + emit_label (loop_start); + + do_compare_rtx_and_jump (opcode, tocompare, NE, 1, + SImode, NULL_RTX, 0, NULL_RTX, + no_toc_restore_needed); + + mem = gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, bottom_of_stack, + GEN_INT (5 * GET_MODE_SIZE (Pmode)))); + emit_move_insn (gen_rtx_REG (Pmode, 2), mem); + + emit_label (no_toc_restore_needed); + do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1, + Pmode, NULL_RTX, 0, NULL_RTX, + loop_exit); + + mem = gen_rtx_MEM (Pmode, bottom_of_stack); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + emit_move_insn (bottom_of_stack, mem); + + mem = gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, bottom_of_stack, + GEN_INT (2 * GET_MODE_SIZE (Pmode)))); + emit_move_insn (opcode_addr, mem); + emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr)); + + emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT); + emit_jump (loop_start); + emit_note (NULL_PTR, NOTE_INSN_LOOP_END); + emit_label (loop_exit); +} +#endif /* TARGET_AIX */ -/* Emit the correct code for allocating stack space. If COPY_R12, make sure a copy - of the old frame is left in r12. */ +/* This ties together stack memory + (MEM with an alias set of rs6000_sr_alias_set) + and the change to the stack pointer. */ +static void +rs6000_emit_stack_tie () +{ + rtx mem; + mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM)); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + emit_insn (gen_stack_tie (mem)); +} -void -rs6000_allocate_stack_space (file, size, copy_r12) - FILE *file; - int size; +/* Emit the correct code for allocating stack space, as insns. + If COPY_R12, make sure a copy of the old frame is left in r12. + The generated code may use hard register 0 as a temporary. */ + +static void +rs6000_emit_allocate_stack (size, copy_r12) + HOST_WIDE_INT size; int copy_r12; { - int neg_size = -size; + rtx insn; + rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx tmp_reg = gen_rtx_REG (Pmode, 0); + rtx todec = GEN_INT (-size); if (current_function_limit_stack) { @@ -4187,111 +4679,400 @@ rs6000_allocate_stack_space (file, size, copy_r12) && REGNO (stack_limit_rtx) > 1 && REGNO (stack_limit_rtx) <= 31) { - if (size <= 32767) - asm_fprintf (file, "\t{cal %s,%d(%s)|addi %s,%s,%d}\n", - reg_names[0], reg_names[REGNO (stack_limit_rtx)], - size); - else - { - asm_fprintf (file, "\t{cau|addis} %s,%s,0x%x\n", - reg_names[0], reg_names[REGNO (stack_limit_rtx)], - ((size + 0x8000) >> 16) & 0xffff); - asm_fprintf (file, "\t{ai|addic} %s,%s,%d\n", - reg_names[0], reg_names[0], - (size & 0x7fff) | -(size & 0x8000)); - } - if (TARGET_32BIT) - asm_fprintf (file, "\t{t|tw}llt %s,%s\n", - reg_names[1], reg_names[0]); - else - asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]); + emit_insn (Pmode == SImode + ? gen_addsi3 (tmp_reg, + stack_limit_rtx, + GEN_INT (size)) + : gen_adddi3 (tmp_reg, + stack_limit_rtx, + GEN_INT (size))); + + emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, + const0_rtx)); } else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF + && TARGET_32BIT && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) { - const char * l_name = XSTR (stack_limit_rtx, 0); - const char * stripped_name; - - STRIP_NAME_ENCODING (stripped_name, l_name); - asm_fprintf (file, "\t{liu|lis} %s,%s@ha+%d\n", - reg_names[0], stripped_name, size); - asm_fprintf (file, "\t{ai|addic} %s,%s,%s@l+%d\n", - reg_names[0], reg_names[0], stripped_name, size); - if (TARGET_32BIT) - asm_fprintf (file, "\t{t|tw}llt %s,%s\n", - reg_names[1], reg_names[0]); - else - asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]); + rtx toload = gen_rtx_CONST (VOIDmode, + gen_rtx_PLUS (Pmode, + stack_limit_rtx, + GEN_INT (size))); + + emit_insn (gen_elf_high (tmp_reg, toload)); + emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload)); + emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, + const0_rtx)); } else warning ("stack limit expression is not supported"); } + if (copy_r12 || ! TARGET_UPDATE) + emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg); + if (TARGET_UPDATE) { - if (size < 32767) - asm_fprintf (file, - (TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); - else + if (size > 32767) { - if (copy_r12) - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - - asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, - (TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n", - reg_names[1], reg_names[1], reg_names[0]); + /* Need a note here so that try_split doesn't get confused. */ + if (get_last_insn() == NULL_RTX) + emit_note (0, NOTE_INSN_DELETED); + insn = emit_move_insn (tmp_reg, todec); + try_split (PATTERN (insn), insn, 0); + todec = tmp_reg; } + + if (Pmode == SImode) + insn = emit_insn (gen_movsi_update (stack_reg, stack_reg, + todec, stack_reg)); + else + insn = emit_insn (gen_movdi_update (stack_reg, stack_reg, + todec, stack_reg)); } else { - fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - if (size < 32767) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], neg_size, reg_names[1]); + if (Pmode == SImode) + insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec)); else + insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec)); + emit_move_insn (gen_rtx_MEM (Pmode, stack_reg), + gen_rtx_REG (Pmode, 12)); + } + + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = + gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_reg, + gen_rtx_PLUS (Pmode, stack_reg, + GEN_INT (-size))), + REG_NOTES (insn)); +} + +/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced with + (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2 is not + NULL. + It would be nice if dwarf2out_frame_debug_expr could deduce these + equivalences by itself so it wasn't necessary to hold its hand so much. */ + +static void +rs6000_frame_related (insn, reg, val, reg2, rreg) + rtx insn; + rtx reg; + HOST_WIDE_INT val; + rtx reg2; + rtx rreg; +{ + rtx real, temp; + + real = copy_rtx (PATTERN (insn)); + + real = replace_rtx (real, reg, + gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, + STACK_POINTER_REGNUM), + GEN_INT (val))); + + /* We expect that 'real' is either a SET or a PARALLEL containing + SETs (and possibly other stuff). In a PARALLEL, all the SETs + are important so they all have to be marked RTX_FRAME_RELATED_P. */ + + if (GET_CODE (real) == SET) + { + rtx set = real; + + temp = simplify_rtx (SET_SRC (set)); + if (temp) + SET_SRC (set) = temp; + temp = simplify_rtx (SET_DEST (set)); + if (temp) + SET_DEST (set) = temp; + if (GET_CODE (SET_DEST (set)) == MEM) { - asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); - asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", reg_names[1], - reg_names[0], reg_names[1]); + temp = simplify_rtx (XEXP (SET_DEST (set), 0)); + if (temp) + XEXP (SET_DEST (set), 0) = temp; } - - asm_fprintf (file, - (TARGET_32BIT) ? "\t{st|stw} %s,0(%s)\n" : "\tstd %s,0(%s)\n", - reg_names[12], reg_names[1]); } + else if (GET_CODE (real) == PARALLEL) + { + int i; + for (i = 0; i < XVECLEN (real, 0); i++) + if (GET_CODE (XVECEXP (real, 0, i)) == SET) + { + rtx set = XVECEXP (real, 0, i); + + temp = simplify_rtx (SET_SRC (set)); + if (temp) + SET_SRC (set) = temp; + temp = simplify_rtx (SET_DEST (set)); + if (temp) + SET_DEST (set) = temp; + if (GET_CODE (SET_DEST (set)) == MEM) + { + temp = simplify_rtx (XEXP (SET_DEST (set), 0)); + if (temp) + XEXP (SET_DEST (set), 0) = temp; + } + RTX_FRAME_RELATED_P (set) = 1; + } + } + else + abort(); + + if (reg2 != NULL_RTX) + real = replace_rtx (real, reg2, rreg); + + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + real, + REG_NOTES (insn)); } - -/* Write function prologue. */ +/* Emit function prologue as insns. */ + void -output_prolog (file, size) - FILE *file; - int size ATTRIBUTE_UNUSED; +rs6000_emit_prologue() { rs6000_stack_t *info = rs6000_stack_info (); - int reg_size = info->reg_size; - const char *store_reg; - const char *load_reg; - int sp_reg = 1; - int sp_offset = 0; + enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode; + int reg_size = TARGET_POWERPC64 ? 8 : 4; + rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12); + rtx frame_reg_rtx = sp_reg_rtx; + rtx cr_save_rtx = NULL; + rtx insn; + int saving_FPRs_inline; + int using_store_multiple; + HOST_WIDE_INT sp_offset = 0; + + using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 + && info->first_gp_reg_save < 31); + saving_FPRs_inline = (info->first_fp_reg_save == 64 + || FP_SAVE_INLINE (info->first_fp_reg_save)); + + /* For V.4, update stack before we do any saving and set back pointer. */ + if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) + { + if (info->total_size < 32767) + sp_offset = info->total_size; + else + frame_reg_rtx = frame_ptr_rtx; + rs6000_emit_allocate_stack (info->total_size, + (frame_reg_rtx != sp_reg_rtx + && (info->cr_save_p + || info->lr_save_p + || info->first_fp_reg_save < 64 + || info->first_gp_reg_save < 32 + ))); + if (frame_reg_rtx != sp_reg_rtx) + rs6000_emit_stack_tie (); + } + + /* If we use the link register, get it into r0. */ + if (info->lr_save_p) + emit_move_insn (gen_rtx_REG (Pmode, 0), + gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); + + /* If we need to save CR, put it into r12. */ + if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx) + { + cr_save_rtx = gen_rtx_REG (SImode, 12); + emit_insn (gen_movesi_from_cr (cr_save_rtx)); + } + + /* Do any required saving of fpr's. If only one or two to save, do it + ourself. Otherwise, call function. */ + if (saving_FPRs_inline) + { + int i; + for (i = 0; i < 64 - info->first_fp_reg_save; i++) + if ((regs_ever_live[info->first_fp_reg_save+i] + && ! call_used_regs[info->first_fp_reg_save+i])) + { + rtx addr, reg, mem; + reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->fp_save_offset + + sp_offset + + 8*i)); + mem = gen_rtx_MEM (DFmode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + insn = emit_move_insn (mem, reg); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); + } + } + else if (info->first_fp_reg_save != 64) + { + int i; + char rname[30]; + char *alloc_rname; + rtvec p; + p = rtvec_alloc (2 + 64 - info->first_fp_reg_save); + + RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode, + gen_rtx_REG (Pmode, + LINK_REGISTER_REGNUM)); + sprintf (rname, "%s%d%s", SAVE_FP_PREFIX, + info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); + alloc_rname = ggc_alloc_string (rname, -1); + RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, + gen_rtx_SYMBOL_REF (Pmode, + alloc_rname)); + for (i = 0; i < 64 - info->first_fp_reg_save; i++) + { + rtx addr, reg, mem; + reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->fp_save_offset + + sp_offset + 8*i)); + mem = gen_rtx_MEM (DFmode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg); + } + insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); + } - if (TARGET_32BIT) + /* Save GPRs. This is done as a PARALLEL if we are using + the store-multiple instructions. */ + if (using_store_multiple) { - store_reg = "\t{st|stw} %s,%d(%s)\n"; - load_reg = "\t{l|lwz} %s,%d(%s)\n"; + rtvec p, dwarfp; + int i; + p = rtvec_alloc (32 - info->first_gp_reg_save); + dwarfp = rtvec_alloc (32 - info->first_gp_reg_save); + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + { + rtx addr, reg, mem; + reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->gp_save_offset + + sp_offset + + reg_size * i)); + mem = gen_rtx_MEM (reg_mode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg); + } + insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); } else { - store_reg = "\tstd %s,%d(%s)\n"; - load_reg = "\tlld %s,%d(%s)\n"; + int i; + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + if ((regs_ever_live[info->first_gp_reg_save+i] + && ! call_used_regs[info->first_gp_reg_save+i]) + || (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM + && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && flag_pic == 1)) + { + rtx addr, reg, mem; + reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->gp_save_offset + + sp_offset + + reg_size * i)); + mem = gen_rtx_MEM (reg_mode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + insn = emit_move_insn (mem, reg); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); + } + } + + /* Save lr if we used it. */ + if (info->lr_save_p) + { + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->lr_save_offset + sp_offset)); + rtx reg = gen_rtx_REG (Pmode, 0); + rtx mem = gen_rtx_MEM (Pmode, addr); + /* This should not be of rs6000_sr_alias_set, because of + __builtin_return_address. */ + + insn = emit_move_insn (mem, reg); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); + } + + /* Save CR if we use any that must be preserved. */ + if (info->cr_save_p) + { + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->cr_save_offset + sp_offset)); + rtx mem = gen_rtx_MEM (SImode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + /* If r12 was used to hold the original sp, copy cr into r0 now + that it's free. */ + if (REGNO (frame_reg_rtx) == 12) + { + cr_save_rtx = gen_rtx_REG (SImode, 0); + emit_insn (gen_movesi_from_cr (cr_save_rtx)); + } + insn = emit_move_insn (mem, cr_save_rtx); + + /* Now, there's no way that dwarf2out_frame_debug_expr is going + to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's + OK. All we have to do is specify that _one_ condition code + register is saved in this stack slot. The thrower's epilogue + will then restore all the call-saved registers. */ + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + cr_save_rtx, gen_rtx_REG (SImode, CR0_REGNO)); + } + + /* Update stack and set back pointer unless this is V.4, + for which it was done previously. */ + if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) + rs6000_emit_allocate_stack (info->total_size, FALSE); + + /* Set frame pointer, if needed. */ + if (frame_pointer_needed) + { + insn = emit_move_insn (gen_rtx_REG (reg_mode, FRAME_POINTER_REGNUM), + sp_reg_rtx); + RTX_FRAME_RELATED_P (insn) = 1; } + /* If we are using PIC_OFFSET_TABLE_REGNUM, we need to set it up. */ + if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) + || ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])) + { + /* If emit_load_toc_table will use the link register, we need to save + it. We use R11 for this purpose because emit_load_toc_table + can use register 0. This allows us to use a plain 'blr' to return + from the procedure more often. */ + int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0 && + ! info->lr_save_p); + if (save_LR_around_toc_setup) + emit_move_insn (gen_rtx_REG (Pmode, 11), + gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); + + rs6000_emit_load_toc_table (TRUE); + + if (save_LR_around_toc_setup) + emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), + gen_rtx_REG (Pmode, 11)); + } +} + + +/* Write function prologue. */ +void +output_prolog (file, size) + FILE *file; + int size ATTRIBUTE_UNUSED; +{ + rs6000_stack_t *info = rs6000_stack_info (); + if (TARGET_DEBUG_STACK) debug_stack_info (info); @@ -4322,222 +5103,295 @@ output_prolog (file, size) common_mode_defined = 1; } - /* For V.4, update stack before we do any saving and set back pointer. */ - if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) + if (! HAVE_prologue) { - if (info->total_size < 32767) - sp_offset = info->total_size; - else - sp_reg = 12; - rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12); + start_sequence (); + + /* A NOTE_INSN_DELETED is supposed to be at the start + and end of the "toplevel" insn chain. */ + emit_note (0, NOTE_INSN_DELETED); + rs6000_emit_prologue (); + emit_note (0, NOTE_INSN_DELETED); + + if (TARGET_DEBUG_STACK) + debug_rtx_list (get_insns(), 100); + final (get_insns(), file, FALSE, FALSE); + end_sequence (); } - /* If we use the link register, get it into r0. */ - if (info->lr_save_p) - asm_fprintf (file, "\tmflr %s\n", reg_names[0]); + rs6000_pic_labelno++; +} + +/* Emit function epilogue as insns. - /* If we need to save CR, put it into r12. */ - if (info->cr_save_p && sp_reg != 12) - asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); + At present, dwarf2out_frame_debug_expr doesn't understand + register restores, so we don't bother setting RTX_FRAME_RELATED_P + anywhere in the epilogue. Most of the insns below would in any case + need special notes to explain where r11 is in relation to the stack. */ - /* Do any required saving of fpr's. If only one or two to save, do it - ourself. Otherwise, call function. Note that since they are statically - linked, we do not need a nop following them. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) +void +rs6000_emit_epilogue(sibcall) + int sibcall; +{ + rs6000_stack_t *info; + int restoring_FPRs_inline; + int using_load_multiple; + int using_mfcr_multiple; + int use_backchain_to_restore_sp; + int sp_offset = 0; + rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); + rtx frame_reg_rtx = sp_reg_rtx; + enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode; + int reg_size = TARGET_POWERPC64 ? 8 : 4; + int i; + + info = rs6000_stack_info (); + using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 + && info->first_gp_reg_save < 31); + restoring_FPRs_inline = (sibcall + || info->first_fp_reg_save == 64 + || FP_SAVE_INLINE (info->first_fp_reg_save)); + use_backchain_to_restore_sp = (frame_pointer_needed + || current_function_calls_alloca + || info->total_size > 32767); + using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601 + || rs6000_cpu == PROCESSOR_PPC603 + || rs6000_cpu == PROCESSOR_PPC750 + || optimize_size); + + /* If we have a frame pointer, a call to alloca, or a large stack + frame, restore the old stack pointer using the backchain. Otherwise, + we know what size to update it with. */ + if (use_backchain_to_restore_sp) { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; + /* Under V.4, don't reset the stack pointer until after we're done + loading the saved registers. */ + if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + frame_reg_rtx = gen_rtx_REG (Pmode, 11); - for ( ; regno < 64; regno++, loc += 8) - asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); + emit_move_insn (frame_reg_rtx, + gen_rtx_MEM (Pmode, sp_reg_rtx)); + } - else if (info->first_fp_reg_save != 64) - asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, - info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); - - /* Now save gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) + else if (info->push_p) { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - - for ( ; regno < 32; regno++, loc += reg_size) - asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]); + if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + sp_offset = info->total_size; + else + { + emit_insn (TARGET_32BIT + ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, + GEN_INT (info->total_size)) + : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, + GEN_INT (info->total_size))); + } } - - else if (info->first_gp_reg_save != 32) - asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Save main's arguments if we need to call a function */ -#ifdef NAME__MAIN - if (info->main_save_p) + + /* Get the old lr if we saved it. */ + if (info->lr_save_p) { - int regno; - int loc = info->main_save_offset + sp_offset; - int size = info->main_size; + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->lr_save_offset + sp_offset)); + rtx mem = gen_rtx_MEM (Pmode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; - for (regno = 3; size > 0; regno++, loc += reg_size, size -= reg_size) - asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]); + emit_move_insn (gen_rtx_REG (Pmode, 0), mem); } -#endif + + /* Get the old cr if we saved it. */ + if (info->cr_save_p) + { + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->cr_save_offset + sp_offset)); + rtx mem = gen_rtx_MEM (SImode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; - /* Save lr if we used it. */ + emit_move_insn (gen_rtx_REG (SImode, 12), mem); + } + + /* Set LR here to try to overlap restores below. */ if (info->lr_save_p) - asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Save CR if we use any that must be preserved. */ - if (info->cr_save_p) + emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), + gen_rtx_REG (Pmode, 0)); + + + /* Restore GPRs. This is done as a PARALLEL if we are using + the load-multiple instructions. */ + if (using_load_multiple) { - if (sp_reg == 12) /* If r12 is used to hold the original sp, copy cr now */ + rtvec p; + p = rtvec_alloc (32 - info->first_gp_reg_save); + for (i = 0; i < 32 - info->first_gp_reg_save; i++) { - asm_fprintf (file, "\tmfcr %s\n", reg_names[0]); - asm_fprintf (file, store_reg, reg_names[0], - info->cr_save_offset + sp_offset, - reg_names[sp_reg]); + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->gp_save_offset + + sp_offset + + reg_size * i)); + rtx mem = gen_rtx_MEM (reg_mode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + RTVEC_ELT (p, i) = + gen_rtx_SET (VOIDmode, + gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + mem); } - else - asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset, - reg_names[sp_reg]); + emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); } + else + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + if ((regs_ever_live[info->first_gp_reg_save+i] + && ! call_used_regs[info->first_gp_reg_save+i]) + || (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM + && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) + && flag_pic == 1)) + { + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->gp_save_offset + + sp_offset + + reg_size * i)); + rtx mem = gen_rtx_MEM (reg_mode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + emit_move_insn (gen_rtx_REG (reg_mode, + info->first_gp_reg_save + i), + mem); + } - /* If we need PIC_OFFSET_TABLE_REGNUM, initialize it now */ - if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) - { - if (! info->lr_save_p) - asm_fprintf (file, "\tmflr %s\n", reg_names[0]); - - fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\tmflr %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]); - - if (! info->lr_save_p) - asm_fprintf (file, "\tmtlr %s\n", reg_names[0]); - } + /* Restore fpr's if we need to do it without calling a function. */ + if (restoring_FPRs_inline) + for (i = 0; i < 64 - info->first_fp_reg_save; i++) + if ((regs_ever_live[info->first_fp_reg_save+i] + && ! call_used_regs[info->first_fp_reg_save+i])) + { + rtx addr, mem; + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->fp_save_offset + + sp_offset + + 8*i)); + mem = gen_rtx_MEM (DFmode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + emit_move_insn (gen_rtx_REG (DFmode, + info->first_fp_reg_save + i), + mem); + } - /* NT needs us to probe the stack frame every 4k pages for large frames, so - do it here. */ - if (DEFAULT_ABI == ABI_NT && info->total_size > 4096) + /* If we saved cr, restore it here. Just those that were used. */ + if (info->cr_save_p) { - if (info->total_size < 32768) + rtx r12_rtx = gen_rtx_REG (SImode, 12); + + if (using_mfcr_multiple) { - int probe_offset = 4096; - while (probe_offset < info->total_size) - { - asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", reg_names[0], -probe_offset, reg_names[1]); - probe_offset += 4096; - } + rtvec p; + int mask = 0; + int count = 0; + + for (i = 0; i < 8; i++) + if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i]) + { + mask |= 1 << (7-i); + count++; + } + if (count == 0) + abort(); + + p = rtvec_alloc (count + 1); + + RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, GEN_INT (mask)); + count = 1; + for (i = 0; i < 8; i++) + if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i]) + { + rtvec r = rtvec_alloc (2); + RTVEC_ELT (r, 0) = r12_rtx; + RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); + RTVEC_ELT (p, count) = + gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), + gen_rtx_UNSPEC (CCmode, r, 20)); + count++; + } + emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); } else - { - int probe_iterations = info->total_size / 4096; - static int probe_labelno = 0; - char buf[256]; - - if (probe_iterations < 32768) - asm_fprintf (file, "\tli %s,%d\n", reg_names[12], probe_iterations); - else + for (i = 0; i < 8; i++) + if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i]) { - asm_fprintf (file, "\tlis %s,%d\n", reg_names[12], probe_iterations >> 16); - if (probe_iterations & 0xffff) - asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], reg_names[12], - probe_iterations & 0xffff); + emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, + CR0_REGNO+i), + r12_rtx)); } - asm_fprintf (file, "\tmtctr %s\n", reg_names[12]); - asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); - ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno); - asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", reg_names[0], reg_names[12]); - ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno++); - fputs ("\tbdnz ", file); - assemble_name (file, buf); - putc ('\n', file); - } } - /* Update stack and set back pointer unless this is V.4, which was done previously */ - if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) - rs6000_allocate_stack_space (file, info->total_size, FALSE); - - /* Set frame pointer, if needed. */ - if (frame_pointer_needed) - asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]); - -#ifdef NAME__MAIN - /* If we need to call a function to set things up for main, do so now - before dealing with the TOC. */ - if (info->main_p) + /* If this is V.4, unwind the stack pointer after all of the loads + have been done. We need to emit a block here so that sched + doesn't decide to move the sp change before the register restores + (which may not have any obvious dependency on the stack). This + doesn't hurt performance, because there is no scheduling that can + be done after this point. */ + if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) { - const char *prefix = ""; + if (frame_reg_rtx != sp_reg_rtx) + rs6000_emit_stack_tie (); - switch (DEFAULT_ABI) + if (use_backchain_to_restore_sp) { - case ABI_AIX: prefix = "."; break; - case ABI_NT: prefix = ".."; break; + emit_move_insn (sp_reg_rtx, frame_reg_rtx); } - - fprintf (file, "\tbl %s%s\n", prefix, NAME__MAIN); -#ifdef RS6000_CALL_GLUE2 - fprintf (file, "\t%s%s%s\n", RS6000_CALL_GLUE2, prefix, NAME_MAIN); -#else -#ifdef RS6000_CALL_GLUE - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + else if (sp_offset != 0) { - putc('\t', file); - asm_fprintf (file, RS6000_CALL_GLUE); - putc('\n', file); + emit_insn (Pmode == SImode + ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, + GEN_INT (sp_offset)) + : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, + GEN_INT (sp_offset))); } -#endif -#endif + } - if (info->main_save_p) - { - int regno; - int loc; - int size = info->main_size; + if (!sibcall) + { + rtvec p; + if (! restoring_FPRs_inline) + p = rtvec_alloc (3 + 64 - info->first_fp_reg_save); + else + p = rtvec_alloc (2); - if (info->total_size < 32767) - { - loc = info->total_size + info->main_save_offset; - for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]); - } - else - { - int neg_size = info->main_save_offset - info->total_size; - loc = 0; - asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n", - reg_names[0], (neg_size >> 16) & 0xffff, - reg_names[0], reg_names[0], neg_size & 0xffff); + RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, + gen_rtx_REG (Pmode, + LINK_REGISTER_REGNUM)); + RTVEC_ELT (p, 1) = gen_rtx_RETURN (VOIDmode); + + /* If we have to restore more than two FP registers, branch to the + restore function. It will return to our caller. */ + if (! restoring_FPRs_inline) + { + int i; + char rname[30]; + char *alloc_rname; - asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", reg_names[0], reg_names[0], - reg_names[1]); + sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX, + info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); + alloc_rname = ggc_alloc_string (rname, -1); + RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, + gen_rtx_SYMBOL_REF (Pmode, + alloc_rname)); - for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[0]); + for (i = 0; i < 64 - info->first_fp_reg_save; i++) + { + rtx addr, mem; + addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, + GEN_INT (info->fp_save_offset + 8*i)); + mem = gen_rtx_MEM (DFmode, addr); + MEM_ALIAS_SET (mem) = rs6000_sr_alias_set; + + RTVEC_ELT (p, i+3) = + gen_rtx_SET (VOIDmode, + gen_rtx_REG (DFmode, info->first_fp_reg_save + i), + mem); } } - } -#endif - - - /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the - TOC_TABLE address into register 30. */ - if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) - { -#ifdef USING_SVR4_H - if (! profile_flag) - rs6000_pic_func_labelno = rs6000_pic_labelno; -#endif - rs6000_output_load_toc_table (file, 30); - } - - if (DEFAULT_ABI == ABI_NT) - { - assemble_name (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".b:\n", file); + + emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); } } @@ -4549,101 +5403,31 @@ output_epilog (file, size) int size ATTRIBUTE_UNUSED; { rs6000_stack_t *info = rs6000_stack_info (); - const char *load_reg = (TARGET_32BIT) ? "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n"; - rtx insn = get_last_insn (); - int sp_reg = 1; - int sp_offset = 0; - /* If the last insn was a BARRIER, we don't have to write anything except - the trace table. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn == 0 || GET_CODE (insn) != BARRIER) + if (! HAVE_epilogue) { - /* If we have a frame pointer, a call to alloca, or a large stack - frame, restore the old stack pointer using the backchain. Otherwise, - we know what size to update it with. */ - if (frame_pointer_needed || current_function_calls_alloca - || info->total_size > 32767) - { - /* Under V.4, don't reset the stack pointer until after we're done - loading the saved registers. */ - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - sp_reg = 11; - - asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]); - } - else if (info->push_p) - { - if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - sp_offset = info->total_size; - else - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], info->total_size, reg_names[1]); - } - - /* Get the old lr if we saved it. */ - if (info->lr_save_p) - asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]); - - /* Get the old cr if we saved it. */ - if (info->cr_save_p) - asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]); - - /* Set LR here to try to overlap restores below. */ - if (info->lr_save_p) - asm_fprintf (file, "\tmtlr %s\n", reg_names[0]); - - /* Restore gpr's. */ - if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) - { - int regno = info->first_gp_reg_save; - int loc = info->gp_save_offset + sp_offset; - int reg_size = (TARGET_32BIT) ? 4 : 8; - - for ( ; regno < 32; regno++, loc += reg_size) - asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]); - } - - else if (info->first_gp_reg_save != 32) - asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", - reg_names[info->first_gp_reg_save], - info->gp_save_offset + sp_offset, - reg_names[sp_reg]); - - /* Restore fpr's if we can do it without calling a function. */ - if (FP_SAVE_INLINE (info->first_fp_reg_save)) + rtx insn = get_last_insn (); + /* If the last insn was a BARRIER, we don't have to write anything except + the trace table. */ + if (GET_CODE (insn) == NOTE) + insn = prev_nonnote_insn (insn); + if (insn == 0 || GET_CODE (insn) != BARRIER) { - int regno = info->first_fp_reg_save; - int loc = info->fp_save_offset + sp_offset; - - for ( ; regno < 64; regno++, loc += 8) - asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); + /* This is slightly ugly, but at least we don't have two + copies of the epilogue-emitting code. */ + start_sequence (); + + /* A NOTE_INSN_DELETED is supposed to be at the start + and end of the "toplevel" insn chain. */ + emit_note (0, NOTE_INSN_DELETED); + rs6000_emit_epilogue (FALSE); + emit_note (0, NOTE_INSN_DELETED); + + if (TARGET_DEBUG_STACK) + debug_rtx_list (get_insns(), 100); + final (get_insns(), file, FALSE, FALSE); + end_sequence (); } - - /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 - that were used. */ - if (info->cr_save_p) - asm_fprintf (file, "\tmtcrf %d,%s\n", - (regs_ever_live[70] != 0) * 0x20 - + (regs_ever_live[71] != 0) * 0x10 - + (regs_ever_live[72] != 0) * 0x8, reg_names[12]); - - /* If this is V.4, unwind the stack pointer after all of the loads - have been done */ - if (sp_offset != 0) - asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n", - reg_names[1], sp_offset, reg_names[1]); - else if (sp_reg != 1) - asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]); - - /* If we have to restore more than two FP registers, branch to the - restore function. It will return to our caller. */ - if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save)) - asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX, - info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - else - asm_fprintf (file, "\t{br|blr}\n"); } /* Output a traceback table here. See /usr/include/sys/debug.h for info @@ -4820,9 +5604,17 @@ output_epilog (file, size) /* Offset from start of code to tb table. */ fputs ("\t.long ", file); ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); +#if TARGET_AIX RS6000_OUTPUT_BASENAME (file, fname); +#else + assemble_name (file, fname); +#endif fputs ("-.", file); +#if TARGET_AIX RS6000_OUTPUT_BASENAME (file, fname); +#else + assemble_name (file, fname); +#endif putc ('\n', file); /* Interrupt handler mask. */ @@ -4846,14 +5638,6 @@ output_epilog (file, size) if (frame_pointer_needed) fputs ("\t.byte 31\n", file); } - - if (DEFAULT_ABI == ABI_NT) - { - RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (".e:\nFE_MOT_RESVD..", file); - RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fputs (":\n", file); - } } /* A C compound statement that outputs the assembler code for a thunk function, @@ -4897,7 +5681,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function) const char *prefix; const char *fname; const char *r0 = reg_names[0]; - const char *sp = reg_names[1]; const char *toc = reg_names[2]; const char *schain = reg_names[11]; const char *r12 = reg_names[12]; @@ -4959,10 +5742,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function) case ABI_SOLARIS: prefix = ""; break; - - case ABI_NT: - prefix = ".."; - break; } /* If the function is compiled in this module, jump to it directly. @@ -4970,7 +5749,7 @@ output_mi_thunk (file, thunk_fndecl, delta, function) fname = XSTR (XEXP (DECL_RTL (function), 0), 0); - if (current_file_function_operand (XEXP (DECL_RTL (function), 0)) + if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode) && ! lookup_attribute ("longcall", TYPE_ATTRIBUTES (TREE_TYPE (function)))) { @@ -4985,7 +5764,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function) switch (DEFAULT_ABI) { default: - case ABI_NT: abort (); case ABI_AIX: @@ -5022,71 +5800,192 @@ output_mi_thunk (file, thunk_fndecl, delta, function) asm_fprintf (file, "\tbctr\n"); break; + case ABI_AIX_NODESC: + case ABI_SOLARIS: case ABI_V4: fprintf (file, "\tb %s", prefix); assemble_name (file, fname); if (flag_pic) fputs ("@plt", file); putc ('\n', file); break; - - /* Don't use r11, that contains the static chain, just use r0/r12. */ - case ABI_AIX_NODESC: - case ABI_SOLARIS: - if (flag_pic == 1) - { - fprintf (file, "\tmflr %s\n", r0); - fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\tmflr %s\n", r12); - asm_fprintf (file, "\tmtlr %s\n", r0); - asm_fprintf (file, "\t{l|lwz} %s,", r0); - assemble_name (file, fname); - asm_fprintf (file, "@got(%s)\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r0); - asm_fprintf (file, "\tbctr\n"); - } -#if TARGET_ELF - else if (flag_pic > 1 || TARGET_RELOCATABLE) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno); - labelno++; - fprintf (file, "\tmflr %s\n", r0); - asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", r0, sp); - rs6000_pic_func_labelno = rs6000_pic_labelno; - rs6000_output_load_toc_table (file, 12); - asm_fprintf (file, "\t{l|lwz} %s,", r0); - assemble_name (file, buf); - asm_fprintf (file, "(%s)\n", r12); - asm_fprintf (file, "\t{l|lwz} %s,4(%s)\n", r12, sp); - asm_fprintf (file, "\tmtlr %s\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r0); - asm_fprintf (file, "\tbctr\n"); - asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - assemble_name (file, buf); - fputs (" = .-.LCTOC1\n", file); - fputs ("\t.long ", file); - assemble_name (file, fname); - fputs ("\n\t.previous\n", file); - } -#endif /* TARGET_ELF */ + } + } +} - else - { - asm_fprintf (file, "\t{liu|lis} %s,", r12); - assemble_name (file, fname); - asm_fprintf (file, "@ha\n"); - asm_fprintf (file, "\t{cal|la} %s,", r12); - assemble_name (file, fname); - asm_fprintf (file, "@l(%s)\n", r12); - asm_fprintf (file, "\tmtctr %s\n", r12); - asm_fprintf (file, "\tbctr\n"); - } + +/* A quick summary of the various types of 'constant-pool tables' + under PowerPC: + + Target Flags Name One table per + AIX (none) AIX TOC object file + AIX -mfull-toc AIX TOC object file + AIX -mminimal-toc AIX minimal TOC translation unit + SVR4/EABI (none) SVR4 SDATA object file + SVR4/EABI -fpic SVR4 pic object file + SVR4/EABI -fPIC SVR4 PIC translation unit + SVR4/EABI -mrelocatable EABI TOC function + SVR4/EABI -maix AIX TOC object file + SVR4/EABI -maix -mminimal-toc + AIX minimal TOC translation unit + + Name Reg. Set by entries contains: + made by addrs? fp? sum? + + AIX TOC 2 crt0 as Y option option + AIX minimal TOC 30 prolog gcc Y Y option + SVR4 SDATA 13 crt0 gcc N Y N + SVR4 pic 30 prolog ld Y not yet N + SVR4 PIC 30 prolog gcc Y option option + EABI TOC 30 prolog gcc Y option option + +*/ + +/* Hash table stuff for keeping track of TOC entries. */ + +struct toc_hash_struct +{ + /* `key' will satisfy CONSTANT_P; in fact, it will satisfy + ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */ + rtx key; + int labelno; +}; +static htab_t toc_hash_table; + +/* Hash functions for the hash table. */ + +static unsigned +rs6000_hash_constant (k) + rtx k; +{ + unsigned result = GET_CODE (k); + const char *format = GET_RTX_FORMAT (GET_CODE (k)); + int flen = strlen (format); + int fidx; + + if (GET_CODE (k) == LABEL_REF) + return result * 1231 + XINT (XEXP (k, 0), 3); + + if (GET_CODE (k) == CONST_DOUBLE) + fidx = 2; + else if (GET_CODE (k) == CODE_LABEL) + fidx = 3; + else + fidx = 0; + + for (; fidx < flen; fidx++) + switch (format[fidx]) + { + case 's': + { + unsigned i, len; + const char *str = XSTR (k, fidx); + len = strlen (str); + result = result * 613 + len; + for (i = 0; i < len; i++) + result = result * 613 + (unsigned) str[i]; break; } + case 'u': + case 'e': + result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx)); + break; + case 'i': + case 'n': + result = result * 613 + (unsigned) XINT (k, fidx); + break; + case 'w': + if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT)) + result = result * 613 + (unsigned) XWINT (k, fidx); + else + { + size_t i; + for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++) + result = result * 613 + (unsigned) (XWINT (k, fidx) + >> CHAR_BIT * i); + } + break; + default: + abort(); + } + return result; +} + +static unsigned +toc_hash_function (hash_entry) + const void * hash_entry; +{ + return rs6000_hash_constant (((const struct toc_hash_struct *) + hash_entry)->key); +} + +/* Compare H1 and H2 for equivalence. */ + +static int +toc_hash_eq (h1, h2) + const void * h1; + const void * h2; +{ + rtx r1 = ((const struct toc_hash_struct *) h1)->key; + rtx r2 = ((const struct toc_hash_struct *) h2)->key; + + /* Gotcha: One of these const_doubles will be in memory. + The other may be on the constant-pool chain. + So rtx_equal_p will think they are different... */ + if (r1 == r2) + return 1; + if (GET_CODE (r1) != GET_CODE (r2) + || GET_MODE (r1) != GET_MODE (r2)) + return 0; + if (GET_CODE (r1) == CONST_DOUBLE) + { + int format_len = strlen (GET_RTX_FORMAT (CONST_DOUBLE)); + int i; + for (i = 2; i < format_len; i++) + if (XWINT (r1, i) != XWINT (r2, i)) + return 0; + + return 1; } + else if (GET_CODE (r1) == LABEL_REF) + return XINT (XEXP (r1, 0), 3) == XINT (XEXP (r2, 0), 3); + else + return rtx_equal_p (r1, r2); +} + +/* Mark the hash table-entry HASH_ENTRY. */ + +static int +toc_hash_mark_entry (hash_slot, unused) + void * hash_slot; + void * unused ATTRIBUTE_UNUSED; +{ + const struct toc_hash_struct * hash_entry = + *(const struct toc_hash_struct **) hash_slot; + rtx r = hash_entry->key; + ggc_set_mark (hash_entry); + /* For CODE_LABELS, we don't want to drag in the whole insn chain... */ + if (GET_CODE (r) == LABEL_REF) + { + ggc_set_mark (r); + ggc_set_mark (XEXP (r, 0)); + } + else + ggc_mark_rtx (r); + return 1; +} + +/* Mark all the elements of the TOC hash-table *HT. */ + +static void +toc_hash_mark_table (vht) + void *vht; +{ + htab_t *ht = vht; + + htab_traverse (*ht, toc_hash_mark_entry, (void *)0); } - /* Output a TOC entry. We derive the entry name from what is being written. */ @@ -5105,8 +6004,38 @@ output_toc (file, x, labelno) if (TARGET_NO_TOC) abort (); - /* if we're going to put a double constant in the TOC, make sure it's - aligned properly when strict alignment is on. */ + /* When the linker won't eliminate them, don't output duplicate + TOC entries (this happens on AIX if there is any kind of TOC, + and on SVR4 under -fPIC or -mrelocatable). + This won't work if we are not garbage collecting, so + we don't do it, sorry. */ + if (TARGET_TOC && ggc_p) + { + struct toc_hash_struct *h; + void * * found; + + h = ggc_alloc (sizeof (*h)); + h->key = x; + h->labelno = labelno; + + found = htab_find_slot (toc_hash_table, h, 1); + if (*found == NULL) + *found = h; + else /* This is indeed a duplicate. + Set this label equal to that label. */ + { + fputs ("\t.set ", file); + ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); + fprintf (file, "%d,", labelno); + ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); + fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) + found)->labelno)); + return; + } + } + + /* If we're going to put a double constant in the TOC, make sure it's + aligned properly when strict alignment is on. */ if (GET_CODE (x) == CONST_DOUBLE && STRICT_ALIGNMENT && GET_MODE (x) == DFmode @@ -5114,16 +6043,7 @@ output_toc (file, x, labelno) ASM_OUTPUT_ALIGN (file, 3); } - - if (TARGET_ELF && TARGET_MINIMAL_TOC) - { - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); - fprintf (file, "%d = .-", labelno); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC"); - fputs ("1\n", file); - } - else - ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); + ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); /* Handle FP constants specially. Note that if we have a minimal TOC, things we put here aren't actually in the TOC, so we can allow @@ -5143,7 +6063,7 @@ output_toc (file, x, labelno) fprintf (file, "\t.llong 0x%lx%08lx\n", k[0], k[1]); else fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx%08lx\n", - k[0], k[1], k[0] & 0xffffffff, k[1] & 0xffffffff); + k[0], k[1], k[0] & 0xffffffffu, k[1] & 0xffffffffu); return; } else @@ -5266,7 +6186,7 @@ output_toc (file, x, labelno) section. */ if (! strncmp ("_vt.", name, 4)) { - RS6000_OUTPUT_BASENAME (file, name); + assemble_name (file, name); if (offset < 0) fprintf (file, "%d", offset); else if (offset > 0) @@ -5344,7 +6264,7 @@ output_ascii (file, p, n) /* Now close the string if we have written one. Then end the line. */ if (to_close) - fprintf (file, to_close); + fputs (to_close, file); } /* Generate a unique section name for FILENAME for a section type @@ -5362,10 +6282,10 @@ output_ascii (file, p, n) void rs6000_gen_section_name (buf, filename, section_desc) char **buf; - char *filename; - char *section_desc; + const char *filename; + const char *section_desc; { - char *q, *after_last_slash, *last_period = 0; + const char *q, *after_last_slash, *last_period = 0; char *p; int len; @@ -5434,24 +6354,20 @@ output_function_profiler (file, labelno) assemble_name (file, buf); asm_fprintf (file, "@got(%s)\n", reg_names[12]); } -#if TARGET_ELF - else if (flag_pic > 1 || TARGET_RELOCATABLE) + else if (flag_pic > 1) { asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]); - rs6000_pic_func_labelno = rs6000_pic_labelno; - rs6000_output_load_toc_table (file, 12); - asm_fprintf (file, "\t{l|lwz} %s,", reg_names[12]); - assemble_name (file, buf); - asm_fprintf (file, "X(%s)\n", reg_names[12]); - asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); + /* Now, we need to get the address of the label. */ + fputs ("\tbl 1f\n\t.long ", file); assemble_name (file, buf); - fputs ("X = .-.LCTOC1\n", file); - fputs ("\t.long ", file); - assemble_name (file, buf); - fputs ("\n\t.previous\n", file); + fputs ("-.\n1:", file); + asm_fprintf (file, "\tmflr %s\n", reg_names[11]); + asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", + reg_names[0], reg_names[11]); + asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", + reg_names[0], reg_names[0], reg_names[11]); } -#endif else { asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); @@ -5631,68 +6547,6 @@ int get_issue_rate() } -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - The trampoline should set the static chain pointer to value placed - into the trampoline and should branch to the specified routine. */ - -void -rs6000_trampoline_template (file) - FILE *file; -{ - const char *sc = reg_names[STATIC_CHAIN_REGNUM]; - const char *r0 = reg_names[0]; - const char *r2 = reg_names[2]; - - switch (DEFAULT_ABI) - { - default: - abort (); - - /* Under AIX, this is not code at all, but merely a data area, - since that is the way all functions are called. The first word is - the address of the function, the second word is the TOC pointer (r2), - and the third word is the static chain value. */ - case ABI_AIX: - break; - - - /* V.4/eabi function pointers are just a single pointer, so we need to - do the full gory code to load up the static chain. */ - case ABI_V4: - case ABI_SOLARIS: - case ABI_AIX_NODESC: - break; - - /* NT function pointers point to a two word area (real address, TOC) - which unfortunately does not include a static chain field. So we - use the function field to point to ..LTRAMP1 and the toc field - to point to the whole table. */ - case ABI_NT: - if (STATIC_CHAIN_REGNUM == 0 - || STATIC_CHAIN_REGNUM == 2 - || TARGET_64BIT - || !TARGET_NEW_MNEMONICS) - abort (); - - fprintf (file, "\t.ualong 0\n"); /* offset 0 */ - fprintf (file, "\t.ualong 0\n"); /* offset 4 */ - fprintf (file, "\t.ualong 0\n"); /* offset 8 */ - fprintf (file, "\t.ualong 0\n"); /* offset 12 */ - fprintf (file, "\t.ualong 0\n"); /* offset 16 */ - fprintf (file, "..LTRAMP1..0:\n"); /* offset 20 */ - fprintf (file, "\tlwz %s,8(%s)\n", r0, r2); /* offset 24 */ - fprintf (file, "\tlwz %s,12(%s)\n", sc, r2); /* offset 28 */ - fprintf (file, "\tmtctr %s\n", r0); /* offset 32 */ - fprintf (file, "\tlwz %s,16(%s)\n", r2, r2); /* offset 36 */ - fprintf (file, "\tbctr\n"); /* offset 40 */ - break; - } - - return; -} - /* Length in units of the trampoline for entering a nested function. */ int @@ -5714,10 +6568,6 @@ rs6000_trampoline_size () case ABI_AIX_NODESC: ret = (TARGET_32BIT) ? 40 : 48; break; - - case ABI_NT: - ret = 20; - break; } return ret; @@ -5771,27 +6621,6 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt) fnaddr, pmode, ctx_reg, pmode); break; - - /* Under NT, update the first word to point to the ..LTRAMP1..0 header, - the second word will point to the whole trampoline, third-fifth words - will then have the real address, static chain, and toc value. */ - case ABI_NT: - { - rtx tramp_reg = gen_reg_rtx (pmode); - rtx fn_reg = gen_reg_rtx (pmode); - rtx toc_reg = gen_reg_rtx (pmode); - - emit_move_insn (tramp_reg, gen_rtx_SYMBOL_REF (pmode, "..LTRAMP1..0")); - addr = force_reg (pmode, addr); - emit_move_insn (fn_reg, MEM_DEREF (fnaddr)); - emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize)); - emit_move_insn (MEM_DEREF (addr), tramp_reg); - emit_move_insn (MEM_PLUS (addr, regsize), addr); - emit_move_insn (MEM_PLUS (addr, 2*regsize), fn_reg); - emit_move_insn (MEM_PLUS (addr, 3*regsize), ctx_reg); - emit_move_insn (MEM_PLUS (addr, 4*regsize), gen_rtx_REG (pmode, 2)); - } - break; } return; @@ -5833,51 +6662,6 @@ rs6000_valid_type_attribute_p (type, attributes, identifier, args) if (is_attribute_p ("longcall", identifier)) return (args == NULL_TREE); - if (DEFAULT_ABI == ABI_NT) - { - /* Stdcall attribute says callee is responsible for popping arguments - if they are not variable. */ - if (is_attribute_p ("stdcall", identifier)) - return (args == NULL_TREE); - - /* Cdecl attribute says the callee is a normal C declaration */ - if (is_attribute_p ("cdecl", identifier)) - return (args == NULL_TREE); - - /* Dllimport attribute says the caller is to call the function - indirectly through a __imp_ pointer. */ - if (is_attribute_p ("dllimport", identifier)) - return (args == NULL_TREE); - - /* Dllexport attribute says the callee is to create a __imp_ - pointer. */ - if (is_attribute_p ("dllexport", identifier)) - return (args == NULL_TREE); - - /* Exception attribute allows the user to specify 1-2 strings - or identifiers that will fill in the 3rd and 4th fields - of the structured exception table. */ - if (is_attribute_p ("exception", identifier)) - { - int i; - - if (args == NULL_TREE) - return 0; - - for (i = 0; i < 2 && args != NULL_TREE; i++) - { - tree this_arg = TREE_VALUE (args); - args = TREE_PURPOSE (args); - - if (TREE_CODE (this_arg) != STRING_CST - && TREE_CODE (this_arg) != IDENTIFIER_NODE) - return 0; - } - - return (args == NULL_TREE); - } - } - return 0; } @@ -5904,36 +6688,6 @@ rs6000_set_default_type_attributes (type) return; } -/* Return a dll import reference corresponding to a call's SYMBOL_REF */ -struct rtx_def * -rs6000_dll_import_ref (call_ref) - rtx call_ref; -{ - const char *call_name; - int len; - char *p; - rtx reg1, reg2; - tree node; - - if (GET_CODE (call_ref) != SYMBOL_REF) - abort (); - - call_name = XSTR (call_ref, 0); - len = sizeof ("__imp_") + strlen (call_name); - p = alloca (len); - reg2 = gen_reg_rtx (Pmode); - - strcpy (p, "__imp_"); - strcat (p, call_name); - node = get_identifier (p); - - reg1 = force_reg (Pmode, gen_rtx_SYMBOL_REF (VOIDmode, - IDENTIFIER_POINTER (node))); - emit_move_insn (reg2, gen_rtx_MEM (Pmode, reg1)); - - return reg2; -} - /* Return a reference suitable for calling a function with the longcall attribute. */ struct rtx_def * @@ -6039,7 +6793,7 @@ rs6000_select_section (decl, reloc) /* If we are referencing a function that is static or is known to be in this file, make the SYMBOL_REF special. We can use this to indicate that we can branch to this function without emitting a no-op after the - call. For real AIX and NT calling sequences, we also replace the + call. For real AIX calling sequences, we also replace the function name with the real name (1 or 2 leading .'s), rather than the function descriptor name. This saves a lot of overriding code to read the prefixes. */ @@ -6055,7 +6809,7 @@ rs6000_encode_section_info (decl) && ! DECL_WEAK (decl)) SYMBOL_REF_FLAG (sym_ref) = 1; - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + if (DEFAULT_ABI == ABI_AIX) { size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2; size_t len2 = strlen (XSTR (sym_ref, 0)); @@ -6173,4 +6927,8 @@ rs6000_add_gc_roots () { ggc_add_rtx_root (&rs6000_compare_op0, 1); ggc_add_rtx_root (&rs6000_compare_op1, 1); + + toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL); + ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table), + toc_hash_mark_table); } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index a58f66f6f7b..e55ae93641b 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -22,13 +22,18 @@ Boston, MA 02111-1307, USA. */ /* Note that some other tm.h files include this one and then override - many of the definitions that relate to assembler syntax. */ + many of the definitions. */ +/* Definitions for the object file format. These are set at + compile-time. */ -/* Names to predefine in the preprocessor for this target machine. */ +#define OBJECT_XCOFF 1 +#define OBJECT_ELF 2 +#define OBJECT_PEF 3 -#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \ --Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" +#define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF) +#define TARGET_AIX (TARGET_OBJECT_FORMAT == OBJECT_XCOFF) +#define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF) /* Print subsidiary information on the compiler version in use. */ #define TARGET_VERSION ; @@ -38,16 +43,6 @@ Boston, MA 02111-1307, USA. */ #define TARGET_CPU_DEFAULT ((char *)0) #endif -/* Tell the assembler to assume that all undefined names are external. - - Don't do this until the fixed IBM assembler is more generally available. - When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL, - ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no - longer be needed. Also, the extern declaration of mcount in ASM_FILE_START - will no longer be needed. */ - -/* #define ASM_SPEC "-u %(asm_cpu)" */ - /* Define appropriate architecture macros for preprocessor depending on target switches. */ @@ -89,25 +84,7 @@ Boston, MA 02111-1307, USA. */ %{mcpu=823: -D_ARCH_PPC} \ %{mcpu=860: -D_ARCH_PPC}" -#ifndef CPP_DEFAULT_SPEC #define CPP_DEFAULT_SPEC "-D_ARCH_PWR" -#endif - -#ifndef CPP_SYSV_SPEC -#define CPP_SYSV_SPEC "" -#endif - -#ifndef CPP_ENDIAN_SPEC -#define CPP_ENDIAN_SPEC "" -#endif - -#ifndef CPP_ENDIAN_DEFAULT_SPEC -#define CPP_ENDIAN_DEFAULT_SPEC "" -#endif - -#ifndef CPP_SYSV_DEFAULT_SPEC -#define CPP_SYSV_DEFAULT_SPEC "" -#endif /* Common ASM definitions used by ASM_SPEC among the various targets for handling -mcpu=xxx switches. */ @@ -145,9 +122,7 @@ Boston, MA 02111-1307, USA. */ %{mcpu=823: -mppc} \ %{mcpu=860: -mppc}" -#ifndef ASM_DEFAULT_SPEC #define ASM_DEFAULT_SPEC "" -#endif /* This macro defines names of additional specifications to put in the specs that can be used in various specifications like CC1_SPEC. Its definition @@ -159,65 +134,18 @@ Boston, MA 02111-1307, USA. */ Do not define this macro if it does not need to do anything. */ -#ifndef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS -#endif #define EXTRA_SPECS \ { "cpp_cpu", CPP_CPU_SPEC }, \ { "cpp_default", CPP_DEFAULT_SPEC }, \ - { "cpp_sysv", CPP_SYSV_SPEC }, \ - { "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \ - { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \ - { "cpp_endian", CPP_ENDIAN_SPEC }, \ { "asm_cpu", ASM_CPU_SPEC }, \ { "asm_default", ASM_DEFAULT_SPEC }, \ - { "link_syscalls", LINK_SYSCALLS_SPEC }, \ - { "link_libg", LINK_LIBG_SPEC }, \ SUBTARGET_EXTRA_SPECS -/* Default location of syscalls.exp under AIX */ -#ifndef CROSS_COMPILE -#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp" -#else -#define LINK_SYSCALLS_SPEC "" -#endif - -/* Default location of libg.exp under AIX */ -#ifndef CROSS_COMPILE -#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp" -#else -#define LINK_LIBG_SPEC "" -#endif - -/* Define the options for the binder: Start text at 512, align all segments - to 512 bytes, and warn if there is text relocation. - - The -bhalt:4 option supposedly changes the level at which ld will abort, - but it also suppresses warnings about multiply defined symbols and is - used by the AIX cc command. So we use it here. - - -bnodelcsect undoes a poor choice of default relating to multiply-defined - csects. See AIX documentation for more information about this. - - -bM:SRE tells the linker that the output file is Shared REusable. Note - that to actually build a shared library you will also need to specify an - export list with the -Wl,-bE option. */ - -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ - %{static:-bnso %(link_syscalls) } \ - %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" - -/* Profiled library versions are used by linking with special directories. */ -#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ - %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" - /* gcc must do the search itself to find libgcc.a, not use -l. */ #define LIBGCC_SPEC "libgcc.a%s" -/* Don't turn -B into -L if the argument specifies a relative file name. */ -#define RELATIVE_PREFIX_NOT_LINKDIR - /* Architecture type. */ extern int target_flags; @@ -280,12 +208,14 @@ extern int target_flags; /* Disable fused multiply/add operations */ #define MASK_NO_FUSED_MADD 0x00020000 +/* Nonzero if we need to schedule the prolog and epilog. */ +#define MASK_SCHED_PROLOG 0x00040000 + #define TARGET_POWER (target_flags & MASK_POWER) #define TARGET_POWER2 (target_flags & MASK_POWER2) #define TARGET_POWERPC (target_flags & MASK_POWERPC) #define TARGET_PPC_GPOPT (target_flags & MASK_PPC_GPOPT) #define TARGET_PPC_GFXOPT (target_flags & MASK_PPC_GFXOPT) -#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64) #define TARGET_NEW_MNEMONICS (target_flags & MASK_NEW_MNEMONICS) #define TARGET_NO_FP_IN_TOC (target_flags & MASK_NO_FP_IN_TOC) #define TARGET_NO_SUM_IN_TOC (target_flags & MASK_NO_SUM_IN_TOC) @@ -298,6 +228,7 @@ extern int target_flags; #define TARGET_STRING_SET (target_flags & MASK_STRING_SET) #define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE) #define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD) +#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG) #define TARGET_32BIT (! TARGET_64BIT) #define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT) @@ -306,48 +237,16 @@ extern int target_flags; #ifdef IN_LIBGCC2 /* For libgcc2 we make sure this is a compile time constant */ -#undef TARGET_POWERPC64 #ifdef __64BIT__ #define TARGET_POWERPC64 1 #else #define TARGET_POWERPC64 0 #endif -#endif - -/* Pseudo target to indicate whether the object format is ELF - (to get around not having conditional compilation in the md file) */ -#ifndef TARGET_ELF -#define TARGET_ELF 0 -#endif - -/* If this isn't V.4, don't support -mno-toc. */ -#ifndef TARGET_NO_TOC -#define TARGET_NO_TOC 0 -#define TARGET_TOC 1 -#endif - -/* Pseudo target to say whether this is Windows NT */ -#ifndef TARGET_WINDOWS_NT -#define TARGET_WINDOWS_NT 0 -#endif - -/* Pseudo target to say whether this is MAC */ -#ifndef TARGET_MACOS -#define TARGET_MACOS 0 -#endif - -/* Pseudo target to say whether this is AIX */ -#ifndef TARGET_AIX -#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS) -#define TARGET_AIX 0 #else -#define TARGET_AIX 1 -#endif +#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64) #endif -#ifndef TARGET_XL_CALL #define TARGET_XL_CALL 0 -#endif /* Run-time compilation parameters selecting different hardware subsets. @@ -357,55 +256,95 @@ extern int target_flags; where VALUE is the bits to set or minus the bits to clear. An empty string NAME is used to identify the default VALUE. */ -/* This is meant to be redefined in the host dependent files */ -#ifndef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES -#endif - #define TARGET_SWITCHES \ - {{"power", MASK_POWER | MASK_MULTIPLE | MASK_STRING}, \ + {{"power", MASK_POWER | MASK_MULTIPLE | MASK_STRING, \ + "Use POWER instruction set"}, \ {"power2", (MASK_POWER | MASK_MULTIPLE | MASK_STRING \ - | MASK_POWER2)}, \ - {"no-power2", - MASK_POWER2}, \ + | MASK_POWER2), \ + "Use POWER2 instruction set"}, \ + {"no-power2", - MASK_POWER2, \ + "Do not use POWER2 instruction set"}, \ {"no-power", - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE \ - | MASK_STRING)}, \ - {"powerpc", MASK_POWERPC}, \ + | MASK_STRING), \ + "Do not use POWER instruction set"}, \ + {"powerpc", MASK_POWERPC, \ + "Use PowerPC instruction set"}, \ {"no-powerpc", - (MASK_POWERPC | MASK_PPC_GPOPT \ - | MASK_PPC_GFXOPT | MASK_POWERPC64)}, \ - {"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT}, \ - {"no-powerpc-gpopt", - MASK_PPC_GPOPT}, \ - {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT}, \ - {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT}, \ - {"powerpc64", MASK_POWERPC64}, \ - {"no-powerpc64", - MASK_POWERPC64}, \ - {"new-mnemonics", MASK_NEW_MNEMONICS}, \ - {"old-mnemonics", -MASK_NEW_MNEMONICS}, \ + | MASK_PPC_GFXOPT | MASK_POWERPC64), \ + "Do not use PowerPC instruction set"}, \ + {"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT, \ + "Use PowerPC General Purpose group optional instructions"},\ + {"no-powerpc-gpopt", - MASK_PPC_GPOPT, \ + "Don't use PowerPC General Purpose group optional instructions"},\ + {"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT, \ + "Use PowerPC Graphics group optional instructions"},\ + {"no-powerpc-gfxopt", - MASK_PPC_GFXOPT, \ + "Don't use PowerPC Graphics group optional instructions"},\ + {"powerpc64", MASK_POWERPC64, \ + "Use PowerPC-64 instruction set"}, \ + {"no-powerpc64", - MASK_POWERPC64, \ + "Don't use PowerPC-64 instruction set"}, \ + {"new-mnemonics", MASK_NEW_MNEMONICS, \ + "Use new mnemonics for PowerPC architecture"}, \ + {"old-mnemonics", -MASK_NEW_MNEMONICS, \ + "Use old mnemonics for PowerPC architecture"}, \ {"full-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC \ - | MASK_MINIMAL_TOC)}, \ - {"fp-in-toc", - MASK_NO_FP_IN_TOC}, \ - {"no-fp-in-toc", MASK_NO_FP_IN_TOC}, \ - {"sum-in-toc", - MASK_NO_SUM_IN_TOC}, \ - {"no-sum-in-toc", MASK_NO_SUM_IN_TOC}, \ - {"minimal-toc", MASK_MINIMAL_TOC}, \ - {"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)}, \ - {"no-minimal-toc", - MASK_MINIMAL_TOC}, \ - {"hard-float", - MASK_SOFT_FLOAT}, \ - {"soft-float", MASK_SOFT_FLOAT}, \ - {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET}, \ - {"no-multiple", - MASK_MULTIPLE}, \ - {"no-multiple", MASK_MULTIPLE_SET}, \ - {"string", MASK_STRING | MASK_STRING_SET}, \ - {"no-string", - MASK_STRING}, \ - {"no-string", MASK_STRING_SET}, \ - {"update", - MASK_NO_UPDATE}, \ - {"no-update", MASK_NO_UPDATE}, \ - {"fused-madd", - MASK_NO_FUSED_MADD}, \ - {"no-fused-madd", MASK_NO_FUSED_MADD}, \ + | MASK_MINIMAL_TOC), \ + "Put everything in the regular TOC"}, \ + {"fp-in-toc", - MASK_NO_FP_IN_TOC, \ + "Place floating point constants in TOC"}, \ + {"no-fp-in-toc", MASK_NO_FP_IN_TOC, \ + "Don't place floating point constants in TOC"}, \ + {"sum-in-toc", - MASK_NO_SUM_IN_TOC, \ + "Place symbol+offset constants in TOC"}, \ + {"no-sum-in-toc", MASK_NO_SUM_IN_TOC, \ + "Don't place symbol+offset constants in TOC"}, \ + {"minimal-toc", MASK_MINIMAL_TOC, \ + "Use only one TOC entry per procedure"}, \ + {"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC), \ + ""}, \ + {"no-minimal-toc", - MASK_MINIMAL_TOC, \ + "Place variable addresses in the regular TOC"}, \ + {"hard-float", - MASK_SOFT_FLOAT, \ + "Use hardware fp"}, \ + {"soft-float", MASK_SOFT_FLOAT, \ + "Do not use hardware fp"}, \ + {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET, \ + "Generate load/store multiple instructions"}, \ + {"no-multiple", - MASK_MULTIPLE, \ + "Do not generate load/store multiple instructions"},\ + {"no-multiple", MASK_MULTIPLE_SET, \ + ""},\ + {"string", MASK_STRING | MASK_STRING_SET, \ + "Generate string instructions for block moves"},\ + {"no-string", - MASK_STRING, \ + "Do not generate string instructions for block moves"},\ + {"no-string", MASK_STRING_SET, \ + ""},\ + {"update", - MASK_NO_UPDATE, \ + "Generate load/store with update instructions"},\ + {"no-update", MASK_NO_UPDATE, \ + "Do not generate load/store with update instructions"},\ + {"fused-madd", - MASK_NO_FUSED_MADD, \ + "Generate fused multiply/add instructions"}, \ + {"no-fused-madd", MASK_NO_FUSED_MADD, \ + "Don't generate fused multiply/add instructions"},\ + {"sched-prolog", MASK_SCHED_PROLOG, \ + ""}, \ + {"no-sched-prolog", -MASK_SCHED_PROLOG, \ + "Don't schedule the start and end of the procedure"},\ + {"sched-epilog", MASK_SCHED_PROLOG, \ + ""}, \ + {"no-sched-epilog", -MASK_SCHED_PROLOG, \ + ""}, \ SUBTARGET_SWITCHES \ - {"", TARGET_DEFAULT | SUBTARGET_DEFAULT}} + {"", TARGET_DEFAULT | MASK_SCHED_PROLOG, \ + ""}} #define TARGET_DEFAULT (MASK_POWER | MASK_MULTIPLE | MASK_STRING) -#define SUBTARGET_DEFAULT 0 + +/* This is meant to be redefined in the host dependent files */ +#define SUBTARGET_SWITCHES /* Processor type. Order must match cpu attribute in MD file. */ enum processor_type @@ -441,7 +380,7 @@ extern enum processor_type rs6000_cpu; /* Specify the dialect of assembler to use. New mnemonics is dialect one and the old mnemonics are dialect zero. */ -#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0 +#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0) /* This macro is similar to `TARGET_SWITCHES' but defines names of command options that have values. Its definition is an @@ -461,17 +400,14 @@ extern enum processor_type rs6000_cpu; #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ /* This is meant to be overridden in target specific files. */ -#ifndef SUBTARGET_OPTIONS #define SUBTARGET_OPTIONS -#endif -#define TARGET_OPTIONS \ -{ \ - {"cpu=", &rs6000_select[1].string}, \ - {"tune=", &rs6000_select[2].string}, \ - {"debug-", &rs6000_debug_name}, \ - {"debug=", &rs6000_debug_name}, \ - SUBTARGET_OPTIONS \ +#define TARGET_OPTIONS \ +{ \ + {"cpu=", &rs6000_select[1].string, "Use features of and schedule code for given CPU" },\ + {"tune=", &rs6000_select[2].string, "Schedule code for given CPU" }, \ + {"debug=", &rs6000_debug_name, "Enable debug output" }, \ + SUBTARGET_OPTIONS \ } /* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */ @@ -685,9 +621,9 @@ extern int rs6000_debug_arg; /* debug argument handling */ many times greater than aligned accesses, for example if they are emulated in a trap handler. */ #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \ - ((((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \ - && (ALIGN) < 4) ? 1 : 0) - + ((STRICT_ALIGNMENT \ + || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \ + && (ALIGN) < 4)) ? 1 : 0) /* Standard register usage. */ @@ -722,10 +658,6 @@ extern int rs6000_debug_arg; /* debug argument handling */ On System V implementations, r13 is fixed and not available for use. */ -#ifndef FIXED_R13 -#define FIXED_R13 0 -#endif - #define FIXED_REGISTERS \ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ @@ -747,6 +679,15 @@ extern int rs6000_debug_arg; /* debug argument handling */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1} +#define MQ_REGNO 64 +#define CR0_REGNO 68 +#define CR1_REGNO 69 +#define CR2_REGNO 70 +#define CR3_REGNO 71 +#define CR4_REGNO 72 +#define MAX_CR_REGNO 75 +#define XER_REGNO 76 + /* List the order in which to allocate registers. Each register must be listed once, even those in FIXED_REGISTERS. @@ -768,7 +709,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ mq (not saved; best to use it if we can) ctr (not saved; when we have the choice ctr is better) lr (saved) - cr5, r1, r2, ap, fpmem (fixed) */ + cr5, r1, r2, ap, xer (fixed) */ #define REG_ALLOC_ORDER \ {32, \ @@ -791,18 +732,15 @@ extern int rs6000_debug_arg; /* debug argument handling */ /* True if register is a condition register. */ #define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75) -/* True if register is condition register 0. */ -#define CR0_REGNO_P(N) ((N) == 68) - /* True if register is a condition register, but not cr0. */ #define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75) /* True if register is an integer register. */ -#define INT_REGNO_P(N) ((N) <= 31 || (N) == 67) +#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM) /* True if register is the temporary memory location used for int/float conversion. */ -#define FPMEM_REGNO_P(N) ((N) == FPMEM_REGNUM) +#define XER_REGNO_P(N) ((N) == XER_REGNO) /* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. @@ -813,7 +751,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ PowerPC64 GPRs and FPRs point register holds 64 bits worth. */ #define HARD_REGNO_NREGS(REGNO, MODE) \ - (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO) \ + (FP_REGNO_P (REGNO) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) @@ -829,7 +767,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ || (GET_MODE_CLASS (MODE) == MODE_INT \ && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ - : FPMEM_REGNO_P (REGNO) ? ((MODE) == DImode || (MODE) == DFmode) \ + : XER_REGNO_P (REGNO) ? (MODE) == PSImode \ : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \ && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ : 1) @@ -949,11 +887,11 @@ extern int rs6000_debug_arg; /* debug argument handling */ /* Place to put static chain when calling a function that requires it. */ #define STATIC_CHAIN_REGNUM 11 -/* count register number for special purposes */ -#define COUNT_REGISTER_REGNUM 66 +/* Link register number. */ +#define LINK_REGISTER_REGNUM 65 -/* Special register that represents memory, used for float/int conversions. */ -#define FPMEM_REGNUM 76 +/* Count register number. */ +#define COUNT_REGISTER_REGNUM 66 /* Place that structure value return address is placed. @@ -1013,8 +951,7 @@ enum reg_class CR0_REGS, CR_REGS, NON_FLOAT_REGS, - FPMEM_REGS, - FLOAT_OR_FPMEM_REGS, + XER_REGS, ALL_REGS, LIM_REG_CLASSES }; @@ -1039,8 +976,7 @@ enum reg_class "CR0_REGS", \ "CR_REGS", \ "NON_FLOAT_REGS", \ - "FPMEM_REGS", \ - "FLOAT_OR_FPMEM_REGS", \ + "XER_REGS", \ "ALL_REGS" \ } @@ -1064,8 +1000,7 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000010 }, /* CR0_REGS */ \ { 0x00000000, 0x00000000, 0x00000ff0 }, /* CR_REGS */ \ { 0xffffffff, 0x00000000, 0x0000ffff }, /* NON_FLOAT_REGS */ \ - { 0x00000000, 0x00000000, 0x00010000 }, /* FPMEM_REGS */ \ - { 0x00000000, 0xffffffff, 0x00010000 }, /* FLOAT_OR_FPMEM_REGS */ \ + { 0x00000000, 0x00000000, 0x00010000 }, /* XER_REGS */ \ { 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \ } @@ -1084,7 +1019,7 @@ enum reg_class : (REGNO) == 65 ? LINK_REGS \ : (REGNO) == 66 ? CTR_REGS \ : (REGNO) == 67 ? BASE_REGS \ - : (REGNO) == 76 ? FPMEM_REGS \ + : (REGNO) == 76 ? XER_REGS \ : NO_REGS) /* The class value for index registers, and the one for base regs. */ @@ -1102,7 +1037,7 @@ enum reg_class : (C) == 'l' ? LINK_REGS \ : (C) == 'x' ? CR0_REGS \ : (C) == 'y' ? CR_REGS \ - : (C) == 'z' ? FPMEM_REGS \ + : (C) == 'z' ? XER_REGS \ : NO_REGS) /* The letters I, J, K, L, M, N, and P in a register constraint string @@ -1122,7 +1057,7 @@ enum reg_class #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \ - : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0 \ + : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000u)) == 0 \ : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \ : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \ && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0)) \ @@ -1195,15 +1130,14 @@ enum reg_class On RS/6000, this is the size of MODE in words, except in the FP regs, where a single reg is enough for two words. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ - (((CLASS) == FLOAT_REGS || (CLASS) == FPMEM_REGS \ - || (CLASS) == FLOAT_OR_FPMEM_REGS) \ + (((CLASS) == FLOAT_REGS) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* If defined, gives a class of registers that cannot be used as the operand of a SUBREG that changes the size of the object. */ -#define CLASS_CANNOT_CHANGE_SIZE FLOAT_OR_FPMEM_REGS +#define CLASS_CANNOT_CHANGE_SIZE FLOAT_REGS /* Stack layout; function entry, exit and calling. */ @@ -1213,19 +1147,11 @@ enum rs6000_abi { ABI_AIX, /* IBM's AIX */ ABI_AIX_NODESC, /* AIX calling sequence minus function descriptors */ ABI_V4, /* System V.4/eabi */ - ABI_NT, /* Windows/NT */ ABI_SOLARIS /* Solaris */ }; extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ -/* Default ABI to compile code for */ -#ifndef DEFAULT_ABI -#define DEFAULT_ABI ABI_AIX -/* The prefix to add to user-visible assembler symbols. */ -#define USER_LABEL_PREFIX "." -#endif - /* Structure used to define the rs6000 stack */ typedef struct rs6000_stack { int first_gp_reg_save; /* first callee saved GP register used */ @@ -1235,9 +1161,6 @@ typedef struct rs6000_stack { int toc_save_p; /* true if the TOC needs to be saved */ int push_p; /* true if we need to allocate stack space */ int calls_p; /* true if the function makes any calls */ - int main_p; /* true if this is main */ - int main_save_p; /* true if this is main and we need to save args */ - int fpmem_p; /* true if float/int conversion temp needed */ enum rs6000_abi abi; /* which ABI to use */ int gp_save_offset; /* offset to save GP regs from initial SP */ int fp_save_offset; /* offset to save FP regs from initial SP */ @@ -1245,20 +1168,16 @@ typedef struct rs6000_stack { int cr_save_offset; /* offset to save CR from initial SP */ int toc_save_offset; /* offset to save the TOC pointer */ int varargs_save_offset; /* offset to save the varargs registers */ - int main_save_offset; /* offset to save main's args */ - int fpmem_offset; /* offset for float/int conversion temp */ int reg_size; /* register size (4 or 8) */ int varargs_size; /* size to hold V.4 args passed in regs */ int vars_size; /* variable save area size */ int parm_size; /* outgoing parameter size */ - int main_size; /* size to hold saving main's args */ int save_size; /* save area size */ int fixed_size; /* fixed size of stack frame */ int gp_size; /* size of saved GP registers */ int fp_size; /* size of saved FP registers */ int cr_size; /* size to hold CR if not in save_size */ int lr_size; /* size to hold LR if not in save_size */ - int fpmem_size; /* size to hold float/int conversion */ int toc_size; /* size to hold TOC if not in save_size */ int total_size; /* total bytes allocated for stack */ } rs6000_stack_t; @@ -1277,21 +1196,21 @@ typedef struct rs6000_stack { /* #define FRAME_GROWS_DOWNWARD */ /* Size of the outgoing register save area */ -#define RS6000_REG_SAVE (TARGET_32BIT ? 32 : 64) +#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ + || DEFAULT_ABI == ABI_AIX_NODESC) \ + ? (TARGET_64BIT ? 64 : 32) \ + : 0) /* Size of the fixed area on the stack */ -#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48) +#define RS6000_SAVE_AREA \ + (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8) \ + << (TARGET_64BIT ? 1 : 0)) /* MEM representing address to save the TOC register */ #define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \ plus_constant (stack_pointer_rtx, \ (TARGET_32BIT ? 20 : 40))) -/* Offset & size for fpmem stack locations used for converting between - float and integral types. */ -extern int rs6000_fpmem_offset; -extern int rs6000_fpmem_size; - /* Size of the V.4 varargs area if needed */ #define RS6000_VARARGS_AREA 0 @@ -1420,7 +1339,9 @@ extern int rs6000_sysv_varargs_p; #define FP_ARG_MIN_REG 33 #define FP_ARG_AIX_MAX_REG 45 #define FP_ARG_V4_MAX_REG 40 -#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG +#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \ + || DEFAULT_ABI == ABI_AIX_NODESC) \ + ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1) /* Return registers */ @@ -1429,14 +1350,11 @@ extern int rs6000_sysv_varargs_p; /* Flags for the call/call_value rtl operations set up by function_arg */ #define CALL_NORMAL 0x00000000 /* no special processing */ -#define CALL_NT_DLLIMPORT 0x00000001 /* NT, this is a DLL import call */ +/* Bits in 0x00000001 are unused. */ #define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */ #define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */ #define CALL_LONG 0x00000008 /* always call indirect */ -/* Define cutoff for using external functions to save floating point */ -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) - /* 1 if N is a possible register number for a function value as seen by the caller. @@ -1561,8 +1479,7 @@ typedef struct rs6000_args the argument, `downward' to pad below, or `none' to inhibit padding. */ -#define FUNCTION_ARG_PADDING(MODE, TYPE) \ - (enum direction) function_arg_padding (MODE, TYPE) +#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE) /* If defined, a C expression that gives the alignment boundary, in bits, of an argument with the specified mode and type. If it is not defined, @@ -1635,40 +1552,6 @@ typedef struct rs6000_args before returning. */ #define FUNCTION_EPILOGUE(FILE, SIZE) output_epilog (FILE, SIZE) - -/* A C compound statement that outputs the assembler code for a thunk function, - used to implement C++ virtual function calls with multiple inheritance. The - thunk acts as a wrapper around a virtual function, adjusting the implicit - object parameter before handing control off to the real function. - - First, emit code to add the integer DELTA to the location that contains the - incoming first argument. Assume that this argument contains a pointer, and - is the one used to pass the `this' pointer in C++. This is the incoming - argument *before* the function prologue, e.g. `%o0' on a sparc. The - addition must preserve the values of all other incoming arguments. - - After the addition, emit code to jump to FUNCTION, which is a - `FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch - the return address. Hence returning from FUNCTION will return to whoever - called the current `thunk'. - - The effect must be as if FUNCTION had been called directly with the adjusted - first argument. This macro is responsible for emitting all of the code for - a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not - invoked. - - The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already been - extracted from it.) It might possibly be useful on some targets, but - probably not. - - If you do not define this macro, the target-independent code in the C++ - frontend will generate a less efficient heavyweight thunk that calls - FUNCTION instead of jumping to it. The generic approach does not support - varargs. */ -#if TARGET_ELF -#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ - output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION) -#endif /* TRAMPOLINE_TEMPLATE deleted */ @@ -1730,7 +1613,6 @@ typedef struct rs6000_args || DEFAULT_ABI == ABI_AIX_NODESC) ? 8 : \ (DEFAULT_ABI == ABI_V4 \ || DEFAULT_ABI == ABI_SOLARIS) ? (TARGET_32BIT ? 4 : 8) : \ - (DEFAULT_ABI == ABI_NT) ? -4 : \ (fatal ("RETURN_ADDRESS_OFFSET not supported"), 0)) /* The current return address is in link register (65). The return address @@ -1738,7 +1620,7 @@ typedef struct rs6000_args frame pointer. */ #define RETURN_ADDR_RTX(count, frame) \ ((count == -1) \ - ? gen_rtx_REG (Pmode, 65) \ + ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) \ : gen_rtx_MEM (Pmode, \ memory_address \ (Pmode, \ @@ -1906,18 +1788,16 @@ typedef struct rs6000_args adjacent memory cells are accessed by adding word-sized offsets during assembly output. */ -#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) \ - (TARGET_TOC && GET_CODE (X) == SYMBOL_REF \ - && CONSTANT_POOL_ADDRESS_P (X) \ - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X))) +#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X)) + +#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X)) -/* AIX64 guaranteed to have 64 bit TOC alignment. */ #define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \ - (LEGITIMATE_CONSTANT_POOL_BASE_P (X) \ - || (TARGET_TOC \ - && GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ - && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0)))) + (TARGET_TOC \ + && GET_CODE (X) == PLUS \ + && GET_CODE (XEXP (X, 0)) == REG \ + && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER) \ + && CONSTANT_POOL_EXPR_P (XEXP (X, 1))) #define LEGITIMATE_SMALL_DATA_P(MODE, X) \ ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \ @@ -2012,43 +1892,13 @@ typedef struct rs6000_args Then check for the sum of a register and something not constant, try to load the other things into a register and return the sum. */ -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ -{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \ - { HOST_WIDE_INT high_int, low_int; \ - rtx sum; \ - high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff); \ - low_int = INTVAL (XEXP (X, 1)) & 0xffff; \ - if (low_int & 0x8000) \ - high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16; \ - sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - GEN_INT (high_int)), 0); \ - (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); \ - goto WIN; \ - } \ - else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) != CONST_INT \ - && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \ - && (TARGET_POWERPC64 || (MODE) != DImode) \ - && (MODE) != TImode) \ - { \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \ - goto WIN; \ - } \ - else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC \ - && !flag_pic \ - && GET_CODE (X) != CONST_INT \ - && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X) \ - && (TARGET_HARD_FLOAT || (MODE) != DFmode) \ - && (MODE) != DImode && (MODE) != TImode) \ - { \ - rtx reg = gen_reg_rtx (Pmode); \ - emit_insn (gen_elf_high (reg, (X))); \ - (X) = gen_rtx_LO_SUM (Pmode, reg, (X)); \ - goto WIN; \ - } \ +#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ +{ rtx result = rs6000_legitimize_address (X, OLDX, MODE); \ + if (result != NULL_RTX) \ + { \ + (X) = result; \ + goto WIN; \ + } \ } /* Try a machine-dependent way of reloading an illegitimate address @@ -2082,7 +1932,7 @@ do { \ 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; \ + = (((val - low) & 0xffffffffu) ^ 0x80000000u) - 0x80000000u; \ \ /* Check for 32-bit overflow. */ \ if (high + low != val) \ @@ -2101,6 +1951,13 @@ do { \ OPNUM, TYPE); \ goto WIN; \ } \ + else if (TARGET_TOC \ + && CONSTANT_POOL_EXPR_P (X) \ + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X))) \ + { \ + (X) = create_TOC_reference (X); \ + goto WIN; \ + } \ } while (0) /* Go to LABEL if ADDR (a legitimate address expression) @@ -2136,6 +1993,8 @@ do { \ #define PIC_OFFSET_TABLE_REGNUM 30 +#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2) + /* Define this macro if the register defined by `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */ @@ -2172,12 +2031,9 @@ do { \ /* In rare cases, correct code generation requires extra machine dependent processing between the second jump optimization pass and delayed branch scheduling. On those machines, define this macro - as a C statement to act on the code starting at INSN. + as a C statement to act on the code starting at INSN. */ - On the RS/6000, we use it to make sure the GOT_TOC register marker - that FINALIZE_PIC is supposed to remove actually got removed. */ - -#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN) +/* #define MACHINE_DEPENDENT_REORG(INSN) */ /* Define this if some processing needs to be done immediately before @@ -2232,38 +2088,6 @@ do { \ /* Define if loading short immediate values into registers sign extends. */ #define SHORT_IMMEDIATES_SIGN_EXTEND -/* The RS/6000 uses the XCOFF format. */ - -#define XCOFF_DEBUGGING_INFO - -/* Define if the object format being used is COFF or a superset. */ -#define OBJECT_FORMAT_COFF - -/* Define the magic numbers that we recognize as COFF. - - AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c - does not include files in the correct order to conditionally define - the symbolic name in this macro. - - The AIX linker accepts import/export files as object files, - so accept "#!" (0x2321) magic number. */ -#define MY_ISCOFF(magic) \ - ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \ - || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0x2321) - -/* This is the only version of nm that collect2 can work with. */ -#define REAL_NM_FILE_NAME "/usr/ucb/nm" - -/* We don't have GAS for the RS/6000 yet, so don't write out special - .stabs in cc1plus. */ - -#define FASCIST_ASSEMBLER - -/* AIX does not have any init/fini or ctor/dtor sections, so create - static constructors and destructors as normal functions. */ -/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */ -/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */ - /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 @@ -2467,21 +2291,6 @@ extern int rs6000_trunc_used; #define RS6000_ITRUNC "__itrunc" #define RS6000_UITRUNC "__uitrunc" -/* Prefix and suffix to use to saving floating point */ -#ifndef SAVE_FP_PREFIX -#define SAVE_FP_PREFIX "._savef" -#define SAVE_FP_SUFFIX "" -#endif - -/* Prefix and suffix to use to restoring floating point */ -#ifndef RESTORE_FP_PREFIX -#define RESTORE_FP_PREFIX "._restf" -#define RESTORE_FP_SUFFIX "" -#endif - -/* Function name to call to do profiling. */ -#define RS6000_MCOUNT ".__mcount" - /* Control the assembler format that we output. */ @@ -2490,55 +2299,6 @@ extern int rs6000_trunc_used; the end of the line. */ #define ASM_COMMENT_START " #" -/* Output at beginning of assembler file. - - Initialize the section names for the RS/6000 at this point. - - Specify filename, including full path, to assembler. - - We want to go into the TOC section so at least one .toc will be emitted. - Also, in order to output proper .bs/.es pairs, we need at least one static - [RW] section emitted. - - We then switch back to text to force the gcc2_compiled. label and the space - allocated after it (when profiling) into the text section. - - Finally, declare mcount when profiling to make the assembler happy. */ - -#define ASM_FILE_START(FILE) \ -{ \ - rs6000_gen_section_name (&xcoff_bss_section_name, \ - main_input_filename, ".bss_"); \ - rs6000_gen_section_name (&xcoff_private_data_section_name, \ - main_input_filename, ".rw_"); \ - rs6000_gen_section_name (&xcoff_read_only_section_name, \ - main_input_filename, ".ro_"); \ - \ - fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename); \ - if (TARGET_64BIT) \ - fputs ("\t.machine\t\"ppc64\"\n", FILE); \ - toc_section (); \ - if (write_symbols != NO_DEBUG) \ - private_data_section (); \ - text_section (); \ - if (profile_flag) \ - fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT); \ - rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ -} - -/* Output at end of assembler file. - - On the RS/6000, referencing data should automatically pull in text. */ - -#define ASM_FILE_END(FILE) \ -{ \ - text_section (); \ - fputs ("_section_.text:\n", FILE); \ - data_section (); \ - fputs (TARGET_32BIT \ - ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \ -} - /* We define this to prevent the name mangler from putting dollar signs into function names. */ @@ -2554,20 +2314,6 @@ extern int rs6000_trunc_used; #define TARGET_MEM_FUNCTIONS -/* Define the extra sections we need. We define three: one is the read-only - data section which is used for constants. This is a csect whose name is - derived from the name of the input file. The second is for initialized - global variables. This is a csect whose name is that of the variable. - The third is the TOC. */ - -#define EXTRA_SECTIONS \ - read_only_data, private_data, read_only_private_data, toc, bss - -/* Define the name of our readonly data section. */ - -#define READONLY_DATA_SECTION read_only_data_section - - /* Define the name of the section to use for the exception tables. TODO: test and see if we can use read_only_data_section, if so, remove this. */ @@ -2585,118 +2331,9 @@ extern int rs6000_trunc_used; && ! DECL_WEAK (DECL)) \ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; -/* Indicate that jump tables go in the text section. */ - -#define JUMP_TABLES_IN_TEXT_SECTION 1 - -/* Define the routines to implement these extra sections. - BIGGEST_ALIGNMENT is 64, so align the sections that much. */ - -#define EXTRA_SECTION_FUNCTIONS \ - \ -void \ -read_only_data_section () \ -{ \ - if (in_section != read_only_data) \ - { \ - fprintf (asm_out_file, "\t.csect %s[RO],3\n", \ - xcoff_read_only_section_name); \ - in_section = read_only_data; \ - } \ -} \ - \ -void \ -private_data_section () \ -{ \ - if (in_section != private_data) \ - { \ - fprintf (asm_out_file, "\t.csect %s[RW],3\n", \ - xcoff_private_data_section_name); \ - in_section = private_data; \ - } \ -} \ - \ -void \ -read_only_private_data_section () \ -{ \ - if (in_section != read_only_private_data) \ - { \ - fprintf (asm_out_file, "\t.csect %s[RO],3\n", \ - xcoff_private_data_section_name); \ - in_section = read_only_private_data; \ - } \ -} \ - \ -void \ -toc_section () \ -{ \ - if (TARGET_MINIMAL_TOC) \ - { \ - /* toc_section is always called at least once from ASM_FILE_START, \ - so this is guaranteed to always be defined once and only once \ - in each file. */ \ - if (! toc_initialized) \ - { \ - fputs ("\t.toc\nLCTOC..0:\n", asm_out_file); \ - fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \ - toc_initialized = 1; \ - } \ - \ - if (in_section != toc) \ - fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n", \ - (TARGET_32BIT ? "" : ",3")); \ - } \ - else \ - { \ - if (in_section != toc) \ - fputs ("\t.toc\n", asm_out_file); \ - } \ - in_section = toc; \ -} - /* Flag to say the TOC is initialized */ extern int toc_initialized; -/* This macro produces the initial definition of a function name. - On the RS/6000, we need to place an extra '.' in the function name and - output the function descriptor. - - The csect for the function will have already been created by the - `text_section' call previously done. We do have to go back to that - csect, however. - - The third and fourth parameters to the .function pseudo-op (16 and 044) - are placeholders which no longer have any use. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ -{ if (TREE_PUBLIC (DECL)) \ - { \ - fputs ("\t.globl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - putc ('\n', FILE); \ - } \ - else \ - { \ - fputs ("\t.lglobl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - putc ('\n', FILE); \ - } \ - fputs ("\t.csect ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (":\n", FILE); \ - fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (", TOC[tc0], 0\n", FILE); \ - fputs (TARGET_32BIT \ - ? "\t.csect .text[PR]\n." : "\t.csect .text[PR],3\n.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ - fputs (":\n", FILE); \ - if (write_symbols == XCOFF_DEBUG) \ - xcoffout_declare_function (FILE, DECL, NAME); \ -} - /* Return non-zero if this entry is to be written into the constant pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST containing one of them. If -mfp-in-toc (the default), we also do @@ -2719,19 +2356,6 @@ extern int toc_initialized; && BITS_PER_WORD == HOST_BITS_PER_INT))) #endif -/* Select section for constant in constant pool. - - On RS/6000, all constants are in the private read-only data area. - However, if this is being placed in the TOC it must be output as a - toc entry. */ - -#define SELECT_RTX_SECTION(MODE, X) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \ - toc_section (); \ - else \ - read_only_private_data_section (); \ -} - /* Macro to output a special constant pool entry. Go to WIN if we output it. Otherwise, it is written the usual way. @@ -2745,114 +2369,38 @@ extern int toc_initialized; } \ } -/* Select the section for an initialized data object. - - On the RS/6000, we have a special section for all variables except those - that are static. */ - -#define SELECT_SECTION(EXP,RELOC) \ -{ \ - if ((TREE_CODE (EXP) == STRING_CST \ - && ! flag_writable_strings) \ - || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd' \ - && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \ - && DECL_INITIAL (EXP) \ - && (DECL_INITIAL (EXP) == error_mark_node \ - || TREE_CONSTANT (DECL_INITIAL (EXP))) \ - && ! (RELOC))) \ - { \ - if (TREE_PUBLIC (EXP)) \ - read_only_data_section (); \ - else \ - read_only_private_data_section (); \ - } \ - else \ - { \ - if (TREE_PUBLIC (EXP)) \ - data_section (); \ - else \ - private_data_section (); \ - } \ -} - -/* This outputs NAME to FILE up to the first null or '['. */ - -#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ - { \ - const char *_p; \ - \ - STRIP_NAME_ENCODING (_p, (NAME)); \ - assemble_name ((FILE), _p); \ - } - -/* Remove any trailing [DS] or the like from the symbol name. */ - -#define STRIP_NAME_ENCODING(VAR,NAME) \ - do \ - { \ - const char *_name = (NAME); \ - int _len; \ - if (_name[0] == '*') \ - _name++; \ - _len = strlen (_name); \ - if (_name[_len - 1] != ']') \ - (VAR) = _name; \ - else \ - { \ - char *_new_name = (char *) alloca (_len + 1); \ - strcpy (_new_name, _name); \ - _new_name[_len - 4] = '\0'; \ - (VAR) = _new_name; \ - } \ - } \ - while (0) - -/* Output something to declare an external symbol to the assembler. Most - assemblers don't need this. - - If we haven't already, add "[RW]" (or "[DS]" for a function) to the - name. Normally we write this out along with the name. In the few cases - where we can't, it gets stripped off. */ - -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \ - XSTR (_symref, 0) = _name; \ - } \ - fputs ("\t.extern ", FILE); \ - assemble_name (FILE, XSTR (_symref, 0)); \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - { \ - fputs ("\n\t.extern .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0)); \ - } \ - putc ('\n', FILE); \ -} - -/* Similar, but for libcall. We only have to worry about the function name, - not that of the descriptor. */ +/* This is how we tell the assembler that two symbols have the same value. */ -#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ -{ fputs ("\t.extern .", FILE); \ - assemble_name (FILE, XSTR (FUN, 0)); \ - putc ('\n', FILE); \ -} +#define SET_ASM_OP ".set" -/* This is how we tell the assembler that two symbols have the same value. */ +/* This implementes the `alias' attribute. */ -#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \ -do { \ - fputs("\t.set ", FILE); \ - assemble_name(FILE, NAME1); \ - fputc(',', FILE); \ - assemble_name(FILE, NAME2); \ - fputc('\n', FILE); \ +#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target) \ +do { \ + char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \ + char * name = IDENTIFIER_POINTER (target); \ + if (TREE_CODE (decl) == FUNCTION_DECL \ + && DEFAULT_ABI == ABI_AIX) \ + { \ + if (TREE_PUBLIC (decl)) \ + { \ + fputs ("\t.globl .", FILE); \ + assemble_name (FILE, alias); \ + putc ('\n', FILE); \ + } \ + else \ + { \ + fputs ("\t.lglobl .", FILE); \ + assemble_name (FILE, alias); \ + putc ('\n', FILE); \ + } \ + fputs ("\t.set .", FILE); \ + assemble_name (FILE, alias); \ + fputs (",.", FILE); \ + assemble_name (FILE, name); \ + fputc ('\n', FILE); \ + } \ + ASM_OUTPUT_DEF (FILE, alias, name); \ } while (0) /* Output to assembler file text saying following lines @@ -2865,17 +2413,6 @@ do { \ #define ASM_APP_OFF "" -/* Output before instructions. - Text section for 64-bit target may contain 64-bit address jump table. */ - -#define TEXT_SECTION_ASM_OP (TARGET_32BIT \ - ? "\t.csect .text[PR]" : "\t.csect .text[PR],3") - -/* Output before writable data. - Align entire section to BIGGEST_ALIGNMENT. */ - -#define DATA_SECTION_ASM_OP ".csect .data[RW],3" - /* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */ @@ -2963,7 +2500,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ &rs6000_reg_names[74][0], /* cr6 */ \ &rs6000_reg_names[75][0], /* cr7 */ \ \ - &rs6000_reg_names[76][0], /* fpmem */ \ + &rs6000_reg_names[76][0], /* xer */ \ } /* print-rtl can't handle the above REGISTER_NAMES, so define the @@ -2982,7 +2519,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ "mq", "lr", "ctr", "ap", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "fpmem" \ + "xer" \ } /* Table of additional register names to use in user input. */ @@ -3017,52 +2554,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ the loader. This depends on the AIX version. */ #define RS6000_CALL_GLUE "cror 31,31,31" -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fputs ("\t.globl ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0) - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fputs (NAME, FILE) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s..%d:\n", PREFIX, NUM) - -/* This is how to output an internal label prefix. rs6000.c uses this - when generating traceback tables. */ - -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, "%s..", PREFIX) - -/* This is how to output a label for a jump table. Arguments are the same as - for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is - passed. */ - -#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \ -{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); } - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s..%d", PREFIX, NUM) - /* This is how to output an assembler line defining a `double' constant. */ #define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ @@ -3070,7 +2561,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ long t[2]; \ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \ - t[0] & 0xffffffff, t[1] & 0xffffffff); \ + t[0] & 0xffffffffu, t[1] & 0xffffffffu); \ } /* This is how to output an assembler line defining a `float' constant. */ @@ -3079,7 +2570,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ { \ long t; \ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \ + fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffffu); \ } /* This is how to output an assembler line defining an `int' constant. */ @@ -3123,22 +2614,8 @@ do { \ #define ASM_OUTPUT_BYTE(FILE,VALUE) \ fprintf (FILE, "\t.byte 0x%x\n", (VALUE)) -/* This is how to output an assembler line to define N characters starting - at P to FILE. */ - -#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N)) - -/* This is how to output an element of a case-vector that is absolute. - (RS/6000 does not use such vectors, but we must define this macro - anyway.) */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - do { char buf[100]; \ - fputs ("\t.long ", FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ - assemble_name (FILE, buf); \ - putc ('\n', FILE); \ - } while (0) +/* This is used by the definition of ASM_OUTPUT_ADDR_ELT in defaults.h. */ +#define ASM_LONG (TARGET_32BIT ? ".long" : ".quad") /* This is how to output an element of a case-vector that is relative. */ @@ -3161,21 +2638,6 @@ do { \ if ((LOG) != 0) \ fprintf (FILE, "\t.align %d\n", (LOG)) -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.space %d\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \ - do { fputs (".comm ", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - if ( (SIZE) > 4) \ - fprintf ((FILE), ",%d,3\n", (SIZE)); \ - else \ - fprintf( (FILE), ",%d\n", (SIZE)); \ - } while (0) - /* This says how to output an assembler line to define a local common symbol. Alignment cannot be specified, but we can try to maintain @@ -3203,6 +2665,12 @@ do { \ #define ASM_OPEN_PAREN "(" #define ASM_CLOSE_PAREN ")" +/* Pick up the return address upon entry to a procedure. Used for + dwarf2 unwind information. This also enables the table driven + mechanism. */ + +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) + /* Define results of standard character escape sequences. */ #define TARGET_BELL 007 #define TARGET_BS 010 @@ -3240,6 +2708,7 @@ do { \ {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \ {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \ {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \ + {"reg_or_u_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \ {"easy_fp_constant", {CONST_DOUBLE}}, \ @@ -3253,11 +2722,13 @@ do { \ {"and_operand", {SUBREG, REG, CONST_INT}}, \ {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ {"logical_operand", {SUBREG, REG, CONST_INT}}, \ + {"logical_u_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ {"non_logical_cint_operand", {CONST_INT}}, \ + {"non_logical_u_cint_operand", {CONST_INT, CONST_DOUBLE}}, \ {"mask_operand", {CONST_INT}}, \ {"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \ {"count_register_operand", {REG}}, \ - {"fpmem_operand", {REG}}, \ + {"xer_operand", {REG}}, \ {"call_operand", {SYMBOL_REF, REG}}, \ {"current_file_function_operand", {SYMBOL_REF}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT, \ @@ -3285,109 +2756,3 @@ extern int flag_pic; extern int optimize; extern int flag_expensive_optimizations; extern int frame_pointer_needed; - -/* Declare functions in rs6000.c */ -extern void optimization_options (); -extern void output_options (); -extern void rs6000_override_options (); -extern void rs6000_file_start (); -extern struct rtx_def *rs6000_float_const (); -extern struct rtx_def *rs6000_got_register (); -extern struct rtx_def *find_addr_reg(); -extern int direct_return (); -extern int get_issue_rate (); -extern int any_operand (); -extern int short_cint_operand (); -extern int u_short_cint_operand (); -extern int non_short_cint_operand (); -extern int gpc_reg_operand (); -extern int cc_reg_operand (); -extern int cc_reg_not_cr0_operand (); -extern int reg_or_short_operand (); -extern int reg_or_neg_short_operand (); -extern int reg_or_u_short_operand (); -extern int reg_or_cint_operand (); -extern int got_operand (); -extern int got_no_const_operand (); -extern int num_insns_constant (); -extern int easy_fp_constant (); -extern int volatile_mem_operand (); -extern int offsettable_mem_operand (); -extern int mem_or_easy_const_operand (); -extern int add_operand (); -extern int non_add_cint_operand (); -extern int non_logical_cint_operand (); -extern int logical_operand (); -extern int mask_operand (); -extern int mask64_operand (); -extern int and64_operand (); -extern int and_operand (); -extern int count_register_operand (); -extern int fpmem_operand (); -extern int reg_or_mem_operand (); -extern int lwa_operand (); -extern int call_operand (); -extern int current_file_function_operand (); -extern int input_operand (); -extern int small_data_operand (); -extern void init_cumulative_args (); -extern void function_arg_advance (); -extern int function_arg_boundary (); -extern struct rtx_def *function_arg (); -extern int function_arg_partial_nregs (); -extern int function_arg_pass_by_reference (); -extern void setup_incoming_varargs (); -extern union tree_node *rs6000_build_va_list (); -extern void rs6000_va_start (); -extern struct rtx_def *rs6000_va_arg (); -extern struct rtx_def *rs6000_stack_temp (); -extern int expand_block_move (); -extern int load_multiple_operation (); -extern int store_multiple_operation (); -extern int branch_comparison_operator (); -extern int scc_comparison_operator (); -extern int trap_comparison_operator (); -extern int includes_lshift_p (); -extern int includes_rshift_p (); -extern int registers_ok_for_quad_peep (); -extern int addrs_ok_for_quad_peep (); -extern enum reg_class secondary_reload_class (); -extern int ccr_bit (); -extern void rs6000_finalize_pic (); -extern void rs6000_reorg (); -extern void rs6000_save_machine_status (); -extern void rs6000_restore_machine_status (); -extern void rs6000_init_expanders (); -extern void print_operand (); -extern void print_operand_address (); -extern int first_reg_to_save (); -extern int first_fp_reg_to_save (); -extern int rs6000_makes_calls (); -extern rs6000_stack_t *rs6000_stack_info (); -extern void output_prolog (); -extern void output_epilog (); -extern void output_mi_thunk (); -extern void output_toc (); -extern void output_ascii (); -extern void rs6000_gen_section_name (); -extern void output_function_profiler (); -extern int rs6000_adjust_cost (); -extern int rs6000_adjust_priority (); -extern void rs6000_trampoline_template (); -extern int rs6000_trampoline_size (); -extern void rs6000_initialize_trampoline (); -extern void rs6000_output_load_toc_table (); -extern int rs6000_comp_type_attributes (); -extern int rs6000_valid_decl_attribute_p (); -extern int rs6000_valid_type_attribute_p (); -extern void rs6000_set_default_type_attributes (); -extern struct rtx_def *rs6000_dll_import_ref (); -extern struct rtx_def *rs6000_longcall_ref (); -extern int function_arg_padding (); -extern void toc_section (); -extern void private_data_section (); -extern void rs6000_fatal_bad_address (); - -/* See nonlocal_goto_receiver for when this must be set. */ - -#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_TOC && TARGET_MINIMAL_TOC) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 5620eb443bf..2e237780c6a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,6 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 -;; Free Software Foundation, Inc. +;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, +;; 1999, 2000 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -21,6 +21,19 @@ ;; Boston, MA 02111-1307, USA. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. + +;; `unspec' values used in rs6000.md: +;; Number Use +;; 0 frsp for POWER machines +;; 0/v blockage +;; 5 used to tie the stack contents and the stack pointer +;; 6 address of a word pointing to the TOC +;; 7 address of the TOC (more-or-less) +;; 8 movsi_got +;; 9/v eh_reg_restore +;; 10 fctiwz +;; 19 movesi_from_cr +;; 20 movesi_to_cr ;; Define an insn type attribute. This is used in function unit delay ;; computations. @@ -521,23 +534,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "rldicl. %2,%1,0,56" - [(set_attr "type" "compare")]) + "@ + rldicl. %2,%1,0,56 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (zero_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "rldicl. %0,%1,0,56" - [(set_attr "type" "compare")]) + "@ + rldicl. %0,%1,0,56 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "extendqidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -546,23 +592,56 @@ "extsb %0,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "extsb. %2,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (sign_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "extsb. %0,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (sign_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (sign_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "zero_extendhidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -580,23 +659,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "rldicl. %2,%1,0,48" - [(set_attr "type" "compare")]) + "@ + rldicl. %2,%1,0,48 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (zero_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "rldicl. %0,%1,0,48" - [(set_attr "type" "compare")]) + "@ + rldicl. %0,%1,0,48 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendhidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -614,23 +726,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "extsh. %2,%1" - [(set_attr "type" "compare")]) + "@ + extsh. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (sign_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "extsh. %0,%1" - [(set_attr "type" "compare")]) + "@ + extsh. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (sign_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (sign_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "zero_extendsidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -648,23 +793,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "rldicl. %2,%1,0,32" - [(set_attr "type" "compare")]) + "@ + rldicl. %2,%1,0,32 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (zero_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "rldicl. %0,%1,0,32" - [(set_attr "type" "compare")]) + "@ + rldicl. %0,%1,0,32 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendsidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -682,23 +860,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "extsw. %2,%1" - [(set_attr "type" "compare")]) + "@ + extsw. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (sign_extend:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64" - "extsw. %0,%1" - [(set_attr "type" "compare")]) + "@ + extsw. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (sign_extend:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (sign_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -716,23 +927,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r"))] + (clobber (match_scratch:SI 2 "=r,r"))] "" - "{andil.|andi.} %2,%1,0xff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %2,%1,0xff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 2 ""))] + "reload_completed" + [(set (match_dup 2) + (zero_extend:SI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_dup 1)))] "" - "{andil.|andi.} %0,%1,0xff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %0,%1,0xff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (match_dup 1)))] + "reload_completed" + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendqisi2" [(use (match_operand:SI 0 "gpc_reg_operand" "")) @@ -756,23 +1000,56 @@ "extsb %0,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r"))] + (clobber (match_scratch:SI 2 "=r,r"))] "TARGET_POWERPC" - "extsb. %2,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 2 ""))] + "TARGET_POWERPC && reload_completed" + [(set (match_dup 2) + (sign_extend:SI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (sign_extend:SI (match_dup 1)))] "TARGET_POWERPC" - "extsb. %0,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (sign_extend:SI (match_dup 1)))] + "TARGET_POWERPC && reload_completed" + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendqisi2_power" [(parallel [(set (match_dup 2) @@ -816,23 +1093,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:HI 2 "=r"))] + (clobber (match_scratch:HI 2 "=r,r"))] "" - "{andil.|andi.} %2,%1,0xff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %2,%1,0xff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:HI 2 ""))] + "reload_completed" + [(set (match_dup 2) + (zero_extend:HI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r") + (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") (zero_extend:HI (match_dup 1)))] "" - "{andil.|andi.} %0,%1,0xff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %0,%1,0xff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:HI 0 "gpc_reg_operand" "") + (zero_extend:HI (match_dup 1)))] + "reload_completed" + [(set (match_dup 0) + (zero_extend:HI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendqihi2" [(use (match_operand:HI 0 "gpc_reg_operand" "")) @@ -856,23 +1166,56 @@ "extsb %0,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:HI 2 "=r"))] + (clobber (match_scratch:HI 2 "=r,r"))] "TARGET_POWERPC" - "extsb. %2,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:HI 2 ""))] + "TARGET_POWERPC && reload_completed" + [(set (match_dup 2) + (sign_extend:HI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r") + (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") (sign_extend:HI (match_dup 1)))] "TARGET_POWERPC" - "extsb. %0,%1" - [(set_attr "type" "compare")]) + "@ + extsb. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:HI 0 "gpc_reg_operand" "") + (sign_extend:HI (match_dup 1)))] + "TARGET_POWERPC && reload_completed" + [(set (match_dup 0) + (sign_extend:HI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendqihi2_power" [(parallel [(set (match_dup 2) @@ -918,23 +1261,56 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r"))] + (clobber (match_scratch:SI 2 "=r,r"))] "" - "{andil.|andi.} %2,%1,0xffff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %2,%1,0xffff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 2 ""))] + "reload_completed" + [(set (match_dup 2) + (zero_extend:SI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_dup 1)))] "" - "{andil.|andi.} %0,%1,0xffff" - [(set_attr "type" "compare")]) + "@ + {andil.|andi.} %0,%1,0xffff + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (match_dup 1)))] + "reload_completed" + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "extendhisi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -952,24 +1328,57 @@ [(set_attr "type" "load,*")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r"))] + (clobber (match_scratch:SI 2 "=r,r"))] "" - "{exts.|extsh.} %2,%1" - [(set_attr "type" "compare")]) + "@ + {exts.|extsh.} %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 2 ""))] + "reload_completed" + [(set (match_dup 2) + (sign_extend:SI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (sign_extend:SI (match_dup 1)))] "" - "{exts.|extsh.} %0,%1" - [(set_attr "type" "compare")]) + "@ + {exts.|extsh.} %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (sign_extend:SI (match_dup 1)))] + "reload_completed" + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + ;; Fixed-point arithmetic insns. ;; Discourage ai/addic because of carry but provide it in an alternative @@ -993,6 +1402,9 @@ if (low & 0x8000) high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16; + /* The ordering here is important for the prolog expander. + When space is allocated from the stack, adding 'low' first may + produce a temporary deallocation (which would be bad). */ emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (high))); emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low))); DONE; @@ -1374,33 +1786,80 @@ "doz%I2 %0,%1,%2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_POWER" - "doz%I2. %3,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + doz%I2. %3,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0) + (minus:SI (match_dup 2) (match_dup 1))) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "TARGET_POWER && reload_completed" + [(set (match_dup 3) + (if_then_else:SI (gt (match_dup 1) (match_dup 2)) + (const_int 0) + (minus:SI (match_dup 2) (match_dup 1)))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (if_then_else:SI (gt (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] "TARGET_POWER" - "doz%I2. %0,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + doz%I2. %0,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0) + (minus:SI (match_dup 2) (match_dup 1))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (if_then_else:SI (gt (match_dup 1) (match_dup 2)) + (const_int 0) + (minus:SI (match_dup 2) (match_dup 1))))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (if_then_else:SI (gt (match_dup 1) (match_dup 2)) + (const_int 0) + (minus:SI (match_dup 2) (match_dup 1)))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; We don't need abs with condition code because such comparisons should ;; never be done. @@ -1482,23 +1941,56 @@ "neg %0,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r"))] + (clobber (match_scratch:SI 2 "=r,r"))] "! TARGET_POWERPC64" - "neg. %2,%1" - [(set_attr "type" "compare")]) + "@ + neg. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 2 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (neg:SI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (neg:SI (match_dup 1)))] "! TARGET_POWERPC64" - "neg. %0,%1" - [(set_attr "type" "compare")]) + "@ + neg. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (neg:SI (match_dup 1)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (neg:SI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "ffssi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") @@ -1543,48 +2035,122 @@ [(set_attr "type" "imul")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r")) - (clobber (match_scratch:SI 4 "=q"))] + (clobber (match_scratch:SI 3 "=r,r")) + (clobber (match_scratch:SI 4 "=q,q"))] "TARGET_POWER" - "{muls.|mullw.} %3,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + {muls.|mullw.} %3,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 3) + (mult:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWER" - "{muls.|mullw.} %3,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + {muls.|mullw.} %3,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWER && reload_completed" + [(set (match_dup 3) + (mult:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q"))] + (clobber (match_scratch:SI 4 "=q,q"))] "TARGET_POWER" - "{muls.|mullw.} %0,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + {muls.|mullw.} %0,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (mult:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (mult:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER" - "{muls.|mullw.} %0,%1,%2" - [(set_attr "type" "delayed_compare")]) + "@ + {muls.|mullw.} %0,%1,%2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (mult:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWER && reload_completed" + [(set (match_dup 0) + (mult:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; Operand 1 is divided by operand 2; quotient goes to operand ;; 0 and remainder to operand 3. @@ -1748,27 +2314,60 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "N")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "N,N")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "exact_log2 (INTVAL (operands[2])) >= 0" - "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3" + "@ + {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed" + [(set (match_dup 3) + (div:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "N")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "N,N")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (div:SI (match_dup 1) (match_dup 2)))] "exact_log2 (INTVAL (operands[2])) >= 0" - "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0" + "@ + {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (div:SI (match_dup 1) (match_dup 2)))] + "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed" + [(set (match_dup 0) + (div:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1951,8 +2550,7 @@ and %0,%1,%2 {rlinm|rlwinm} %0,%1,0,%m2,%M2 {andil.|andi.} %0,%1,%b2 - {andiu.|andis.} %0,%1,%u2" - [(set_attr "length" "4")]) + {andiu.|andis.} %0,%1,%u2") ;; Note to set cr's other than cr0 we do the and immediate and then ;; the test again -- this avoids a mcrf which on the higher end @@ -2623,65 +3221,157 @@ "maskir %0,%3,%2") (define_insn "*maskir_internal5" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) - (match_operand:SI 1 "gpc_reg_operand" "0")) + (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (match_operand:SI 1 "gpc_reg_operand" "0,0")) (and:SI (match_dup 2) - (match_operand:SI 3 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3))))] "TARGET_POWER" - "maskir. %0,%3,%2" - [(set_attr "type" "compare")]) + "@ + maskir. %0,%3,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) + (match_operand:SI 1 "gpc_reg_operand" "")) + (and:SI (match_dup 2) + (match_operand:SI 3 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) + (and:SI (match_dup 2) (match_dup 3))))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) + (and:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*maskir_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) - (match_operand:SI 1 "gpc_reg_operand" "0")) - (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") + (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (match_operand:SI 1 "gpc_reg_operand" "0,0")) + (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") (match_dup 2))) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2))))] "TARGET_POWER" - "maskir. %0,%3,%2" - [(set_attr "type" "compare")]) + "@ + maskir. %0,%3,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) + (match_operand:SI 1 "gpc_reg_operand" "")) + (and:SI (match_operand:SI 3 "gpc_reg_operand" "") + (match_dup 2))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) + (and:SI (match_dup 3) (match_dup 2))))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) + (and:SI (match_dup 3) (match_dup 2)))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*maskir_internal7" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand:SI 3 "gpc_reg_operand" "r")) + (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r,r") + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0"))) + (match_operand:SI 1 "gpc_reg_operand" "0,0"))) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER" - "maskir. %0,%3,%2" - [(set_attr "type" "compare")]) + "@ + maskir. %0,%3,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "") + (match_operand:SI 3 "gpc_reg_operand" "")) + (and:SI (not:SI (match_dup 2)) + (match_operand:SI 1 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ior:SI (and:SI (match_dup 2) (match_dup 3)) + (and:SI (not:SI (match_dup 2)) (match_dup 1))))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ior:SI (and:SI (match_dup 2) (match_dup 3)) + (and:SI (not:SI (match_dup 2)) (match_dup 1)))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*maskir_internal8" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")) + (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (and:SI (not:SI (match_dup 2)) - (match_operand:SI 1 "gpc_reg_operand" "0"))) + (match_operand:SI 1 "gpc_reg_operand" "0,0"))) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER" - "maskir. %0,%3,%2" - [(set_attr "type" "compare")]) + "@ + maskir. %0,%3,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (and:SI (not:SI (match_dup 2)) + (match_operand:SI 1 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ior:SI (and:SI (match_dup 3) (match_dup 2)) + (and:SI (not:SI (match_dup 2)) (match_dup 1))))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ior:SI (and:SI (match_dup 3) (match_dup 2)) + (and:SI (not:SI (match_dup 2)) (match_dup 1)))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" @@ -2853,18 +3543,22 @@ }") (define_insn "*extzvsi_internal1" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i") + (match_operand:SI 3 "const_int_operand" "i,i")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r"))] + (clobber (match_scratch:SI 4 "=r,r"))] "! TARGET_POWERPC64" "* { int start = INTVAL (operands[3]) & 31; int size = INTVAL (operands[2]) & 31; + /* Force split for non-cc0 compare. */ + if (which_alternative == 1) + return \"#\"; + /* If the bitfield being tested fits in the upper or lower half of a word, it is possible to use andiu. or andil. to test it. This is useful because the condition register set-use delay is smaller for @@ -2887,15 +3581,32 @@ operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\"; }" - [(set_attr "type" "compare")]) + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (zero_extract:SI (match_dup 1) (match_dup 2) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "*extzvsi_internal2" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")) + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i") + (match_operand:SI 3 "const_int_operand" "i,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] "! TARGET_POWERPC64" "* @@ -2903,6 +3614,10 @@ int start = INTVAL (operands[3]) & 31; int size = INTVAL (operands[2]) & 31; + /* Force split for non-cc0 compare. */ + if (which_alternative == 1) + return \"#\"; + if (start >= 16 && start + size == 32) { operands[3] = GEN_INT ((1 << (32 - start)) - 1); @@ -2915,7 +3630,24 @@ operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\"; }" - [(set_attr "type" "delayed_compare")]) + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "extzvdi" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -2987,25 +3719,60 @@ "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") (define_insn "*rotlsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWERPC64" - "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (rotate:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (rotate:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC64" - "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (rotate:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (rotate:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal4" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3016,29 +3783,70 @@ "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") (define_insn "*rotlsi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) - (match_operand:SI 3 "mask_operand" "T")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r"))] + (clobber (match_scratch:SI 4 "=r,r"))] "! TARGET_POWERPC64" - "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (and:SI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (and:SI (rotate:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) - (match_operand:SI 3 "mask_operand" "T")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "! TARGET_POWERPC64" - "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC (and:SI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal7" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3050,29 +3858,70 @@ "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff") (define_insn "*rotlsi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "" - "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI + (subreg:QI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "reload_completed" + [(set (match_dup 3) + (zero_extend:SI (subreg:QI + (rotate:SI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" - "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI + (subreg:QI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] + "reload_completed" + [(set (match_dup 0) + (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal10" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3084,29 +3933,70 @@ "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") (define_insn "*rotlsi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "" - "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI + (subreg:HI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "reload_completed" + [(set (match_dup 3) + (zero_extend:SI (subreg:HI + (rotate:SI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotlsi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" - "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:SI + (subreg:HI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] + "reload_completed" + [(set (match_dup 0) + (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; Note that we use "sle." instead of "sl." so that we can set ;; SHIFT_COUNT_TRUNCATED. @@ -3133,64 +4023,136 @@ "TARGET_POWER" "@ sle %0,%1,%2 - {sli|slwi} %0,%1,%h2" - [(set_attr "length" "8")]) + {sli|slwi} %0,%1,%h2") (define_insn "ashlsi3_no_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "! TARGET_POWER" - "{sl|slw}%I2 %0,%1,%h2" - [(set_attr "length" "8")]) + "{sl|slw}%I2 %0,%1,%h2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r")) - (clobber (match_scratch:SI 4 "=q,X"))] + (clobber (match_scratch:SI 3 "=r,r,r,r")) + (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ sle. %3,%1,%2 - {sli.|slwi.} %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {sli.|slwi.} %3,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 3) + (ashift:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWER && ! TARGET_POWERPC64" - "{sl|slw}%I2. %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + "@ + {sl|slw}%I2. %3,%1,%h2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ashift:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (ashift:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X"))] + (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ sle. %0,%1,%2 - {sli.|slwi.} %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {sli.|slwi.} %0,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ashift:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (ashift:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashift:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER && ! TARGET_POWERPC64" - "{sl|slw}%I2. %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + "@ + {sl|slw}%I2. %0,%1,%h2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ashift:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ashift:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3201,29 +4163,69 @@ "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")) + (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r"))] + (clobber (match_scratch:SI 4 "=r,r"))] "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" - "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + [(set (match_dup 4) + (and:SI (ashift:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")) + (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" - "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + [(set (match_dup 0) + (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; The AIX assembler mis-handles "sri x,x,0", so write that case as ;; "sli x,x,0". @@ -3262,58 +4264,134 @@ {sr|srw}%I2 %0,%1,%h2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,X,r")) - (clobber (match_scratch:SI 4 "=q,X,X"))] + (clobber (match_scratch:SI 3 "=r,X,r,r,X,r")) + (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))] "TARGET_POWER" "@ sre. %3,%1,%2 mr. %1,%1 - {s%A2i.|s%A2wi.} %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {s%A2i.|s%A2wi.} %3,%1,%h2 + # + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,4,8,8,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 3) + (lshiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) (const_int 0))) - (clobber (match_scratch:SI 3 "=X,r"))] + (clobber (match_scratch:SI 3 "=X,r,X,r"))] "! TARGET_POWER && ! TARGET_POWERPC64" "@ mr. %1,%1 - {sr|srw}%I2. %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {sr|srw}%I2. %3,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")) +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (lshiftrt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") + +(define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r") (lshiftrt:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X,X"))] + (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))] "TARGET_POWER" "@ sre. %0,%1,%2 mr. %0,%1 - {s%A2i.|s%A2wi.} %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {s%A2i.|s%A2wi.} %0,%1,%h2 + # + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,4,8,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (lshiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (lshiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (lshiftrt:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER && ! TARGET_POWERPC64" "@ mr. %0,%1 - {sr|srw}%I2. %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {sr|srw}%I2. %0,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (lshiftrt:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (lshiftrt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3324,29 +4402,69 @@ "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")) + (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r"))] + (clobber (match_scratch:SI 4 "=r,r"))] "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" - "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + [(set (match_dup 4) + (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")) + (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:SI 3 "mask_operand" "T,T")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" - "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:SI 3 "mask_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + [(set (match_dup 0) + (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3358,31 +4476,74 @@ "{rlinm|rlwinm} %0,%1,%s2,0xff") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)) + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "includes_rshift_p (operands[2], GEN_INT (255))" - "{rlinm.|rlwinm.} %3,%1,%s2,0xff" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %3,%1,%s2,0xff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (zero_extend:SI + (subreg:QI + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed" + [(set (match_dup 3) + (zero_extend:SI (subreg:QI + (lshiftrt:SI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)) + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], GEN_INT (255))" - "{rlinm.|rlwinm.} %0,%1,%s2,0xff" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %0,%1,%s2,0xff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (zero_extend:SI + (subreg:QI + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] + "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed" + [(set (match_dup 0) + (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3394,31 +4555,74 @@ "{rlinm|rlwinm} %0,%1,%s2,0xffff") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)) + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "includes_rshift_p (operands[2], GEN_INT (65535))" - "{rlinm.|rlwinm.} %3,%1,%s2,0xffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %3,%1,%s2,0xffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (zero_extend:SI + (subreg:HI + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed" + [(set (match_dup 3) + (zero_extend:SI (subreg:HI + (lshiftrt:SI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)) + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], GEN_INT (65535))" - "{rlinm.|rlwinm.} %0,%1,%s2,0xffff" - [(set_attr "type" "delayed_compare")]) + "@ + {rlinm.|rlwinm.} %0,%1,%s2,0xffff + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (zero_extend:SI + (subreg:HI + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] + "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed" + [(set (match_dup 0) + (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3480,53 +4684,127 @@ "{sra|sraw}%I2 %0,%1,%h2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r")) - (clobber (match_scratch:SI 4 "=q,X"))] + (clobber (match_scratch:SI 3 "=r,r,r,r")) + (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ srea. %3,%1,%2 - {srai.|srawi.} %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {srai.|srawi.} %3,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 3) + (ashiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWER" - "{sra|sraw}%I2. %3,%1,%h2" - [(set_attr "type" "delayed_compare")]) + "@ + {sra|sraw}%I2. %3,%1,%h2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWER && reload_completed" + [(set (match_dup 3) + (ashiftrt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (ashiftrt:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 4 "=q,X"))] + (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ srea. %0,%1,%2 - {srai.|srawi.} %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + {srai.|srawi.} %0,%1,%h2 + # + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ashiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashiftrt:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER" - "{sra|sraw}%I2. %0,%1,%h2" - [(set_attr "type" "delayed_compare")]) + "@ + {sra|sraw}%I2. %0,%1,%h2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ashiftrt:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + ;; Floating-point insns, excluding normal data motion. ;; ;; PowerPC has a full set of single-precision floating point instructions. @@ -4174,6 +5452,11 @@ ;; Conversions to and from floating-point. +; For each of these conversions, there is a define_expand, a define_insn +; with a '#' template, and a define_split (with C code). The idea is +; to allow constant folding with the template of the define_insn, +; then to have the insns split later (between sched1 and final). + (define_expand "floatsidf2" [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) @@ -4181,14 +5464,15 @@ (use (match_dup 3)) (clobber (match_dup 4)) (clobber (match_dup 5)) - (clobber (reg:DF 76))])] + (clobber (match_dup 6))])] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" " { operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode)); - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (Pmode); + operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); + operands[5] = gen_reg_rtx (DFmode); + operands[6] = gen_reg_rtx (SImode); }") (define_insn "*floatsidf2_internal" @@ -4196,9 +5480,9 @@ (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) - (clobber (match_operand 5 "gpc_reg_operand" "=b")) - (clobber (reg:DF 76))] + (clobber (match_operand:DF 4 "memory_operand" "=o")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "=f")) + (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "#" [(set_attr "length" "24")]) @@ -4208,32 +5492,37 @@ (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "")) - (clobber (match_operand 5 "gpc_reg_operand" "")) - (clobber (reg:DF 76))] + (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "")) + (clobber (match_operand:SI 6 "gpc_reg_operand" ""))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" - [(set (match_dup 4) - (xor:SI (match_dup 1) - (match_dup 6))) - (set (match_dup 5) - (unspec [(const_int 0)] 11)) - (set (match_dup 7) - (unspec [(match_dup 4) - (match_dup 5)] 12)) ;; low word - (set (match_dup 7) - (unspec [(match_dup 2) - (match_dup 5) - (match_dup 7)] 13)) ;; high word - (set (match_dup 0) - (unspec [(match_dup 7) - (match_dup 5)] 14)) - (set (match_dup 0) - (minus:DF (match_dup 0) - (match_dup 3)))] + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) + (use (match_operand:SI 2 "gpc_reg_operand" "")) + (use (match_operand:DF 3 "gpc_reg_operand" "")) + (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "")) + (clobber (match_operand:SI 6 "gpc_reg_operand" ""))] " { - operands[6] = GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff); - operands[7] = gen_rtx_REG (DFmode, FPMEM_REGNUM); + rtx lowword, highword; + if (GET_CODE (operands[4]) != MEM) + abort(); + highword = XEXP (operands[4], 0); + lowword = plus_constant (highword, 4); + if (! WORDS_BIG_ENDIAN) + { + rtx tmp; + tmp = highword; highword = lowword; lowword = tmp; + } + + emit_insn (gen_xorsi3 (operands[6], operands[1], + GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); + emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[6]); + emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]); + emit_move_insn (operands[5], operands[4]); + emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); + DONE; }") (define_expand "floatunssidf2" @@ -4242,13 +5531,14 @@ (use (match_dup 2)) (use (match_dup 3)) (clobber (match_dup 4)) - (clobber (reg:DF 76))])] + (clobber (match_dup 5))])] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" " { operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode)); - operands[4] = gen_reg_rtx (Pmode); + operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); + operands[5] = gen_reg_rtx (DFmode); }") (define_insn "*floatunssidf2_internal" @@ -4256,8 +5546,8 @@ (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (clobber (match_operand 4 "gpc_reg_operand" "=b")) - (clobber (reg:DF 76))] + (clobber (match_operand:DF 4 "memory_operand" "=o")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "#" [(set_attr "length" "20")]) @@ -4267,134 +5557,40 @@ (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand 4 "gpc_reg_operand" "")) - (clobber (reg:DF 76))] + (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) + (clobber (match_operand:DF 5 "gpc_reg_operand" ""))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" - [(set (match_dup 4) - (unspec [(const_int 0)] 11)) - (set (match_dup 5) - (unspec [(match_dup 1) - (match_dup 4)] 12)) ;; low word - (set (match_dup 5) - (unspec [(match_dup 2) - (match_dup 4) - (match_dup 5)] 13)) ;; high word - (set (match_dup 0) - (unspec [(match_dup 5) - (match_dup 4)] 14)) - (set (match_dup 0) - (minus:DF (match_dup 0) - (match_dup 3)))] - "operands[5] = gen_rtx_REG (DFmode, FPMEM_REGNUM);") - -;; Load up scratch register with base address + offset if needed -(define_insn "*floatsidf2_loadaddr" - [(set (match_operand 0 "gpc_reg_operand" "=b") - (unspec [(const_int 0)] 11))] - "TARGET_HARD_FLOAT" - "* -{ - if (rs6000_fpmem_offset > 32760) - { - rtx xop[3]; - - xop[0] = operands[0]; - xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx; - xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15)); - output_asm_insn (\"{cau|addis} %0,%1,%2\", xop); - } - - return \"\"; -}" - [(set_attr "length" "4")]) - -(define_insn "*floatsidf2_store1" - [(set (reg:DF 76) - (unspec [(match_operand:SI 0 "gpc_reg_operand" "r") - (match_operand 1 "gpc_reg_operand" "b")] 12))] - "TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] - = gen_rtx_MEM (SImode, - plus_constant (indx, - (((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - - 0x8000) - + ((WORDS_BIG_ENDIAN != 0) * 4))); - - return \"{st|stw} %0,%2\"; -}" - [(set_attr "type" "store")]) - -(define_insn "*floatsidf2_store2" - [(set (reg:DF 76) - (unspec [(match_operand:SI 0 "gpc_reg_operand" "r") - (match_operand 1 "gpc_reg_operand" "b") - (reg:DF 76)] 13))] - "TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] - = gen_rtx_MEM (SImode, - plus_constant (indx, - (((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - - 0x8000) - + ((WORDS_BIG_ENDIAN == 0) * 4))); - - return \"{st|stw} %0,%2\"; -}" - [(set_attr "type" "store")]) - -(define_insn "*floatsidf2_load" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec [(reg:DF 76) - (match_operand 1 "gpc_reg_operand" "b")] 14))] - "TARGET_HARD_FLOAT" - "* + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) + (use (match_operand:SI 2 "gpc_reg_operand" "")) + (use (match_operand:DF 3 "gpc_reg_operand" "")) + (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) + (clobber (match_operand:DF 5 "gpc_reg_operand" ""))] + " { - rtx indx; - HOST_WIDE_INT offset = rs6000_fpmem_offset; - - if (rs6000_fpmem_offset > 32760) + rtx lowword, highword; + if (GET_CODE (operands[4]) != MEM) + abort(); + highword = XEXP (operands[4], 0); + lowword = plus_constant (highword, 4); + if (! WORDS_BIG_ENDIAN) { - indx = operands[1]; - offset = (((offset & 0xffff) ^ 0x8000) - 0x8000); + rtx tmp; + tmp = highword; highword = lowword; lowword = tmp; } - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (SImode, plus_constant (indx, offset)); - return \"lfd %0,%2\"; -}" - [(set_attr "type" "fpload")]) + emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[1]); + emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]); + emit_move_insn (operands[5], operands[4]); + emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); + DONE; +}") (define_expand "fix_truncdfsi2" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4))])] + (clobber (match_dup 3))])] "TARGET_HARD_FLOAT" " { @@ -4406,91 +5602,42 @@ } operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_reg_rtx (Pmode); - operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM); + operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); }") (define_insn "*fix_truncdfsi2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) - (clobber (match_operand 3 "gpc_reg_operand" "=b")) - (clobber (reg:DI 76))] + (clobber (match_operand:DI 3 "memory_operand" "=o"))] "TARGET_HARD_FLOAT" "#" - [(set_attr "length" "12")]) + [(set_attr "length" "16")]) (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand 3 "gpc_reg_operand" "")) - (clobber (reg:DI 76))] + (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] "TARGET_HARD_FLOAT" - [(clobber (match_dup 2)) - (set (subreg:SI (match_dup 2) 0) - (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) - (set (match_dup 3) - (unspec [(const_int 0)] 11)) - (set (match_dup 4) - (unspec [(match_dup 2) - (match_dup 3)] 15)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec [(match_dup 4) - (match_dup 3)] 16))] - "operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM);") - -(define_insn "*fix_truncdfsi2_store" - [(set (reg:DI 76) - (unspec [(match_operand:DI 0 "gpc_reg_operand" "f") - (match_operand 1 "gpc_reg_operand" "b")] 15))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - "* -{ - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] = gen_rtx_MEM (DFmode, - plus_constant (indx, - (((rs6000_fpmem_offset & 0xffff) - ^ 0x8000) - 0x8000))); - - return \"stfd %0,%2\"; -}" - [(set_attr "type" "fpstore")]) - -(define_insn "*fix_truncdfsi2_load" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(reg:DI 76) - (match_operand 1 "gpc_reg_operand" "b")] 16))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - "* + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "")) + (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] + " { - rtx indx; - - if (rs6000_fpmem_offset > 32760) - indx = operands[1]; - else if (frame_pointer_needed) - indx = frame_pointer_rtx; - else - indx = stack_pointer_rtx; - - operands[2] - = gen_rtx_MEM (DFmode, - plus_constant (indx, - (((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - - 0x8000) - + ((WORDS_BIG_ENDIAN) ? 4 : 0))); + rtx lowword; + if (GET_CODE (operands[3]) != MEM) + abort(); + lowword = XEXP (operands[3], 0); + if (WORDS_BIG_ENDIAN) + lowword = plus_constant (lowword, 4); - return \"{l|lwz} %0,%2\"; -}" - [(set_attr "type" "load")]) + emit_insn (gen_fctiwz (operands[2], operands[1])); + emit_move_insn (operands[3], operands[2]); + emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword)); + DONE; +}") (define_expand "fixuns_truncdfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -4537,9 +5684,13 @@ rs6000_trunc_used = 1; }") -(define_insn "*fctiwz" - [(set (subreg:SI (match_operand:DI 0 "gpc_reg_operand" "=f") 0) - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))] +; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10)) +; rather than (set (subreg:SI (reg)) (fix:SI ...)) +; because the first makes it clear that operand 0 is not live +; before the instruction. +(define_insn "fctiwz" + [(set (match_operand:DI 0 "gpc_reg_operand" "=f") + (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) @@ -4933,29 +6084,64 @@ addis %0,%1,%v2") (define_insn "*adddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] + (clobber (match_scratch:DI 3 "=r,r,r,r"))] "TARGET_POWERPC64" "@ add. %3,%1,%2 - addic. %3,%1,%2" - [(set_attr "type" "compare")]) + addic. %3,%1,%2 + # + #" + [(set_attr "type" "compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (plus:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*adddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" "@ add. %0,%1,%2 - addic. %0,%1,%2" - [(set_attr "type" "compare")]) + addic. %0,%1,%2 + # + #" + [(set_attr "type" "compare") + (set_attr "length" "4,4,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (plus:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (plus:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; Split an add that we can't do in one insn into two insns, each of which ;; does one 16-bit part. This is used by combine. Note that the low-order @@ -4987,23 +6173,56 @@ "nor %0,%1,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "nor. %2,%1,%1" - [(set_attr "type" "compare")]) + "@ + nor. %2,%1,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (not:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (not:DI (match_dup 1)))] "TARGET_POWERPC64" - "nor. %0,%1,%1" - [(set_attr "type" "compare")]) + "@ + nor. %0,%1,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (not:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (not:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") @@ -5015,25 +6234,60 @@ subfic %0,%2,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "subf. %3,%2,%1" - [(set_attr "type" "compare")]) + "@ + subf. %3,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (minus:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (minus:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "subf. %0,%2,%1" - [(set_attr "type" "compare")]) + "@ + subf. %0,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (minus:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (minus:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "subdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -5099,23 +6353,56 @@ "neg %0,%1") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r"))] + (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_POWERPC64" - "neg. %2,%1" - [(set_attr "type" "compare")]) + "@ + neg. %2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 2 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 2) + (neg:DI (match_dup 1))) + (set (match_dup 0) + (compare:CC (match_dup 2) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (neg:DI (match_dup 1)))] "TARGET_POWERPC64" - "neg. %0,%1" - [(set_attr "type" "compare")]) + "@ + neg. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (neg:DI (match_dup 1)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (neg:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "ffsdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") @@ -5202,30 +6489,63 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "N")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "const_int_operand" "N,N")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0" - "sradi %3,%1,%p2\;addze. %3,%3" + "@ + sradi %3,%1,%p2\;addze. %3,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "const_int_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed" + [(set (match_dup 3) + (div:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "N")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "const_int_operand" "N,N")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (div:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0" - "sradi %0,%1,%p2\;addze. %0,%0" + "@ + sradi %0,%1,%p2\;addze. %0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "const_int_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (div:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed" + [(set (match_dup 0) + (div:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:DI 2 "gpc_reg_operand" "r")))] "TARGET_POWERPC64" @@ -5248,25 +6568,60 @@ "rld%I2cl %0,%1,%H2,0") (define_insn "*rotldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "rld%I2cl. %3,%1,%H2,0" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %3,%1,%H2,0 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (rotate:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (rotate:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "rld%I2cl. %0,%1,%H2,0" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %0,%1,%H2,0 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (rotate:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (rotate:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5277,29 +6632,70 @@ "rld%I2c%B3 %0,%1,%H2,%S3") (define_insn "*rotldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (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")) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) + (match_operand:DI 3 "mask64_operand" "S,S")) (const_int 0))) - (clobber (match_scratch:DI 4 "=r"))] + (clobber (match_scratch:DI 4 "=r,r"))] "TARGET_POWERPC64" - "rld%I2c%B3. %4,%1,%H2,%S3" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2c%B3. %4,%1,%H2,%S3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (and:DI (rotate:DI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "*rotldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (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")) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) + (match_operand:DI 3 "mask64_operand" "S,S")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] "TARGET_POWERPC64" - "rld%I2c%B3. %0,%1,%H2,%S3" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2c%B3. %0,%1,%H2,%S3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotldi3_internal7" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5311,29 +6707,70 @@ "rld%I2cl %0,%1,%H2,56") (define_insn "*rotldi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "rld%I2cl. %3,%1,%H2,56" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %3,%1,%H2,56 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:QI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotldi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64" - "rld%I2cl. %0,%1,%H2,56" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %0,%1,%H2,56 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotldi3_internal10" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5345,29 +6782,70 @@ "rld%I2cl %0,%1,%H2,48") (define_insn "*rotldi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "rld%I2cl. %3,%1,%H2,48" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %3,%1,%H2,48 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:HI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotldi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64" - "rld%I2cl. %0,%1,%H2,48" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %0,%1,%H2,48 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*rotldi3_internal13" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5379,29 +6857,70 @@ "rld%I2cl %0,%1,%H2,32") (define_insn "*rotldi3_internal14" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "rld%I2cl. %3,%1,%H2,32" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %3,%1,%H2,32 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:SI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*rotldi3_internal15" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)) + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64" - "rld%I2cl. %0,%1,%H2,32" - [(set_attr "type" "delayed_compare")]) + "@ + rld%I2cl. %0,%1,%H2,32 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "ashldi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -5430,25 +6949,60 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "sld%I2. %3,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + sld%I2. %3,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ashift:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") + (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (ashift:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "sld%I2. %0,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + sld%I2. %0,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ashift:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ashift:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5460,33 +7014,77 @@ "rldic %0,%1,%H2,%S3") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "S")) + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "S,S")) (const_int 0))) - (clobber (match_scratch:DI 4 "=r"))] + (clobber (match_scratch:DI 4 "=r,r"))] "((GET_CODE (operands[3]) == CONST_INT ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1" - "rldic. %0,%1,%H2,%S3" - [(set_attr "type" "delayed_compare")]) + "@ + rldic. %0,%1,%H2,%S3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 4 ""))] + "((GET_CODE (operands[3]) == CONST_INT + ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1 + && reload_completed" + [(set (match_dup 4) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "S")) + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "S,S")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] "((GET_CODE (operands[3]) == CONST_INT ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1" - "rldic. %0,%1,%H2,%S3" - [(set_attr "type" "delayed_compare")]) - -(define_expand "lshrdi3" + "@ + rldic. %0,%1,%H2,%S3 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "((GET_CODE (operands[3]) == CONST_INT + ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1 + && reload_completed" + [(set (match_dup 0) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_expand "lshrdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")))] @@ -5512,25 +7110,60 @@ "srd%I2 %0,%1,%H2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "srd%I2. %3,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + srd%I2. %3,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (lshiftrt:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (lshiftrt:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "srd%I2. %0,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + srd%I2. %0,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (lshiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (lshiftrt:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "ashrdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -5558,25 +7191,60 @@ "srad%I2 %0,%1,%H2") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "srad%I2. %3,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + srad%I2. %3,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ashiftrt:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (ashiftrt:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "srad%I2. %0,%1,%H2" - [(set_attr "type" "delayed_compare")]) + "@ + srad%I2. %0,%1,%H2 + #" + [(set_attr "type" "delayed_compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ashiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ashiftrt:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "anddi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") @@ -5591,43 +7259,89 @@ andis. %0,%1,%u2") (define_insn "*anddi3_internal2" - [(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,r") - (match_operand:DI 2 "and64_operand" "r,K,J,S")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,") + (match_operand:DI 2 "and64_operand" "r,K,J,S,r,K,J,S")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] + (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r")) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] "TARGET_POWERPC64" "@ and. %3,%1,%2 andi. %3,%1,%b2 andis. %3,%1,%u2 - rldic%B2. %3,%1,0,%S2" - [(set_attr "type" "compare,compare,compare,delayed_compare")]) + rldic%B2. %3,%1,0,%S2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,delayed_compare") + (set_attr "length" "4,4,4,4,8,8,8,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "and64_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 "")) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 3) + (and:DI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*anddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_operand" "r,K,J,S")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:DI 2 "and64_operand" "r,K,J,S,r,K,J,S")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_dup 1) (match_dup 2)))] + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] "TARGET_POWERPC64" "@ and. %0,%1,%2 andi. %0,%1,%b2 andis. %0,%1,%u2 - rldic%B2. %0,%1,0,%S2" - [(set_attr "type" "compare,compare,compare,delayed_compare")]) + rldic%B2. %0,%1,0,%S2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,delayed_compare") + (set_attr "length" "4,4,4,4,8,8,8,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "and64_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_expand "iordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5638,12 +7352,26 @@ emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_iordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*iordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ or %0,%1,%2 @@ -5651,25 +7379,60 @@ oris %0,%1,%u2") (define_insn "*iordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "or. %3,%1,%2" - [(set_attr "type" "compare")]) + "@ + or. %3,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ior:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*iordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (ior:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "or. %0,%1,%2" - [(set_attr "type" "compare")]) + "@ + or. %0,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ior:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ior:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; Split an IOR that we can't do in one insn into two insns, each of which ;; does one 16-bit part. This is used by combine. @@ -5677,25 +7440,36 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_expand "xordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5706,12 +7480,26 @@ emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_xordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*xordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ xor %0,%1,%2 @@ -5719,25 +7507,60 @@ xoris %0,%1,%u2") (define_insn "*xordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "xor. %3,%1,%2" - [(set_attr "type" "compare")]) + "@ + xor. %3,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (xor:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*xordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (xor:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "xor. %0,%1,%2" - [(set_attr "type" "compare")]) + "@ + xor. %0,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (xor:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (xor:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; Split an XOR that we can't do in one insn into two insns, each of which ;; does one 16-bit part. This is used by combine. @@ -5745,14 +7568,25 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_insn "*eqvdi3_internal1" @@ -5763,53 +7597,123 @@ "eqv %0,%1,%2") (define_insn "*eqvdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "eqv. %3,%1,%2" - [(set_attr "type" "compare")]) + "@ + eqv. %3,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (not:DI (xor:DI (match_dup 1) (match_dup 2)))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*eqvdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (not:DI (xor:DI (match_dup 1) (match_dup 2))))] "TARGET_POWERPC64" - "eqv. %0,%1,%2" - [(set_attr "type" "compare")]) - -(define_insn "*andcdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + "@ + eqv. %0,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (not:DI (xor:DI (match_dup 1) (match_dup 2))))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (not:DI (xor:DI (match_dup 1) (match_dup 2)))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_insn "*andcdi3_internal1" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) (match_operand:DI 2 "gpc_reg_operand" "r")))] "TARGET_POWERPC64" "andc %0,%2,%1") (define_insn "*andcdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "andc. %3,%2,%1" - [(set_attr "type" "compare")]) + "@ + andc. %3,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (and:DI (not:DI (match_dup 1)) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*andcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (not:DI (match_dup 1)) (match_dup 2)))] "TARGET_POWERPC64" - "andc. %0,%2,%1" - [(set_attr "type" "compare")]) + "@ + andc. %0,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (not:DI (match_dup 1)) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (and:DI (not:DI (match_dup 1)) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*iorcdi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5819,25 +7723,60 @@ "orc %0,%2,%1") (define_insn "*iorcdi3_inernal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "orc. %3,%2,%1" - [(set_attr "type" "compare")]) + "@ + orc. %3,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ior:DI (not:DI (match_dup 1)) (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*iorcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (ior:DI (not:DI (match_dup 1)) (match_dup 2)))] "TARGET_POWERPC64" - "orc. %0,%2,%1" - [(set_attr "type" "compare")]) + "@ + orc. %0,%2,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ior:DI (not:DI (match_dup 1)) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ior:DI (not:DI (match_dup 1)) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*nanddi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5847,25 +7786,60 @@ "nand %0,%1,%2") (define_insn "*nanddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "nand. %3,%1,%2" - [(set_attr "type" "compare")]) + "@ + nand. %3,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2)))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*nanddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] "TARGET_POWERPC64" - "nand. %0,%1,%2" - [(set_attr "type" "compare")]) + "@ + nand. %0,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2)))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "*nordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -5875,51 +7849,88 @@ "nor %0,%1,%2") (define_insn "*nordi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (clobber (match_scratch:DI 3 "=r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" - "nor. %3,%1,%2" - [(set_attr "type" "compare")]) + "@ + nor. %3,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2)))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "*nordi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] "TARGET_POWERPC64" - "nor. %0,%1,%2" - [(set_attr "type" "compare")]) + "@ + nor. %0,%1,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2)))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + ;; Now define ways of moving data around. ;; Elf specific ways of loading addresses for non-PIC code. -;; The output of this could be r0, but we limit it to base -;; registers, since almost all uses of this will need it -;; in a base register shortly. +;; The output of this could be r0, but we make a very strong +;; preference for a base register because it will usually +;; be needed there. (define_insn "elf_high" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b") + [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") (high:SI (match_operand 1 "" "")))] "TARGET_ELF && ! TARGET_64BIT" "{liu|lis} %0,%1@ha") (define_insn "elf_low" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") (match_operand 2 "" "")))] "TARGET_ELF && ! TARGET_64BIT" - "{cal|la} %0,%2@l(%1)") + "@ + {cal|la} %0,%2@l(%1) + {ai|addic} %0,%1,%l2") ;; Set up a register with a value from the GOT table (define_expand "movsi_got" [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec [(match_operand:SI 1 "got_operand" "") - (match_dup 2)] 8))] + (unspec:SI [(match_operand:SI 1 "got_operand" "") + (match_dup 2)] 8))] "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1" " { @@ -5944,8 +7955,8 @@ (define_insn "*movsi_got_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "b")] 8))] + (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "b")] 8))] "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1" "{l|lwz} %0,%a1@got(%2)" [(set_attr "type" "load")]) @@ -5954,13 +7965,13 @@ ;; didn't get allocated to a hard register. (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "memory_operand" "m")] 8))] + (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") + (match_operand:SI 2 "memory_operand" "m")] 8))] "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1 && (reload_in_progress || reload_completed)" [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (unspec [(match_dup 1)(match_dup 0)] 8))] + (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 8))] "") ;; For SI, we special-case integers that can't be loaded in one insn. We @@ -5973,7 +7984,7 @@ "" " { - if (GET_CODE (operands[0]) != REG) + if (! no_new_pseudos && GET_CODE (operands[0]) != REG) operands[1] = force_reg (SImode, operands[1]); /* Convert a move of a CONST_DOUBLE into a CONST_INT */ @@ -6012,13 +8023,13 @@ { rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (SImode)); - /* If this is a function address on -mcall-aixdesc or -mcall-nt, + /* If this is a function address on -mcall-aixdesc, convert it to the address of the descriptor. */ - if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + if (DEFAULT_ABI == ABI_AIX && GET_CODE (operands[1]) == SYMBOL_REF && XSTR (operands[1], 0)[0] == '.') { - const char *name = XSTR (operands[1], 0); + char *name = XSTR (operands[1], 0); rtx new_ref; while (*name == '.') name++; @@ -6035,34 +8046,11 @@ DONE; } - if (GET_CODE (operands[1]) == CONST - && DEFAULT_ABI == ABI_NT - && ! side_effects_p (operands[0])) - { - rtx const_term = const0_rtx; - rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term); - if (sym && GET_CODE (const_term) == CONST_INT - && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF)) - { - unsigned HOST_WIDE_INT value = INTVAL (const_term); - int new_reg_p = (flag_expensive_optimizations && ! no_new_pseudos); - rtx tmp1 = ((new_reg_p && value != 0) - ? gen_reg_rtx (SImode) : operands[0]); - - emit_insn (gen_movsi (tmp1, sym)); - if (INTVAL (const_term) != 0) - emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value))); - DONE; - } - else - rs6000_fatal_bad_address (operands[1]); - } - - if ((! TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT) - && CONSTANT_P (operands[1]) + if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT && GET_CODE (operands[1]) != HIGH - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])) + && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) + && ! TOC_RELATIVE_EXPR_P (operands[1])) { /* Emit a USE operation so that the constant isn't deleted if expensive optimizations are turned on because nobody @@ -6093,6 +8081,17 @@ } operands[1] = force_const_mem (SImode, operands[1]); + + if (TARGET_TOC + && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant ( + XEXP (operands[1], 0)))) + { + XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0)); + MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); + RTX_UNCHANGING_P (operands[1]) = 1; + } + if (! memory_address_p (SImode, XEXP (operands[1], 0)) && ! reload_in_progress) operands[1] = change_address (operands[1], SImode, @@ -6141,21 +8140,36 @@ }") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r") (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] "! TARGET_POWERPC64" - "mr. %0,%1" - [(set_attr "type" "compare")]) + "@ + mr. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 1))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + (define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "any_operand" ""))] "" " { - if (GET_CODE (operands[0]) != REG) + if (! no_new_pseudos && GET_CODE (operands[0]) != REG) operands[1] = force_reg (HImode, operands[1]); if (CONSTANT_P (operands[1]) @@ -6191,7 +8205,7 @@ "" " { - if (GET_CODE (operands[0]) != REG) + if (! no_new_pseudos && GET_CODE (operands[0]) != REG) operands[1] = force_reg (QImode, operands[1]); if (CONSTANT_P (operands[1]) @@ -6635,7 +8649,7 @@ "" " { - if (GET_CODE (operands[0]) != REG) + if (! no_new_pseudos && GET_CODE (operands[0]) != REG) operands[1] = force_reg (DImode, operands[1]); /* Convert a move of a CONST_DOUBLE into a CONST_INT @@ -6663,7 +8677,8 @@ && GET_CODE (operands[1]) != CONST_INT #endif && ! easy_fp_constant (operands[1], DImode) - && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])) + && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) + && ! TOC_RELATIVE_EXPR_P (operands[1])) { /* Emit a USE operation so that the constant isn't deleted if expensive optimizations are turned on because nobody @@ -6694,11 +8709,27 @@ } operands[1] = force_const_mem (DImode, operands[1]); + if (TARGET_TOC && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))) + { + XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0)); + MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); + RTX_UNCHANGING_P (operands[1]) = 1; + } if (! memory_address_p (DImode, XEXP (operands[1], 0)) && ! reload_in_progress) operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0)); } + + if (TARGET_TOC + && GET_CODE (operands[1]) == MEM + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) + { + XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0)); + MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set (); + RTX_UNCHANGING_P (operands[1]) = 1; + } + }") (define_insn "*movdi_32" @@ -6906,7 +8937,11 @@ (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))] " -{ operands[2] = GEN_INT ((INTVAL (operands[1]) << 32) >> 32); }") +{ +#if HOST_BITS_PER_WIDE_INT != 32 +operands[2] = GEN_INT ((INTVAL (operands[1]) << 32) >> 32); +#endif +}") ;; 32-bit value in upper half of doubleword (define_split @@ -6928,14 +8963,18 @@ (match_operand:DI 1 "const_int_operand" ""))] "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64 && GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) & 0xffffffff == 0" + && (INTVAL (operands[1]) & 0xffffffff) == 0" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))] " -{ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); }") +{ +#if HOST_BITS_PER_WIDE_INT != 32 +operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); +#endif +}") ;; Generate all one-bits and clear left or right. ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber. @@ -6972,13 +9011,14 @@ if (GET_CODE (operands[1]) == CONST_DOUBLE) { operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); + operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]), + 0, DImode); } else { HOST_WIDE_INT value = INTVAL (operands[1]); operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx; - operands[3] = operands[1]; + operands[3] = immed_double_const (value, 0, DImode); } }") @@ -6997,20 +9037,37 @@ (match_dup 3)))] " { +#if HOST_BITS_PER_WIDE_INT != 32 HOST_WIDE_INT value = INTVAL (operands[1]); operands[2] = GEN_INT (value >> 32); operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); +#endif }") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r") + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r") (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))] + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] "TARGET_POWERPC64" - "mr. %0,%1" - [(set_attr "type" "compare")]) + "@ + mr. %0,%1 + #" + [(set_attr "type" "compare") + (set_attr "length" "4,8")]) +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC (match_operand:DI 1 "gpc_reg_operand" "") + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") (match_dup 1))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + ;; TImode is similar, except that we usually want to compute the address into ;; a register and use lsi/stsi (the exception is during reload). MQ is also ;; clobbered in stsi for POWER, so we need a SCRATCH for it. @@ -7893,21 +9950,6 @@ emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); } - /* Under Windows NT, we need to add stack probes for large/variable - allocations, so do it via a call to the external function alloca - instead of doing it inline. */ - if (DEFAULT_ABI == ABI_NT - && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096)) - { - rtx tmp = gen_reg_rtx (Pmode); - emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, - \"__allocate_stack\"), - tmp, 0, Pmode, 1, operands[1], Pmode); - emit_insn (gen_set_sp (tmp)); - emit_move_insn (operands[0], tmp); - DONE; - } - if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < -32767 || INTVAL (operands[1]) > 32768) @@ -7936,16 +9978,6 @@ DONE; }") -;; Marker to indicate that the stack pointer was changed under NT in -;; ways not known to the compiler - -(define_insn "set_sp" - [(set (reg:SI 1) - (unspec [(match_operand:SI 0 "register_operand" "r")] 7))] - "" - "" - [(set_attr "length" "0")]) - ;; These patterns say how to save and restore the stack pointer. We need not ;; save the stack pointer at function level since we are careful to ;; preserve the backchain. At block level, we have to restore the backchain @@ -8014,21 +10046,100 @@ emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp); DONE; }") + +;; TOC register handling. -;; If we have -mminimal-toc, we need to reload r30 after a nonlocal goto. +;; Code to initialize the TOC register... -(define_insn "nonlocal_goto_receiver" - [(unspec_volatile [(const_int 0)] 1)] - "TARGET_TOC && TARGET_MINIMAL_TOC" +(define_insn "load_toc_aix_si" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(const_int 0)] 7))] + "! TARGET_ELF && TARGET_32BIT" "* { - rs6000_output_load_toc_table (asm_out_file, 30); - return \"\"; + char buf[30]; + ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); + operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); + operands[2] = gen_rtx_REG (Pmode, 2); + return \"{l|lwz} %0,%1(%2)\"; }" [(set_attr "type" "load")]) - -;; A function pointer under AIX is a pointer to a data area whose first word -;; contains the actual address of the function, whose second word contains a + +(define_insn "load_toc_aix_di" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] 7))] + "! TARGET_ELF && TARGET_64BIT" + "* +{ + char buf[30]; + ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); + operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1)); + operands[2] = gen_rtx_REG (Pmode, 2); + return \"ld %0,%1(%2)\"; +}" + [(set_attr "type" "load")]) + +(define_insn "load_toc_v4_pic_si" + [(set (match_operand:SI 0 "register_operand" "=l") + (unspec:SI [(const_int 0)] 7))] + "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1 + && TARGET_32BIT" + "bl _GLOBAL_OFFSET_TABLE_@local-4" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "load_toc_v4_pic_di" + [(set (match_operand:DI 0 "register_operand" "=l") + (unspec:DI [(const_int 0)] 7))] + "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1 + && TARGET_64BIT" + "bl _GLOBAL_OFFSET_TABLE_@local-4" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "load_toc_v4_PIC_1" + [(set (match_operand:SI 0 "register_operand" "=l") + (match_operand:SI 1 "immediate_operand" "s")) + (unspec [(match_dup 1)] 7)] + "TARGET_ELF && flag_pic == 2" + "bl %1\\n%1:" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "load_toc_v4_PIC_1b" + [(set (match_operand:SI 0 "register_operand" "=l") + (match_operand:SI 1 "immediate_operand" "s")) + (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)] + "TARGET_ELF && flag_pic == 2" + "bl %1\\n\\t.long %2-%1+4\\n%1:" + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn "load_toc_v4_PIC_2" + [(set (match_operand:SI 0 "register_operand" "=r") + (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") + (minus:SI (match_operand:SI 2 "immediate_operand" "s") + (match_operand:SI 3 "immediate_operand" "s")))))] + "TARGET_ELF && flag_pic == 2" + "{l|lwz} %0,%2-%3(%1)" + [(set_attr "type" "load")]) + +;; If the TOC is shared over a translation unit, as happens with all +;; the kinds of PIC that we support, we need to restore the TOC +;; pointer only when jumping over units of translation. + +(define_expand "builtin_setjmp_receiver" + [(use (label_ref (match_operand 0 "" "")))] + "((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1) + || (TARGET_TOC && TARGET_MINIMAL_TOC)" + " +{ + rs6000_emit_load_toc_table (FALSE); + DONE; +}") + +;; A function pointer under AIX is a pointer to a data area whose first word +;; contains the actual address of the function, whose second word contains a ;; pointer to its TOC, and whose third word contains a value to place in the ;; static chain register (r11). Note that if we load the static chain, our ;; "trampoline" need not have any executable code. @@ -8105,49 +10216,6 @@ [(set_attr "type" "load") (set_attr "length" "28")]) -;; A function pointer undef NT is a pointer to a data area whose first word -;; contains the actual address of the function, whose second word contains a -;; pointer to its TOC. The static chain is not stored under NT, which means -;; that we need a trampoline. -;; -;; operands[0] is an SImode pseudo in which we place the address of the function. -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT) -;; operands[3] is location to store the TOC -;; operands[4] is the TOC register -;; -;; We do not break this into separate insns, so that the scheduler will not try -;; to move the load of the new TOC before any loads from the TOC. - -(define_insn "call_indirect_nt" - [(call (mem:SI (match_operand:SI 0 "gpc_reg_operand" "b")) - (match_operand 1 "const_int_operand" "n")) - (use (match_operand 2 "const_int_operand" "n")) - (use (match_operand 3 "offsettable_mem_operand" "o")) - (use (match_operand 4 "gpc_reg_operand" "r")) - (clobber (match_scratch:SI 5 "=&r")) - (clobber (match_scratch:SI 6 "=l"))] - "DEFAULT_ABI == ABI_NT - && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)" - "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3" - [(set_attr "type" "load") - (set_attr "length" "24")]) - -(define_insn "call_value_indirect_nt" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) - (match_operand 2 "const_int_operand" "n"))) - (use (match_operand 3 "const_int_operand" "n")) - (use (match_operand 4 "offsettable_mem_operand" "o")) - (use (match_operand 5 "gpc_reg_operand" "r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=l"))] - "DEFAULT_ABI == ABI_NT - && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)" - "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4" - [(set_attr "type" "load") - (set_attr "length" "24")]) - ;; A function pointer under System V is just a normal pointer ;; operands[0] is the function pointer ;; operands[1] is the stack size to clean up @@ -8206,14 +10274,6 @@ operands[0] = XEXP (operands[0], 0); - /* Convert NT DLL imports into an indirect call. */ - if (GET_CODE (operands[0]) == SYMBOL_REF - && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0) - { - operands[0] = rs6000_dll_import_ref (operands[0]); - operands[2] = GEN_INT ((int)CALL_NORMAL); - } - if (GET_CODE (operands[0]) != SYMBOL_REF || (INTVAL (operands[2]) & CALL_LONG) != 0) { @@ -8241,13 +10301,6 @@ operands[1], operands[2], toc_addr, toc_reg, static_chain)); } - else if (DEFAULT_ABI == ABI_NT) - { - /* NT function pointers are really pointers to a two word area */ - emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]), - operands[1], operands[2], - toc_addr, toc_reg)); - } else abort (); } @@ -8269,14 +10322,6 @@ operands[1] = XEXP (operands[1], 0); - /* Convert NT DLL imports into an indirect call. */ - if (GET_CODE (operands[1]) == SYMBOL_REF - && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0) - { - operands[1] = rs6000_dll_import_ref (operands[1]); - operands[3] = GEN_INT ((int)CALL_NORMAL); - } - if (GET_CODE (operands[1]) != SYMBOL_REF || (INTVAL (operands[3]) & CALL_LONG) != 0) { @@ -8306,14 +10351,6 @@ operands[2], operands[3], toc_addr, toc_reg, static_chain)); } - else if (DEFAULT_ABI == ABI_NT) - { - /* NT function pointers are really pointers to a two word area */ - emit_call_insn (gen_call_value_indirect_nt (operands[0], - force_reg (Pmode, operands[1]), - operands[2], operands[3], - toc_addr, toc_reg)); - } else abort (); } @@ -8418,7 +10455,7 @@ (match_operand 1 "" "fg,fg")) (use (match_operand:SI 2 "immediate_operand" "O,n")) (clobber (match_scratch:SI 3 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + "DEFAULT_ABI == ABI_AIX && (INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -8432,7 +10469,7 @@ 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\;%.\"; + return \"bl %z0\;%.\"; }" [(set_attr "type" "branch") (set_attr "length" "8,12")]) @@ -8442,7 +10479,8 @@ (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) + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -8456,7 +10494,7 @@ 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\;%.\"; + return \"bl %z0\;%.\"; }" [(set_attr "type" "branch") (set_attr "length" "8,12")]) @@ -8491,7 +10529,7 @@ (match_operand 2 "" "fg,fg"))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (match_scratch:SI 4 "=l,l"))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + "DEFAULT_ABI == ABI_AIX && (INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -8505,7 +10543,7 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\"; + return \"bl %z1\;%.\"; }" [(set_attr "type" "branch") (set_attr "length" "8,12")]) @@ -8516,7 +10554,8 @@ (match_operand 2 "" "fg,fg"))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (match_scratch:SI 4 "=l,l"))] - "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -8530,7 +10569,7 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\"; + return \"bl %z1\;%.\"; }" [(set_attr "type" "branch") (set_attr "length" "8,12")]) @@ -8595,17 +10634,6 @@ [(unspec_volatile [(const_int 0)] 0)] "" "") - -;; V.4 specific code to initialize the PIC register - -(define_insn "init_v4_pic" - [(set (match_operand:SI 0 "register_operand" "=l") - (unspec [(const_int 0)] 7))] - "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS" - "bl _GLOBAL_OFFSET_TABLE_@local-4" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - ;; Compare insns are next. Note that the RS/6000 has two types of compares, ;; signed & unsigned, and one type of branch. @@ -8832,10 +10860,22 @@ (eq:SI (match_dup 2) (const_int 0)))] "" " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; +{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode; operands[1] = gen_rtx_COMPARE (mode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (mode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_EQ (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sne" @@ -8850,6 +10890,14 @@ operands[1] = gen_rtx_COMPARE (CCFPmode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (CCFPmode); + + if (TARGET_POWERPC64) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_NE (DImode, operands[2], const0_rtx), 0); + DONE; + } }") ;; A > 0 is best done using the portable sequence, so fail in that case. @@ -8859,7 +10907,7 @@ (gt:SI (match_dup 2) (const_int 0)))] "" " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; +{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode; if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; @@ -8867,6 +10915,18 @@ operands[1] = gen_rtx_COMPARE (mode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (mode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_GT (DImode, operands[2], const0_rtx), 0); + DONE; + } }") ;; A < 0 is best done in the portable way for A an integer. @@ -8876,7 +10936,7 @@ (lt:SI (match_dup 2) (const_int 0)))] "" " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; +{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode; if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; @@ -8884,6 +10944,18 @@ operands[1] = gen_rtx_COMPARE (mode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (mode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_LT (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sge" @@ -8892,10 +10964,22 @@ (ge:SI (match_dup 2) (const_int 0)))] "" " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; +{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode; operands[1] = gen_rtx_COMPARE (mode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (mode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_GE (DImode, operands[2], const0_rtx), 0); + DONE; + } }") ;; A <= 0 is best done the portable way for A an integer. @@ -8905,7 +10989,7 @@ (le:SI (match_dup 2) (const_int 0)))] "" " -{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode; +{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode; if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; @@ -8913,6 +10997,18 @@ operands[1] = gen_rtx_COMPARE (mode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (mode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_LE (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sgtu" @@ -8921,9 +11017,23 @@ (gtu:SI (match_dup 2) (const_int 0)))] "" " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, +{ enum machine_mode op_mode; + + operands[1] = gen_rtx_COMPARE (CCUNSmode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (CCUNSmode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && op_mode == DImode) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_GTU (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sltu" @@ -8932,9 +11042,23 @@ (ltu:SI (match_dup 2) (const_int 0)))] "" " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, +{ enum machine_mode op_mode; + + operands[1] = gen_rtx_COMPARE (CCUNSmode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (CCUNSmode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && op_mode == DImode) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_LTU (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sgeu" @@ -8943,9 +11067,23 @@ (geu:SI (match_dup 2) (const_int 0)))] "" " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, +{ enum machine_mode op_mode; + + operands[1] = gen_rtx_COMPARE (CCUNSmode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (CCUNSmode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && op_mode == DImode) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_GEU (DImode, operands[2], const0_rtx), 0); + DONE; + } }") (define_expand "sleu" @@ -8954,9 +11092,23 @@ (leu:SI (match_dup 2) (const_int 0)))] "" " -{ operands[1] = gen_rtx_COMPARE (CCUNSmode, +{ enum machine_mode op_mode; + + operands[1] = gen_rtx_COMPARE (CCUNSmode, rs6000_compare_op0, rs6000_compare_op1); operands[2] = gen_reg_rtx (CCUNSmode); + + op_mode = GET_MODE (rs6000_compare_op0); + if (op_mode == VOIDmode) + op_mode = GET_MODE (rs6000_compare_op1); + + if (TARGET_POWERPC64 && op_mode == DImode) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); + convert_move (operands[0], + gen_rtx_LEU (DImode, operands[2], const0_rtx), 0); + DONE; + } }") ;; Here are the actual compare insns. @@ -9007,7 +11159,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:SI 2 "reg_or_u_short_operand" "rK")))] "" "{cmpl%I2|cmplw%I2} %0,%1,%W2" [(set_attr "type" "compare")]) @@ -9015,7 +11167,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:DI 2 "reg_or_u_short_operand" "rK")))] "" "cmpld%I2 %0,%1,%W2" [(set_attr "type" "compare")]) @@ -9098,17 +11250,44 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (match_operator:DI 1 "scc_comparison_operator" + [(match_operand 2 "cc_reg_operand" "y") + (const_int 0)]))] + "TARGET_POWERPC64" + "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set_attr "length" "12")]) + +(define_insn "" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") + [(match_operand 2 "cc_reg_operand" "y,y") (const_int 0)]) (const_int 0))) - (set (match_operand:SI 3 "gpc_reg_operand" "=r") + (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") (match_op_dup 1 [(match_dup 2) (const_int 0)]))] "! TARGET_POWERPC64" - "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1" + "@ + %D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1 + #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC (match_operator:SI 1 "scc_comparison_operator" + [(match_operand 2 "cc_reg_operand" "") + (const_int 0)]) + (const_int 0))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (match_op_dup 1 [(match_dup 2) (const_int 0)]))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (match_op_dup 1 [(match_dup 2) (const_int 0)])) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9136,23 +11315,27 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") + [(match_operand 2 "cc_reg_operand" "y,y") (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n,n")) (const_int 0))) - (set (match_operand:SI 4 "gpc_reg_operand" "=r") + (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3)))] - "" + "! TARGET_POWERPC64" "* { int is_bit = ccr_bit (operands[1], 1); int put_bit = 31 - (INTVAL (operands[3]) & 31); int count; + /* Force split for non-cc0 compare. */ + if (which_alternative == 1) + return \"#\"; + if (is_bit >= put_bit) count = is_bit - put_bit; else @@ -9164,7 +11347,27 @@ return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; }" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (ashift:SI (match_operator:SI 1 "scc_comparison_operator" + [(match_operand 2 "cc_reg_operand" "") + (const_int 0)]) + (match_operand:SI 3 "const_int_operand" "")) + (const_int 0))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) + (match_dup 3)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") ;; If we are comparing the result of two comparisons, this can be done ;; using creqv or crxor. @@ -9214,6 +11417,19 @@ "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" [(set_attr "length" "20")]) +(define_peephole + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (match_operator:DI 1 "scc_comparison_operator" + [(match_operand 2 "cc_reg_operand" "y") + (const_int 0)])) + (set (match_operand:DI 3 "gpc_reg_operand" "=r") + (match_operator:DI 4 "scc_comparison_operator" + [(match_operand 5 "cc_reg_operand" "y") + (const_int 0)]))] + "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" + "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" + [(set_attr "length" "20")]) + ;; There are some scc insns that can be done directly, without a compare. ;; These are faster because they don't involve the communications between ;; the FXU and branch units. In fact, we will be replacing all of the @@ -9257,42 +11473,88 @@ [(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,?y,?y,?y,?y,?y") (compare:CC - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")) + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") (eq:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))] + (clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] "! TARGET_POWERPC64" "@ xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0" + {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 + # + # + # + # + #" [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12")]) + (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (eq:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (eq:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (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,?y,?y,?y,?y,?y") (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")) + (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") (eq:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))] + (clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] "TARGET_POWERPC64" "@ xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 subfic %3,%1,0\;adde. %0,%3,%1 xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0 xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0" + subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 + # + # + # + # + #" [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12")]) + (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (eq:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (eq:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (eq:DI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") ;; 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. @@ -9325,45 +11587,94 @@ [(set_attr "length" "12,8,12,12,12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") (compare:CC (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")) + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3" + {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 + # + # + # + # + #" [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12")]) + (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:SI (eq:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") (compare:CC (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")) + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12")]) - + {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 + # + # + # + # + #" + [(set_attr "type" "compare") + (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI + (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") @@ -9384,7 +11695,7 @@ (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (const_int 31))) (clobber (match_scratch:SI 2 "=&r"))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" [(set_attr "length" "8")]) @@ -9421,66 +11732,156 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (plus:SI (lshiftrt:SI - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))) (const_int 31)) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=&r"))] + (clobber (match_scratch:SI 3 "=&r,&r"))] "! TARGET_POWERPC64" - "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2" + "@ + {ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (lshiftrt:SI + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" ""))) + (const_int 31)) + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) + (const_int 31)) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (plus:DI (lshiftrt:DI - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))) (const_int 63)) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=&r"))] + (clobber (match_scratch:DI 3 "=&r,&r"))] "TARGET_POWERPC64" - "addic %3,%1,-1\;addze. %3,%2" + "@ + addic %3,%1,-1\;addze. %3,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (lshiftrt:DI + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) + (const_int 63)) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) + (const_int 63)) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (plus:SI (lshiftrt:SI - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))) (const_int 31)) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r"))] + (clobber (match_scratch:SI 3 "=&r,&r"))] "! TARGET_POWERPC64" - "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2" + "@ + {ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (lshiftrt:SI + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" ""))) + (const_int 31)) + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) + (match_dup 2))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) + (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (plus:DI (lshiftrt:DI - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))) (const_int 63)) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) (match_dup 2))) - (clobber (match_scratch:DI 3 "=&r"))] + (clobber (match_scratch:DI 3 "=&r,&r"))] "TARGET_POWERPC64" - "addic %3,%1,-1\;addze. %0,%2" + "@ + addic %3,%1,-1\;addze. %0,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (lshiftrt:DI + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) + (const_int 63)) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) + (match_dup 2))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) + (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -9494,20 +11895,40 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O")) + (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (le:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,X"))] + (clobber (match_scratch:SI 3 "=r,X,r,X"))] "TARGET_POWER" "@ doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3 - {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31" - [(set_attr "type" "compare,delayed_compare") - (set_attr "length" "12")]) + {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31 + # + #" + [(set_attr "type" "compare,delayed_compare,compare,delayed_compare") + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (le:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (le:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 3 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (le:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -9522,36 +11943,76 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "TARGET_POWER" "@ doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3" + {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(set (match_dup 4) + (plus:SI (le:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,O")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "TARGET_POWER" "@ doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 - {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3" + {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -9580,43 +12041,81 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")) + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (leu:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0" + "@ + subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (leu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (leu:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (leu:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" + "@ + {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (leu:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (leu:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")) + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (leu:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0" + "@ + subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9629,32 +12128,72 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3" + "@ + {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:SI (leu:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3" + "@ + {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9676,34 +12215,77 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" - [(set_attr "type" "compare") - (set_attr "length" "12")]) + "@ + {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 + #" + [(set_attr "type" "compare") + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (neg:SI + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" ""))) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (and:SI (neg:SI (leu:SI (match_dup 1) + (match_dup 2))) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") (compare:CC (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" + "@ + {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (neg:SI + (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" ""))) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9714,17 +12296,35 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (lt:SI (match_dup 1) (match_dup 2)))] "TARGET_POWER" - "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31" + "@ + doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31 + #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (lt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (lt:SI (match_dup 1) (match_dup 2)))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (lt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9737,32 +12337,72 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3" + "@ + doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(set (match_dup 4) + (plus:SI (lt:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3" + "@ + doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9783,19 +12423,37 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) + (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (ltu:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" + {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ltu:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ltu:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -9810,36 +12468,76 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3" + {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" + {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -9861,18 +12559,116 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (const_int 0)))] + "! TARGET_POWER && ! TARGET_POWERPC64" + "nand %0,%1,%1\;{sri|srwi} %0,%0,31" + [(set_attr "length" "8")]) + +(define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (ge:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)))] + "TARGET_POWERPC64" + "nand %0,%1,%1\;srdi %0,%0,63" + [(set_attr "length" "8")]) + +(define_insn "" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ge:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_POWER" - "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3" + "@ + doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3 + #" + [(set_attr "type" "compare") + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ge:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ge:SI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:SI 3 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (ge:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_insn "" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (const_int 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (ge:SI (match_dup 1) (const_int 0)))] + "! TARGET_POWER" + "@ + nand %0,%1,%1\;{sri.|srwi.} %0,%0,31 + #" + [(set_attr "type" "compare") + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ge:SI (match_operand:SI 1 "gpc_reg_operand" "") + (const_int 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (ge:SI (match_dup 1) (const_int 0)))] + "! TARGET_POWER && reload_completed" + [(set (match_dup 0) + (ge:SI (match_dup 1) (const_int 0))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_insn "" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (ge:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (const_int 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (ge:DI (match_dup 1) (const_int 0)))] + "TARGET_POWERPC64" + "@ + nand %0,%1,%1\;srdi. %0,%0,63 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (ge:DI (match_operand:DI 1 "gpc_reg_operand" "") + (const_int 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (ge:DI (match_dup 1) (const_int 0)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (ge:DI (match_dup 1) (const_int 0))) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9885,32 +12681,72 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3" + "@ + doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(set (match_dup 4) + (plus:SI (ge:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3" + "@ + doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -9947,72 +12783,172 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (and:SI (neg:SI (lshiftrt:SI - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) + (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 31))) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=&r"))] + (clobber (match_scratch:SI 3 "=&r,&r"))] "" - "{srai|srawi} %3,%1,31\;andc. %3,%2,%3" + "@ + {srai|srawi} %3,%1,31\;andc. %3,%2,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (neg:SI + (lshiftrt:SI + (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) + (const_int 31))) + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "reload_completed" + [(set (match_dup 3) + (and:SI (neg:SI (lshiftrt:SI + (not:SI (match_dup 1)) + (const_int 31))) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (and:DI (neg:DI (lshiftrt:DI - (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 63))) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=&r"))] + (clobber (match_scratch:DI 3 "=&r,&r"))] "TARGET_POWERPC64" - "sradi %3,%1,63\;andc. %3,%2,%3" + "@ + sradi %3,%1,63\;andc. %3,%2,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:DI (neg:DI + (lshiftrt:DI + (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 63))) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (and:DI (neg:DI (lshiftrt:DI + (not:DI (match_dup 1)) + (const_int 63))) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (and:SI (neg:SI + (lshiftrt:SI + (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (const_int 31))) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1)) + (const_int 31))) + (match_dup 2))) + (clobber (match_scratch:SI 3 "=&r,&r"))] + "" + "@ + {srai|srawi} %3,%1,31\;andc. %0,%2,%3 + #" + [(set_attr "type" "compare") + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC (and:SI (neg:SI (lshiftrt:SI - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) + (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (const_int 31))) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1)) (const_int 31))) (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r"))] - "" - "{srai|srawi} %3,%1,31\;andc. %0,%2,%3" - [(set_attr "type" "compare") - (set_attr "length" "8")]) + (clobber (match_scratch:SI 3 ""))] + "reload_completed" + [(parallel [(set (match_dup 0) + (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1)) + (const_int 31))) + (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (and:DI (neg:DI (lshiftrt:DI - (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) (const_int 63))) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1)) (const_int 63))) (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r"))] + (clobber (match_scratch:SI 3 "=&r,&r"))] "TARGET_POWERPC64" - "sradi %3,%1,63\;andc. %0,%2,%3" + "@ + sradi %3,%1,63\;andc. %0,%2,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,12")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:DI (neg:DI + (lshiftrt:DI + (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + (const_int 63))) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1)) + (const_int 63))) + (match_dup 2))) + (clobber (match_scratch:SI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1)) + (const_int 63))) + (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -10035,34 +12971,70 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (geu:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 - {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" + {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (geu:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (geu:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")) + (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_neg_short_operand" "r,P,r,P")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") (geu:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" "@ subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0" + addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (geu:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_neg_short_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (geu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (geu:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -10077,36 +13049,76 @@ [(set_attr "length" "8")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3 - {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3" + {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,8,12,12")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:SI (geu:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3 - {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3" + {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8")]) + (set_attr "length" "8,8,12,12")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -10132,38 +13144,81 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" + {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (neg:SI + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" ""))) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (and:SI (neg:SI (geu:SI (match_dup 1) + (match_dup 2))) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" + {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 + # + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,12,16,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (and:SI (neg:SI + (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_neg_short_operand" ""))) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10182,30 +13237,66 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (const_int 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (gt:SI (match_dup 1) (const_int 0)))] "! TARGET_POWERPC64" - "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31" + "@ + {sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31 + #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC + (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (const_int 0)) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (gt:SI (match_dup 1) (const_int 0)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (gt:SI (match_dup 1) (const_int 0))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x") + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC - (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (const_int 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (gt:DI (match_dup 1) (const_int 0)))] "TARGET_POWERPC64" - "subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63" + "@ + subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63 + #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + (compare:CC + (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (const_int 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (gt:DI (match_dup 1) (const_int 0)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (gt:DI (match_dup 1) (const_int 0))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10216,17 +13307,35 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) + (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (gt:SI (match_dup 1) (match_dup 2)))] "TARGET_POWER" - "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31" + "@ + doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31 + #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (gt:SI (match_dup 1) (match_dup 2)))] + "TARGET_POWER && reload_completed" + [(set (match_dup 0) + (gt:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10249,60 +13358,140 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=&r"))] + (clobber (match_scratch:SI 3 "=&r,&r"))] "! TARGET_POWERPC64" - "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2" + "@ + {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (const_int 0)) + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (plus:SI (gt:SI (match_dup 1) (const_int 0)) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 3 "=&r"))] + (clobber (match_scratch:DI 3 "=&r,&r"))] "TARGET_POWERPC64" - "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2" + "@ + addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (const_int 0)) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 3) + (plus:DI (gt:DI (match_dup 1) (const_int 0)) + (match_dup 2))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (const_int 0)) + (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) + (clobber (match_scratch:SI 3 "=&r,&r"))] + "! TARGET_POWERPC64" + "@ + {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2 + #" + [(set_attr "type" "compare") + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r")) + (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) - (clobber (match_scratch:SI 3 "=&r"))] - "! TARGET_POWERPC64" - "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2" - [(set_attr "type" "compare") - (set_attr "length" "12")]) + (clobber (match_scratch:SI 3 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r")) + (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) - (clobber (match_scratch:DI 3 "=&r"))] + (clobber (match_scratch:DI 3 "=&r,&r"))] "TARGET_POWERPC64" - "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2" + "@ + addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (const_int 0)) + (match_operand:DI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) + (clobber (match_dup 3))]) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10315,32 +13504,72 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,r")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3" + "@ + doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(set (match_dup 4) + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r")) - (match_operand:SI 3 "gpc_reg_operand" "r")) + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,r")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r"))] + (clobber (match_scratch:SI 4 "=&r,&r"))] "TARGET_POWER" - "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3" + "@ + doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "TARGET_POWER && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10383,30 +13612,66 @@ [(set_attr "length" "12")]) (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) + (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (gtu:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" + "@ + {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (gtu:SI (match_dup 1) (match_dup 2)))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (gtu:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")) + (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (gtu:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0" + "@ + subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0 + #" [(set_attr "type" "compare") - (set_attr "length" "12")]) + (set_attr "length" "12,16")]) + +(define_split + [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + (compare:CC + (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (gtu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 0) + (gtu:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") @@ -10433,68 +13698,148 @@ [(set_attr "length" "8,12")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3" + {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12,12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "I,r")) - (match_operand:DI 3 "gpc_reg_operand" "r,r")) + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r")) + (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (clobber (match_scratch:DI 4 "=&r,&r"))] + (clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))] "TARGET_POWERPC64" "@ addic %4,%1,%k2\;addze. %4,%3 - subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3" + subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12,12,16")]) + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (match_operand:DI 3 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(set (match_dup 4) + (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 0) + (compare:CC (match_dup 4) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) + (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:SI 4 "=&r,&r"))] + (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] "! TARGET_POWERPC64" "@ {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" + {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12,12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) + (match_operand:SI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:SI 4 ""))] + "! TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" - [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "I,r")) - (match_operand:DI 3 "gpc_reg_operand" "r,r")) + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r")) + (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (clobber (match_scratch:DI 4 "=&r,&r"))] + (clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))] "TARGET_POWERPC64" "@ addic %4,%1,%k2\;addze. %0,%3 - subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3" + subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3 + # + #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12,12,16")]) + +(define_split + [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "") + (compare:CC + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_short_operand" "")) + (match_operand:DI 3 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_dup 4))]) + (set (match_dup 5) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -10650,16 +13995,18 @@ }") (define_expand "tablejumpdi" - [(set (match_dup 3) - (plus:DI (match_operand:DI 0 "" "") + [(set (match_dup 4) + (sign_extend:DI (match_operand:SI 0 "lwa_operand" "rm"))) + (set (match_dup 3) + (plus:DI (match_dup 4) (match_dup 2))) (parallel [(set (pc) (match_dup 3)) (use (label_ref (match_operand 1 "" "")))])] "TARGET_64BIT" " -{ operands[0] = force_reg (DImode, operands[0]); - operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); +{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (DImode); }") (define_insn "" @@ -11065,7 +14412,7 @@ (const_int 1)]) (match_operand 5 "" "") (match_operand 6 "" ""))) - (set (match_operand:SI 0 "general_operand" "") + (set (match_operand:SI 0 "nonimmediate_operand" "") (plus:SI (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:SI 4 ""))] @@ -11120,7 +14467,7 @@ (const_int 1)]) (match_operand 5 "" "") (match_operand 6 "" ""))) - (set (match_operand:DI 0 "general_operand" "") + (set (match_operand:DI 0 "nonimmediate_operand" "") (plus:DI (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:DI 4 ""))] @@ -11171,3 +14518,268 @@ (const_int 0))] "TARGET_POWERPC64" "td%V0%I2 %1,%2") + +;; Insns related to generating the function prologue and epilogue. + +(define_expand "prologue" + [(use (const_int 0))] + "TARGET_SCHED_PROLOG" + " +{ + rs6000_emit_prologue (); + DONE; +}") + +(define_insn "movesi_from_cr" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) + (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))] + "" + "mfcr %0") + +(define_insn "*stmw" + [(match_parallel 0 "stmw_operation" + [(set (match_operand:SI 1 "memory_operand" "=m") + (match_operand:SI 2 "gpc_reg_operand" "r"))])] + "TARGET_MULTIPLE" + "{stm|stmw} %2,%1") + +(define_insn "*save_fpregs_si" + [(match_parallel 0 "any_operand" + [(clobber (match_operand:SI 1 "register_operand" "=l")) + (use (match_operand:SI 2 "call_operand" "s")) + (set (match_operand:DF 3 "memory_operand" "=m") + (match_operand:DF 4 "gpc_reg_operand" "f"))])] + "TARGET_32BIT" + "bl %z2") + +(define_insn "*save_fpregs_di" + [(match_parallel 0 "any_operand" + [(clobber (match_operand:DI 1 "register_operand" "=l")) + (use (match_operand:DI 2 "call_operand" "s")) + (set (match_operand:DF 3 "memory_operand" "=m") + (match_operand:DF 4 "gpc_reg_operand" "f"))])] + "TARGET_64BIT" + "bl %z2") + +; These are to explain that changes to the stack pointer should +; not be moved over stores to stack memory. +(define_insn "stack_tie" + [(set (match_operand:BLK 0 "memory_operand" "+m") + (unspec:BLK [(match_dup 0)] 5))] + "" + "" + [(set_attr "length" "0")]) + + +(define_expand "epilogue" + [(use (const_int 0))] + "TARGET_SCHED_PROLOG" + " +{ + rs6000_emit_epilogue (FALSE); + DONE; +}") + +; On some processors, doing the mtcrf one CC register at a time is +; faster (like on the 604e). On others, doing them all at once is +; faster; for instance, on the 601 and 750. + +(define_expand "movsi_to_cr_one" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_dup 2)] 20))] + "" + "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") + +(define_insn "*movsi_to_cr" + [(match_parallel 0 "mtcrf_operation" + [(use (match_operand 1 "immediate_operand" "n")) + (set (match_operand:CC 2 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 3 "gpc_reg_operand" "r") + (match_operand 4 "immediate_operand" "n")] + 20))])] + "" + "mtcrf %1,%3") + +(define_insn "" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand 2 "immediate_operand" "n")] 20))] + "GET_CODE (operands[0]) == REG + && CR_REGNO_P (REGNO (operands[0])) + && GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" + "mtcrf %R0,%1") + +; The load-multiple instructions have similar properties. +; Note that "load_multiple" is a name known to the machine-independent +; code that actually corresponds to the powerpc load-string. + +(define_insn "*lmw" + [(match_parallel 0 "lmw_operation" + [(set (match_operand:SI 1 "gpc_reg_operand" "=r") + (match_operand:SI 2 "memory_operand" "m"))])] + "TARGET_MULTIPLE" + "{lm|lmw} %1,%2") + +(define_insn "*return_internal_si" + [(use (match_operand:SI 0 "register_operand" "l,c")) + (return)] + "TARGET_32BIT" + "@ + {br|blr} + bctr" + [(set_attr "type" "jmpreg")]) + +(define_insn "*return_internal_di" + [(use (match_operand:DI 0 "register_operand" "l,c")) + (return)] + "TARGET_64BIT" + "@ + {br|blr} + bctr" + [(set_attr "type" "jmpreg")]) + +; FIXME: This would probably be somewhat simpler if the Cygnus sibcall +; stuff was in GCC. Oh, and "any_operand" is a bit flexible... + +(define_insn "*return_and_restore_fpregs_si" + [(match_parallel 0 "any_operand" + [(use (match_operand:SI 1 "register_operand" "l")) + (return) + (use (match_operand:SI 2 "call_operand" "s")) + (set (match_operand:DF 3 "gpc_reg_operand" "=f") + (match_operand:DF 4 "memory_operand" "m"))])] + "TARGET_32BIT" + "b %z2") + +(define_insn "*return_and_restore_fpregs_di" + [(match_parallel 0 "any_operand" + [(use (match_operand:DI 1 "register_operand" "l")) + (return) + (use (match_operand:DI 2 "call_operand" "s")) + (set (match_operand:DF 3 "gpc_reg_operand" "=f") + (match_operand:DF 4 "memory_operand" "m"))])] + "TARGET_64BIT" + "b %z2") + +; This is used in compiling the routines __throw and __rethrow. +; It's a little different to the usual definition... + +(define_expand "eh_epilogue" + [(use (match_operand 0 "general_operand" "r")) + (use (match_operand 1 "general_operand" "r")) + (use (match_operand 2 "general_operand" "c"))] + "" + " +{ + rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx insn; + + /* This is required for binary compatibility. If it's wrong, + it probably means that eh_regs() in except.c is broken. */ + if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 3) + abort(); + + /* These can be anything that doesn't interfere with the epilogue. */ + if (GET_CODE (operands[1]) != REG || REGNO (operands[1]) != 4) + { + rtx r = gen_rtx_REG (Pmode, 4); + emit_move_insn (r, operands[1]); + operands[1] = r; + } + + if (GET_CODE (operands[2]) != REG + || REGNO (operands[2]) != COUNT_REGISTER_REGNUM) + { + rtx r = gen_rtx_REG (Pmode, COUNT_REGISTER_REGNUM); + emit_move_insn (r, operands[2]); + operands[2] = r; + } + +#if TARGET_AIX + rs6000_emit_eh_toc_restore (operands[1]); +#endif + + emit_insn (gen_eh_reg_restore ()); + + if (Pmode == SImode) + emit_insn (gen_addsi3 (stack_reg, stack_reg, operands[1])); + else + emit_insn (gen_adddi3 (stack_reg, stack_reg, operands[1])); + + if (Pmode == SImode) + insn = emit_jump_insn (gen_return_eh_si (operands[2])); + else + insn = emit_jump_insn (gen_return_eh_di (operands[2])); + emit_barrier_after (insn); + + DONE; +}") + +; We can't expand this before we know which registers are restored, +; but we do want to expand it before flow2 because that way flow2 can +; remove the redundant loads of the link register. +(define_expand "eh_reg_restore" + [(unspec_volatile [(const_int 0)] 9)] + "" + "") + +(define_split + [(unspec_volatile [(const_int 0)] 9)] + "reload_completed && TARGET_SCHED_PROLOG" + [(unspec_volatile [(const_int 0)] 9)] + " +{ + rs6000_emit_epilogue (TRUE); + DONE; +}") + +(define_insn "" + [(unspec_volatile [(const_int 0)] 9)] + "" + "* +{ + if (TARGET_SCHED_PROLOG) + return \"#\"; + + /* This is slightly ugly, but at least we don't have multiple + copies of the epilogue-emitting code. */ + start_sequence (); + + /* A NOTE_INSN_DELETED is supposed to be at the start + and end of the \"toplevel\" insn chain. */ + emit_note (0, NOTE_INSN_DELETED); + rs6000_emit_epilogue (TRUE); + emit_note (0, NOTE_INSN_DELETED); + + if (TARGET_DEBUG_STACK) + debug_rtx_list (get_insns(), 100); + final (get_insns(), asm_out_file, FALSE, FALSE); + end_sequence (); + return \"\"; +}") + + +(define_insn "return_eh_si" + [(use (match_operand:SI 0 "register_operand" "l,c")) + (return) + (use (reg:SI 2)) + (use (reg:SI 3))] + "TARGET_32BIT" + "@ + {br|blr} + bctr" + [(set_attr "type" "jmpreg")]) + +(define_insn "return_eh_di" + [(use (match_operand:DI 0 "register_operand" "l,c")) + (return) + (use (reg:DI 2)) + (use (reg:DI 3))] + "TARGET_64BIT" + "@ + {br|blr} + bctr" + [(set_attr "type" "jmpreg")]) diff --git a/gcc/config/rs6000/sol2.h b/gcc/config/rs6000/sol2.h index 91e5b421018..76df9b01529 100644 --- a/gcc/config/rs6000/sol2.h +++ b/gcc/config/rs6000/sol2.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000 running AIX version 3.1. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. Contributed by David Reese (Dave.Reese@East.Sun.COM) This file is part of GNU CC. @@ -65,9 +65,6 @@ Boston, MA 02111-1307, USA. */ #undef CPP_ENDIAN_LITTLE_SPEC #define CPP_ENDIAN_LITTLE_SPEC CPP_ENDIAN_SOLARIS_SPEC -/* Don't turn -B into -L if the argument specifies a relative file name. */ -#undef RELATIVE_PREFIX_NOT_LINKDIR - #define DEFAULT_PCC_STRUCT_RETURN 0 #undef TARGET_VERSION diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index 13922045e09..644438cc6c6 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -1,5 +1,5 @@ /* Target definitions for GNU compiler for PowerPC running System V.4 - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GNU CC. @@ -19,109 +19,126 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Small data support types */ +#include "rs6000/rs6000.h" + +/* Use the regular svr4 definitions. */ + +#include "svr4.h" + +/* Yes! We are ELF. */ +#define TARGET_OBJECT_FORMAT OBJECT_ELF + +/* Default ABI to compile code for. */ +#define DEFAULT_ABI rs6000_current_abi + +/* Default ABI to use. */ +#define RS6000_ABI_NAME "sysv" + +/* Override rs6000.h definition. */ +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc" + +/* Override rs6000.h definition. */ +#undef CPP_DEFAULT_SPEC +#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" + +/* Small data support types. */ enum rs6000_sdata_type { - SDATA_NONE, /* no small data support */ - SDATA_DATA, /* just put data in .sbss/.sdata, don't use relocs */ - SDATA_SYSV, /* Use r13 to point to .sdata/.sbss */ - SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2 */ + SDATA_NONE, /* No small data support. */ + SDATA_DATA, /* Just put data in .sbss/.sdata, don't use relocs. */ + SDATA_SYSV, /* Use r13 to point to .sdata/.sbss. */ + SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2. */ }; extern enum rs6000_sdata_type rs6000_sdata; -/* V.4/eabi switches */ -#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */ +/* V.4/eabi switches. */ +#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0. */ #define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */ -#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */ -#define MASK_EABI 0x08000000 /* Adhere to eabi, not System V spec */ -#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */ -#define MASK_REGNAMES 0x02000000 /* use alternate register names. */ -#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */ +#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative. */ +#define MASK_EABI 0x08000000 /* Adhere to eabi, not System V spec. */ +#define MASK_LITTLE_ENDIAN 0x04000000 /* Target is little endian. */ +#define MASK_REGNAMES 0x02000000 /* Use alternate register names. */ +#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args. */ #define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE) -#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN) -#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE) -#define TARGET_EABI (target_flags & MASK_EABI) -#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN) -#define TARGET_REGNAMES (target_flags & MASK_REGNAMES) +#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN) +#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE) +#define TARGET_EABI (target_flags & MASK_EABI) +#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN) +#define TARGET_REGNAMES (target_flags & MASK_REGNAMES) #define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE) #define TARGET_TOC ((target_flags & MASK_64BIT) \ || ((target_flags & (MASK_RELOCATABLE \ | MASK_MINIMAL_TOC)) \ && flag_pic > 1) \ - || DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_NT) + || DEFAULT_ABI == ABI_AIX) #define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE) -#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) +#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) #define TARGET_NO_PROTOTYPE (! TARGET_PROTOTYPE) #define TARGET_NO_TOC (! TARGET_TOC) -#define TARGET_NO_EABI (! TARGET_EABI) - -/* Pseudo target to indicate whether the object format is ELF - (to get around not having conditional compilation in the md file) */ -#define TARGET_ELF 1 - -/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just - the same as -mminimal-toc. */ -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - { "bit-align", -MASK_NO_BITFIELD_TYPE }, \ - { "no-bit-align", MASK_NO_BITFIELD_TYPE }, \ - { "strict-align", MASK_STRICT_ALIGN }, \ - { "no-strict-align", -MASK_STRICT_ALIGN }, \ - { "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ - { "no-relocatable", -MASK_RELOCATABLE }, \ - { "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \ - { "no-relocatable-lib", -MASK_RELOCATABLE }, \ - { "little-endian", MASK_LITTLE_ENDIAN }, \ - { "little", MASK_LITTLE_ENDIAN }, \ - { "big-endian", -MASK_LITTLE_ENDIAN }, \ - { "big", -MASK_LITTLE_ENDIAN }, \ - { "no-toc", 0 }, \ - { "toc", MASK_MINIMAL_TOC }, \ - { "full-toc", MASK_MINIMAL_TOC }, \ - { "prototype", MASK_PROTOTYPE }, \ - { "no-prototype", -MASK_PROTOTYPE }, \ - { "no-traceback", 0 }, \ - { "eabi", MASK_EABI }, \ - { "no-eabi", -MASK_EABI }, \ - { "regnames", MASK_REGNAMES }, \ - { "no-regnames", -MASK_REGNAMES }, \ - { "sdata", 0 }, \ - { "no-sdata", 0 }, \ - { "sim", 0 }, \ - { "ads", 0 }, \ - { "yellowknife", 0 }, \ - { "mvme", 0 }, \ - { "emb", 0 }, \ - { "solaris-cclib", 0 }, \ - { "shlib", 0 }, \ - EXTRA_SUBTARGET_SWITCHES \ - { "newlib", 0 }, - -/* This is meant to be redefined in the host dependent files */ -#define EXTRA_SUBTARGET_SWITCHES - -/* Default ABI to use */ -#define RS6000_ABI_NAME "sysv" +#define TARGET_NO_EABI (! TARGET_EABI) /* Strings provided by SUBTARGET_OPTIONS */ extern const char *rs6000_abi_name; extern const char *rs6000_sdata_name; -#define SUBTARGET_OPTIONS \ - { "call-", &rs6000_abi_name}, \ - { "sdata=", &rs6000_sdata_name} +/* Override rs6000.h definition. */ +#undef SUBTARGET_OPTIONS +#define SUBTARGET_OPTIONS \ + { "call-", &rs6000_abi_name, "Select ABI calling convention." }, \ + { "sdata=", &rs6000_sdata_name, "Select method for sdata handling." } /* Max # of bytes for variables to automatically be put into the .sdata or .sdata2 sections. */ -extern int g_switch_value; /* value of the -G xx switch */ -extern int g_switch_set; /* whether -G xx was passed. */ +extern int g_switch_value; /* Value of the -G xx switch. */ +extern int g_switch_set; /* Whether -G xx was passed. */ -#ifndef SDATA_DEFAULT_SIZE #define SDATA_DEFAULT_SIZE 8 -#endif + +/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just + the same as -mminimal-toc. */ +/* Override rs6000.h definition. */ +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + { "bit-align", -MASK_NO_BITFIELD_TYPE, "Align to the base type of the bitfield." },\ + { "no-bit-align", MASK_NO_BITFIELD_TYPE, "Don't align to the base type of the bitfield." },\ + { "strict-align", MASK_STRICT_ALIGN, "Don't assume that unaligned accesses are handled by the system" },\ + { "no-strict-align", -MASK_STRICT_ALIGN, "Assume that unaligned accesses are handled by the system" },\ + { "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC, "Produce code relocatable at runtime." },\ + { "no-relocatable", -MASK_RELOCATABLE, "Don't produce code relocatable at runtime." },\ + { "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC, "Produce code relocatable at runtime." },\ + { "no-relocatable-lib", -MASK_RELOCATABLE, "Don't produce code relocatable at runtime." },\ + { "little-endian", MASK_LITTLE_ENDIAN, "Produce little endian code." }, \ + { "little", MASK_LITTLE_ENDIAN, "Produce little endian code." }, \ + { "big-endian", -MASK_LITTLE_ENDIAN, "Produce big endian code." }, \ + { "big", -MASK_LITTLE_ENDIAN, "Produce big endian code." }, \ + { "no-toc", 0, "no description yet" }, \ + { "toc", MASK_MINIMAL_TOC, "no description yet" }, \ + { "full-toc", MASK_MINIMAL_TOC, "no description yet" }, \ + { "prototype", MASK_PROTOTYPE, "no description yet" }, \ + { "no-prototype", -MASK_PROTOTYPE, "no description yet" }, \ + { "no-traceback", 0, "no description yet" }, \ + { "eabi", MASK_EABI, "Use EABI." }, \ + { "no-eabi", -MASK_EABI, "Don't use EABI." }, \ + { "regnames", MASK_REGNAMES, "Use alternate register names." }, \ + { "no-regnames", -MASK_REGNAMES, "Don't use alternate register names." },\ + { "sdata", 0, "no description yet" }, \ + { "no-sdata", 0, "no description yet" }, \ + { "sim", 0, "Link with libsim.a, libc.a and sim-crt0.o." }, \ + { "ads", 0, "Link with libads.a, libc.a and crt0.o." }, \ + { "yellowknife", 0, "Link with libyk.a, libc.a and crt0.o." }, \ + { "mvme", 0, "Link with libmvme.a, libc.a and crt0.o." }, \ + { "emb", 0, "Set the PPC_EMB bit in the ELF flags header" }, \ + { "vxworks", 0, "no description yet" }, \ + { "solaris-cclib", 0, "no description yet" }, \ + { "shlib", 0, "no description yet" }, \ + EXTRA_SUBTARGET_SWITCHES \ + { "newlib", 0, "no description yet" }, + +/* This is meant to be redefined in the host dependent files. */ +#define EXTRA_SUBTARGET_SWITCHES /* Sometimes certain combinations of command options do not make sense on a particular target machine. You can define a macro @@ -157,8 +174,6 @@ do { \ } \ else if (!strcmp (rs6000_abi_name, "aixdesc")) \ rs6000_current_abi = ABI_AIX; \ - else if (!strcmp (rs6000_abi_name, "nt")) \ - rs6000_current_abi = ABI_NT; \ else if (!strcmp (rs6000_abi_name, "linux")) \ rs6000_current_abi = ABI_V4; \ else if (!strcmp (rs6000_abi_name, "solaris")) \ @@ -226,16 +241,14 @@ do { \ error ("-mrelocatable and -mno-minimal-toc are incompatible."); \ } \ \ - if (TARGET_RELOCATABLE && \ - (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \ + if (TARGET_RELOCATABLE && rs6000_current_abi == ABI_AIX) \ { \ target_flags &= ~MASK_RELOCATABLE; \ error ("-mrelocatable and -mcall-%s are incompatible.", \ rs6000_abi_name); \ } \ \ - if (flag_pic > 1 && \ - (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \ + if (flag_pic > 1 && rs6000_current_abi == ABI_AIX) \ { \ flag_pic = 0; \ error ("-fPIC and -mcall-%s are incompatible.", \ @@ -248,13 +261,7 @@ do { \ error ("-mcall-aixdesc must be big endian"); \ } \ \ - if (rs6000_current_abi == ABI_NT && TARGET_BIG_ENDIAN) \ - { \ - target_flags |= MASK_LITTLE_ENDIAN; \ - error ("-mcall-nt must be little endian"); \ - } \ - \ - /* Treat -fPIC the same as -mrelocatable */ \ + /* Treat -fPIC the same as -mrelocatable. */ \ if (flag_pic > 1) \ target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \ \ @@ -263,42 +270,30 @@ do { \ \ } while (0) -/* Default ABI to compile code for */ -#define DEFAULT_ABI rs6000_current_abi - -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#define ASM_DEFAULT_SPEC "-mppc" - -#include "rs6000/rs6000.h" -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) +/* Override rs6000.h definition. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC750 +/* Override rs6000.h definition. */ +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_PPC750 /* System V.4 uses register 13 as a pointer to the small data area, so it is not available to the normal user. */ -#undef FIXED_R13 #define FIXED_R13 1 -/* System V.4 passes the first 8 floating arguments in registers, - instead of the first 13 like AIX does. */ -#undef FP_ARG_MAX_REG -#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) \ - ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) - -/* Size of the V.4 varargs area if needed */ +/* Size of the V.4 varargs area if needed. */ +/* Override rs6000.h definition. */ #undef RS6000_VARARGS_AREA #define RS6000_VARARGS_AREA ((rs6000_sysv_varargs_p) ? RS6000_VARARGS_SIZE : 0) -/* Override default big endianism */ -#undef BYTES_BIG_ENDIAN -#undef WORDS_BIG_ENDIAN -#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) -#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) +/* Override default big endianism definitions in rs6000.h. */ +#undef BYTES_BIG_ENDIAN +#undef WORDS_BIG_ENDIAN +#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) +#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) /* Define this to set the endianness to use in libgcc2.c, which can not depend on target_flags. */ @@ -308,88 +303,36 @@ do { \ #define LIBGCC2_WORDS_BIG_ENDIAN 0 #endif -/* Size of the outgoing register save area */ -#undef RS6000_REG_SAVE -#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_AIX_NODESC) \ - ? (TARGET_64BIT ? 64 : 32) \ - : 0) - -/* Size of the fixed area on the stack. For AIX, use the standard 6 word - area, otherwise use 2 words to store back chain & LR. */ -#undef RS6000_SAVE_AREA -#define RS6000_SAVE_AREA \ - (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8) << (TARGET_64BIT ? 1 : 0)) - /* Define cutoff for using external functions to save floating point. - Currently on V.4, always use inline stores */ -#undef FP_SAVE_INLINE + Currently on V.4, always use inline stores. */ #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) -/* Don't generate XCOFF debugging information. */ - -#undef XCOFF_DEBUGGING_INFO - -/* Don't use the COFF object file format. */ - -#undef OBJECT_FORMAT_COFF - -/* Don't bother to output .extern pseudo-ops. They are not needed by - ELF assemblers. */ - -#undef ASM_OUTPUT_EXTERNAL - /* Put jump tables in read-only memory, rather than in .text. */ -#undef JUMP_TABLES_IN_TEXT_SECTION #define JUMP_TABLES_IN_TEXT_SECTION 0 -/* Disable AIX-ism that disables turning -B into -L if the argument specifies a - relative file name. This breaks setting GCC_EXEC_PREFIX to D:\path under - Windows. */ -#undef RELATIVE_PREFIX_NOT_LINKDIR - -/* Undefine some things which are defined by the generic svr4.h. */ - -#undef ASM_DECLARE_FUNCTION_NAME -#undef ASM_FILE_END -#undef ASM_OUTPUT_CONSTRUCTOR -#undef ASM_OUTPUT_DESTRUCTOR -#undef ASM_OUTPUT_DEF -#undef ASM_OUTPUT_EXTERNAL_LIBCALL -#undef HANDLE_PRAGMA_PACK -#undef READONLY_DATA_SECTION -#undef SELECT_SECTION - -/* Use the regular svr4 definitions. */ - -#include "svr4.h" - -/* Prefix and suffix to use to saving floating point */ -#undef SAVE_FP_PREFIX -#undef SAVE_FP_SUFFIX +/* Prefix and suffix to use to saving floating point. */ #define SAVE_FP_PREFIX "_savefpr_" #define SAVE_FP_SUFFIX "_l" -/* Prefix and suffix to use to restoring floating point */ -#undef RESTORE_FP_PREFIX -#undef RESTORE_FP_SUFFIX +/* Prefix and suffix to use to restoring floating point. */ #define RESTORE_FP_PREFIX "_restfpr_" #define RESTORE_FP_SUFFIX "_l" /* Type used for ptrdiff_t, as a string used in a declaration. */ -#undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int" /* Type used for wchar_t, as a string used in a declaration. */ +/* Override svr4.h definition. */ #undef WCHAR_TYPE #define WCHAR_TYPE "long int" /* Width of wchar_t in bits. */ +/* Override svr4.h definition. */ #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE 32 -/* Make int foo : 8 not cause structures to be aligned to an int boundary */ - +/* Make int foo : 8 not cause structures to be aligned to an int boundary. */ +/* Override elfos.h definition. */ #undef PCC_BITFIELD_TYPE_MATTERS #define PCC_BITFIELD_TYPE_MATTERS (TARGET_BITFIELD_TYPE) @@ -399,21 +342,13 @@ do { \ #undef STRICT_ALIGNMENT #define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN) -/* Define this macro to be the value 1 if unaligned accesses have a cost - many times greater than aligned accesses, for example if they are - emulated in a trap handler. */ -#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \ - ((STRICT_ALIGNMENT \ - || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \ - && (ALIGN) < 4)) ? 1 : 0) - /* Alignment in bits of the stack boundary. Note, in order to allow building one set of libraries with -mno-eabi instead of eabi libraries and non-eabi versions, just use 64 as the stack boundary. */ #undef STACK_BOUNDARY #define STACK_BOUNDARY 64 -/* Real stack boundary as mandated by the appropriate ABI */ +/* Real stack boundary as mandated by the appropriate ABI. */ #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128) /* No data type wants to be aligned rounder than this. */ @@ -426,45 +361,47 @@ do { \ /* Use ELF style section commands. */ -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP "\t.section\t\".text\"" +#define TEXT_SECTION_ASM_OP "\t.section\t\".text\"" -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP "\t.section\t\".data\"" +#define DATA_SECTION_ASM_OP "\t.section\t\".data\"" -#undef BSS_SECTION_ASM_OP -#define BSS_SECTION_ASM_OP "\t.section\t\".bss\"" +#define BSS_SECTION_ASM_OP "\t.section\t\".bss\"" -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\"" +/* Override elfos.h definition. */ +#undef INIT_SECTION_ASM_OP +#define INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\"" -#undef FINI_SECTION_ASM_OP -#define FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\"" +/* Override elfos.h definition. */ +#undef FINI_SECTION_ASM_OP +#define FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\"" -#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\"" +#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\"" -/* Put PC relative got entries in .got2 */ -#define MINIMAL_TOC_SECTION_ASM_OP \ +/* Put PC relative got entries in .got2. */ +#define MINIMAL_TOC_SECTION_ASM_OP \ ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"") -/* Put relocatable data in .data, not .rodata so initialized pointers can be updated */ +/* Put relocatable data in .data, not .rodata so initialized pointers can be updated. */ +/* Override elfos.h definition. */ #undef CONST_SECTION_ASM_OP -#define CONST_SECTION_ASM_OP \ +#define CONST_SECTION_ASM_OP \ ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".data\"\t# .rodata" : "\t.section\t\".rodata\"") -#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\"" -#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\"" -#define SBSS_SECTION_ASM_OP \ +#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\"" +#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\"" +#define SBSS_SECTION_ASM_OP \ ((DEFAULT_ABI == ABI_SOLARIS) ? "\t.section\t\".sbss\",\"aw\"" : "\t.section\t\".sbss\",\"aw\",@nobits") /* Besides the usual ELF sections, we need a toc section. */ -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss, in_init, in_fini +/* Override elfos.h definition. */ +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss, in_init, in_fini -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ +/* Override elfos.h definition. */ +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ CONST_SECTION_FUNCTION \ CTORS_SECTION_FUNCTION \ DTORS_SECTION_FUNCTION \ @@ -475,17 +412,14 @@ do { \ INIT_SECTION_FUNCTION \ FINI_SECTION_FUNCTION -extern void toc_section (), sdata_section (), sdata2_section (); -extern void sbss_section (); - -#define TOC_SECTION_FUNCTION \ +#define TOC_SECTION_FUNCTION \ void \ toc_section () \ { \ if (in_section != in_toc) \ { \ in_section = in_toc; \ - if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ + if (DEFAULT_ABI == ABI_AIX \ && TARGET_MINIMAL_TOC \ && !TARGET_RELOCATABLE) \ { \ @@ -506,8 +440,7 @@ toc_section () \ else \ fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \ } \ - else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ - && !TARGET_RELOCATABLE) \ + else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE) \ fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \ else \ { \ @@ -522,7 +455,7 @@ toc_section () \ } \ } -#define SDATA_SECTION_FUNCTION \ +#define SDATA_SECTION_FUNCTION \ void \ sdata_section () \ { \ @@ -533,7 +466,7 @@ sdata_section () \ } \ } -#define SDATA2_SECTION_FUNCTION \ +#define SDATA2_SECTION_FUNCTION \ void \ sdata2_section () \ { \ @@ -544,7 +477,7 @@ sdata2_section () \ } \ } -#define SBSS_SECTION_FUNCTION \ +#define SBSS_SECTION_FUNCTION \ void \ sbss_section () \ { \ @@ -555,7 +488,7 @@ sbss_section () \ } \ } -#define INIT_SECTION_FUNCTION \ +#define INIT_SECTION_FUNCTION \ void \ init_section () \ { \ @@ -566,7 +499,7 @@ init_section () \ } \ } -#define FINI_SECTION_FUNCTION \ +#define FINI_SECTION_FUNCTION \ void \ fini_section () \ { \ @@ -586,18 +519,18 @@ fini_section () \ Do not define this macro if you put all constants in the read-only data section. */ -extern void rs6000_select_rtx_section (), rs6000_select_section (); - -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X) +/* Override elfos.h definition. */ +#undef SELECT_RTX_SECTION +#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X) /* A C statement or statements to switch to the appropriate section for output of DECL. DECL is either a `VAR_DECL' node or a constant of some sort. RELOC indicates whether forming the initial value of DECL requires link-time relocations. */ -#undef SELECT_SECTION -#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC) +/* Override elfos.h definition. */ +#undef SELECT_SECTION +#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC) /* Return non-zero if this entry is to be written into the constant pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST @@ -611,7 +544,7 @@ extern void rs6000_select_rtx_section (), rs6000_select_section (); allow floating point constants in the TOC if -mrelocatable. */ #undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \ +#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X) \ (TARGET_TOC \ && (GET_CODE (X) == SYMBOL_REF \ || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ @@ -634,14 +567,14 @@ extern void rs6000_select_rtx_section (), rs6000_select_section (); extern int rs6000_pic_labelno; +/* Override elfos.h definition. */ #undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ do { \ - const char *orig_name; \ const char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \ - STRIP_NAME_ENCODING (orig_name, NAME); \ \ - if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag)) \ + if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag) \ + && uses_TOC()) \ { \ char buf[256]; \ const char *buf_ptr; \ @@ -649,22 +582,27 @@ extern int rs6000_pic_labelno; ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno); \ \ ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); \ - STRIP_NAME_ENCODING (buf_ptr, buf); \ - fprintf (FILE, "\t%s %s-", init_ptr, buf_ptr); \ - \ + fprintf (FILE, "\t%s ", init_ptr); \ + assemble_name (FILE, buf); \ + putc ('-', FILE); \ ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); \ - fprintf (FILE, "%s\n", buf_ptr); \ + assemble_name (FILE, buf); \ + putc ('\n', FILE); \ } \ \ - fprintf (FILE, "\t%s\t %s,", TYPE_ASM_OP, orig_name); \ + fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (FILE, NAME); \ + putc (',', FILE); \ fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ putc ('\n', FILE); \ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ \ - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \ + if (DEFAULT_ABI == ABI_AIX) \ { \ - const char *desc_name = orig_name; \ + const char *desc_name, *orig_name; \ \ + STRIP_NAME_ENCODING (orig_name, NAME); \ + desc_name = orig_name; \ while (*desc_name == '.') \ desc_name++; \ \ @@ -679,23 +617,72 @@ extern int rs6000_pic_labelno; fprintf (FILE, "\t%s 0\n", init_ptr); \ fprintf (FILE, "\t.previous\n"); \ } \ - fprintf (FILE, "%s:\n", orig_name); \ + ASM_OUTPUT_LABEL (FILE, NAME); \ } while (0) +/* A C compound statement that outputs the assembler code for a thunk function, + used to implement C++ virtual function calls with multiple inheritance. The + thunk acts as a wrapper around a virtual function, adjusting the implicit + object parameter before handing control off to the real function. + + First, emit code to add the integer DELTA to the location that contains the + incoming first argument. Assume that this argument contains a pointer, and + is the one used to pass the this' pointer in C++. This is the incoming + argument *before* the function prologue, e.g. %o0' on a sparc. The + addition must preserve the values of all other incoming arguments. + + After the addition, emit code to jump to FUNCTION, which is a + FUNCTION_DECL'. This is a direct pure jump, not a call, and does not touch + the return address. Hence returning from FUNCTION will return to whoever + called the current thunk'. + + The effect must be as if FUNCTION had been called directly with the adjusted + first argument. This macro is responsible for emitting all of the code for + a thunk function; FUNCTION_PROLOGUE' and FUNCTION_EPILOGUE' are not + invoked. + + The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already been + extracted from it.) It might possibly be useful on some targets, but + probably not. + + If you do not define this macro, the target-independent code in the C++ + frontend will generate a less efficient heavyweight thunk that calls + FUNCTION instead of jumping to it. The generic approach does not support + varargs. */ + +#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ + output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION) + /* How to renumber registers for dbx and gdb. */ -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) +#define DBX_REGISTER_NUMBER(REGNO) (REGNO) + +/* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore + flag. The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */ + +#define LOCAL_LABEL_PREFIX "." +#define USER_LABEL_PREFIX "" /* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL. */ -#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, ".%s", PREFIX) +#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ + asm_fprintf (FILE, "%L%s", PREFIX) + +#define ASM_OUTPUT_LABEL(FILE,NAME) \ + (assemble_name (FILE, NAME), fputs (":\n", FILE)) + +/* This is how to output a command to make the user-level label named NAME + defined for reference from other files. */ + +#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ + do { fputs ("\t.globl ", FILE); \ + assemble_name (FILE, NAME); putc ('\n', FILE);} while (0) /* This is how to allocate empty space in some section. Use .space instead of .zero because the Solaris PowerPC assembler doesn't like it, and gas accepts either syntax. */ +/* Override elfos.h definition. */ #undef SKIP_ASM_OP #define SKIP_ASM_OP ".space" @@ -704,16 +691,13 @@ extern int rs6000_pic_labelno; the linker seems to want the alignment of data objects to depend on their types. We do exactly that here. */ -#ifndef LOCAL_ASM_OP -#define LOCAL_ASM_OP ".local" -#endif +#define LOCAL_ASM_OP ".local" -#ifndef LCOMM_ASM_OP -#define LCOMM_ASM_OP ".lcomm" -#endif +#define LCOMM_ASM_OP ".lcomm" -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ +/* Override elfos.h definition. */ +#undef ASM_OUTPUT_ALIGNED_LOCAL +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ do { \ if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \ && (SIZE) <= g_switch_value) \ @@ -737,17 +721,18 @@ do { \ } \ } while (0) -/* Describe how to emit uninitialized external linkage items */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ +/* Describe how to emit uninitialized external linkage items. */ +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ do { \ ASM_GLOBALIZE_LABEL (FILE, NAME); \ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ } while (0) -/* Switch Recognition by gcc.c. Add -G xx support */ +/* Switch Recognition by gcc.c. Add -G xx support. */ -#undef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) \ +/* Override svr4.h definition. */ +#undef SWITCH_TAKES_ARG +#define SWITCH_TAKES_ARG(CHAR) \ ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \ @@ -755,22 +740,26 @@ do { \ || (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'G') /* Output .file. */ -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ +/* Override elfos.h definition. */ +#undef ASM_FILE_START +#define ASM_FILE_START(FILE) \ do { \ output_file_directive ((FILE), main_input_filename); \ rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ } while (0) +extern int fixuplabelno; + /* This is how to output an assembler line defining an `int' constant. For -mrelocatable, we mark all addresses that need to be fixed up in the .fixup section. */ +/* Override rs6000.h definition. */ #undef ASM_OUTPUT_INT #define ASM_OUTPUT_INT(FILE,VALUE) \ do { \ static int recurse = 0; \ - if ((TARGET_RELOCATABLE || flag_pic) \ + if (TARGET_RELOCATABLE \ && in_section != in_toc \ && in_section != in_text \ && in_section != in_ctors \ @@ -780,29 +769,28 @@ do { \ && GET_CODE (VALUE) != CONST_DOUBLE \ && CONSTANT_P (VALUE)) \ { \ - static int labelno = 0; \ char buf[256]; \ - const char *p; \ \ recurse = 1; \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", labelno++); \ - STRIP_NAME_ENCODING (p, buf); \ - fprintf (FILE, "%s:\n", p); \ + ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno); \ + fixuplabelno++; \ + ASM_OUTPUT_LABEL (FILE, buf); \ fprintf (FILE, "\t.long ("); \ output_addr_const (FILE, (VALUE)); \ fprintf (FILE, ")@fixup\n"); \ - fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n"); \ + fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n"); \ ASM_OUTPUT_ALIGN (FILE, 2); \ - fprintf (FILE, "\t.long\t%s\n", p); \ - fprintf (FILE, "\t.previous\n"); \ + fprintf (FILE, "\t.long\t"); \ + assemble_name (FILE, buf); \ + fprintf (FILE, "\n\t.previous\n"); \ recurse = 0; \ } \ - /* Remove initial .'s to turn a -mcall-aixdesc or -mcall-nt function \ + /* Remove initial .'s to turn a -mcall-aixdesc function \ address into the address of the descriptor, not the function \ itself. */ \ else if (GET_CODE (VALUE) == SYMBOL_REF \ && XSTR (VALUE, 0)[0] == '.' \ - && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)) \ + && DEFAULT_ABI == ABI_AIX) \ { \ const char *name = XSTR (VALUE, 0); \ while (*name == '.') \ @@ -818,34 +806,66 @@ do { \ } \ } while (0) +/* This is how to output an assembler line defining an address + constant for the dwarf call unwinding information. + For -mrelocatable, we mark all addresses that need to be fixed up + in the .fixup section. */ + +#define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \ +do { \ + if (TARGET_RELOCATABLE) \ + { \ + char buf[256]; \ + const char *p; \ + \ + ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno); \ + fixuplabelno++; \ + ASM_OUTPUT_LABEL (FILE, buf); \ + fprintf (FILE, "\t.%dbyte\t", POINTER_SIZE / BITS_PER_UNIT); \ + assemble_name (FILE, LABEL); \ + fprintf (FILE, "\n"); \ + fprintf (FILE, "\t.section \".fixup\",\"aw\"\n"); \ + ASM_OUTPUT_ALIGN (FILE, 2); \ + fprintf (FILE, "\t.long\t"); \ + assemble_name (FILE, buf); \ + fprintf (FILE, "\n\t.previous\n"); \ + } \ + else \ + { \ + fprintf (FILE, "\t.%dbyte\t", POINTER_SIZE / BITS_PER_UNIT); \ + assemble_name (FILE, LABEL); \ + } \ +} while (0) + /* This is the end of what might become sysv4.h. */ /* Allow stabs and dwarf, for now, make stabs the default debugging type, - not dwarf since G++ doesn't support dwarf. */ + not dwarf since G++ doesn't support dwarf. */ #undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #define DBX_DEBUGGING_INFO -#define DWARF_DEBUGGING_INFO /* If we are referencing a function that is static or is known to be in this file, make the SYMBOL_REF special. We can use this to indicate that we can branch to this function without emitting a no-op after the - call. For real AIX and NT calling sequences, we also replace the + call. For real AIX calling sequences, we also replace the function name with the real name (1 or 2 leading .'s), rather than the function descriptor name. This saves a lot of overriding code - to readd the prefixes. */ + to read the prefixes. */ #undef ENCODE_SECTION_INFO -#define ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL) +#define ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL) -extern void rs6000_encode_section_info (); +/* The ELF version doesn't encode [DS] or whatever at the end of symbols. */ + +#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ + assemble_name (FILE, NAME) /* This macro gets just the user-specified name out of the string in a SYMBOL_REF. Discard - a leading * or @. */ -#undef STRIP_NAME_ENCODING -#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ + a leading * or @. */ +#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ do { \ const char *_name = SYMBOL_NAME; \ while (*_name == '*' || *_name == '@') \ @@ -856,32 +876,36 @@ do { \ /* This is how to output a reference to a user-level label named NAME. `assemble_name' uses this. */ -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ -do { \ - const char *_name = NAME; \ - while (*_name == '*' || *_name == '@') \ - _name++; \ - fputs (_name, FILE); \ +/* Override elfos.h definition. */ +#undef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ +do { \ + const char *_name = NAME; \ + if (*_name == '@') \ + _name++; \ + \ + if (*_name == '*') \ + fprintf (FILE, "%s", _name + 1); \ + else \ + asm_fprintf (FILE, "%U%s", _name); \ } while (0) -/* - * Switch into a generic section. - * - * We make the section read-only and executable for a function decl, - * read-only for a const data decl, and writable for a non-const data decl. - * - * If the section has already been defined, we must not - * emit the attributes here. The SVR4 assembler does not - * recognize section redefinitions. - * If DECL is NULL, no attributes are emitted. - * - * Note, Solaris as doesn't like @nobits, and gas can handle .sbss without - * needing @nobits. - */ +/* Switch into a generic section. + + We make the section read-only and executable for a function decl, + read-only for a const data decl, and writable for a non-const data decl. + + If the section has already been defined, we must not + emit the attributes here. The SVR4 assembler does not + recognize section redefinitions. + If DECL is NULL, no attributes are emitted. + + Note, Solaris as doesn't like @nobits, and gas can handle .sbss without + needing @nobits. */ +/* Override elfos.h definition. */ #undef ASM_OUTPUT_SECTION_NAME -#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ +#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ do { \ static struct section_info \ { \ @@ -923,8 +947,9 @@ do { \ } \ } while (0) -#undef ASM_OUTPUT_CONSTRUCTOR -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ +/* Override elfos.h definition. */ +#undef ASM_OUTPUT_CONSTRUCTOR +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ do { \ if (DEFAULT_ABI != ABI_SOLARIS) \ { \ @@ -943,8 +968,9 @@ do { \ /* A C statement (sans semicolon) to output an element in the table of global destructors. */ -#undef ASM_OUTPUT_DESTRUCTOR -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ +/* Override elfos.h definition. */ +#undef ASM_OUTPUT_DESTRUCTOR +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ do { \ if (DEFAULT_ABI != ABI_SOLARIS) \ { \ @@ -968,16 +994,17 @@ do { \ /* This is the end of what might become sysv4dbx.h. */ -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)"); +/* Override rs6000.h definition. */ +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)"); -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ +#define CPP_PREDEFINES \ "-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)" -/* Pass various options to the assembler */ -#undef ASM_SPEC -#define ASM_SPEC "%(asm_cpu) \ +/* Pass various options to the assembler. */ +/* Override svr4.h definition. */ +#undef ASM_SPEC +#define ASM_SPEC "%(asm_cpu) \ %{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \ %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \ %{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \ @@ -987,34 +1014,26 @@ do { \ %{mcall-solaris: -mlittle -msolaris} \ %{mcall-linux: -mbig} }}}}" -#ifndef CC1_ENDIAN_BIG_SPEC -#define CC1_ENDIAN_BIG_SPEC "" -#endif +#define CC1_ENDIAN_BIG_SPEC "" -#ifndef CC1_ENDIAN_LITTLE_SPEC -#define CC1_ENDIAN_LITTLE_SPEC "\ +#define CC1_ENDIAN_LITTLE_SPEC "\ %{!mstrict-align: %{!mno-strict-align: \ -mstrict-align \ }}" -#endif -#ifndef CC1_ENDIAN_DEFAULT_SPEC -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)" -#endif +#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)" -#undef CC1_SPEC -/* Pass -G xxx to the compiler and set correct endian mode */ -#define CC1_SPEC "%{G*} \ +/* Pass -G xxx to the compiler and set correct endian mode. */ +#define CC1_SPEC "%{G*} \ %{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \ %{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \ %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-nt: -mlittle %(cc1_endian_little) } \ %{mcall-aixdesc: -mbig %(cc1_endian_big) } \ %{mcall-solaris: -mlittle %(cc1_endian_little) } \ %{mcall-linux: -mbig %(cc1_endian_big) } \ - %{!mcall-nt: %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \ + %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \ %(cc1_endian_default) \ - }}}} \ + }}} \ }}}} \ %{mcall-solaris: -mregnames } \ %{mno-sdata: -msdata=none } \ @@ -1027,8 +1046,7 @@ do { \ %{mno-sdata: -msdata=none} \ %{profile: -p}" -/* Don't put -Y P, for cross compilers */ -#undef LINK_PATH_SPEC +/* Don't put -Y P, for cross compilers. */ #ifndef CROSS_COMPILE #define LINK_PATH_SPEC "\ %{!R*:%{L*:-R %*}} \ @@ -1045,8 +1063,7 @@ do { \ #define LINK_PATH_SPEC "" #endif -/* Default starting address if specified */ -#ifndef LINK_START_SPEC +/* Default starting address if specified. */ #define LINK_START_SPEC "\ %{mads: %(link_start_ads) } \ %{myellowknife: %(link_start_yellowknife) } \ @@ -1055,14 +1072,12 @@ do { \ %{mcall-linux: %(link_start_linux) } \ %{mcall-solaris: %(link_start_solaris) } \ %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(link_start_default) }}}}}}" -#endif -#ifndef LINK_START_DEFAULT_SPEC #define LINK_START_DEFAULT_SPEC "" -#endif -#undef LINK_SPEC -#define LINK_SPEC "\ +/* Override svr4.h definition. */ +#undef LINK_SPEC +#define LINK_SPEC "\ %{h*} %{v:-V} %{G*} \ %{Wl,*:%*} %{YP,*} %{R*} \ %{Qy:} %{!Qn:-Qy} \ @@ -1076,7 +1091,6 @@ do { \ #define NO_SHARED_LIB_SUPPORT #endif -#undef LINK_SHLIB_SPEC #ifndef NO_SHARED_LIB_SUPPORT /* Shared libraries are default. */ #define LINK_SHLIB_SPEC "\ @@ -1097,13 +1111,13 @@ do { \ #endif /* Override the default target of the linker. */ -#undef LINK_TARGET_SPEC #define LINK_TARGET_SPEC "\ %{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-solaris: -oformat elf32-powerpcle}}}}}" +%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ + %{mcall-solaris: -oformat elf32-powerpcle} \ + }}}}" -/* Any specific OS flags */ -#ifndef LINK_OS_SPEC +/* Any specific OS flags. */ #define LINK_OS_SPEC "\ %{mads: %(link_os_ads) } \ %{myellowknife: %(link_os_yellowknife) } \ @@ -1112,39 +1126,39 @@ do { \ %{mcall-linux: %(link_os_linux) } \ %{mcall-solaris: %(link_os_solaris) } \ %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(link_os_default) }}}}}}" -#endif -#ifndef LINK_OS_DEFAULT_SPEC #define LINK_OS_DEFAULT_SPEC "" -#endif -#undef CPP_SYSV_SPEC #define CPP_SYSV_SPEC \ "%{mrelocatable*: -D_RELOCATABLE} \ %{fpic: -D__PIC__=1 -D__pic__=1} \ %{!fpic: %{fPIC: -D__PIC__=2 -D__pic__=2}} \ -%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \ +%{mcall-sysv: -D_CALL_SYSV} \ %{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \ -%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \ -%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT}" +%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %(cpp_sysv_default) }}} \ +%{msoft-float: -D_SOFT_FLOAT} \ +%{!msoft-float: %{!mhard-float: \ + %{mcpu=401: -D_SOFT_FLOAT} \ + %{mcpu=403: -D_SOFT_FLOAT} \ + %{mcpu=ec603e: -D_SOFT_FLOAT} \ + %{mcpu=801: -D_SOFT_FLOAT} \ + %{mcpu=821: -D_SOFT_FLOAT} \ + %{mcpu=823: -D_SOFT_FLOAT} \ + %{mcpu=860: -D_SOFT_FLOAT} \ + %{!mcpu*: %(cpp_float_default) }}}" + +/* Whether floating point is disabled by default. */ +#define CPP_FLOAT_DEFAULT_SPEC "" -#undef CPP_SYSV_DEFAULT_SPEC #define CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV" -#ifndef CPP_ENDIAN_BIG_SPEC #define CPP_ENDIAN_BIG_SPEC "-D_BIG_ENDIAN -D__BIG_ENDIAN__ -Amachine(bigendian)" -#endif -#ifndef CPP_ENDIAN_LITTLE_SPEC #define CPP_ENDIAN_LITTLE_SPEC "-D_LITTLE_ENDIAN -D__LITTLE_ENDIAN__ -Amachine(littleendian)" -#endif -#ifndef CPP_ENDIAN_SOLARIS_SPEC #define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" -#endif /* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file. */ -#undef CPP_ENDIAN_SPEC #define CPP_ENDIAN_SPEC \ "%{mlittle: %(cpp_endian_little) } \ %{mlittle-endian: %(cpp_endian_little) } \ @@ -1152,16 +1166,15 @@ do { \ %{mbig-endian: %(cpp_endian_big) } \ %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ %{mcall-solaris: %(cpp_endian_solaris) } \ - %{mcall-nt: %(cpp_endian_little) } \ %{mcall-linux: %(cpp_endian_big) } \ %{mcall-aixdesc: %(cpp_endian_big) } \ - %{!mcall-solaris: %{!mcall-linux: %{!mcall-nt: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}}" + %{!mcall-solaris: %{!mcall-linux: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}" -#undef CPP_ENDIAN_DEFAULT_SPEC #define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_big)" -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \ +/* Override rs6000.h definition. */ +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \ %{mads: %(cpp_os_ads) } \ %{myellowknife: %(cpp_os_yellowknife) } \ %{mmvme: %(cpp_os_mvme) } \ @@ -1170,11 +1183,10 @@ do { \ %{mcall-solaris: %(cpp_os_solaris) } \ %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}}}" -#ifndef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "" -#endif +#define CPP_OS_DEFAULT_SPEC "" -#undef STARTFILE_SPEC +/* Override svr4.h definition. */ +#undef STARTFILE_SPEC #define STARTFILE_SPEC "\ %{mads: %(startfile_ads) } \ %{myellowknife: %(startfile_yellowknife) } \ @@ -1184,9 +1196,9 @@ do { \ %{mcall-solaris: %(startfile_solaris) } \ %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(startfile_default) }}}}}}" -#undef STARTFILE_DEFAULT_SPEC #define STARTFILE_DEFAULT_SPEC "" +/* Override svr4.h definition. */ #undef LIB_SPEC #define LIB_SPEC "\ %{mads: %(lib_ads) } \ @@ -1197,13 +1209,13 @@ do { \ %{mcall-solaris: %(lib_solaris) } \ %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(lib_default) }}}}}}" +/* Override rs6000.h definition. */ #undef LIBGCC_SPEC #define LIBGCC_SPEC "libgcc.a%s" -#ifndef LIB_DEFAULT_SPEC #define LIB_DEFAULT_SPEC "" -#endif +/* Override svr4.h definition. */ #undef ENDFILE_SPEC #define ENDFILE_SPEC "\ %{mads: ecrtn.o%s} \ @@ -1212,113 +1224,64 @@ do { \ %{msim: ecrtn.o%s} \ %{mcall-linux: %(endfile_linux) } \ %{mcall-solaris: scrtn.o%s} \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(endfile_default) }}}}}}" +%{mvxworks: %(endfile_vxworks) } \ +%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %{!mvxworks: %(endfile_default) }}}}}}}" -#undef ENDFILE_DEFAULT_SPEC #define ENDFILE_DEFAULT_SPEC "" /* Motorola ADS support. */ -#ifndef LIB_ADS_SPEC #define LIB_ADS_SPEC "--start-group -lads -lc --end-group" -#endif -#ifndef STARTFILE_ADS_SPEC #define STARTFILE_ADS_SPEC "ecrti.o%s crt0.o%s" -#endif -#ifndef ENDFILE_ADS_SPEC #define ENDFILE_ADS_SPEC "ecrtn.o%s" -#endif -#ifndef LINK_START_ADS_SPEC #define LINK_START_ADS_SPEC "-T ads.ld%s" -#endif -#ifndef LINK_OS_ADS_SPEC #define LINK_OS_ADS_SPEC "" -#endif -#ifndef CPP_OS_ADS_SPEC #define CPP_OS_ADS_SPEC "" -#endif /* Motorola Yellowknife support. */ -#ifndef LIB_YELLOWKNIFE_SPEC #define LIB_YELLOWKNIFE_SPEC "--start-group -lyk -lc --end-group" -#endif -#ifndef STARTFILE_YELLOWKNIFE_SPEC #define STARTFILE_YELLOWKNIFE_SPEC "ecrti.o%s crt0.o%s" -#endif -#ifndef ENDFILE_YELLOWKNIFE_SPEC #define ENDFILE_YELLOWKNIFE_SPEC "ecrtn.o%s" -#endif -#ifndef LINK_START_YELLOWKNIFE_SPEC #define LINK_START_YELLOWKNIFE_SPEC "-T yellowknife.ld%s" -#endif -#ifndef LINK_OS_YELLOWKNIFE_SPEC #define LINK_OS_YELLOWKNIFE_SPEC "" -#endif -#ifndef CPP_OS_YELLOWKNIFE_SPEC #define CPP_OS_YELLOWKNIFE_SPEC "" -#endif /* Motorola MVME support. */ -#ifndef LIB_MVME_SPEC #define LIB_MVME_SPEC "--start-group -lmvme -lc --end-group" -#endif -#ifndef STARTFILE_MVME_SPEC #define STARTFILE_MVME_SPEC "ecrti.o%s crt0.o%s" -#endif -#ifndef ENDFILE_MVME_SPEC #define ENDFILE_MVME_SPEC "ecrtn.o%s" -#endif -#ifndef LINK_START_MVME_SPEC #define LINK_START_MVME_SPEC "%{!Wl,-T*: %{!T*: -Ttext 0x40000}}" -#endif -#ifndef LINK_OS_MVME_SPEC #define LINK_OS_MVME_SPEC "" -#endif -#ifndef CPP_OS_MVME_SPEC #define CPP_OS_MVME_SPEC "" -#endif /* PowerPC simulator based on netbsd system calls support. */ -#ifndef LIB_SIM_SPEC #define LIB_SIM_SPEC "--start-group -lsim -lc --end-group" -#endif -#ifndef STARTFILE_SIM_SPEC #define STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s" -#endif -#ifndef ENDFILE_SIM_SPEC #define ENDFILE_SIM_SPEC "ecrtn.o%s" -#endif -#ifndef LINK_START_SIM_SPEC #define LINK_START_SIM_SPEC "-Ttext 0x10000074" -#endif -#ifndef LINK_OS_SIM_SPEC #define LINK_OS_SIM_SPEC "" -#endif -#ifndef CPP_OS_SIM_SPEC #define CPP_OS_SIM_SPEC "" -#endif /* GNU/Linux support. */ -#ifndef LIB_LINUX_SPEC #ifdef USE_GNULIBC_1 #define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \ %{!mnewlib: -lc }" @@ -1327,30 +1290,20 @@ do { \ %{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \ %{profile:-lc_p} %{!profile:-lc}}}" #endif -#endif -#ifndef STARTFILE_LINUX_SPEC #define STARTFILE_LINUX_SPEC "\ %{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \ %{mnewlib: ecrti.o%s} \ %{!mnewlib: crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" -#endif -#ifndef ENDFILE_LINUX_SPEC #define ENDFILE_LINUX_SPEC "\ %{mnewlib: ecrtn.o%s} \ %{!mnewlib: %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s}" -#endif -#ifndef LINK_START_LINUX_SPEC #define LINK_START_LINUX_SPEC "-Ttext 0x400074" -#endif -#ifndef LINK_OS_LINUX_SPEC #define LINK_OS_LINUX_SPEC "" -#endif -#ifndef CPP_OS_LINUX_SPEC #ifdef USE_GNULIBC_1 #define CPP_OS_LINUX_SPEC "-D__unix__ -D__linux__ \ %{!undef:%{!ansi:%{!std=*:-Dunix -Dlinux}%{std=gnu*:-Dunix -Dlinux}}} \ @@ -1360,7 +1313,6 @@ do { \ %{!undef:%{!ansi:%{!std=*:-Dunix -Dlinux}%{std=gnu*:-Dunix -Dlinux}}} \ -Asystem(unix) -Asystem(posix) %{pthread:-D_REENTRANT}" #endif -#endif /* Solaris support. */ /* For Solaris, Gcc automatically adds in one of the files @@ -1374,7 +1326,6 @@ do { \ value of `_lib_version') if they will act in a strictly ANSI conforming manner or not. */ -#ifndef LIB_SOLARIS_SPEC #define LIB_SOLARIS_SPEC "\ %{mnewlib: --start-group -lsolaris -lc --end-group } \ %{!mnewlib: \ @@ -1385,48 +1336,83 @@ do { \ %{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \ %{solaris-cclib: /opt/SUNWspro/SC4.0/lib/libabi.a} \ %{!shared: %{!symbolic: -lc }}}" -#endif -#ifndef STARTFILE_SOLARIS_SPEC #define STARTFILE_SOLARIS_SPEC "\ %{!msolaris-cclib: scrti.o%s scrt0.o%s} \ %{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crti.o%s /opt/SUNWspro/SC4.0/lib/crt1.o%s}" -#endif -#ifndef ENDFILE_SOLARIS_SPEC #define ENDFILE_SOLARIS_SPEC "\ %{!msolaris-cclib: scrtn.o%s} \ %{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crtn.o%s}" -#endif -#ifndef LINK_START_SOLARIS_SPEC -#ifdef CROSS_COMPILER +#ifdef CROSS_COMPILE #define LINK_START_SOLARIS_SPEC "-Ttext 0x2000074" #else #define LINK_START_SOLARIS_SPEC "" #endif -#endif -#ifndef LINK_OS_SOLARIS_SPEC #define LINK_OS_SOLARIS_SPEC "" -#endif -#ifndef CPP_OS_SOLARIS_SPEC #define CPP_OS_SOLARIS_SPEC "-D__ppc -D__sun__=1 -D__unix__ -D__svr4__ -D__SVR4__ \ %{!undef:%{!ansi:%{!std=*:-Dsun=1 -Dunix -DSVR4 -D__EXTENSIONS__} \ %{std=gnu*:-Dsun=1 -Dunix -DSVR4 -D__EXTENSIONS__}}} \ -Amachine(prep)" -#endif + +/* VxWorks support. */ +/* VxWorks does all the library stuff itself. */ +#define LIB_VXWORKS_SPEC "" + +/* VxWorks provides the functionality of crt0.o and friends itself. */ + +#define STARTFILE_VXWORKS_SPEC "" + +#define ENDFILE_VXWORKS_SPEC "" + +/* Because it uses ld -r, vxworks has no start/end files, nor starting + address. */ + +#define LINK_START_VXWORKS_SPEC "" + +#define LINK_OS_VXWORKS_SPEC "-r" + +#define CPP_OS_VXWORKS_SPEC "\ +-DCPU_FAMILY=PPC \ +%{!mcpu*: \ + %{mpowerpc*: -DCPU=PPC603} \ + %{!mno-powerpc: -DCPU=PPC603}} \ +%{mcpu=powerpc: -DCPU=PPC603} \ +%{mcpu=401: -DCPU=PPC403} \ +%{mcpu=403: -DCPU=PPC403} \ +%{mcpu=601: -DCPU=PPC601} \ +%{mcpu=602: -DCPU=PPC603} \ +%{mcpu=603: -DCPU=PPC603} \ +%{mcpu=603e: -DCPU=PPC603} \ +%{mcpu=ec603e: -DCPU=PPC603} \ +%{mcpu=604: -DCPU=PPC604} \ +%{mcpu=604e: -DCPU=PPC604} \ +%{mcpu=620: -DCPU=PPC604} \ +%{mcpu=740: -DCPU=PPC603} \ +%{mcpu=750: -DCPU=PPC603} \ +%{mcpu=801: -DCPU=PPC603} \ +%{mcpu=821: -DCPU=PPC603} \ +%{mcpu=823: -DCPU=PPC603} \ +%{mcpu=860: -DCPU=PPC603}" /* Define any extra SPECS that the compiler needs to generate. */ +/* Override rs6000.h definition. */ #undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ +#define SUBTARGET_EXTRA_SPECS \ + { "cpp_sysv", CPP_SYSV_SPEC }, \ + { "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \ + { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \ + { "cpp_endian", CPP_ENDIAN_SPEC }, \ { "lib_ads", LIB_ADS_SPEC }, \ { "lib_yellowknife", LIB_YELLOWKNIFE_SPEC }, \ { "lib_mvme", LIB_MVME_SPEC }, \ { "lib_sim", LIB_SIM_SPEC }, \ { "lib_linux", LIB_LINUX_SPEC }, \ { "lib_solaris", LIB_SOLARIS_SPEC }, \ + { "lib_vxworks", LIB_VXWORKS_SPEC }, \ { "lib_default", LIB_DEFAULT_SPEC }, \ { "startfile_ads", STARTFILE_ADS_SPEC }, \ { "startfile_yellowknife", STARTFILE_YELLOWKNIFE_SPEC }, \ @@ -1434,6 +1420,7 @@ do { \ { "startfile_sim", STARTFILE_SIM_SPEC }, \ { "startfile_linux", STARTFILE_LINUX_SPEC }, \ { "startfile_solaris", STARTFILE_SOLARIS_SPEC }, \ + { "startfile_vxworks", STARTFILE_VXWORKS_SPEC }, \ { "startfile_default", STARTFILE_DEFAULT_SPEC }, \ { "endfile_ads", ENDFILE_ADS_SPEC }, \ { "endfile_yellowknife", ENDFILE_YELLOWKNIFE_SPEC }, \ @@ -1441,6 +1428,7 @@ do { \ { "endfile_sim", ENDFILE_SIM_SPEC }, \ { "endfile_linux", ENDFILE_LINUX_SPEC }, \ { "endfile_solaris", ENDFILE_SOLARIS_SPEC }, \ + { "endfile_vxworks", ENDFILE_VXWORKS_SPEC }, \ { "endfile_default", ENDFILE_DEFAULT_SPEC }, \ { "link_path", LINK_PATH_SPEC }, \ { "link_shlib", LINK_SHLIB_SPEC }, \ @@ -1452,6 +1440,7 @@ do { \ { "link_start_sim", LINK_START_SIM_SPEC }, \ { "link_start_linux", LINK_START_LINUX_SPEC }, \ { "link_start_solaris", LINK_START_SOLARIS_SPEC }, \ + { "link_start_vxworks", LINK_START_VXWORKS_SPEC }, \ { "link_start_default", LINK_START_DEFAULT_SPEC }, \ { "link_os", LINK_OS_SPEC }, \ { "link_os_ads", LINK_OS_ADS_SPEC }, \ @@ -1460,6 +1449,7 @@ do { \ { "link_os_sim", LINK_OS_SIM_SPEC }, \ { "link_os_linux", LINK_OS_LINUX_SPEC }, \ { "link_os_solaris", LINK_OS_SOLARIS_SPEC }, \ + { "link_os_vxworks", LINK_OS_VXWORKS_SPEC }, \ { "link_os_default", LINK_OS_DEFAULT_SPEC }, \ { "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \ { "cc1_endian_little", CC1_ENDIAN_LITTLE_SPEC }, \ @@ -1467,12 +1457,14 @@ do { \ { "cpp_endian_big", CPP_ENDIAN_BIG_SPEC }, \ { "cpp_endian_little", CPP_ENDIAN_LITTLE_SPEC }, \ { "cpp_endian_solaris", CPP_ENDIAN_SOLARIS_SPEC }, \ + { "cpp_float_default", CPP_FLOAT_DEFAULT_SPEC }, \ { "cpp_os_ads", CPP_OS_ADS_SPEC }, \ { "cpp_os_yellowknife", CPP_OS_YELLOWKNIFE_SPEC }, \ { "cpp_os_mvme", CPP_OS_MVME_SPEC }, \ { "cpp_os_sim", CPP_OS_SIM_SPEC }, \ { "cpp_os_linux", CPP_OS_LINUX_SPEC }, \ { "cpp_os_solaris", CPP_OS_SOLARIS_SPEC }, \ + { "cpp_os_vxworks", CPP_OS_VXWORKS_SPEC }, \ { "cpp_os_default", CPP_OS_DEFAULT_SPEC }, /* Define this macro as a C expression for the initializer of an @@ -1484,7 +1476,6 @@ do { \ the target makefile fragment or if none of the options listed in `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ -#undef MULTILIB_DEFAULTS #define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" } /* Define this macro if the code for function profiling should come @@ -1493,5 +1484,4 @@ do { \ #define PROFILE_BEFORE_PROLOGUE 1 /* Function name to call to do profiling. */ -#undef RS6000_MCOUNT #define RS6000_MCOUNT "_mcount" diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h index 1e21acd7b86..a19dd787991 100644 --- a/gcc/config/rs6000/sysv4le.h +++ b/gcc/config/rs6000/sysv4le.h @@ -1,6 +1,6 @@ /* Target definitions for GNU compiler for a little endian PowerPC running System V.4 - Copyright (C) 1995, Free Software Foundation, Inc. + Copyright (C) 1995, 2000 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GNU CC. @@ -34,7 +34,9 @@ Boston, MA 02111-1307, USA. */ #undef LINK_TARGET_SPEC #define LINK_TARGET_SPEC "\ %{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-linux: -oformat elf32-powerpc}}}}}" +%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ + %{mcall-linux: -oformat elf32-powerpc} \ + }}}}" /* Define this macro as a C expression for the initializer of an array of string to tell the driver program which options are diff --git a/gcc/config/rs6000/t-aix43 b/gcc/config/rs6000/t-aix43 index 20507008296..814ef42e6f3 100644 --- a/gcc/config/rs6000/t-aix43 +++ b/gcc/config/rs6000/t-aix43 @@ -49,3 +49,11 @@ MULTILIB_MATCHES = msoft-float=mcpu?403 \ LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib + +# Both 32-bit and 64-bit objects in archives +AR_FLAGS_FOR_TARGET=-X32_64 rc + +# We need -lld for collect2 (actually this only matters +# for a native compiler, but this is as good a place as any +# to define the symbol). +CLIB=-lld diff --git a/gcc/config/rs6000/t-ppccomm b/gcc/config/rs6000/t-ppccomm index 408f535f85d..231c9cec446 100644 --- a/gcc/config/rs6000/t-ppccomm +++ b/gcc/config/rs6000/t-ppccomm @@ -39,7 +39,7 @@ MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \ msoft-float=mcpu?823 \ msoft-float=mcpu?860 MULTILIB_MATCHES_ENDIAN = mlittle=mlittle-endian mbig=mbig-endian -MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi +MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi mcall-sysv=mcall-linux LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas index 8ea37beebd5..0765a9e4c6e 100644 --- a/gcc/config/rs6000/t-ppcgas +++ b/gcc/config/rs6000/t-ppcgas @@ -3,16 +3,17 @@ MULTILIB_OPTIONS = msoft-float \ mlittle/mbig \ - mcall-sysv/mcall-aix/mcall-linux + mcall-sysv/mcall-aix \ + fleading-underscore MULTILIB_DIRNAMES = nof \ le be \ - cs ca lin + cs ca \ + und MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align -MULTILIB_EXCEPTIONS = *mbig/*mcall-linux* \ - *mlittle/*mcall-linux* \ - *msoft-float/*mcall-linux* +MULTILIB_EXCEPTIONS = *mcall-aix/*fleading-underscore* \ + *mlittle/*mcall-aix* MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ ${MULTILIB_MATCHES_ENDIAN} \ diff --git a/gcc/config/rs6000/t-winnt b/gcc/config/rs6000/t-winnt deleted file mode 100644 index 1aafae47422..00000000000 --- a/gcc/config/rs6000/t-winnt +++ /dev/null @@ -1,41 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -EXTRA_PARTS = crti.o crtn.o - -# These are really part of libgcc1, but this will cause them to be -# built correctly, so... [taken from t-sparclite] -LIB2FUNCS_EXTRA = ntstack.S - -# We want fine grained libraries, so use the new code to build the -# floating point emulation libraries. -FPBIT = fp-bit.c -DPBIT = 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 - -ntstack.S: $(srcdir)/config/rs6000/ntstack.asm - cat $(srcdir)/config/rs6000/ntstack.asm > ntstack.S - -# For NT we build crti.o and crtn.o which serve to add begin and -# end labels for the static constructors and destructors. - -# Assemble startup files. -crti.s: $(srcdir)/config/rs6000/nt-ci.asm - cat $(srcdir)/config/rs6000/nt-ci.asm >crti.s - -crtn.s: $(srcdir)/config/rs6000/nt-cn.asm - cat $(srcdir)/config/rs6000/nt-cn.asm >crtn.s - -crti.o: crti.s - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crti.o crti.s - -crtn.o: crtn.s - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtn.o crtn.s diff --git a/gcc/config/rs6000/tramp.asm b/gcc/config/rs6000/tramp.asm index 47ab7d65b1f..5f3048990d9 100644 --- a/gcc/config/rs6000/tramp.asm +++ b/gcc/config/rs6000/tramp.asm @@ -1,6 +1,6 @@ /* Special support for trampolines * - * Copyright (C) 1996, 1997 Free Software Foundation, Inc. + * Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. * Written By Michael Meissner * * This file is free software; you can redistribute it and/or modify it @@ -33,21 +33,20 @@ * the executable file might be covered by the GNU General Public License. */ -/* Set up trampolines */ +/* Set up trampolines. */ .file "tramp.asm" .section ".text" #include "ppc-asm.h" - .globl __trampoline_initial - .type __trampoline_initial,@object + .type trampoline_initial,@object .align 2 -__trampoline_initial: +trampoline_initial: mflr r0 bl 1f -.Lfunc = .-__trampoline_initial +.Lfunc = .-trampoline_initial .long 0 /* will be replaced with function address */ -.Lchain = .-__trampoline_initial +.Lchain = .-trampoline_initial .long 0 /* will be replaced with static chain */ 1: mflr r11 mtlr r0 @@ -56,17 +55,9 @@ __trampoline_initial: mtctr r0 bctr -__trampoline_size = .-__trampoline_initial - .size __trampoline_initial,__trampoline_size +trampoline_size = .-trampoline_initial + .size trampoline_initial,trampoline_size - .section ".got2","aw" -.LCTOC1 = .+32768 -.Ltramp = .-.LCTOC1 - .long __trampoline_initial-4 - - .section ".text" -.LCL0: - .long .LCTOC1-.LCF0 /* R3 = stack address to store trampoline */ /* R4 = length of trampoline area */ @@ -74,18 +65,16 @@ __trampoline_size = .-__trampoline_initial /* R6 = static chain */ FUNC_START(__trampoline_setup) - mflr r0 /* save return address */ - bl .LCF0 /* load up __trampoline_initial into r7 */ + mflr r0 /* save return address */ + bl .LCF0 /* load up __trampoline_initial into r7 */ .LCF0: mflr r11 - lwz r12,(.LCL0-.LCF0)(r11) - add r11,r12,r11 - lwz r7,.Ltramp(r11) /* trampoline address -4 */ + addi r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */ - li r8,__trampoline_size /* verify that the trampoline is big enough */ + li r8,trampoline_size /* verify that the trampoline is big enough */ cmpw cr1,r8,r4 - srwi r4,r4,2 /* # words to move */ - addi r9,r3,-4 /* adjust pointer for lwzu */ + srwi r4,r4,2 /* # words to move */ + addi r9,r3,-4 /* adjust pointer for lwzu */ mtctr r4 blt cr1,.Labort @@ -115,6 +104,6 @@ FUNC_START(__trampoline_setup) blr .Labort: - bl abort + bl FUNC_NAME(abort) FUNC_END(__trampoline_setup) -/* END CYGNUS LOCAL -- waiting for FSF sources to be restored/meissner */ + diff --git a/gcc/config/rs6000/vxppc.h b/gcc/config/rs6000/vxppc.h index 0fb8aac9cb0..fa25760264c 100644 --- a/gcc/config/rs6000/vxppc.h +++ b/gcc/config/rs6000/vxppc.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. Vxworks PowerPC version. - Copyright (C) 1996, 1999 Free Software Foundation, Inc. + Copyright (C) 1996, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -18,62 +18,41 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* This file primarily exists to give specs for the PowerPC running on - VxWorks. */ +/* This file just exists to give specs for the PowerPC running on VxWorks. */ #include "rs6000/sysv4.h" -/* ??? This file redefines CPP_SPEC which is wrong. It should instead define - one of the extra specs that gets included in CPP_SPEC. For instance, - CPP_OS_DEFAULT_SPEC. The mrelocatable line was copied from CPP_SYSV_SPEC. - There is probably other stuff missing. */ - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \ -%{mads: %(cpp_os_ads) } \ -%{myellowknife: %(cpp_os_yellowknife) } \ -%{mmvme: %(cpp_os_mvme) } \ -%{msim: %(cpp_os_sim) } \ -%{mcall-linux: %(cpp_os_linux) } \ -%{mcall-solaris: %(cpp_os_solaris) } \ -%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}}} \ -%{!DCPU=*: \ - %{!mcpu*: -DCPU=PPC603} \ - %{mcpu=powerpc: -DCPU=PPC603} \ - %{mcpu=403: -DCPU=PPC403} \ - %{mcpu=601: -DCPU=PPC601} \ - %{mcpu=603: -DCPU=PPC603} \ - %{mcpu=604: -DCPU=PPC604}}" +/* Reset defaults */ +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)" -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "\ --D__vxworks -Asystem(vxworks) -Asystem(embedded) \ --Acpu(powerpc) -Amachine(powerpc)" +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_vxworks)" -/* VxWorks does all the library stuff itself. */ +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)" -#undef LIB_SPEC -#define LIB_SPEC "" +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)" -/* VxWorks uses object files, not loadable images. make linker just - combine objects. */ +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)" -#undef LINK_SPEC -#define LINK_SPEC "-r" +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)" -/* VxWorks provides the functionality of crt0.o and friends itself. */ +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "\ +-D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \ +-Acpu(powerpc) -Amachine(powerpc)" -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "" +/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */ +#undef CPP_ENDIAN_BIG_SPEC +#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)" -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "" +#undef CPP_ENDIAN_LITTLE_SPEC +#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" /* We use stabs-in-elf for debugging */ #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -/* VxWorks normally doesn't have an unaligned handler, so make -mstrict-align - the default. */ -#undef SUBTARGET_DEFAULT -#define SUBTARGET_DEFAULT MASK_STRICT_ALIGN diff --git a/gcc/config/rs6000/vxppcle.h b/gcc/config/rs6000/vxppcle.h new file mode 100644 index 00000000000..fadec99ed78 --- /dev/null +++ b/gcc/config/rs6000/vxppcle.h @@ -0,0 +1,58 @@ +/* Definitions of target machine for GNU compiler. Vxworks PowerPC version. + Copyright (C) 1996, 1998 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* This file just exists to give specs for the PowerPC running on VxWorks. */ + +#include "rs6000/sysv4le.h" + +/* Reset defaults */ +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)" + +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_vxworks)" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)" + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "\ +-D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \ +-Acpu(powerpc) -Amachine(powerpc)" + +/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */ +#undef CPP_ENDIAN_BIG_SPEC +#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)" + +#undef CPP_ENDIAN_LITTLE_SPEC +#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)" + +/* We use stabs-in-elf for debugging */ +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h deleted file mode 100644 index 796e487b0de..00000000000 --- a/gcc/config/rs6000/win-nt.h +++ /dev/null @@ -1,483 +0,0 @@ -/* Definitions of target machine for GNU compiler, for PowerPC - running Windows/NT. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Say this is Windows/NT for the other config files. */ -#define WINDOWS_NT 1 -#define COFF_WITH_PE 1 - -/* Default ABI to compile code for */ -#define DEFAULT_ABI ABI_NT - -#define CPP_DEFAULT_SPEC "-D_ARCH_PPC" - -#define ASM_DEFAULT_SPEC "-mppc" - -/* Pseudo target that we can test in the md file. */ -#define TARGET_WINDOWS_NT 1 - -#include "rs6000/rs6000.h" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWERPC - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-DWIN32 -D_WIN32 \ - -DWINNT -D__STDC__=0 -DALMOST_STDC \ - -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)" - -#if 0 -#include "winnt/win-nt.h" -#endif - -#undef LIB_SPEC -#define LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \ - USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \ - %{!mwindows:-subsystem console -e mainCRTStartup} \ - %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \ - %{v}" - -#undef LINK_SPEC -#define LINK_SPEC "%{v:-V}" - -/* Allow switches specified in LIB_SPEC, but don't do anything with them - in the compiler. */ -#undef SUBTARGET_SWITCHES -#define SUBTARGET_SWITCHES \ - { "windows", 0 }, \ - { "crtmt", 0 }, - -#undef XCOFF_DEBUGGING_INFO - -/* this is pure coff, not xcoff */ -#define SDB_DEBUGGING_INFO -#define DBX_DEBUGGING_INFO - -#undef SDB_DELIM -#define SDB_DELIM ";" - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -/* NT always runs little endian */ -#undef BYTES_BIG_ENDIAN -#define BYTES_BIG_ENDIAN 0 - -#undef WORDS_BIG_ENDIAN -#define WORDS_BIG_ENDIAN 0 - -/* Define cutoff for using external functions to save floating point. - Currently on NT, always use inline stores */ -#undef FP_SAVE_INLINE -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) - -/* Note, little endian systems trap on unaligned addresses, so never - turn off strict alignment in that case. */ - -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT 1 - -/* Align stack to 16 byte boundaries */ -#undef STACK_BOUNDARY -#define STACK_BOUNDARY 128 - -/* No data type wants to be aligned rounder than this. */ -#undef BIGGEST_ALIGNMENT -#define BIGGEST_ALIGNMENT 128 - -/* NT aligns internal doubles in structures on dword boundaries. */ -#undef BIGGEST_FIELD_ALIGNMENT -#define BIGGEST_FIELD_ALIGNMENT 64 - -#undef ADJUST_FIELD_ALIGN -#undef ROUND_TYPE_ALIGN - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (PowerPC PE)"); - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC) - -/* MEM representing address to save the TOC register */ -#undef RS6000_SAVE_TOC -#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \ - plus_constant (virtual_incoming_args_rtx, - -RS6000_SAVE_AREA - 8)) - -/* Windows NT specifies that r13 is reserved to the OS, so it is not available - to the normal user. */ - -#undef FIXED_R13 -#define FIXED_R13 1 - -/* This says how to output an assembler line - to define a global common symbol. */ - -#undef ASM_OUTPUT_ALIGNED_COMMON -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \ - do { fputs ("\t.comm \t", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - if ( (SIZE) > 4) \ - fprintf ((FILE), ",%d,%d\n", (SIZE), 3); \ - else \ - fprintf( (FILE), ",%d\n", (SIZE)); \ - } while (0) - -#undef ASM_OUTPUT_ALIGNED_LOCAL - -/* This says how to output an assembler line - to define a global common symbol. */ - -#undef ASM_OUTPUT_COMMON -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ - do { fputs ("\t.comm \t", (FILE)); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%d\n", (SIZE)); } while (0) - -/* This says how to output an assembler line - to define an aligned local common symbol. */ - -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ -do { \ - bss_section (); \ - ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - ASM_OUTPUT_SKIP (FILE, SIZE); \ -} while (0) - -/* Describe how to emit uninitialized external linkage items */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ -do { \ - ASM_GLOBALIZE_LABEL (FILE, NAME); \ - ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ -} while (0) - -/* This says out to put a global symbol in the BSS section */ -#undef ASM_OUTPUT_ALIGNED_BSS -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ - asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) - - -/* Stuff to force fit us into the Motorola PPC assembler */ - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -do { \ - output_file_directive ((FILE), main_input_filename); \ - rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \ - data_section (); \ -} while (0) - -#undef ASM_FILE_END - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ -{ \ - tree exception_args; \ - int i; \ - \ - if (TREE_PUBLIC (DECL)) \ - { \ - fprintf (FILE, "\t.globl .."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - \ - fprintf (FILE, "\n#\tFunction: '.."); \ - assemble_name (FILE, NAME); \ - fputs ("'\n", FILE); \ - fputs ("#\tText in section: \n\n", FILE); \ - fputs ("#\tSetup MS Structured-Exception-Handling\n", FILE); \ - fputs ("\t.pdata\n", FILE); \ - fputs ("\t.align 2\n", FILE); \ - fputs ("\t.ualong ..", FILE); \ - assemble_name (FILE, NAME); \ - fputs (",", FILE); \ - assemble_name (FILE, NAME); \ - fputs (".e,", FILE); \ - exception_args = lookup_attribute ("exception", \ - TYPE_ATTRIBUTES (TREE_TYPE (DECL))); \ - \ - if (exception_args) \ - exception_args = TREE_VALUE (exception_args); \ - \ - for (i = 0; i < 2; i++) \ - { \ - if (!exception_args) \ - fputs ("0,", FILE); \ - else \ - { \ - tree field = TREE_VALUE (exception_args); \ - exception_args = TREE_PURPOSE (exception_args); \ - if (TREE_CODE (field) == STRING_CST) \ - fprintf (FILE, "%.*s,", TREE_STRING_LENGTH (field), \ - TREE_STRING_POINTER (field)); \ - else if (TREE_CODE (field) == IDENTIFIER_NODE) \ - fprintf (FILE, "%.*s,", IDENTIFIER_LENGTH (field), \ - IDENTIFIER_POINTER (field)); \ - else \ - abort (); \ - } \ - } \ - \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ".b\n\n"); \ - fprintf (FILE, "#\tSwitch to the relocation section\n"); \ - fprintf (FILE, "\t.reldata\n"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n"); \ - fprintf (FILE, "\t.ualong .."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",.toc\n"); \ - \ - if (lookup_attribute ("dllexport", \ - TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \ - { \ - fprintf (FILE, "\t.globl __imp_"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n__imp_"); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n\t.ulong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } \ - \ - fprintf (FILE, "\t.section .text\n\t.align 2\n.."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ":\n"); \ - fprintf (FILE, "\t.function\t.."); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ -} - -/* This is how to output an assembler line defining a `double' constant. */ - -#undef ASM_OUTPUT_DOUBLE -#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t.ualong 0x%lx\n\t.long 0x%lx\n", \ - t[0] & 0xffffffff, t[1] & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \ - fprintf (FILE, "\t.double %s\n", str); \ - } \ - } - -/* This is how to output an assembler line defining a `float' constant. */ - -#undef ASM_OUTPUT_FLOAT -#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.ualong 0x%lx\n", t & 0xffffffff); \ - } \ - else \ - { \ - char str[30]; \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t.float %s\n", str); \ - } \ - } - -/* Output before instructions. */ -#undef TEXT_SECTION_ASM_OP -#define TEXT_SECTION_ASM_OP "\t.text" - -/* Output before writable data. */ -#undef DATA_SECTION_ASM_OP -#define DATA_SECTION_ASM_OP "\t.data" - -/* Output to the bss section. */ -#undef BSS_SECTION_ASM_OP -#define BSS_SECTION_ASM_OP "\t.section .bss" - -/* Define the extra sections we need. We define a dummy TOC section, - plus sections to hold the list of static constructors (.ctors) and - destructors (.dtors). */ - -#undef READONLY_DATA_SECTION -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_toc, in_ctors, in_dtors - -/* Define the routines to implement these extra sections. */ - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION \ - TOC_SECTION_FUNCTION \ - -#define TOC_SECTION_FUNCTION \ -void \ -toc_section () \ -{ \ -} - -#define CTORS_SECTION_ASM_OP ".section\t.ctors" -#define CTORS_SECTION_FUNCTION \ -void \ -ctors_section () \ -{ \ - if (in_section != in_ctors) \ - { \ - fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ - in_section = in_ctors; \ - } \ -} - -#define DTORS_SECTION_ASM_OP ".section\t.dtors" -#define DTORS_SECTION_FUNCTION \ -void \ -dtors_section () \ -{ \ - if (in_section != in_dtors) \ - { \ - fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ - in_section = in_dtors; \ - } \ -} - -#undef SELECT_SECTION -#undef SELECT_RTX_SECTION - -/* Make sure __main gets called */ -#define INVOKE__main 1 - -/* A C statement (sans semicolon) to output an element in the table of - global constructors. */ -#undef ASM_OUTPUT_CONSTRUCTOR -#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ - do { \ - ctors_section (); \ - fprintf (FILE, "\t.ualong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* A C statement (sans semicolon) to output an element in the table of - global destructors. */ -#undef ASM_OUTPUT_DESTRUCTOR -#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ - do { \ - dtors_section (); \ - fprintf (FILE, "\t.ualong "); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, "\n"); \ - } while (0) - - -/* Text to write out after a CALL that may be replaced by glue code by - the loader. The motorola asm demands that, for dll support, a .znop - be issued after a bl instruction, and the symbol on the .znop is the - symbol on the bl instruction */ - -#undef RS6000_CALL_GLUE -#define RS6000_CALL_GLUE "nop #\tFIXME: only works for non-dll calls." - -#define RS6000_CALL_GLUE2 ".znop " - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY - -/* Output something to declare an external symbol to the assembler. Most - assemblers don't need this. */ - -#undef ASM_OUTPUT_EXTERNAL - -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ \ - char *_name; \ - rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - _name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \ - strcpy (_name, XSTR (_symref, 0)); \ - XSTR (_symref, 0) = _name; \ - } \ - else \ - _name = XSTR (_symref, 0); \ - \ - if (DECL_FUNCTION_CODE (DECL) == 0) \ - { \ - fputs ("\t.extern ", FILE); \ - assemble_name (FILE, _name); \ - putc ('\n', FILE); \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - { \ - fputs ("\t.extern ..", FILE); \ - assemble_name (FILE, _name); \ - putc ('\n', FILE); \ - } \ - } \ -} - -/* Similar, but for libcall. We only have to worry about the function name, - not that of the descriptor. */ - -#undef ASM_OUTPUT_EXTERNAL_LIBCALL - -#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ -{ fprintf (FILE, "\t.extern .."); \ - assemble_name (FILE, XSTR (FUN, 0)); \ - fprintf (FILE, "\n"); \ -} - -/* The prefix to add to user-visible assembler symbols. */ - -#define USER_LABEL_PREFIX ".." - -/* Eliminate AIX style constant pool processing */ -#undef LEGITIMATE_CONSTANT_POOL_BASE_P -#define LEGITIMATE_CONSTANT_POOL_BASE_P(X) 0 - -#undef LEGITIMATE_CONSTANT_POOL_ADDRESS_P -#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) 0 - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY - -#undef ASM_IDENTIFY_GCC -#define ASM_IDENTIFY_GCC(x) - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - The trampoline should set the static chain pointer to value placed - into the trampoline and should branch to the specified routine. */ -#define TRAMPOLINE_TEMPLATE(FILE) rs6000_trampoline_template (FILE) diff --git a/gcc/config/rs6000/x-aix41 b/gcc/config/rs6000/x-aix41 index 69c666b43bc..f978be17295 100644 --- a/gcc/config/rs6000/x-aix41 +++ b/gcc/config/rs6000/x-aix41 @@ -2,11 +2,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 diff --git a/gcc/config/rs6000/x-aix41-gld b/gcc/config/rs6000/x-aix41-gld deleted file mode 100644 index ca444ae013c..00000000000 --- a/gcc/config/rs6000/x-aix41-gld +++ /dev/null @@ -1,12 +0,0 @@ -# configuration for IBM RS/6000 running AIX 4.1+ - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lld - -# f771 and cc1plus overflow the AIX TOC, however gld doesn't support -bbigtoc -# BOOT_LDFLAGS=-Wl,-bbigtoc diff --git a/gcc/config/rs6000/x-aix43 b/gcc/config/rs6000/x-aix43 deleted file mode 100644 index 072d925fe2d..00000000000 --- a/gcc/config/rs6000/x-aix43 +++ /dev/null @@ -1,15 +0,0 @@ -# configuration for IBM RS/6000 running AIX 4.3+ - -# Show we need to use the C version of ALLOCA -ALLOCA=alloca.o - -# We need -lld for collect2 (actually this only matters -# for a native compiler, but this is as good a place as any -# to define the symbol). -CLIB=-lld - -# f771 and cc1plus overflow the AIX TOC -BOOT_LDFLAGS=-Wl,-bbigtoc - -# Both 32-bit and 64-bit objects in archives -AR_FOR_TARGET=ar -X32_64 diff --git a/gcc/configure b/gcc/configure index 4fdd12f15af..432f12039dc 100755 --- a/gcc/configure +++ b/gcc/configure @@ -1369,7 +1369,7 @@ else fi # Find some useful tools -for ac_prog in mawk gawk nawk awk +for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -5694,6 +5694,15 @@ for machine in $build $host $target; do extra_headers=ppc-asm.h thread_file='vxworks' ;; + powerpcle-wrs-vxworks*) + cpu_type=rs6000 + xm_file="rs6000/xm-sysv4.h" + xm_defines="USG POSIX" + tm_file=rs6000/vxppcle.h + tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" + extra_headers=ppc-asm.h + thread_file='vxworks' + ;; powerpcle-*-sysv* | powerpcle-*-elf*) tm_file=rs6000/sysv4le.h xm_file="rs6000/xm-sysv4.h" @@ -5722,27 +5731,6 @@ for machine in $build $host $target; do fi extra_headers=ppc-asm.h ;; - powerpcle-*-winnt* ) - tm_file=rs6000/win-nt.h - tmake_file=rs6000/t-winnt -# extra_objs=pe.o - if test x$enable_threads = xyes; then - thread_file='win32' - fi - extra_headers=ppc-asm.h - ;; - powerpcle-*-pe | powerpcle-*-cygwin*) - tm_file=rs6000/cygwin.h - xm_file="rs6000/xm-cygwin.h ${xm_file}" - tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin -# extra_objs=pe.o - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - extra_headers=ppc-asm.h - ;; powerpcle-*-solaris2*) tm_file=rs6000/sol2.h xm_file="rs6000/xm-sysv4.h" @@ -5781,36 +5769,21 @@ for machine in $build $host $target; do else tmake_file=rs6000/t-newas fi - if test "$gnu_ld" = yes - then - xmake_file=rs6000/x-aix41-gld - else - xmake_file=rs6000/x-aix41 - fi + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;; rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*) tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 + tmake_file=rs6000/t-aix43 + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;; rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 + tmake_file=rs6000/t-aix43 + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;; @@ -6678,7 +6651,7 @@ fi echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6 -echo "configure:6682: checking for strerror in -lcposix" >&5 +echo "configure:6655: checking for strerror in -lcposix" >&5 ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6686,7 +6659,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6720,12 +6693,12 @@ fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:6724: checking for working const" >&5 +echo "configure:6697: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -6795,21 +6768,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:6799: checking for inline" >&5 +echo "configure:6772: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -6835,12 +6808,12 @@ EOF esac echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:6839: checking for off_t" >&5 +echo "configure:6812: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -6868,12 +6841,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:6872: checking for size_t" >&5 +echo "configure:6845: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -6903,19 +6876,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:6907: checking for working alloca.h" >&5 +echo "configure:6880: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:6919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -6936,12 +6909,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:6940: checking for alloca" >&5 +echo "configure:6913: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -7001,12 +6974,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:7005: checking whether alloca needs Cray hooks" >&5 +echo "configure:6978: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7035: checking for $ac_func" >&5 +echo "configure:7008: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7086,7 +7059,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:7090: checking stack direction for C alloca" >&5 +echo "configure:7063: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7094,7 +7067,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -7138,17 +7111,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7142: checking for $ac_hdr" >&5 +echo "configure:7115: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7125: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7177,12 +7150,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7181: checking for $ac_func" >&5 +echo "configure:7154: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7230,7 +7203,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:7234: checking for working mmap" >&5 +echo "configure:7207: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7238,7 +7211,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -7406,17 +7379,17 @@ unistd.h sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7410: checking for $ac_hdr" >&5 +echo "configure:7383: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7446,12 +7419,12 @@ done strdup __argz_count __argz_stringify __argz_next do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7450: checking for $ac_func" >&5 +echo "configure:7423: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7503,12 +7476,12 @@ done for ac_func in stpcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7507: checking for $ac_func" >&5 +echo "configure:7480: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7565,19 +7538,19 @@ EOF if test $ac_cv_header_locale_h = yes; then echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 -echo "configure:7569: checking for LC_MESSAGES" >&5 +echo "configure:7542: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF -if { (eval echo configure:7581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* am_cv_val_LC_MESSAGES=yes else @@ -7598,7 +7571,7 @@ EOF fi fi echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 -echo "configure:7602: checking whether NLS is requested" >&5 +echo "configure:7575: checking whether NLS is requested" >&5 # Check whether --enable-nls or --disable-nls was given. if test "${enable_nls+set}" = set; then enableval="$enable_nls" @@ -7618,7 +7591,7 @@ fi EOF echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 -echo "configure:7622: checking whether included gettext is requested" >&5 +echo "configure:7595: checking whether included gettext is requested" >&5 # Check whether --with-included-gettext or --without-included-gettext was given. if test "${with_included_gettext+set}" = set; then withval="$with_included_gettext" @@ -7637,17 +7610,17 @@ fi ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 -echo "configure:7641: checking for libintl.h" >&5 +echo "configure:7614: checking for libintl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7624: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7664,19 +7637,19 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 -echo "configure:7668: checking for gettext in libc" >&5 +echo "configure:7641: checking for gettext in libc" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return (int) gettext ("") ; return 0; } EOF -if { (eval echo configure:7680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libc=yes else @@ -7692,7 +7665,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 if test "$gt_cv_func_gettext_libc" != "yes"; then echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 -echo "configure:7696: checking for bindtextdomain in -lintl" >&5 +echo "configure:7669: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7700,7 +7673,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7727,12 +7700,12 @@ fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 -echo "configure:7731: checking for gettext in libintl" >&5 +echo "configure:7704: checking for gettext in libintl" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 -echo "configure:7736: checking for gettext in -lintl" >&5 +echo "configure:7709: checking for gettext in -lintl" >&5 ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7740,7 +7713,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7790,7 +7763,7 @@ EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7794: checking for $ac_word" >&5 +echo "configure:7767: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7824,12 +7797,12 @@ fi for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7828: checking for $ac_func" >&5 +echo "configure:7801: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7879,7 +7852,7 @@ done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7883: checking for $ac_word" >&5 +echo "configure:7856: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7915,7 +7888,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7919: checking for $ac_word" >&5 +echo "configure:7892: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7947,7 +7920,7 @@ else fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share @@ -7978,7 +7951,7 @@ fi if test "$CATOBJEXT" = "NONE"; then echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 -echo "configure:7982: checking whether catgets can be used" >&5 +echo "configure:7955: checking whether catgets can be used" >&5 # Check whether --with-catgets or --without-catgets was given. if test "${with_catgets+set}" = set; then withval="$with_catgets" @@ -7991,7 +7964,7 @@ fi if test "$nls_cv_use_catgets" = "yes"; then echo $ac_n "checking for main in -li""... $ac_c" 1>&6 -echo "configure:7995: checking for main in -li" >&5 +echo "configure:7968: checking for main in -li" >&5 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7999,14 +7972,14 @@ else ac_save_LIBS="$LIBS" LIBS="-li $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8034,12 +8007,12 @@ else fi echo $ac_n "checking for catgets""... $ac_c" 1>&6 -echo "configure:8038: checking for catgets" >&5 +echo "configure:8011: checking for catgets" >&5 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_catgets=yes" else @@ -8084,7 +8057,7 @@ EOF # Extract the first word of "gencat", so it can be a program name with args. set dummy gencat; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8088: checking for $ac_word" >&5 +echo "configure:8061: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8120,7 +8093,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8124: checking for $ac_word" >&5 +echo "configure:8097: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8157,7 +8130,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8161: checking for $ac_word" >&5 +echo "configure:8134: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8192,7 +8165,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8196: checking for $ac_word" >&5 +echo "configure:8169: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8250,7 +8223,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8254: checking for $ac_word" >&5 +echo "configure:8227: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8284,7 +8257,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8288: checking for $ac_word" >&5 +echo "configure:8261: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8320,7 +8293,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:8324: checking for $ac_word" >&5 +echo "configure:8297: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8413,7 +8386,7 @@ fi LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 -echo "configure:8417: checking for catalogs to be installed" >&5 +echo "configure:8390: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in @@ -8441,17 +8414,17 @@ echo "configure:8417: checking for catalogs to be installed" >&5 if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 -echo "configure:8445: checking for linux/version.h" >&5 +echo "configure:8418: checking for linux/version.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8455: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8526,7 +8499,7 @@ fi echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6 -echo "configure:8530: checking whether windows registry support is requested" >&5 +echo "configure:8503: checking whether windows registry support is requested" >&5 if test x$enable_win32_registry != xno; then cat >> confdefs.h <<\EOF #define ENABLE_WIN32_REGISTRY 1 @@ -8555,7 +8528,7 @@ esac if test x$enable_win32_registry != xno; then echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6 -echo "configure:8559: checking registry key on windows hosts" >&5 +echo "configure:8532: checking registry key on windows hosts" >&5 cat >> confdefs.h <&6 -echo "configure:8735: checking assembler alignment features" >&5 +echo "configure:8708: checking assembler alignment features" >&5 gcc_cv_as= gcc_cv_as_alignment_features= gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas @@ -8852,7 +8825,7 @@ fi echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6 echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6 -echo "configure:8856: checking assembler subsection support" >&5 +echo "configure:8829: checking assembler subsection support" >&5 gcc_cv_as_subsections= if test x$gcc_cv_as != x; then # Check if we have .subsection @@ -8892,7 +8865,7 @@ fi echo "$ac_t""$gcc_cv_as_subsections" 1>&6 echo $ac_n "checking assembler weak support""... $ac_c" 1>&6 -echo "configure:8896: checking assembler weak support" >&5 +echo "configure:8869: checking assembler weak support" >&5 gcc_cv_as_weak= if test x$gcc_cv_as != x; then # Check if we have .weak @@ -8911,7 +8884,7 @@ echo "$ac_t""$gcc_cv_as_weak" 1>&6 case "$target" in sparc*-*-*) echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6 -echo "configure:8915: checking assembler .register pseudo-op support" >&5 +echo "configure:8888: checking assembler .register pseudo-op support" >&5 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8941,7 +8914,7 @@ EOF case "$tm_file" in *64*) echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6 -echo "configure:8945: checking for 64 bit support in assembler ($gcc_cv_as)" >&5 +echo "configure:8918: checking for 64 bit support in assembler ($gcc_cv_as)" >&5 if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8986,7 +8959,7 @@ EOF if test "x$gcc_cv_as_flags64" != xno; then echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6 -echo "configure:8990: checking for assembler offsetable %lo() support" >&5 +echo "configure:8963: checking for assembler offsetable %lo() support" >&5 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9025,7 +8998,7 @@ EOF i[34567]86-*-*) echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 -echo "configure:9029: checking assembler instructions" >&5 +echo "configure:9002: checking assembler instructions" >&5 gcc_cv_as_instructions= if test x$gcc_cv_as != x; then set "filds fists" "filds mem; fists mem" diff --git a/gcc/configure.in b/gcc/configure.in index 75fa2e29651..0b79091a278 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -3078,6 +3078,15 @@ changequote([,])dnl extra_headers=ppc-asm.h thread_file='vxworks' ;; + powerpcle-wrs-vxworks*) + cpu_type=rs6000 + xm_file="rs6000/xm-sysv4.h" + xm_defines="USG POSIX" + tm_file=rs6000/vxppcle.h + tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" + extra_headers=ppc-asm.h + thread_file='vxworks' + ;; powerpcle-*-sysv* | powerpcle-*-elf*) tm_file=rs6000/sysv4le.h xm_file="rs6000/xm-sysv4.h" @@ -3106,27 +3115,6 @@ changequote([,])dnl fi extra_headers=ppc-asm.h ;; - powerpcle-*-winnt* ) - tm_file=rs6000/win-nt.h - tmake_file=rs6000/t-winnt -# extra_objs=pe.o - if test x$enable_threads = xyes; then - thread_file='win32' - fi - extra_headers=ppc-asm.h - ;; - powerpcle-*-pe | powerpcle-*-cygwin*) - tm_file=rs6000/cygwin.h - xm_file="rs6000/xm-cygwin.h ${xm_file}" - tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin -# extra_objs=pe.o - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - extra_headers=ppc-asm.h - ;; powerpcle-*-solaris2*) tm_file=rs6000/sol2.h xm_file="rs6000/xm-sysv4.h" @@ -3171,12 +3159,7 @@ changequote([,])dnl else tmake_file=rs6000/t-newas fi - if test "$gnu_ld" = yes - then - xmake_file=rs6000/x-aix41-gld - else - xmake_file=rs6000/x-aix41 - fi + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;; @@ -3184,13 +3167,8 @@ changequote(,)dnl rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*) changequote([,])dnl tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 + tmake_file=rs6000/t-aix43 + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;; @@ -3198,13 +3176,8 @@ changequote(,)dnl rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) changequote([,])dnl tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 + tmake_file=rs6000/t-aix43 + xmake_file=rs6000/x-aix41 float_format=none use_collect2=yes ;;