diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-01 05:50:51 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-01 05:50:51 +0000 |
commit | e49e8bd540832217538f9720f502da8c20f1f9b0 (patch) | |
tree | 8f6bc6f898cfafd809ea3bf6f2a7660a896f9a40 /gcc/config | |
parent | b528597c9f3f2e3a64a664c7be6c82a7c2688287 (diff) | |
download | gcc-e49e8bd540832217538f9720f502da8c20f1f9b0.tar.gz |
2008-07-01 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r137307
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@137309 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
49 files changed, 1714 insertions, 1303 deletions
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index b5e2cb96547..067d9f7ec79 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -173,11 +173,11 @@ arc_init (void) char *tmp; /* Set the pseudo-ops for the various standard sections. */ - arc_text_section = tmp = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1); + arc_text_section = tmp = XNEWVEC (char, strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1); sprintf (tmp, ARC_SECTION_FORMAT, arc_text_string); - arc_data_section = tmp = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1); + arc_data_section = tmp = XNEWVEC (char, strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1); sprintf (tmp, ARC_SECTION_FORMAT, arc_data_string); - arc_rodata_section = tmp = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1); + arc_rodata_section = tmp = XNEWVEC (char, strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1); sprintf (tmp, ARC_SECTION_FORMAT, arc_rodata_string); arc_init_reg_tables (); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c7f223a6b63..fa3d06dcd75 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15609,8 +15609,8 @@ arm_expand_unop_builtin (enum insn_code icode, static int neon_builtin_compare (const void *a, const void *b) { - const neon_builtin_datum *key = a; - const neon_builtin_datum *memb = b; + const neon_builtin_datum *const key = (const neon_builtin_datum *) a; + const neon_builtin_datum *const memb = (const neon_builtin_datum *) b; unsigned int soughtcode = key->base_fcode; if (soughtcode >= memb->base_fcode @@ -15629,7 +15629,8 @@ locate_neon_builtin_icode (int fcode, neon_itype *itype) int idx; key.base_fcode = fcode; - found = bsearch (&key, &neon_builtin_data[0], ARRAY_SIZE (neon_builtin_data), + found = (neon_builtin_datum *) + bsearch (&key, &neon_builtin_data[0], ARRAY_SIZE (neon_builtin_data), sizeof (neon_builtin_data[0]), neon_builtin_compare); gcc_assert (found); idx = fcode - (int) found->base_fcode; diff --git a/gcc/config/arm/pe.c b/gcc/config/arm/pe.c index 90bc7299386..8b8adff0e14 100644 --- a/gcc/config/arm/pe.c +++ b/gcc/config/arm/pe.c @@ -112,7 +112,7 @@ arm_mark_dllexport (tree decl) else if (arm_dllexport_name_p (oldname)) return; /* already done */ - newname = alloca (strlen (oldname) + 4); + newname = XALLOCAVEC (char, strlen (oldname) + 4); sprintf (newname, "%ce.%s", ARM_PE_FLAG_CHAR, oldname); /* We pass newname through get_identifier to ensure it has a unique @@ -178,7 +178,7 @@ arm_mark_dllimport (tree decl) TREE_PUBLIC (decl) = 1; } - newname = alloca (strlen (oldname) + 11); + newname = XALLOCAVEC (char, strlen (oldname) + 11); sprintf (newname, "%ci.__imp_%s", ARM_PE_FLAG_CHAR, oldname); /* We pass newname through get_identifier to ensure it has a unique @@ -250,7 +250,7 @@ arm_pe_unique_section (tree decl, int reloc) else prefix = ".data$"; len = strlen (name) + strlen (prefix); - string = alloca (len + 1); + string = XALLOCAVEC (char, len + 1); sprintf (string, "%s%s", prefix, name); DECL_SECTION_NAME (decl) = build_string (len, string); diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index a7600cf80e2..05a5e495cea 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -2436,7 +2436,7 @@ bfin_init_machine_status (void) { struct machine_function *f; - f = ggc_alloc_cleared (sizeof (struct machine_function)); + f = GGC_CNEW (struct machine_function); return f; } @@ -3838,7 +3838,7 @@ bfin_optimize_loop (loop_info loop) if (JUMP_P (last_insn)) { - loop_info inner = bb->aux; + loop_info inner = (loop_info) bb->aux; if (inner && inner->outer == loop && inner->loop_end == last_insn diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index 8efcb5ea189..6f2d16c98d6 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -121,7 +121,7 @@ extern int target_flags; if (bfin_si_revision != -1) \ { \ /* space of 0xnnnn and a NUL */ \ - char *buf = alloca (7); \ + char *buf = XALLOCAVEC (char, 7); \ \ sprintf (buf, "0x%04x", bfin_si_revision); \ builtin_define_with_value ("__SILICON_REVISION__", buf, 0); \ diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 810366f5681..3a0eb2de066 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -2533,7 +2533,7 @@ cris_init_expanders (void) static struct machine_function * cris_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } /* Split a 2 word move (DI or presumably DF) into component parts. diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c index ba0eca14ed0..9f3b444d6bc 100644 --- a/gcc/config/darwin-c.c +++ b/gcc/config/darwin-c.c @@ -179,7 +179,7 @@ darwin_pragma_ms_struct (cpp_reader *pfile ATTRIBUTE_UNUSED) BAD ("junk at end of '#pragma ms_struct'"); } -static struct { +static struct frameworks_in_use { size_t len; const char *name; cpp_dir* dir; @@ -211,8 +211,8 @@ add_framework (const char *name, size_t len, cpp_dir *dir) { max_frameworks = i*2; max_frameworks += i == 0; - frameworks_in_use = xrealloc (frameworks_in_use, - max_frameworks*sizeof(*frameworks_in_use)); + frameworks_in_use = XRESIZEVEC (struct frameworks_in_use, + frameworks_in_use, max_frameworks); } dir_name = XNEWVEC (char, len + 1); memcpy (dir_name, name, len); diff --git a/gcc/config/darwin-driver.c b/gcc/config/darwin-driver.c index 524f31ec04c..02226308639 100644 --- a/gcc/config/darwin-driver.c +++ b/gcc/config/darwin-driver.c @@ -93,7 +93,7 @@ darwin_default_min_version (int * argc_p, char *** argv_p) && macosx_deployment_target[0]) { ++*argc_p; - *argv_p = xmalloc (sizeof (char *) * *argc_p); + *argv_p = XNEWVEC (char *, *argc_p); (*argv_p)[0] = argv[0]; (*argv_p)[1] = concat ("-mmacosx-version-min=", macosx_deployment_target, NULL); @@ -144,7 +144,7 @@ darwin_default_min_version (int * argc_p, char *** argv_p) /* Add the new flag. */ ++*argc_p; - *argv_p = xmalloc (sizeof (char *) * *argc_p); + *argv_p = XNEWVEC (char *, *argc_p); (*argv_p)[0] = argv[0]; (*argv_p)[1] = new_flag; memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *)); diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 5461fe083e0..20cce264101 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -366,7 +366,8 @@ machopic_indirection_hash (const void *slot) static int machopic_indirection_eq (const void *slot, const void *key) { - return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0; + return strcmp (((const machopic_indirection *) slot)->ptr_name, + (const char *) key) == 0; } /* Return the name of the non-lazy pointer (if STUB_P is false) or @@ -420,7 +421,7 @@ machopic_indirection_name (rtx sym_ref, bool stub_p) else suffix = NON_LAZY_POINTER_SUFFIX; - buffer = alloca (strlen ("&L") + buffer = XALLOCAVEC (char, strlen ("&L") + strlen (prefix) + namelen + strlen (suffix) @@ -969,7 +970,7 @@ machopic_output_indirection (void **slot, void *data) sym_name = IDENTIFIER_POINTER (id); } - sym = alloca (strlen (sym_name) + 2); + sym = XALLOCAVEC (char, strlen (sym_name) + 2); if (sym_name[0] == '*' || sym_name[0] == '&') strcpy (sym, sym_name + 1); else if (sym_name[0] == '-' || sym_name[0] == '+') @@ -977,7 +978,7 @@ machopic_output_indirection (void **slot, void *data) else sprintf (sym, "%s%s", user_label_prefix, sym_name); - stub = alloca (strlen (ptr_name) + 2); + stub = XALLOCAVEC (char, strlen (ptr_name) + 2); if (ptr_name[0] == '*' || ptr_name[0] == '&') strcpy (stub, ptr_name + 1); else diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 93648ccf39d..6ba924b1df7 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -6950,7 +6950,7 @@ frv_assemble_integer (rtx value, unsigned int size, int aligned_p) static struct machine_function * frv_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } /* Implement TARGET_SCHED_ISSUE_RATE. */ @@ -7525,7 +7525,8 @@ frv_sort_insn_group_1 (enum frv_insn_group group, static int frv_compare_insns (const void *first, const void *second) { - const rtx *insn1 = first, *insn2 = second; + const rtx *const insn1 = (rtx const *) first, + *const insn2 = (rtx const *) second; return frv_insn_unit (*insn1) - frv_insn_unit (*insn2); } @@ -7758,7 +7759,7 @@ frv_extract_membar (struct frv_io *io, rtx insn) static void frv_io_check_address (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) { - rtx *other = data; + rtx *other = (rtx *) data; if (REG_P (x) && *other != 0 && reg_overlap_mentioned_p (x, *other)) *other = 0; @@ -7770,7 +7771,7 @@ frv_io_check_address (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) static void frv_io_handle_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) { - HARD_REG_SET *set = data; + HARD_REG_SET *set = (HARD_REG_SET *) data; unsigned int regno; if (REG_P (x)) @@ -7784,7 +7785,7 @@ frv_io_handle_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) static int frv_io_handle_use_1 (rtx *x, void *data) { - HARD_REG_SET *set = data; + HARD_REG_SET *set = (HARD_REG_SET *) data; unsigned int regno; if (REG_P (*x)) @@ -8005,8 +8006,8 @@ frv_optimize_membar (void) rtx *last_membar; compute_bb_for_insn (); - first_io = xcalloc (last_basic_block, sizeof (struct frv_io)); - last_membar = xcalloc (last_basic_block, sizeof (rtx)); + first_io = XCNEWVEC (struct frv_io, last_basic_block); + last_membar = XCNEWVEC (rtx, last_basic_block); FOR_EACH_BB (bb) frv_optimize_membar_local (bb, &first_io[bb->index], diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h index 1af48805660..f61cacb3e1a 100644 --- a/gcc/config/i386/cygwin.h +++ b/gcc/config/i386/cygwin.h @@ -203,12 +203,12 @@ char *cvt_to_mingw[] = #undef GEN_CVT_ARRAY #endif /*GEN_CVT_ARRAY*/ -void mingw_scan (int, const char * const *, char **); +void mingw_scan (int, const char * const *, const char **); #if 1 #define GCC_DRIVER_HOST_INITIALIZATION \ do \ { \ - mingw_scan(argc, (const char * const *) argv, (char **) &spec_machine); \ + mingw_scan(argc, (const char * const *) argv, &spec_machine); \ } \ while (0) #else diff --git a/gcc/config/i386/cygwin1.c b/gcc/config/i386/cygwin1.c index fb8657acd3c..3ba812fe449 100644 --- a/gcc/config/i386/cygwin1.c +++ b/gcc/config/i386/cygwin1.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see void mingw_scan (int argc ATTRIBUTE_UNUSED, const char *const *argv, - char **spec_machine) + const char **spec_machine) { putenv (xstrdup ("GCC_CYGWIN_MINGW=0")); @@ -42,7 +42,7 @@ mingw_scan (int argc ATTRIBUTE_UNUSED, if (p) { int len = p - *spec_machine; - char *s = xmalloc (strlen (*spec_machine) + 3); + char *s = XNEWVEC (char, strlen (*spec_machine) + 3); memcpy (s, *spec_machine, len); strcpy (s + len, "-mingw32"); *spec_machine = s; diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index b823d435c6d..44845cd8c2e 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -70,7 +70,7 @@ decode_l2_cache (unsigned *l2_size, unsigned *l2_line, unsigned *l2_assoc) /* Returns the description of caches for an AMD processor. */ -static char * +static const char * detect_caches_amd (unsigned max_ext_level) { unsigned eax, ebx, ecx, edx; @@ -78,7 +78,7 @@ detect_caches_amd (unsigned max_ext_level) unsigned l2_sizekb, l2_line, l2_assoc; if (max_ext_level < 0x80000005) - return (char *) ""; + return ""; __cpuid (0x80000005, eax, ebx, ecx, edx); @@ -282,7 +282,7 @@ decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line, /* Returns the description of caches for an intel processor. */ -static char * +static const char * detect_caches_intel (unsigned max_level, unsigned max_ext_level) { unsigned eax, ebx, ecx, edx; @@ -290,7 +290,7 @@ detect_caches_intel (unsigned max_level, unsigned max_ext_level) unsigned l2_sizekb = 0, l2_line = 0, l2_assoc = 0; if (max_level < 2) - return (char *) ""; + return ""; __cpuid (2, eax, ebx, ecx, edx); @@ -304,7 +304,7 @@ detect_caches_intel (unsigned max_level, unsigned max_ext_level) &l2_sizekb, &l2_line, &l2_assoc); if (!l1_sizekb) - return (char *) ""; + return ""; /* Newer Intel CPUs are equipped with AMD style L2 cache info */ if (max_ext_level >= 0x80000006) @@ -393,13 +393,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (!arch) { - if (vendor == *(unsigned int*) "Auth") + if (vendor == *(const unsigned int*) "Auth") cache = detect_caches_amd (ext_level); - else if (vendor == *(unsigned int*) "Genu") + else if (vendor == *(const unsigned int*) "Genu") cache = detect_caches_intel (max_level, ext_level); } - if (vendor == *(unsigned int*) "Auth") + if (vendor == *(const unsigned int*) "Auth") { processor = PROCESSOR_PENTIUM; @@ -412,7 +412,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (has_sse4a) processor = PROCESSOR_AMDFAM10; } - else if (vendor == *(unsigned int*) "Geod") + else if (vendor == *(const unsigned int*) "Geod") processor = PROCESSOR_GEODE; else { diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5ebb31c22d0..2edeec01c58 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4744,7 +4744,9 @@ static bool contains_aligned_value_p (tree type) { enum machine_mode mode = TYPE_MODE (type); - if (((TARGET_SSE && SSE_REG_MODE_P (mode)) || mode == TDmode) + if (((TARGET_SSE && SSE_REG_MODE_P (mode)) + || mode == TDmode + || mode == TFmode) && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128)) return true; if (TYPE_ALIGN (type) < 128) @@ -4803,8 +4805,9 @@ ix86_function_arg_boundary (enum machine_mode mode, tree type) align = GET_MODE_ALIGNMENT (mode); if (align < PARM_BOUNDARY) align = PARM_BOUNDARY; - /* In 32bit, only _Decimal128 is aligned to its natural boundary. */ - if (!TARGET_64BIT && mode != TDmode) + /* In 32bit, only _Decimal128 and __float128 are aligned to their + natural boundaries. */ + if (!TARGET_64BIT && mode != TDmode && mode != TFmode) { /* i386 ABI defines all arguments to be 4 byte aligned. We have to make an exception for SSE modes since these require 128bit @@ -4815,7 +4818,7 @@ ix86_function_arg_boundary (enum machine_mode mode, tree type) to 8 byte boundaries. */ if (!type) { - if (!(TARGET_SSE && SSE_REG_MODE_P (mode)) && mode != TDmode) + if (!(TARGET_SSE && SSE_REG_MODE_P (mode))) align = PARM_BOUNDARY; } else @@ -5041,9 +5044,6 @@ return_in_memory_32 (const_tree type, enum machine_mode mode) if (mode == XFmode) return 0; - if (mode == TDmode) - return 1; - if (size > 12) return 1; return 0; @@ -9207,7 +9207,7 @@ print_operand (FILE *file, rtx x, int code) if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT) { PRINT_OPERAND (file, x, 0); - putc (',', file); + fputs (", ", file); } return; @@ -14122,7 +14122,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) size = (GET_MODE_SIZE (mode) + 4) / 8; gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand))); - gcc_assert (size >= 2 && size <= 3); + gcc_assert (size >= 2 && size <= 4); /* Optimize constant pool reference to immediates. This is used by fp moves, that force all constants to memory to allow combining. */ @@ -14142,7 +14142,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) operand = copy_rtx (operand); PUT_MODE (operand, Pmode); - parts[0] = parts[1] = parts[2] = operand; + parts[0] = parts[1] = parts[2] = parts[3] = operand; return size; } @@ -14163,21 +14163,20 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) split_di (&operand, 1, &parts[0], &parts[1]); else { + int i; + if (REG_P (operand)) { gcc_assert (reload_completed); - parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0); - parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1); - if (size == 3) - parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2); + for (i = 0; i < size; i++) + parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i); } else if (offsettable_memref_p (operand)) { operand = adjust_address (operand, SImode, 0); parts[0] = operand; - parts[1] = adjust_address (operand, SImode, 4); - if (size == 3) - parts[2] = adjust_address (operand, SImode, 8); + for (i = 1; i < size; i++) + parts[i] = adjust_address (operand, SImode, 4 * i); } else if (GET_CODE (operand) == CONST_DOUBLE) { @@ -14187,6 +14186,11 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) REAL_VALUE_FROM_CONST_DOUBLE (r, operand); switch (mode) { + case TFmode: + real_to_target (l, &r, mode); + parts[3] = gen_int_mode (l[3], SImode); + parts[2] = gen_int_mode (l[2], SImode); + break; case XFmode: REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); parts[2] = gen_int_mode (l[2], SImode); @@ -14260,7 +14264,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) return size; } -/* Emit insns to perform a move or push of DI, DF, and XF values. +/* Emit insns to perform a move or push of DI, DF, XF, and TF values. Return false when normal moves are needed; true when all required insns have been emitted. Operands 2-4 contain the input values int the correct order; operands 5-7 contain the output values. */ @@ -14268,11 +14272,12 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) void ix86_split_long_move (rtx operands[]) { - rtx part[2][3]; - int nparts; + rtx part[2][4]; + int nparts, i, j; int push = 0; int collisions = 0; enum machine_mode mode = GET_MODE (operands[0]); + bool collisionparts[4]; /* The DFmode expanders may ask us to move double. For 64bit target this is single move. By hiding the fact @@ -14311,34 +14316,46 @@ ix86_split_long_move (rtx operands[]) /* When emitting push, take care for source operands on the stack. */ if (push && MEM_P (operands[1]) && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) - { - if (nparts == 3) - part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]), - XEXP (part[1][2], 0)); - part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]), - XEXP (part[1][1], 0)); - } + for (i = 0; i < nparts - 1; i++) + part[1][i] = change_address (part[1][i], + GET_MODE (part[1][i]), + XEXP (part[1][i + 1], 0)); /* We need to do copy in the right order in case an address register of the source overlaps the destination. */ if (REG_P (part[0][0]) && MEM_P (part[1][0])) { - if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))) - collisions++; - if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0))) - collisions++; - if (nparts == 3 - && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0))) - collisions++; + rtx tmp; + + for (i = 0; i < nparts; i++) + { + collisionparts[i] + = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0)); + if (collisionparts[i]) + collisions++; + } /* Collision in the middle part can be handled by reordering. */ - if (collisions == 1 && nparts == 3 - && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0))) + if (collisions == 1 && nparts == 3 && collisionparts [1]) { - rtx tmp; tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp; tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp; } + else if (collisions == 1 + && nparts == 4 + && (collisionparts [1] || collisionparts [2])) + { + if (collisionparts [1]) + { + tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp; + tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp; + } + else + { + tmp = part[0][2]; part[0][2] = part[0][3]; part[0][3] = tmp; + tmp = part[1][2]; part[1][2] = part[1][3]; part[1][3] = tmp; + } + } /* If there are more collisions, we can't handle it by reordering. Do an lea to the last part and use only one colliding move. */ @@ -14357,11 +14374,11 @@ ix86_split_long_move (rtx operands[]) emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0))); part[1][0] = replace_equiv_address (part[1][0], base); - part[1][1] = replace_equiv_address (part[1][1], - plus_constant (base, UNITS_PER_WORD)); - if (nparts == 3) - part[1][2] = replace_equiv_address (part[1][2], - plus_constant (base, 8)); + for (i = 1; i < nparts; i++) + { + tmp = plus_constant (base, UNITS_PER_WORD * i); + part[1][i] = replace_equiv_address (part[1][i], tmp); + } } } @@ -14375,6 +14392,11 @@ ix86_split_long_move (rtx operands[]) emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4))); emit_move_insn (part[0][2], part[1][2]); } + else if (nparts == 4) + { + emit_move_insn (part[0][3], part[1][3]); + emit_move_insn (part[0][2], part[1][2]); + } } else { @@ -14412,77 +14434,42 @@ ix86_split_long_move (rtx operands[]) && REG_P (part[1][1]) && (REGNO (part[0][0]) == REGNO (part[1][1]) || (nparts == 3 - && REGNO (part[0][0]) == REGNO (part[1][2])))) + && REGNO (part[0][0]) == REGNO (part[1][2])) + || (nparts == 4 + && REGNO (part[0][0]) == REGNO (part[1][3])))) || (collisions > 0 && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))) { - if (nparts == 3) + for (i = 0, j = nparts - 1; i < nparts; i++, j--) { - operands[2] = part[0][2]; - operands[3] = part[0][1]; - operands[4] = part[0][0]; - operands[5] = part[1][2]; - operands[6] = part[1][1]; - operands[7] = part[1][0]; - } - else - { - operands[2] = part[0][1]; - operands[3] = part[0][0]; - operands[5] = part[1][1]; - operands[6] = part[1][0]; + operands[2 + i] = part[0][j]; + operands[6 + i] = part[1][j]; } } else { - if (nparts == 3) + for (i = 0; i < nparts; i++) { - operands[2] = part[0][0]; - operands[3] = part[0][1]; - operands[4] = part[0][2]; - operands[5] = part[1][0]; - operands[6] = part[1][1]; - operands[7] = part[1][2]; - } - else - { - operands[2] = part[0][0]; - operands[3] = part[0][1]; - operands[5] = part[1][0]; - operands[6] = part[1][1]; + operands[2 + i] = part[0][i]; + operands[6 + i] = part[1][i]; } } /* If optimizing for size, attempt to locally unCSE nonzero constants. */ if (optimize_size) { - if (CONST_INT_P (operands[5]) - && operands[5] != const0_rtx - && REG_P (operands[2])) - { - if (CONST_INT_P (operands[6]) - && INTVAL (operands[6]) == INTVAL (operands[5])) - operands[6] = operands[2]; - - if (nparts == 3 - && CONST_INT_P (operands[7]) - && INTVAL (operands[7]) == INTVAL (operands[5])) - operands[7] = operands[2]; - } - - if (nparts == 3 - && CONST_INT_P (operands[6]) - && operands[6] != const0_rtx - && REG_P (operands[3]) - && CONST_INT_P (operands[7]) - && INTVAL (operands[7]) == INTVAL (operands[6])) - operands[7] = operands[3]; + for (j = 0; j < nparts - 1; j++) + if (CONST_INT_P (operands[6 + j]) + && operands[6 + j] != const0_rtx + && REG_P (operands[2 + j])) + for (i = j; i < nparts - 1; i++) + if (CONST_INT_P (operands[7 + i]) + && INTVAL (operands[7 + i]) == INTVAL (operands[6 + j])) + operands[7 + i] = operands[2 + j]; } - emit_move_insn (operands[2], operands[5]); - emit_move_insn (operands[3], operands[6]); - if (nparts == 3) - emit_move_insn (operands[4], operands[7]); + for (i = 0; i < nparts; i++) + emit_move_insn (operands[2 + i], operands[6 + i]); return; } @@ -14542,7 +14529,7 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); emit_insn ((mode == DImode - ? gen_x86_shld_1 + ? gen_x86_shld : gen_x86_64_shld) (high[0], low[0], GEN_INT (count))); ix86_expand_ashl_const (low[0], count, mode); } @@ -14627,7 +14614,7 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) (mode == DImode ? split_di : split_ti) (operands, 1, low, high); emit_insn ((mode == DImode - ? gen_x86_shld_1 + ? gen_x86_shld : gen_x86_64_shld) (high[0], low[0], operands[2])); } @@ -14685,7 +14672,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode) if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); emit_insn ((mode == DImode - ? gen_x86_shrd_1 + ? gen_x86_shrd : gen_x86_64_shrd) (low[0], high[0], GEN_INT (count))); emit_insn ((mode == DImode ? gen_ashrsi3 @@ -14700,7 +14687,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode) (mode == DImode ? split_di : split_ti) (operands, 1, low, high); emit_insn ((mode == DImode - ? gen_x86_shrd_1 + ? gen_x86_shrd : gen_x86_64_shrd) (low[0], high[0], operands[2])); emit_insn ((mode == DImode ? gen_ashrsi3 @@ -14751,7 +14738,7 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode) if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); emit_insn ((mode == DImode - ? gen_x86_shrd_1 + ? gen_x86_shrd : gen_x86_64_shrd) (low[0], high[0], GEN_INT (count))); emit_insn ((mode == DImode ? gen_lshrsi3 @@ -14766,7 +14753,7 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode) (mode == DImode ? split_di : split_ti) (operands, 1, low, high); emit_insn ((mode == DImode - ? gen_x86_shrd_1 + ? gen_x86_shrd : gen_x86_64_shrd) (low[0], high[0], operands[2])); emit_insn ((mode == DImode ? gen_lshrsi3 @@ -18674,6 +18661,9 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsqrtv2df2, "__builtin_ia32_sqrtsd", IX86_BUILTIN_SQRTSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_VEC_MERGE }, + { OPTION_MASK_ISA_SSE2, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 }, + { OPTION_MASK_ISA_SSE2, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 }, + /* SSE2 MMX */ { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_addv1di3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI }, { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_subv1di3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI }, @@ -18799,10 +18789,6 @@ static const struct builtin_description bdesc_args[] = /* PCLMUL */ { OPTION_MASK_ISA_SSE2, CODE_FOR_pclmulqdq, 0, IX86_BUILTIN_PCLMULQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT }, - - /* 64bit */ - { OPTION_MASK_ISA_64BIT, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 }, - { OPTION_MASK_ISA_64BIT, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 }, }; /* SSE5 */ @@ -19600,47 +19586,6 @@ ix86_init_mmx_sse_builtins (void) tree ftype; - /* The __float80 type. */ - if (TYPE_MODE (long_double_type_node) == XFmode) - (*lang_hooks.types.register_builtin_type) (long_double_type_node, - "__float80"); - else - { - /* The __float80 type. */ - tree float80_type_node = make_node (REAL_TYPE); - - TYPE_PRECISION (float80_type_node) = 80; - layout_type (float80_type_node); - (*lang_hooks.types.register_builtin_type) (float80_type_node, - "__float80"); - } - - if (TARGET_64BIT) - { - tree float128_type_node = make_node (REAL_TYPE); - - TYPE_PRECISION (float128_type_node) = 128; - layout_type (float128_type_node); - (*lang_hooks.types.register_builtin_type) (float128_type_node, - "__float128"); - - /* TFmode support builtins. */ - ftype = build_function_type (float128_type_node, - void_list_node); - def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_infq", ftype, IX86_BUILTIN_INFQ); - - ftype = build_function_type_list (float128_type_node, - float128_type_node, - NULL_TREE); - def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ); - - ftype = build_function_type_list (float128_type_node, - float128_type_node, - float128_type_node, - NULL_TREE); - def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ); - } - /* Add all special builtins with variable number of operands. */ for (i = 0, d = bdesc_special_args; i < ARRAY_SIZE (bdesc_special_args); @@ -20246,6 +20191,52 @@ ix86_init_mmx_sse_builtins (void) static void ix86_init_builtins (void) { + tree float128_type_node = make_node (REAL_TYPE); + tree ftype, decl; + + /* The __float80 type. */ + if (TYPE_MODE (long_double_type_node) == XFmode) + (*lang_hooks.types.register_builtin_type) (long_double_type_node, + "__float80"); + else + { + /* The __float80 type. */ + tree float80_type_node = make_node (REAL_TYPE); + + TYPE_PRECISION (float80_type_node) = 80; + layout_type (float80_type_node); + (*lang_hooks.types.register_builtin_type) (float80_type_node, + "__float80"); + } + + /* The __float128 type. */ + TYPE_PRECISION (float128_type_node) = 128; + layout_type (float128_type_node); + (*lang_hooks.types.register_builtin_type) (float128_type_node, + "__float128"); + + /* TFmode support builtins. */ + ftype = build_function_type (float128_type_node, void_list_node); + decl = add_builtin_function ("__builtin_infq", ftype, + IX86_BUILTIN_INFQ, BUILT_IN_MD, + NULL, NULL_TREE); + ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl; + + if (HOST_BITS_PER_WIDE_INT >= 64) + { + /* Those builtins need TImode to compile. */ + ftype = build_function_type_list (float128_type_node, + float128_type_node, + NULL_TREE); + def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ); + + ftype = build_function_type_list (float128_type_node, + float128_type_node, + float128_type_node, + NULL_TREE); + def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ); + } + if (TARGET_MMX) ix86_init_mmx_sse_builtins (); } @@ -22967,11 +22958,11 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub) symb = (*targetm.strip_name_encoding) (symb); length = strlen (stub); - binder_name = alloca (length + 32); + binder_name = XALLOCAVEC (char, length + 32); GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length); length = strlen (symb); - symbol_name = alloca (length + 32); + symbol_name = XALLOCAVEC (char, length + 32); GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length); sprintf (lazy_ptr_name, "L%d$lz", label); @@ -24702,7 +24693,7 @@ ix86_scalar_mode_supported_p (enum machine_mode mode) if (DECIMAL_FLOAT_MODE_P (mode)) return true; else if (mode == TFmode) - return TARGET_64BIT; + return true; else return default_scalar_mode_supported_p (mode); } @@ -24726,9 +24717,9 @@ ix86_vector_mode_supported_p (enum machine_mode mode) static enum machine_mode ix86_c_mode_for_suffix (char suffix) { - if (TARGET_64BIT && suffix == 'q') + if (suffix == 'q') return TFmode; - if (TARGET_MMX && suffix == 'w') + if (suffix == 'w') return XFmode; return VOIDmode; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f6e0f4b12b2..c67cf467bc9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -597,7 +597,7 @@ (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) ;; Immediate operand constraint for integer modes. -(define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")]) +(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")]) ;; General operand predicate for integer modes. (define_mode_attr general_operand @@ -725,7 +725,7 @@ (define_insn "cmpdi_ccno_1_rex64" [(set (reg FLAGS_REG) (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") - (match_operand:DI 1 "const0_operand" "n,n")))] + (match_operand:DI 1 "const0_operand" "")))] "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" "@ test{q}\t%0, %0 @@ -764,7 +764,7 @@ (define_insn "*cmpsi_ccno_1" [(set (reg FLAGS_REG) (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") - (match_operand:SI 1 "const0_operand" "n,n")))] + (match_operand:SI 1 "const0_operand" "")))] "ix86_match_ccmode (insn, CCNOmode)" "@ test{l}\t%0, %0 @@ -803,7 +803,7 @@ (define_insn "*cmphi_ccno_1" [(set (reg FLAGS_REG) (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") - (match_operand:HI 1 "const0_operand" "n,n")))] + (match_operand:HI 1 "const0_operand" "")))] "ix86_match_ccmode (insn, CCNOmode)" "@ test{w}\t%0, %0 @@ -815,7 +815,7 @@ (define_insn "*cmphi_minus_1" [(set (reg FLAGS_REG) (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") - (match_operand:HI 1 "general_operand" "ri,mr")) + (match_operand:HI 1 "general_operand" "rn,mr")) (const_int 0)))] "ix86_match_ccmode (insn, CCGOCmode)" "cmp{w}\t{%1, %0|%0, %1}" @@ -825,7 +825,7 @@ (define_insn "*cmphi_1" [(set (reg FLAGS_REG) (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") - (match_operand:HI 1 "general_operand" "ri,mr")))] + (match_operand:HI 1 "general_operand" "rn,mr")))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && ix86_match_ccmode (insn, CCmode)" "cmp{w}\t{%1, %0|%0, %1}" @@ -835,7 +835,7 @@ (define_insn "*cmpqi_ccno_1" [(set (reg FLAGS_REG) (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") - (match_operand:QI 1 "const0_operand" "n,n")))] + (match_operand:QI 1 "const0_operand" "")))] "ix86_match_ccmode (insn, CCNOmode)" "@ test{b}\t%0, %0 @@ -847,7 +847,7 @@ (define_insn "*cmpqi_1" [(set (reg FLAGS_REG) (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") - (match_operand:QI 1 "general_operand" "qi,mq")))] + (match_operand:QI 1 "general_operand" "qn,mq")))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%1, %0|%0, %1}" @@ -857,7 +857,7 @@ (define_insn "*cmpqi_minus_1" [(set (reg FLAGS_REG) (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") - (match_operand:QI 1 "general_operand" "qi,mq")) + (match_operand:QI 1 "general_operand" "qn,mq")) (const_int 0)))] "ix86_match_ccmode (insn, CCGOCmode)" "cmp{b}\t{%1, %0|%0, %1}" @@ -900,7 +900,7 @@ (match_operand 0 "ext_register_operand" "Q") (const_int 8) (const_int 8)) 0) - (match_operand:QI 1 "const0_operand" "n")))] + (match_operand:QI 1 "const0_operand" "")))] "ix86_match_ccmode (insn, CCNOmode)" "test{b}\t%h0, %h0" [(set_attr "type" "test") @@ -1006,7 +1006,7 @@ (unspec:HI [(compare:CCFP (match_operand 1 "register_operand" "f") - (match_operand 2 "const0_operand" "X"))] + (match_operand 2 "const0_operand" ""))] UNSPEC_FNSTSW))] "X87_FLOAT_MODE_P (GET_MODE (operands[1])) && GET_MODE (operands[1]) == GET_MODE (operands[2])" @@ -1025,7 +1025,7 @@ [(set (reg:CCFP FLAGS_REG) (compare:CCFP (match_operand 1 "register_operand" "f") - (match_operand 2 "const0_operand" "X"))) + (match_operand 2 "const0_operand" ""))) (clobber (match_operand:HI 0 "register_operand" "=a"))] "X87_FLOAT_MODE_P (GET_MODE (operands[1])) && TARGET_SAHF && !TARGET_CMOVE @@ -1415,7 +1415,7 @@ (define_insn "*movsi_xor" [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "const0_operand" "i")) + (match_operand:SI 1 "const0_operand" "")) (clobber (reg:CC FLAGS_REG))] "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" "xor{l}\t%0, %0" @@ -1440,9 +1440,9 @@ (define_insn "*movsi_1" [(set (match_operand:SI 0 "nonimmediate_operand" - "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") + "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") (match_operand:SI 1 "general_operand" - "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] + "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -1571,7 +1571,7 @@ ;; For 64BIT abi we always round up to 8 bytes. (define_insn "*pushhi2_rex64" [(set (match_operand:HI 0 "push_operand" "=X") - (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] + (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] "TARGET_64BIT" "push{q}\t%q1" [(set_attr "type" "push") @@ -1706,7 +1706,7 @@ (define_insn "*movstricthi_xor" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) - (match_operand:HI 1 "const0_operand" "i")) + (match_operand:HI 1 "const0_operand" "")) (clobber (reg:CC FLAGS_REG))] "reload_completed && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" @@ -1736,7 +1736,7 @@ ;; For 64BIT abi we always round up to 8 bytes. (define_insn "*pushqi2_rex64" [(set (match_operand:QI 0 "push_operand" "=X") - (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] + (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))] "TARGET_64BIT" "push{q}\t%q1" [(set_attr "type" "push") @@ -1863,7 +1863,7 @@ (define_insn "*movstrictqi_xor" [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) - (match_operand:QI 1 "const0_operand" "i")) + (match_operand:QI 1 "const0_operand" "")) (clobber (reg:CC FLAGS_REG))] "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" "xor{b}\t%0, %0" @@ -2189,7 +2189,7 @@ (define_insn "*movdi_xor_rex64" [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "const0_operand" "i")) + (match_operand:DI 1 "const0_operand" "")) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) && reload_completed" @@ -2464,7 +2464,7 @@ (const_string "TI")))]) (define_insn "*movti_rex64" - [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") + [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm") (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -3261,7 +3261,7 @@ (define_expand "movtf" [(set (match_operand:TF 0 "nonimmediate_operand" "") (match_operand:TF 1 "nonimmediate_operand" ""))] - "TARGET_64BIT" + "TARGET_SSE2" { ix86_expand_move (TFmode, operands); DONE; @@ -3270,7 +3270,7 @@ (define_insn "*movtf_internal" [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o") (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))] - "TARGET_64BIT + "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (which_alternative) @@ -5462,8 +5462,7 @@ (define_expand "addti3" [(set (match_operand:TI 0 "nonimmediate_operand" "") (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") - (match_operand:TI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:TI 2 "x86_64_general_operand" "")))] "TARGET_64BIT" "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") @@ -5499,8 +5498,7 @@ (define_expand "adddi3" [(set (match_operand:DI 0 "nonimmediate_operand" "") (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:DI 2 "x86_64_general_operand" "")))] "" "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") @@ -5606,7 +5604,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") (match_operand:QI 1 "nonimmediate_operand" "%0,0")) - (match_operand:QI 2 "general_operand" "qi,qm"))) + (match_operand:QI 2 "general_operand" "qn,qm"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, QImode, operands)" "adc{b}\t{%2, %0|%0, %2}" @@ -5618,7 +5616,7 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") (match_operand:HI 1 "nonimmediate_operand" "%0,0")) - (match_operand:HI 2 "general_operand" "ri,rm"))) + (match_operand:HI 2 "general_operand" "rn,rm"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, HImode, operands)" "adc{w}\t{%2, %0|%0, %2}" @@ -5666,7 +5664,7 @@ (define_insn "addqi3_cc" [(set (reg:CC FLAGS_REG) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qi,qm")] + (match_operand:QI 2 "general_operand" "qn,qm")] UNSPEC_ADD_CARRY)) (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (plus:QI (match_dup 1) (match_dup 2)))] @@ -5676,10 +5674,9 @@ (set_attr "mode" "QI")]) (define_expand "addsi3" - [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" "")))] "" "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") @@ -6144,7 +6141,7 @@ (define_insn "*addsi_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") - (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) + (match_operand:SI 2 "general_operand" "g,ri,li"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -6228,7 +6225,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") - (match_operand:SI 2 "general_operand" "rmni,lni")))) + (match_operand:SI 2 "general_operand" "g,li")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -6294,7 +6291,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") - (match_operand:SI 2 "general_operand" "rmni,rni")) + (match_operand:SI 2 "general_operand" "g,ri")) (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") (plus:SI (match_dup 1) (match_dup 2)))] @@ -6342,7 +6339,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "rmni")) + (match_operand:SI 2 "general_operand" "g")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6385,7 +6382,7 @@ (define_insn "*addsi_3" [(set (reg FLAGS_REG) - (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) + (compare (neg:SI (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:SI 0 "=r"))] "ix86_match_ccmode (insn, CCZmode) @@ -6430,7 +6427,7 @@ ;; See comment for addsi_1_zext why we do use nonimmediate_operand (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) - (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) + (compare (neg:SI (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 1 "nonimmediate_operand" "%0"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6520,7 +6517,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "rmni")) + (match_operand:SI 2 "general_operand" "g")) (const_int 0))) (clobber (match_scratch:SI 0 "=r"))] "ix86_match_ccmode (insn, CCGOCmode) @@ -6563,10 +6560,9 @@ (set_attr "mode" "SI")]) (define_expand "addhi3" - [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:HI 0 "nonimmediate_operand" "") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "general_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") @@ -6577,7 +6573,7 @@ (define_insn "*addhi_1_lea" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") - (match_operand:HI 2 "general_operand" "ri,rm,lni"))) + (match_operand:HI 2 "general_operand" "rn,rm,ln"))) (clobber (reg:CC FLAGS_REG))] "!TARGET_PARTIAL_REG_STALL && ix86_binary_operator_ok (PLUS, HImode, operands)" @@ -6620,7 +6616,7 @@ (define_insn "*addhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm"))) + (match_operand:HI 2 "general_operand" "rn,rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_PARTIAL_REG_STALL && ix86_binary_operator_ok (PLUS, HImode, operands)" @@ -6660,7 +6656,7 @@ [(set (reg FLAGS_REG) (compare (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "rmni,rni")) + (match_operand:HI 2 "general_operand" "rmn,rn")) (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (plus:HI (match_dup 1) (match_dup 2)))] @@ -6700,7 +6696,7 @@ (define_insn "*addhi_3" [(set (reg FLAGS_REG) - (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) + (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn")) (match_operand:HI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:HI 0 "=r"))] "ix86_match_ccmode (insn, CCZmode) @@ -6780,7 +6776,7 @@ [(set (reg FLAGS_REG) (compare (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") - (match_operand:HI 2 "general_operand" "rmni")) + (match_operand:HI 2 "general_operand" "rmn")) (const_int 0))) (clobber (match_scratch:HI 0 "=r"))] "ix86_match_ccmode (insn, CCGOCmode) @@ -6818,10 +6814,9 @@ (set_attr "mode" "HI")]) (define_expand "addqi3" - [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "general_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") @@ -6966,7 +6961,7 @@ [(set (reg FLAGS_REG) (compare (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qmni,qni")) + (match_operand:QI 2 "general_operand" "qmn,qn")) (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (plus:QI (match_dup 1) (match_dup 2)))] @@ -7005,7 +7000,7 @@ (define_insn "*addqi_3" [(set (reg FLAGS_REG) - (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) + (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn")) (match_operand:QI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:QI 0 "=q"))] "ix86_match_ccmode (insn, CCZmode) @@ -7084,7 +7079,7 @@ [(set (reg FLAGS_REG) (compare (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") - (match_operand:QI 2 "general_operand" "qmni")) + (match_operand:QI 2 "general_operand" "qmn")) (const_int 0))) (clobber (match_scratch:QI 0 "=q"))] "ix86_match_ccmode (insn, CCGOCmode) @@ -7233,10 +7228,9 @@ ;; %%% splits for subditi3 (define_expand "subti3" - [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") - (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") - (match_operand:TI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:TI 0 "nonimmediate_operand" "") + (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") + (match_operand:TI 2 "x86_64_general_operand" "")))] "TARGET_64BIT" "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") @@ -7266,10 +7260,9 @@ ;; %%% splits for subsidi3 (define_expand "subdi3" - [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") - (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:DI 2 "x86_64_general_operand" "")))] "" "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") @@ -7348,7 +7341,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") - (match_operand:QI 2 "general_operand" "qi,qm")))) + (match_operand:QI 2 "general_operand" "qn,qm")))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, QImode, operands)" "sbb{b}\t{%2, %0|%0, %2}" @@ -7360,7 +7353,7 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") - (match_operand:HI 2 "general_operand" "ri,rm")))) + (match_operand:HI 2 "general_operand" "rn,rm")))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, HImode, operands)" "sbb{w}\t{%2, %0|%0, %2}" @@ -7394,10 +7387,9 @@ (set_attr "mode" "SI")]) (define_expand "subsi3" - [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") - (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" "")))] "" "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") @@ -7479,17 +7471,16 @@ (set_attr "mode" "DI")]) (define_expand "subhi3" - [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") - (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:HI 0 "nonimmediate_operand" "") + (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "general_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") (define_insn "*subhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") - (match_operand:HI 2 "general_operand" "ri,rm"))) + (match_operand:HI 2 "general_operand" "rn,rm"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, HImode, operands)" "sub{w}\t{%2, %0|%0, %2}" @@ -7500,7 +7491,7 @@ [(set (reg FLAGS_REG) (compare (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") - (match_operand:HI 2 "general_operand" "ri,rm")) + (match_operand:HI 2 "general_operand" "rn,rm")) (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_dup 1) (match_dup 2)))] @@ -7513,7 +7504,7 @@ (define_insn "*subhi_3" [(set (reg FLAGS_REG) (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") - (match_operand:HI 2 "general_operand" "ri,rm"))) + (match_operand:HI 2 "general_operand" "rn,rm"))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) @@ -7523,17 +7514,16 @@ (set_attr "mode" "HI")]) (define_expand "subqi3" - [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") - (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "general_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") (define_insn "*subqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "general_operand" "qn,qmn"))) + (match_operand:QI 2 "general_operand" "qn,qm"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, QImode, operands)" "sub{b}\t{%2, %0|%0, %2}" @@ -7543,7 +7533,7 @@ (define_insn "*subqi_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) (minus:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "qn,qmn"))) + (match_operand:QI 1 "general_operand" "qn,qm"))) (clobber (reg:CC FLAGS_REG))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -7555,10 +7545,10 @@ [(set (reg FLAGS_REG) (compare (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "general_operand" "qi,qm")) + (match_operand:QI 2 "general_operand" "qn,qm")) (const_int 0))) - (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") - (minus:HI (match_dup 1) (match_dup 2)))] + (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") + (minus:QI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (MINUS, QImode, operands)" "sub{b}\t{%2, %0|%0, %2}" @@ -7568,9 +7558,9 @@ (define_insn "*subqi_3" [(set (reg FLAGS_REG) (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "general_operand" "qi,qm"))) - (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") - (minus:HI (match_dup 1) (match_dup 2)))] + (match_operand:QI 2 "general_operand" "qn,qm"))) + (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") + (minus:QI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) && ix86_binary_operator_ok (MINUS, QImode, operands)" "sub{b}\t{%2, %0|%0, %2}" @@ -7732,7 +7722,7 @@ (define_insn "*mulhi3_1" [(set (match_operand:HI 0 "register_operand" "=r,r,r") (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:HI 2 "general_operand" "K,i,mr"))) + (match_operand:HI 2 "general_operand" "K,n,mr"))) (clobber (reg:CC FLAGS_REG))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ @@ -8543,7 +8533,7 @@ [(set (reg FLAGS_REG) (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") - (match_operand:SI 1 "general_operand" "in,in,rin")) + (match_operand:SI 1 "general_operand" "i,i,ri")) (const_int 0)))] "ix86_match_ccmode (insn, CCNOmode) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -8849,8 +8839,7 @@ (define_expand "anddi3" [(set (match_operand:DI 0 "nonimmediate_operand" "") (and:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "x86_64_szext_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:DI 2 "x86_64_szext_general_operand" "")))] "TARGET_64BIT" "ix86_expand_binary_operator (AND, DImode, operands); DONE;") @@ -8914,8 +8903,7 @@ (define_expand "andsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (and:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:SI 2 "general_operand" "")))] "" "ix86_expand_binary_operator (AND, SImode, operands); DONE;") @@ -9036,15 +9024,14 @@ (define_expand "andhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (and:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:HI 2 "general_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (AND, HImode, operands); DONE;") (define_insn "*andhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") - (match_operand:HI 2 "general_operand" "ri,rm,L"))) + (match_operand:HI 2 "general_operand" "rn,rm,L"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, HImode, operands)" { @@ -9068,7 +9055,7 @@ (define_insn "*andhi_2" [(set (reg FLAGS_REG) (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "g,ri")) + (match_operand:HI 2 "general_operand" "rmn,rn")) (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (and:HI (match_dup 1) (match_dup 2)))] @@ -9081,8 +9068,7 @@ (define_expand "andqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (and:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "general_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (AND, QImode, operands); DONE;") @@ -9090,7 +9076,7 @@ (define_insn "*andqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) + (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, QImode, operands)" "@ @@ -9103,7 +9089,7 @@ (define_insn "*andqi_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) (and:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "qi,qmi"))) + (match_operand:QI 1 "general_operand" "qn,qmn"))) (clobber (reg:CC FLAGS_REG))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -9115,7 +9101,7 @@ [(set (reg FLAGS_REG) (compare (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qim,qi,i")) + (match_operand:QI 2 "general_operand" "qmn,qn,n")) (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") (and:QI (match_dup 1) (match_dup 2)))] @@ -9139,7 +9125,7 @@ [(set (reg FLAGS_REG) (compare (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qim,qi")) + (match_operand:QI 2 "general_operand" "qmn,qn")) (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (and:QI (match_dup 1) (match_dup 2)))] @@ -9153,7 +9139,7 @@ [(set (reg FLAGS_REG) (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") - (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) + (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) (const_int 0))) (set (strict_low_part (match_dup 0)) (and:QI (match_dup 0) (match_dup 1)))] @@ -9322,8 +9308,7 @@ (define_expand "iordi3" [(set (match_operand:DI 0 "nonimmediate_operand" "") (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:DI 2 "x86_64_general_operand" "")))] "TARGET_64BIT" "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") @@ -9369,8 +9354,7 @@ (define_expand "iorsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:SI 2 "general_operand" "")))] "" "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") @@ -9462,15 +9446,14 @@ (define_expand "iorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:HI 2 "general_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") (define_insn "*iorhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "g,ri"))) + (match_operand:HI 2 "general_operand" "rmn,rn"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (IOR, HImode, operands)" "or{w}\t{%2, %0|%0, %2}" @@ -9480,7 +9463,7 @@ (define_insn "*iorhi_2" [(set (reg FLAGS_REG) (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "g,ri")) + (match_operand:HI 2 "general_operand" "rmn,rn")) (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (ior:HI (match_dup 1) (match_dup 2)))] @@ -9493,7 +9476,7 @@ (define_insn "*iorhi_3" [(set (reg FLAGS_REG) (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") - (match_operand:HI 2 "general_operand" "g")) + (match_operand:HI 2 "general_operand" "rmn")) (const_int 0))) (clobber (match_scratch:HI 0 "=r"))] "ix86_match_ccmode (insn, CCNOmode) @@ -9505,8 +9488,7 @@ (define_expand "iorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "general_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") @@ -9514,7 +9496,7 @@ (define_insn "*iorqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) + (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (IOR, QImode, operands)" "@ @@ -9527,7 +9509,7 @@ (define_insn "*iorqi_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) (ior:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "qmi,qi"))) + (match_operand:QI 1 "general_operand" "qmn,qn"))) (clobber (reg:CC FLAGS_REG))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -9538,7 +9520,7 @@ (define_insn "*iorqi_2" [(set (reg FLAGS_REG) (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qim,qi")) + (match_operand:QI 2 "general_operand" "qmn,qn")) (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (ior:QI (match_dup 1) (match_dup 2)))] @@ -9551,7 +9533,7 @@ (define_insn "*iorqi_2_slp" [(set (reg FLAGS_REG) (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") - (match_operand:QI 1 "general_operand" "qim,qi")) + (match_operand:QI 1 "general_operand" "qmn,qn")) (const_int 0))) (set (strict_low_part (match_dup 0)) (ior:QI (match_dup 0) (match_dup 1)))] @@ -9565,7 +9547,7 @@ (define_insn "*iorqi_3" [(set (reg FLAGS_REG) (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") - (match_operand:QI 2 "general_operand" "qim")) + (match_operand:QI 2 "general_operand" "qmn")) (const_int 0))) (clobber (match_scratch:QI 0 "=q"))] "ix86_match_ccmode (insn, CCNOmode) @@ -9695,8 +9677,7 @@ (define_expand "xordi3" [(set (match_operand:DI 0 "nonimmediate_operand" "") (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "x86_64_general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:DI 2 "x86_64_general_operand" "")))] "TARGET_64BIT" "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") @@ -9741,8 +9722,7 @@ (define_expand "xorsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:SI 2 "general_operand" "")))] "" "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") @@ -9835,15 +9815,14 @@ (define_expand "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:HI 2 "general_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") (define_insn "*xorhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "g,ri"))) + (match_operand:HI 2 "general_operand" "rmn,rn"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (XOR, HImode, operands)" "xor{w}\t{%2, %0|%0, %2}" @@ -9853,7 +9832,7 @@ (define_insn "*xorhi_2" [(set (reg FLAGS_REG) (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "g,ri")) + (match_operand:HI 2 "general_operand" "rmn,rn")) (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (xor:HI (match_dup 1) (match_dup 2)))] @@ -9866,7 +9845,7 @@ (define_insn "*xorhi_3" [(set (reg FLAGS_REG) (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") - (match_operand:HI 2 "general_operand" "g")) + (match_operand:HI 2 "general_operand" "rmn")) (const_int 0))) (clobber (match_scratch:HI 0 "=r"))] "ix86_match_ccmode (insn, CCNOmode) @@ -9878,8 +9857,7 @@ (define_expand "xorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "general_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") @@ -9887,7 +9865,7 @@ (define_insn "*xorqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) + (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (XOR, QImode, operands)" "@ @@ -9900,7 +9878,7 @@ (define_insn "*xorqi_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) (xor:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "qi,qmi"))) + (match_operand:QI 1 "general_operand" "qn,qmn"))) (clobber (reg:CC FLAGS_REG))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -9985,7 +9963,7 @@ [(set (reg FLAGS_REG) (compare (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qim,qi")) + (match_operand:QI 2 "general_operand" "qmn,qn")) (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (xor:QI (match_dup 1) (match_dup 2)))] @@ -9998,7 +9976,7 @@ (define_insn "*xorqi_2_slp" [(set (reg FLAGS_REG) (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") - (match_operand:QI 1 "general_operand" "qim,qi")) + (match_operand:QI 1 "general_operand" "qmn,qn")) (const_int 0))) (set (strict_low_part (match_dup 0)) (xor:QI (match_dup 0) (match_dup 1)))] @@ -10013,7 +9991,7 @@ [(set (reg FLAGS_REG) (compare (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") - (match_operand:QI 2 "general_operand" "qim")) + (match_operand:QI 2 "general_operand" "qmn")) (const_int 0))) (clobber (match_scratch:QI 0 "=q"))] "ix86_match_ccmode (insn, CCNOmode) @@ -10127,9 +10105,8 @@ ;; Negation instructions (define_expand "negti2" - [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") - (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:TI 0 "nonimmediate_operand" "") + (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))] "TARGET_64BIT" "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") @@ -10163,9 +10140,8 @@ "split_ti (&operands[0], 2, &operands[0], &operands[2]);") (define_expand "negdi2" - [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") - (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))] "" "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") @@ -10224,9 +10200,8 @@ (define_expand "negsi2" - [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") - (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))] "" "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") @@ -10284,9 +10259,8 @@ (set_attr "mode" "SI")]) (define_expand "neghi2" - [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") - (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:HI 0 "nonimmediate_operand" "") + (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") @@ -10311,9 +10285,8 @@ (set_attr "mode" "HI")]) (define_expand "negqi2" - [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") - (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") @@ -10375,7 +10348,7 @@ (define_expand "<code>tf2" [(set (match_operand:TF 0 "register_operand" "") (absneg:TF (match_operand:TF 1 "register_operand" "")))] - "TARGET_64BIT" + "TARGET_SSE2" "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") (define_insn "*absnegtf2_sse" @@ -10384,7 +10357,7 @@ [(match_operand:TF 1 "register_operand" "0,x")])) (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" + "TARGET_SSE2" "#") ;; Splitters for fp abs and neg. @@ -10563,7 +10536,7 @@ (match_operand:CSGNMODE 1 "nonmemory_operand" "") (match_operand:CSGNMODE 2 "register_operand" "")] "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || (TARGET_64BIT && (<MODE>mode == TFmode))" + || (TARGET_SSE2 && (<MODE>mode == TFmode))" { ix86_expand_copysign (operands); DONE; @@ -10577,7 +10550,7 @@ (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] UNSPEC_COPYSIGN))] "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || (TARGET_64BIT && (<MODE>mode == TFmode))" + || (TARGET_SSE2 && (<MODE>mode == TFmode))" "#" "&& reload_completed" [(const_int 0)] @@ -10596,7 +10569,7 @@ UNSPEC_COPYSIGN)) (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || (TARGET_64BIT && (<MODE>mode == TFmode))" + || (TARGET_SSE2 && (<MODE>mode == TFmode))" "#") (define_split @@ -10609,7 +10582,7 @@ UNSPEC_COPYSIGN)) (clobber (match_scratch:<CSGNVMODE> 1 ""))] "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || (TARGET_64BIT && (<MODE>mode == TFmode))) + || (TARGET_SSE2 && (<MODE>mode == TFmode))) && reload_completed" [(const_int 0)] { @@ -10849,33 +10822,14 @@ ;; than 31. (define_expand "ashlti3" - [(parallel [(set (match_operand:TI 0 "register_operand" "") - (ashift:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_64BIT" -{ - if (! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (ASHIFT, TImode, operands); - DONE; -}) - -(define_insn "ashlti3_1" - [(set (match_operand:TI 0 "register_operand" "=r") - (ashift:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_scratch:DI 3 "=&r")) - (clobber (reg:CC FLAGS_REG))] + [(set (match_operand:TI 0 "register_operand" "") + (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_64BIT" - "#" - [(set_attr "type" "multi")]) + "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;") -;; This pattern must be defined before *ashlti3_2 to prevent -;; combine pass from converting sse2_ashlti3 to *ashlti3_2. +;; This pattern must be defined before *ashlti3_1 to prevent +;; combine pass from converting sse2_ashlti3 to *ashlti3_1. (define_insn "sse2_ashlti3" [(set (match_operand:TI 0 "register_operand" "=x") @@ -10890,45 +10844,45 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "*ashlti3_2" - [(set (match_operand:TI 0 "register_operand" "=r") - (ashift:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "immediate_operand" "O"))) +(define_insn "*ashlti3_1" + [(set (match_operand:TI 0 "register_operand" "=&r,r") + (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0") + (match_operand:QI 2 "nonmemory_operand" "Oc,Oc"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" [(set_attr "type" "multi")]) -(define_split - [(set (match_operand:TI 0 "register_operand" "") - (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") - (match_operand:QI 2 "register_operand" ""))) - (clobber (match_scratch:DI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" +(define_peephole2 + [(match_scratch:DI 3 "r") + (parallel [(set (match_operand:TI 0 "register_operand" "") + (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] + "TARGET_64BIT" [(const_int 0)] "ix86_split_ashl (operands, operands[3], TImode); DONE;") (define_split [(set (match_operand:TI 0 "register_operand" "") - (ashift:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "immediate_operand" ""))) + (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" + "TARGET_64BIT && ((optimize > 0 && flag_peephole2) + ? epilogue_completed : reload_completed)" [(const_int 0)] "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") (define_insn "x86_64_shld" - [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") + [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") (ior:DI (ashift:DI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "J,c")) - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") + (match_operand:QI 2 "nonmemory_operand" "Jc")) + (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") (minus:QI (const_int 64) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "@ - shld{q}\t{%2, %1, %0|%0, %1, %2} - shld{q}\t{%s2%1, %0|%0, %1, %2}" + "shld{q}\t{%s2%1, %0|%0, %1, %2}" [(set_attr "type" "ishift") (set_attr "prefix_0f" "1") (set_attr "mode" "DI") @@ -11021,7 +10975,7 @@ [(set (reg FLAGS_REG) (compare (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "immediate_operand" "e")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (set (match_operand:DI 0 "nonimmediate_operand" "=rm") (ashift:DI (match_dup 1) (match_dup 2)))] @@ -11064,7 +11018,7 @@ [(set (reg FLAGS_REG) (compare (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "immediate_operand" "e")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (clobber (match_scratch:DI 0 "=r"))] "TARGET_64BIT @@ -11135,17 +11089,15 @@ [(const_int 0)] "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") -(define_insn "x86_shld_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") +(define_insn "x86_shld" + [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") (ior:SI (ashift:SI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "I,c")) - (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") + (match_operand:QI 2 "nonmemory_operand" "Ic")) + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") (minus:QI (const_int 32) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))] "" - "@ - shld{l}\t{%2, %1, %0|%0, %1, %2} - shld{l}\t{%s2%1, %0|%0, %1, %2}" + "shld{l}\t{%s2%1, %0|%0, %1, %2}" [(set_attr "type" "ishift") (set_attr "prefix_0f" "1") (set_attr "mode" "SI") @@ -11200,8 +11152,7 @@ (define_expand "ashlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") @@ -11475,8 +11426,7 @@ (define_expand "ashlhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") @@ -11641,8 +11591,7 @@ (define_expand "ashlqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") @@ -11845,70 +11794,51 @@ ;; See comment above `ashldi3' about how this works. (define_expand "ashrti3" - [(parallel [(set (match_operand:TI 0 "register_operand" "") - (ashiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:TI 0 "register_operand" "") + (ashiftrt:TI (match_operand:TI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_64BIT" -{ - if (! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (ASHIFTRT, TImode, operands); - DONE; -}) + "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;") -(define_insn "ashrti3_1" +(define_insn "*ashrti3_1" [(set (match_operand:TI 0 "register_operand" "=r") (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_scratch:DI 3 "=&r")) + (match_operand:QI 2 "nonmemory_operand" "Oc"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" [(set_attr "type" "multi")]) -(define_insn "*ashrti3_2" - [(set (match_operand:TI 0 "register_operand" "=r") - (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "immediate_operand" "O"))) - (clobber (reg:CC FLAGS_REG))] +(define_peephole2 + [(match_scratch:DI 3 "r") + (parallel [(set (match_operand:TI 0 "register_operand" "") + (ashiftrt:TI (match_operand:TI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] "TARGET_64BIT" - "#" - [(set_attr "type" "multi")]) - -(define_split - [(set (match_operand:TI 0 "register_operand" "") - (ashiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "register_operand" ""))) - (clobber (match_scratch:DI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" [(const_int 0)] "ix86_split_ashr (operands, operands[3], TImode); DONE;") (define_split [(set (match_operand:TI 0 "register_operand" "") (ashiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "immediate_operand" ""))) + (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" + "TARGET_64BIT && ((optimize > 0 && flag_peephole2) + ? epilogue_completed : reload_completed)" [(const_int 0)] "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") (define_insn "x86_64_shrd" - [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") + [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") (ior:DI (ashiftrt:DI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "J,c")) - (ashift:DI (match_operand:DI 1 "register_operand" "r,r") + (match_operand:QI 2 "nonmemory_operand" "Jc")) + (ashift:DI (match_operand:DI 1 "register_operand" "r") (minus:QI (const_int 64) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "@ - shrd{q}\t{%2, %1, %0|%0, %1, %2} - shrd{q}\t{%s2%1, %0|%0, %1, %2}" + "shrd{q}\t{%s2%1, %0|%0, %1, %2}" [(set_attr "type" "ishift") (set_attr "prefix_0f" "1") (set_attr "mode" "DI") @@ -12010,7 +11940,7 @@ [(set (reg FLAGS_REG) (compare (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (set (match_operand:DI 0 "nonimmediate_operand" "=rm") (ashiftrt:DI (match_dup 1) (match_dup 2)))] @@ -12026,7 +11956,7 @@ [(set (reg FLAGS_REG) (compare (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (clobber (match_scratch:DI 0 "=r"))] "TARGET_64BIT @@ -12070,17 +12000,15 @@ [(const_int 0)] "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") -(define_insn "x86_shrd_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") +(define_insn "x86_shrd" + [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") (ior:SI (ashiftrt:SI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "I,c")) - (ashift:SI (match_operand:SI 1 "register_operand" "r,r") + (match_operand:QI 2 "nonmemory_operand" "Ic")) + (ashift:SI (match_operand:SI 1 "register_operand" "r") (minus:QI (const_int 32) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))] "" - "@ - shrd{l}\t{%2, %1, %0|%0, %1, %2} - shrd{l}\t{%s2%1, %0|%0, %1, %2}" + "shrd{l}\t{%s2%1, %0|%0, %1, %2}" [(set_attr "type" "ishift") (set_attr "prefix_0f" "1") (set_attr "pent_pair" "np") @@ -12150,8 +12078,7 @@ (define_expand "ashrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") @@ -12307,8 +12234,7 @@ (define_expand "ashrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") @@ -12408,8 +12334,7 @@ (define_expand "ashrqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") @@ -12492,7 +12417,7 @@ [(set (reg FLAGS_REG) (compare (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" "I")) + (match_operand:QI 2 "const1_operand" "")) (const_int 0))) (clobber (match_scratch:QI 0 "=q"))] "(TARGET_SHIFT1 || optimize_size) @@ -12540,33 +12465,14 @@ ;; See comment above `ashldi3' about how this works. (define_expand "lshrti3" - [(parallel [(set (match_operand:TI 0 "register_operand" "") - (lshiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_64BIT" -{ - if (! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (LSHIFTRT, TImode, operands); - DONE; -}) - -(define_insn "lshrti3_1" - [(set (match_operand:TI 0 "register_operand" "=r") - (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "c"))) - (clobber (match_scratch:DI 3 "=&r")) - (clobber (reg:CC FLAGS_REG))] + [(set (match_operand:TI 0 "register_operand" "") + (lshiftrt:TI (match_operand:TI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_64BIT" - "#" - [(set_attr "type" "multi")]) + "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;") -;; This pattern must be defined before *lshrti3_2 to prevent -;; combine pass from converting sse2_lshrti3 to *lshrti3_2. +;; This pattern must be defined before *lshrti3_1 to prevent +;; combine pass from converting sse2_lshrti3 to *lshrti3_1. (define_insn "sse2_lshrti3" [(set (match_operand:TI 0 "register_operand" "=x") @@ -12581,31 +12487,33 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "*lshrti3_2" +(define_insn "*lshrti3_1" [(set (match_operand:TI 0 "register_operand" "=r") (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") - (match_operand:QI 2 "immediate_operand" "O"))) + (match_operand:QI 2 "nonmemory_operand" "Oc"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" [(set_attr "type" "multi")]) -(define_split - [(set (match_operand:TI 0 "register_operand" "") - (lshiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "register_operand" ""))) - (clobber (match_scratch:DI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" +(define_peephole2 + [(match_scratch:DI 3 "r") + (parallel [(set (match_operand:TI 0 "register_operand" "") + (lshiftrt:TI (match_operand:TI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] + "TARGET_64BIT" [(const_int 0)] "ix86_split_lshr (operands, operands[3], TImode); DONE;") (define_split [(set (match_operand:TI 0 "register_operand" "") (lshiftrt:TI (match_operand:TI 1 "register_operand" "") - (match_operand:QI 2 "immediate_operand" ""))) + (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed" + "TARGET_64BIT && ((optimize > 0 && flag_peephole2) + ? epilogue_completed : reload_completed)" [(const_int 0)] "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") @@ -12687,7 +12595,7 @@ [(set (reg FLAGS_REG) (compare (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const_int_operand" "e")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (set (match_operand:DI 0 "nonimmediate_operand" "=rm") (lshiftrt:DI (match_dup 1) (match_dup 2)))] @@ -12703,7 +12611,7 @@ [(set (reg FLAGS_REG) (compare (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const_int_operand" "e")) + (match_operand:QI 2 "const_1_to_63_operand" "J")) (const_int 0))) (clobber (match_scratch:DI 0 "=r"))] "TARGET_64BIT @@ -12750,8 +12658,7 @@ (define_expand "lshrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") @@ -12908,8 +12815,7 @@ (define_expand "lshrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") @@ -13009,8 +12915,7 @@ (define_expand "lshrqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") @@ -13139,8 +13044,7 @@ (define_expand "rotldi3" [(set (match_operand:DI 0 "shiftdi_operand" "") (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" { if (TARGET_64BIT) @@ -13210,8 +13114,7 @@ (define_expand "rotlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") @@ -13270,8 +13173,7 @@ (define_expand "rotlhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") @@ -13314,8 +13216,7 @@ (define_expand "rotlqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") @@ -13375,8 +13276,7 @@ (define_expand "rotrdi3" [(set (match_operand:DI 0 "shiftdi_operand" "") (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" { if (TARGET_64BIT) @@ -13446,8 +13346,7 @@ (define_expand "rotrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "" "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") @@ -13509,8 +13408,7 @@ (define_expand "rotrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_HIMODE_MATH" "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") @@ -13553,8 +13451,7 @@ (define_expand "rotrqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] + (match_operand:QI 2 "nonmemory_operand" "")))] "TARGET_QIMODE_MATH" "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") @@ -14040,7 +13937,7 @@ [(set (pc) (if_then_else (match_operator 1 "comparison_operator" [(match_operand:SWI 2 "register_operand" "<r>") - (match_operand:SWI 3 "const0_operand" "n")]) + (match_operand:SWI 3 "const0_operand" "")]) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT" @@ -14055,7 +13952,7 @@ [(set (pc) (if_then_else (match_operator 1 "comparison_operator" [(match_operand:SWI 2 "register_operand" "<r>") - (match_operand:SWI 3 "const0_operand" "n")]) + (match_operand:SWI 3 "const0_operand" "")]) (pc) (label_ref (match_operand 0 "" ""))))] "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT" @@ -14510,7 +14407,7 @@ [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand 1 "register_operand" "f") - (match_operand 2 "const0_operand" "X")]) + (match_operand 2 "const0_operand" "")]) (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:CCFP FPSR_REG)) diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 4f2ff6b7c9f..f36c6d4cc4a 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -629,6 +629,12 @@ (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), 1, 31)"))) +;; Return nonzero if OP is CONST_INT >= 1 and <= 63 (a valid operand +;; for 64bit shift & compare patterns, as shifting by 0 does not change flags). +(define_predicate "const_1_to_63_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 63)"))) + ;; Match 2 or 3. (define_predicate "const_2_to_3_operand" (and (match_code "const_int") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 115b382b8d8..84fb001cd63 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -3895,7 +3895,7 @@ (and:TF (not:TF (match_operand:TF 1 "register_operand" "0")) (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT" + "TARGET_SSE2" "pandn\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") @@ -3936,7 +3936,7 @@ (plogic:TF (match_operand:TF 1 "nonimmediate_operand" "") (match_operand:TF 2 "nonimmediate_operand" "")))] - "TARGET_64BIT" + "TARGET_SSE2" "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);") (define_insn "*<code>tf3" @@ -3944,7 +3944,7 @@ (plogic:TF (match_operand:TF 1 "nonimmediate_operand" "%0") (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, TFmode, operands)" + "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)" "p<plogicprefix>\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 35d7f9f9eac..7fdd89471a8 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -199,7 +199,7 @@ gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall) } } /* Assume max of 8 base 10 digits in the suffix. */ - p = new_str = alloca (1 + strlen (old_str) + 1 + 8 + 1); + p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1); if (fastcall) *p++ = FASTCALL_PREFIX; sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total); @@ -380,7 +380,7 @@ i386_pe_unique_section (tree decl, int reloc) else prefix = ".data$"; len = strlen (name) + strlen (prefix); - string = alloca (len + 1); + string = XALLOCAVEC (char, len + 1); sprintf (string, "%s%s", prefix, name); DECL_SECTION_NAME (decl) = build_string (len, string); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 22d0c0a3ce1..d1928f6b3c7 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -5248,7 +5248,7 @@ void ia64_init_expanders (void) static struct machine_function * ia64_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } static enum attr_itanium_class ia64_safe_itanium_class (rtx); @@ -6772,7 +6772,7 @@ ia64_h_i_d_extended (void) { int new_max_uid = get_max_uid () + 1; - spec_check_no = xrecalloc (spec_check_no, new_max_uid, + spec_check_no = (int *) xrecalloc (spec_check_no, new_max_uid, max_uid, sizeof (*spec_check_no)); max_uid = new_max_uid; } @@ -6781,14 +6781,14 @@ ia64_h_i_d_extended (void) { int new_clocks_length = get_max_uid () + 1; - stops_p = xrecalloc (stops_p, new_clocks_length, clocks_length, 1); + stops_p = (char *) xrecalloc (stops_p, new_clocks_length, clocks_length, 1); if (ia64_tune == PROCESSOR_ITANIUM) { - clocks = xrecalloc (clocks, new_clocks_length, clocks_length, - sizeof (int)); - add_cycles = xrecalloc (add_cycles, new_clocks_length, clocks_length, - sizeof (int)); + clocks = (int *) xrecalloc (clocks, new_clocks_length, clocks_length, + sizeof (int)); + add_cycles = (int *) xrecalloc (add_cycles, new_clocks_length, + clocks_length, sizeof (int)); } clocks_length = new_clocks_length; @@ -7410,7 +7410,7 @@ get_free_bundle_state (void) } else { - result = xmalloc (sizeof (struct bundle_state)); + result = XNEW (struct bundle_state); result->dfa_state = xmalloc (dfa_state_size); result->allocated_states_chain = allocated_bundle_states_chain; allocated_bundle_states_chain = result; @@ -7920,8 +7920,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail) bundling_p = 1; dfa_clean_insn_cache (); initiate_bundle_state_table (); - index_to_bundle_states = xmalloc ((insn_num + 2) - * sizeof (struct bundle_state *)); + index_to_bundle_states = XNEWVEC (struct bundle_state *, insn_num + 2); /* First (forward) pass -- generation of bundle states. */ curr_state = get_free_bundle_state (); curr_state->insn = NULL; @@ -8612,11 +8611,11 @@ ia64_reorg (void) PREV_INSN (ia64_nop) = NEXT_INSN (ia64_nop) = NULL_RTX; recog_memoized (ia64_nop); clocks_length = get_max_uid () + 1; - stops_p = xcalloc (1, clocks_length); + stops_p = XCNEWVEC (char, clocks_length); if (ia64_tune == PROCESSOR_ITANIUM) { - clocks = xcalloc (clocks_length, sizeof (int)); - add_cycles = xcalloc (clocks_length, sizeof (int)); + clocks = XCNEWVEC (int, clocks_length); + add_cycles = XCNEWVEC (int, clocks_length); } if (ia64_tune == PROCESSOR_ITANIUM2) { diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index 2d20a4ba4c2..b66a485dbb1 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -1389,7 +1389,7 @@ iq2000_init_machine_status (void) { struct machine_function *f; - f = ggc_alloc_cleared (sizeof (struct machine_function)); + f = GGC_CNEW (struct machine_function); return f; } diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 83b73b2414a..314feb183a6 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -1172,7 +1172,7 @@ m68hc11_encode_label (tree decl) { const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0); int len = strlen (str); - char *newstr = alloca (len + 2); + char *newstr = XALLOCAVEC (char, len + 2); newstr[0] = '@'; strcpy (&newstr[1], str); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index f95e37e9479..046132088bc 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for Motorola 68000 family. Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007 + 2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -500,7 +500,11 @@ m68k_handle_option (size_t code, const char *arg, int value) error ("-mshared-library-id=%s is not between 0 and %d", arg, MAX_LIBRARY_ID); else - asprintf ((char **) &m68k_library_id_string, "%d", (value * -4) - 4); + { + char *tmp; + asprintf (&tmp, "%d", (value * -4) - 4); + m68k_library_id_string = tmp; + } return true; default: @@ -3880,20 +3884,26 @@ print_operand (FILE *file, rtx op, int letter) else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode) { REAL_VALUE_TYPE r; + long l; REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_FLOAT_OPERAND (letter, file, r); + REAL_VALUE_TO_TARGET_SINGLE (r, l); + asm_fprintf (file, "%I0x%lx", l); } else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode) { REAL_VALUE_TYPE r; + long l[3]; REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r); + REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); + asm_fprintf (file, "%I0x%lx%08lx%08lx", l[0], l[1], l[2]); } else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode) { REAL_VALUE_TYPE r; + long l[2]; REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_DOUBLE_OPERAND (file, r); + REAL_VALUE_TO_TARGET_DOUBLE (r, l); + asm_fprintf (file, "%I0x%lx%08lx", l[0], l[1]); } else { @@ -5446,8 +5456,7 @@ m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED, { rtx insn; - sched_branch_type = xcalloc (get_max_uid () + 1, - sizeof (*sched_branch_type)); + sched_branch_type = XCNEWVEC (enum attr_type, get_max_uid () + 1); for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) { @@ -5504,8 +5513,7 @@ m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED, case CPU_CFV3: max_insn_size = 3; sched_ib.records.n_insns = 8; - sched_ib.records.adjust = xmalloc (sched_ib.records.n_insns - * sizeof (*sched_ib.records.adjust)); + sched_ib.records.adjust = XNEWVEC (int, sched_ib.records.n_insns); break; default: diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 2bb725f0423..55de085d4a0 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GCC for Motorola 680x0/ColdFire. Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -1015,40 +1015,6 @@ do { if (cc_prev_status.flags & CC_IN_68881) \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (int)(ROUNDED))) -/* Output a float value (represented as a C double) as an immediate operand. - This macro is m68k-specific. */ -#define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ - do { \ - if (CODE == 'f') \ - { \ - char dstr[30]; \ - real_to_decimal (dstr, &(VALUE), sizeof (dstr), 9, 0); \ - asm_fprintf ((FILE), "%I0r%s", dstr); \ - } \ - else \ - { \ - long l; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ - asm_fprintf ((FILE), "%I0x%lx", l); \ - } \ - } while (0) - -/* Output a double value (represented as a C double) as an immediate operand. - This macro is m68k-specific. */ -#define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ - do { char dstr[30]; \ - real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \ - asm_fprintf (FILE, "%I0r%s", dstr); \ - } while (0) - -/* Note, long double immediate operands are not actually - generated by m68k.md. */ -#define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \ - do { char dstr[30]; \ - real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \ - asm_fprintf (FILE, "%I0r%s", dstr); \ - } while (0) - /* On the 68000, we use several CODE characters: '.' for dot needed in Motorola-style opcode names. '-' for an operand pushing on the stack: diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 940c833dc3e..227f7dcd8e8 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -2851,7 +2851,7 @@ mcore_mark_dllexport (tree decl) if (mcore_dllexport_name_p (oldname)) return; /* Already done. */ - newname = alloca (strlen (oldname) + 4); + newname = XALLOCAVEC (char, strlen (oldname) + 4); sprintf (newname, "@e.%s", oldname); /* We pass newname through get_identifier to ensure it has a unique @@ -2909,7 +2909,7 @@ mcore_mark_dllimport (tree decl) TREE_PUBLIC (decl) = 1; } - newname = alloca (strlen (oldname) + 11); + newname = XALLOCAVEC (char, strlen (oldname) + 11); sprintf (newname, "@i.__imp_%s", oldname); /* We pass newname through get_identifier to ensure it has a unique @@ -3066,7 +3066,7 @@ mcore_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) prefix = ".data$"; len = strlen (name) + strlen (prefix); - string = alloca (len + 1); + string = XALLOCAVEC (char, len + 1); sprintf (string, "%s%s", prefix, name); diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md index 73d183ac95c..98b5113fbb5 100644 --- a/gcc/config/mips/loongson.md +++ b/gcc/config/mips/loongson.md @@ -83,7 +83,7 @@ (match_operand:VWHB 1 "move_operand" "f,m,f,dYG,dYG,dYG,m"))] "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fpstore,fpload,mfc,mtc,move,store,load") + [(set_attr "move_type" "fpstore,fpload,mfc,mtc,move,store,load") (set_attr "mode" "DI")]) ;; Initialization of a vector. diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md index 5e6091a3f0a..9a70b665d22 100644 --- a/gcc/config/mips/mips-dsp.md +++ b/gcc/config/mips/mips-dsp.md @@ -1017,8 +1017,7 @@ "ISA_HAS_DSP" "lbux\t%0,%2(%1)" [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4")]) + (set_attr "mode" "SI")]) (define_insn "mips_lhx" [(set (match_operand:SI 0 "register_operand" "=d") @@ -1029,8 +1028,7 @@ "ISA_HAS_DSP" "lhx\t%0,%2(%1)" [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4")]) + (set_attr "mode" "SI")]) (define_insn "mips_lwx" [(set (match_operand:SI 0 "register_operand" "=d") @@ -1039,8 +1037,7 @@ "ISA_HAS_DSP" "lwx\t%0,%2(%1)" [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4")]) + (set_attr "mode" "SI")]) ;; Table 2-8. MIPS DSP ASE Instructions: Branch ;; BPOSGE32 diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index b79b83a0bcb..d092cb6f5c1 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -171,6 +171,7 @@ extern bool mips_legitimate_address_p (enum machine_mode, rtx, bool); extern bool mips_stack_address_p (rtx, enum machine_mode); extern int mips_address_insns (rtx, enum machine_mode, bool); extern int mips_const_insns (rtx); +extern int mips_split_const_insns (rtx); extern int mips_load_store_insns (rtx, rtx); extern int mips_idiv_insns (void); extern rtx mips_emit_move (rtx, rtx); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 56180054d74..48ba54b1cef 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "expr.h" #include "optabs.h" +#include "libfuncs.h" #include "flags.h" #include "reload.h" #include "tm_p.h" @@ -2120,6 +2121,21 @@ mips_const_insns (rtx x) } } +/* X is a doubleword constant that can be handled by splitting it into + two words and loading each word separately. Return the number of + instructions required to do this. */ + +int +mips_split_const_insns (rtx x) +{ + unsigned int low, high; + + low = mips_const_insns (mips_subword (x, false)); + high = mips_const_insns (mips_subword (x, true)); + gcc_assert (low > 0 && high > 0); + return low + high; +} + /* Return the number of instructions needed to implement INSN, given that it loads from or stores to MEM. Count extended MIPS16 instructions as two instructions. */ @@ -5832,7 +5848,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) delta = bits / BITS_PER_UNIT; /* Allocate a buffer for the temporary registers. */ - regs = alloca (sizeof (rtx) * length / delta); + regs = XALLOCAVEC (rtx, length / delta); /* Load as many BITS-sized chunks as possible. Use a normal load if the source has enough alignment, otherwise use left/right pairs. */ @@ -9424,6 +9440,11 @@ mips_init_libfuncs (void) else /* Register the gofast functions if selected using --enable-gofast. */ gofast_maybe_init_libfuncs (); + + /* The MIPS16 ISA does not have an encoding for "sync", so we rely + on an external non-MIPS16 routine to implement __sync_synchronize. */ + if (TARGET_MIPS16) + synchronize_libfunc = init_one_libfunc ("__sync_synchronize"); } /* Return the length of INSN. LENGTH is the initial length computed by @@ -11422,7 +11443,8 @@ struct mips16_rewrite_pool_refs_info { static int mips16_rewrite_pool_refs (rtx *x, void *data) { - struct mips16_rewrite_pool_refs_info *info = data; + struct mips16_rewrite_pool_refs_info *info = + (struct mips16_rewrite_pool_refs_info *) data; if (force_to_mem_operand (*x, Pmode)) { @@ -11597,7 +11619,7 @@ static int mips_sim_wait_regs_2 (rtx *x, void *data) { if (REG_P (*x)) - mips_sim_wait_reg (data, mips_sim_insn, *x); + mips_sim_wait_reg ((struct mips_sim *) data, mips_sim_insn, *x); return 0; } @@ -11651,7 +11673,7 @@ mips_sim_record_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) { struct mips_sim *state; - state = data; + state = (struct mips_sim *) data; if (REG_P (x)) { unsigned int regno, end_regno; diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 842e582b7f4..6b2f5fac64d 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -280,6 +280,44 @@ (symbol_ref "TARGET_CALL_CLOBBERED_GP")] (const_string "no"))) +;; Classification of moves, extensions and truncations. Most values +;; are as for "type" (see below) but there are also the following +;; move-specific values: +;; +;; constN move an N-constraint integer into a MIPS16 register +;; sll0 "sll DEST,SRC,0", which on 64-bit targets is guaranteed +;; to produce a sign-extended DEST, even if SRC is not +;; properly sign-extended +;; andi a single ANDI instruction +;; loadpool move a constant into a MIPS16 register by loading it +;; from the pool +;; shift_shift a shift left followed by a shift right +;; lui_movf an LUI followed by a MOVF (for d<-z CC moves) +;; +;; This attribute is used to determine the instruction's length and +;; scheduling type. For doubleword moves, the attribute always describes +;; the split instructions; in some cases, it is more appropriate for the +;; scheduling type to be "multi" instead. +(define_attr "move_type" + "unknown,load,fpload,store,fpstore,mtc,mfc,mthilo,mfhilo,move,fmove, + const,constN,signext,sll0,andi,loadpool,shift_shift,lui_movf" + (const_string "unknown")) + +;; Main data type used by the insn +(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW" + (const_string "unknown")) + +;; True if the main data type is twice the size of a word. +(define_attr "dword_mode" "no,yes" + (cond [(and (eq_attr "mode" "DI,DF") + (eq (symbol_ref "TARGET_64BIT") (const_int 0))) + (const_string "yes") + + (and (eq_attr "mode" "TI,TF") + (ne (symbol_ref "TARGET_64BIT") (const_int 0))) + (const_string "yes")] + (const_string "no"))) + ;; Classification of each insn. ;; branch conditional branch ;; jump unconditional jump @@ -293,8 +331,8 @@ ;; prefetch memory prefetch (register + offset) ;; prefetchx memory indexed prefetch (register + register) ;; condmove conditional moves -;; mfc transfer from coprocessor ;; mtc transfer to coprocessor +;; mfc transfer from coprocessor ;; mthilo transfer to hi/lo registers ;; mfhilo transfer from hi/lo registers ;; const load constant @@ -330,15 +368,45 @@ ;; nop no operation ;; ghost an instruction that produces no real code (define_attr "type" - "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop,ghost" + "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore, + prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical, + shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul, + fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1, + frsqrt2,multi,nop,ghost" (cond [(eq_attr "jal" "!unset") (const_string "call") - (eq_attr "got" "load") (const_string "load")] + (eq_attr "got" "load") (const_string "load") + + ;; If a doubleword move uses these expensive instructions, + ;; it is usually better to schedule them in the same way + ;; as the singleword form, rather than as "multi". + (eq_attr "move_type" "load") (const_string "load") + (eq_attr "move_type" "fpload") (const_string "fpload") + (eq_attr "move_type" "store") (const_string "store") + (eq_attr "move_type" "fpstore") (const_string "fpstore") + (eq_attr "move_type" "mtc") (const_string "mtc") + (eq_attr "move_type" "mfc") (const_string "mfc") + (eq_attr "move_type" "mthilo") (const_string "mthilo") + (eq_attr "move_type" "mfhilo") (const_string "mfhilo") + + ;; These types of move are always single insns. + (eq_attr "move_type" "fmove") (const_string "fmove") + (eq_attr "move_type" "loadpool") (const_string "load") + (eq_attr "move_type" "signext") (const_string "signext") + (eq_attr "move_type" "sll0") (const_string "shift") + (eq_attr "move_type" "andi") (const_string "logical") + + ;; These types of move are always split. + (eq_attr "move_type" "constN,lui_movf,shift_shift") + (const_string "multi") + + ;; These types of move are split for doubleword modes only. + (and (eq_attr "move_type" "move,const") + (eq_attr "dword_mode" "yes")) + (const_string "multi") + (eq_attr "move_type" "move") (const_string "move") + (eq_attr "move_type" "const") (const_string "const")] (const_string "unknown"))) -;; Main data type used by the insn -(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" - (const_string "unknown")) - ;; Mode for conversion types (fcvt) ;; I2S integer to float single (SI/DI to SF) ;; I2D integer to float double (SI/DI to DF) @@ -352,11 +420,19 @@ ;; Is this an extended instruction in mips16 mode? (define_attr "extended_mips16" "no,yes" - (const_string "no")) + (if_then_else (ior (eq_attr "move_type" "sll0") + (eq_attr "type" "branch") + (eq_attr "jal" "direct")) + (const_string "yes") + (const_string "no"))) ;; Length of instruction in bytes. (define_attr "length" "" - (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc]. + (cond [(and (eq_attr "extended_mips16" "yes") + (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) + (const_int 8) + + ;; Direct branch instructions have a range of [-0x40000,0x3fffc]. ;; If a branch is outside this range, we have a choice of two ;; sequences. For PIC, an out-of-range branch like: ;; @@ -396,16 +472,49 @@ (const_int 24) ] (const_int 12)) + ;; "Ghost" instructions occupy no space. + (eq_attr "type" "ghost") + (const_int 0) + (eq_attr "got" "load") (const_int 4) (eq_attr "got" "xgot_high") (const_int 8) - (eq_attr "type" "const") + ;; In general, constant-pool loads are extended instructions. + (eq_attr "move_type" "loadpool") + (const_int 8) + + ;; LUI_MOVFs are decomposed into two separate instructions. + (eq_attr "move_type" "lui_movf") + (const_int 8) + + ;; SHIFT_SHIFTs are decomposed into two separate instructions. + ;; They are extended instructions on MIPS16 targets. + (eq_attr "move_type" "shift_shift") + (if_then_else (ne (symbol_ref "TARGET_MIPS16") (const_int 0)) + (const_int 16) + (const_int 8)) + + ;; Check for doubleword moves that are decomposed into two + ;; instructions. + (and (eq_attr "move_type" "mtc,mfc,mthilo,mfhilo,move") + (eq_attr "dword_mode" "yes")) + (const_int 8) + + ;; Doubleword CONST{,N} moves are split into two word + ;; CONST{,N} moves. + (and (eq_attr "move_type" "const,constN") + (eq_attr "dword_mode" "yes")) + (symbol_ref "mips_split_const_insns (operands[1]) * 4") + + ;; Otherwise, constants, loads and stores are handled by external + ;; routines. + (eq_attr "move_type" "const,constN") (symbol_ref "mips_const_insns (operands[1]) * 4") - (eq_attr "type" "load,fpload") + (eq_attr "move_type" "load,fpload") (symbol_ref "mips_load_store_insns (operands[1], insn) * 4") - (eq_attr "type" "store,fpstore") + (eq_attr "move_type" "store,fpstore") (symbol_ref "mips_load_store_insns (operands[0], insn) * 4") ;; In the worst case, a call macro will take 8 instructions: @@ -421,10 +530,6 @@ (eq_attr "jal_macro" "yes") (const_int 32) - (and (eq_attr "extended_mips16" "yes") - (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) - (const_int 8) - ;; Various VR4120 errata require a nop to be inserted after a macc ;; instruction. The assembler does this for us, so account for ;; the worst-case length here. @@ -2509,9 +2614,8 @@ "@ sll\t%0,%1,0 sw\t%1,%0" - [(set_attr "type" "shift,store") - (set_attr "mode" "SI") - (set_attr "extended_mips16" "yes,*")]) + [(set_attr "move_type" "sll0,store") + (set_attr "mode" "SI")]) (define_insn "truncdihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") @@ -2520,9 +2624,8 @@ "@ sll\t%0,%1,0 sh\t%1,%0" - [(set_attr "type" "shift,store") - (set_attr "mode" "SI") - (set_attr "extended_mips16" "yes,*")]) + [(set_attr "move_type" "sll0,store") + (set_attr "mode" "SI")]) (define_insn "truncdiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") @@ -2531,9 +2634,8 @@ "@ sll\t%0,%1,0 sb\t%1,%0" - [(set_attr "type" "shift,store") - (set_attr "mode" "SI") - (set_attr "extended_mips16" "yes,*")]) + [(set_attr "move_type" "sll0,store") + (set_attr "mode" "SI")]) ;; Combiner patterns to optimize shift/truncate combinations. @@ -2648,9 +2750,8 @@ (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))] { operands[1] = gen_lowpart (DImode, operands[1]); } - [(set_attr "type" "multi,load") - (set_attr "mode" "DI") - (set_attr "length" "8,*")]) + [(set_attr "move_type" "shift_shift,load") + (set_attr "mode" "DI")]) ;; Combine is not allowed to convert this insn into a zero_extendsidi2 ;; because of TRULY_NOOP_TRUNCATION. @@ -2673,9 +2774,8 @@ (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))] "" - [(set_attr "type" "multi,load") - (set_attr "mode" "DI") - (set_attr "length" "8,*")]) + [(set_attr "move_type" "shift_shift,load") + (set_attr "mode" "DI")]) (define_expand "zero_extend<SHORT:mode><GPR:mode>2" [(set (match_operand:GPR 0 "register_operand") @@ -2701,7 +2801,7 @@ "@ andi\t%0,%1,<SHORT:mask> l<SHORT:size>u\t%0,%1" - [(set_attr "type" "logical,load") + [(set_attr "move_type" "andi,load") (set_attr "mode" "<GPR:MODE>")]) (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e" @@ -2709,7 +2809,8 @@ (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))] "GENERATE_MIPS16E" "ze<SHORT:size>\t%0" - [(set_attr "type" "arith") + ;; This instruction is effectively a special encoding of ANDI. + [(set_attr "move_type" "andi") (set_attr "mode" "<GPR:MODE>")]) (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16" @@ -2717,7 +2818,7 @@ (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))] "TARGET_MIPS16" "l<SHORT:size>u\t%0,%1" - [(set_attr "type" "load") + [(set_attr "move_type" "load") (set_attr "mode" "<GPR:MODE>")]) (define_expand "zero_extendqihi2" @@ -2740,7 +2841,7 @@ "@ andi\t%0,%1,0x00ff lbu\t%0,%1" - [(set_attr "type" "logical,load") + [(set_attr "move_type" "andi,load") (set_attr "mode" "HI")]) (define_insn "*zero_extendqihi2_mips16" @@ -2748,7 +2849,7 @@ (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_MIPS16" "lbu\t%0,%1" - [(set_attr "type" "load") + [(set_attr "move_type" "load") (set_attr "mode" "HI")]) ;; @@ -2782,7 +2883,7 @@ emit_note (NOTE_INSN_DELETED); DONE; } - [(set_attr "type" "arith,load") + [(set_attr "move_type" "move,load") (set_attr "mode" "DI")]) (define_expand "extend<SHORT:mode><GPR:mode>2" @@ -2797,7 +2898,7 @@ "@ se<SHORT:size>\t%0 l<SHORT:size>\t%0,%1" - [(set_attr "type" "signext,load") + [(set_attr "move_type" "signext,load") (set_attr "mode" "<GPR:MODE>")]) (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2" @@ -2816,9 +2917,8 @@ operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode) - GET_MODE_BITSIZE (<SHORT:MODE>mode)); } - [(set_attr "type" "arith,load") - (set_attr "mode" "<GPR:MODE>") - (set_attr "length" "8,*")]) + [(set_attr "move_type" "shift_shift,load") + (set_attr "mode" "<GPR:MODE>")]) (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>" [(set (match_operand:GPR 0 "register_operand" "=d,d") @@ -2828,7 +2928,7 @@ "@ se<SHORT:size>\t%0,%1 l<SHORT:size>\t%0,%1" - [(set_attr "type" "signext,load") + [(set_attr "move_type" "signext,load") (set_attr "mode" "<GPR:MODE>")]) (define_expand "extendqihi2" @@ -2843,7 +2943,7 @@ "@ seb\t%0 lb\t%0,%1" - [(set_attr "type" "signext,load") + [(set_attr "move_type" "signext,load") (set_attr "mode" "SI")]) (define_insn_and_split "*extendqihi2" @@ -2863,9 +2963,8 @@ operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (QImode)); } - [(set_attr "type" "multi,load") - (set_attr "mode" "SI") - (set_attr "length" "8,*")]) + [(set_attr "move_type" "shift_shift,load") + (set_attr "mode" "SI")]) (define_insn "*extendqihi2_seb" [(set (match_operand:HI 0 "register_operand" "=d,d") @@ -2875,7 +2974,7 @@ "@ seb\t%0,%1 lb\t%0,%1" - [(set_attr "type" "signext,load") + [(set_attr "move_type" "signext,load") (set_attr "mode" "SI")]) (define_insn "extendsfdf2" @@ -2913,8 +3012,7 @@ "trunc.w.d %0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "DF") - (set_attr "cnv_mode" "D2I") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "D2I")]) (define_insn "fix_truncdfsi2_macro" [(set (match_operand:SI 0 "register_operand" "=f") @@ -2951,8 +3049,7 @@ "trunc.w.s %0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "SF") - (set_attr "cnv_mode" "S2I") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "S2I")]) (define_insn "fix_truncsfsi2_macro" [(set (match_operand:SI 0 "register_operand" "=f") @@ -2978,8 +3075,7 @@ "trunc.l.d %0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "DF") - (set_attr "cnv_mode" "D2I") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "D2I")]) (define_insn "fix_truncsfdi2" @@ -2989,8 +3085,7 @@ "trunc.l.s %0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "SF") - (set_attr "cnv_mode" "S2I") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "S2I")]) (define_insn "floatsidf2" @@ -3000,8 +3095,7 @@ "cvt.d.w\t%0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "DF") - (set_attr "cnv_mode" "I2D") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "I2D")]) (define_insn "floatdidf2" @@ -3011,8 +3105,7 @@ "cvt.d.l\t%0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "DF") - (set_attr "cnv_mode" "I2D") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "I2D")]) (define_insn "floatsisf2" @@ -3022,8 +3115,7 @@ "cvt.s.w\t%0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "SF") - (set_attr "cnv_mode" "I2S") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "I2S")]) (define_insn "floatdisf2" @@ -3033,8 +3125,7 @@ "cvt.s.l\t%0,%1" [(set_attr "type" "fcvt") (set_attr "mode" "SF") - (set_attr "cnv_mode" "I2S") - (set_attr "length" "4")]) + (set_attr "cnv_mode" "I2S")]) (define_expand "fixuns_truncdfsi2" @@ -3325,7 +3416,7 @@ UNSPEC_LOAD_LEFT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" "<load>l\t%0,%2" - [(set_attr "type" "load") + [(set_attr "move_type" "load") (set_attr "mode" "<MODE>")]) (define_insn "mov_<load>r" @@ -3336,7 +3427,7 @@ UNSPEC_LOAD_RIGHT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" "<load>r\t%0,%2" - [(set_attr "type" "load") + [(set_attr "move_type" "load") (set_attr "mode" "<MODE>")]) (define_insn "mov_<store>l" @@ -3346,7 +3437,7 @@ UNSPEC_STORE_LEFT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" "<store>l\t%z1,%2" - [(set_attr "type" "store") + [(set_attr "move_type" "store") (set_attr "mode" "<MODE>")]) (define_insn "mov_<store>r" @@ -3357,7 +3448,7 @@ UNSPEC_STORE_RIGHT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" "<store>r\t%z1,%2" - [(set_attr "type" "store") + [(set_attr "move_type" "store") (set_attr "mode" "<MODE>")]) ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE. @@ -3563,7 +3654,7 @@ "<d>addiu\t%0,%R2" [(set_attr "type" "arith") (set_attr "mode" "<MODE>") - (set_attr "length" "8")]) + (set_attr "extended_mips16" "yes")]) ;; Allow combine to split complex const_int load sequences, using operand 2 ;; to store the intermediate results. See move_operand for details. @@ -3614,30 +3705,18 @@ (reg:GPR 31))] "TARGET_MIPS16" "<store>\t$31,%0" - [(set_attr "type" "store") + [(set_attr "move_type" "store") (set_attr "mode" "<MODE>")]) (define_insn "*movdi_32bit" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m") - (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] - "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16 + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m") + (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))] + "!TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,multi,load,store,multi,multi,mtc,load,mfc,store") - (set_attr "mode" "DI") - (set_attr "length" "8,16,*,*,8,8,8,*,8,*")]) - -(define_insn "*movdi_gp32_fp64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*d,*m") - (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*J*d,*m,*f,*f"))] - "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16 - && (register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode))" - { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,multi,load,store,multi,multi,mtc,fpload,mfc,fpstore") - (set_attr "mode" "DI") - (set_attr "length" "8,16,*,*,8,8,8,*,8,*")]) + [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore") + (set_attr "mode" "DI")]) (define_insn "*movdi_32bit_mips16" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") @@ -3646,9 +3725,8 @@ && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,multi,multi,multi,multi,load,store,multi") - (set_attr "mode" "DI") - (set_attr "length" "8,8,8,8,12,*,*,8")]) + [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") + (set_attr "mode" "DI")]) (define_insn "*movdi_64bit" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*a,*d,*B*C*D,*B*C*D,*d,*m") @@ -3657,35 +3735,18 @@ && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mthilo,mfhilo,mtc,load,mfc,store") - (set_attr "mode" "DI") - (set_attr "length" "4,*,*,*,*,4,*,4,*,4,4,8,*,8,*")]) + [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mthilo,mfhilo,mtc,fpload,mfc,fpstore") + (set_attr "mode" "DI")]) (define_insn "*movdi_64bit_mips16" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d") - (match_operand:DI 1 "move_operand" "d,d,y,K,N,kf,U,m,d,*a"))] + (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))] "TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,move,move,arith,arith,load,const,load,store,mfhilo") - (set_attr "mode" "DI") - (set_attr_alternative "length" - [(const_int 4) - (const_int 4) - (const_int 4) - (if_then_else (match_operand:VOID 1 "m16_uimm8_1") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") - (const_int 8) - (const_int 12)) - (const_int 8) - (const_string "*") - (const_string "*") - (const_string "*") - (const_int 4)])]) - + [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo") + (set_attr "mode" "DI")]) ;; On the mips16, we can split ld $r,N($r) into an add and a load, ;; when the original load is a 4 byte instruction but the add and the @@ -3752,34 +3813,18 @@ && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,load,mfc,store") - (set_attr "mode" "SI") - (set_attr "length" "4,*,*,*,*,4,*,4,*,4,4,4,4,4,*,4,*")]) + [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,fpload,mfc,fpstore") + (set_attr "mode" "SI")]) (define_insn "*movsi_mips16" [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d") - (match_operand:SI 1 "move_operand" "d,d,y,K,N,kf,U,m,d,*a"))] + (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))] "TARGET_MIPS16 && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,move,move,arith,arith,load,const,load,store,mfhilo") - (set_attr "mode" "SI") - (set_attr_alternative "length" - [(const_int 4) - (const_int 4) - (const_int 4) - (if_then_else (match_operand:VOID 1 "m16_uimm8_1") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") - (const_int 8) - (const_int 12)) - (const_int 8) - (const_string "*") - (const_string "*") - (const_string "*") - (const_int 4)])]) + [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo") + (set_attr "mode" "SI")]) ;; On the mips16, we can split lw $r,N($r) into an add and a load, ;; when the original load is a 4 byte instruction but the add and the @@ -3849,9 +3894,8 @@ (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))] "ISA_HAS_8CC && TARGET_HARD_FLOAT" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,move,load,store,mfc,mtc,fmove,fpload,fpstore") - (set_attr "mode" "SI") - (set_attr "length" "8,4,*,*,4,4,4,*,*")]) + [(set_attr "move_type" "lui_movf,move,load,store,mfc,mtc,fmove,fpload,fpstore") + (set_attr "mode" "SI")]) ;; Reload condition code registers. reload_incc and reload_outcc ;; both handle moves from arbitrary operands into condition code @@ -3930,8 +3974,7 @@ "ISA_HAS_LWXS" "lwxs\t%0,%1(%2)" [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4")]) + (set_attr "mode" "SI")]) ;; 16-bit Integer moves @@ -3956,9 +3999,8 @@ && (register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,arith,load,store,mthilo,mfhilo") - (set_attr "mode" "HI") - (set_attr "length" "4,4,*,*,4,4")]) + [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") + (set_attr "mode" "HI")]) (define_insn "*movhi_mips16" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") @@ -3967,22 +4009,8 @@ && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,move,move,arith,arith,load,store,mfhilo") - (set_attr "mode" "HI") - (set_attr_alternative "length" - [(const_int 4) - (const_int 4) - (const_int 4) - (if_then_else (match_operand:VOID 1 "m16_uimm8_1") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") - (const_int 8) - (const_int 12)) - (const_string "*") - (const_string "*") - (const_string "*")])]) - + [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") + (set_attr "mode" "HI")]) ;; On the mips16, we can split lh $r,N($r) into an add and a load, ;; when the original load is a 4 byte instruction but the add and the @@ -4046,9 +4074,8 @@ && (register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,arith,load,store,mthilo,mfhilo") - (set_attr "mode" "QI") - (set_attr "length" "4,4,*,*,4,4")]) + [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") + (set_attr "mode" "QI")]) (define_insn "*movqi_mips16" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") @@ -4057,9 +4084,8 @@ && (register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,move,move,arith,arith,load,store,mfhilo") - (set_attr "mode" "QI") - (set_attr "length" "4,4,4,4,8,*,*,4")]) + [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") + (set_attr "mode" "QI")]) ;; On the mips16, we can split lb $r,N($r) into an add and a load, ;; when the original load is a 4 byte instruction but the add and the @@ -4106,9 +4132,8 @@ && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + (set_attr "mode" "SF")]) (define_insn "*movsf_softfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m") @@ -4117,9 +4142,8 @@ && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "4,*,*")]) + [(set_attr "move_type" "move,load,store") + (set_attr "mode" "SF")]) (define_insn "*movsf_mips16" [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m") @@ -4128,10 +4152,8 @@ && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "move,move,move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "4,4,4,*,*")]) - + [(set_attr "move_type" "move,move,move,load,store") + (set_attr "mode" "SF")]) ;; 64-bit floating point moves @@ -4144,39 +4166,25 @@ DONE; }) -(define_insn "*movdf_hardfloat_64bit" +(define_insn "*movdf_hardfloat" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && (register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") - (set_attr "mode" "DF") - (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) - -;; This pattern applies to both !TARGET_FLOAT64 and TARGET_FLOAT64. -(define_insn "*movdf_hardfloat_32bit" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") - (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT - && (register_operand (operands[0], DFmode) - || reg_or_0_operand (operands[1], DFmode))" - { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") - (set_attr "mode" "DF") - (set_attr "length" "4,8,*,*,*,8,8,8,*,*")]) + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + (set_attr "mode" "DF")]) (define_insn "*movdf_softfloat" - [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f") - (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m") + (match_operand:DF 1 "move_operand" "dG,m,dG"))] "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 && (register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,load,store,mfc,mtc,fmove") - (set_attr "mode" "DF") - (set_attr "length" "8,*,*,4,4,4")]) + [(set_attr "move_type" "move,load,store") + (set_attr "mode" "DF")]) (define_insn "*movdf_mips16" [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m") @@ -4185,9 +4193,8 @@ && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "multi,multi,multi,load,store") - (set_attr "mode" "DF") - (set_attr "length" "8,8,8,*,*")]) + [(set_attr "move_type" "move,move,move,load,store") + (set_attr "mode" "DF")]) ;; 128-bit integer moves @@ -4201,15 +4208,15 @@ }) (define_insn "*movti" - [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,m,*a,*d") - (match_operand:TI 1 "move_operand" "di,m,dJ,*d*J,*a"))] + [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d") + (match_operand:TI 1 "move_operand" "d,i,m,dJ,*d*J,*a"))] "TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], TImode) || reg_or_0_operand (operands[1], TImode))" "#" - [(set_attr "type" "multi,load,store,multi,multi") - (set_attr "length" "8,*,*,8,8")]) + [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") + (set_attr "mode" "TI")]) (define_insn "*movti_mips16" [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") @@ -4219,8 +4226,8 @@ && (register_operand (operands[0], TImode) || register_operand (operands[1], TImode))" "#" - [(set_attr "type" "multi,multi,multi,multi,multi,load,store,multi") - (set_attr "length" "8,8,8,12,16,*,*,8")]) + [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") + (set_attr "mode" "TI")]) ;; 128-bit floating point moves @@ -4242,8 +4249,8 @@ && (register_operand (operands[0], TFmode) || reg_or_0_operand (operands[1], TFmode))" "#" - [(set_attr "type" "multi,load,store,multi,multi,fpload,fpstore") - (set_attr "length" "8,*,*,8,8,*,*")]) + [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore") + (set_attr "mode" "TF")]) (define_insn "*movtf_mips16" [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m") @@ -4253,8 +4260,8 @@ && (register_operand (operands[0], TFmode) || register_operand (operands[1], TFmode))" "#" - [(set_attr "type" "multi,multi,multi,load,store") - (set_attr "length" "8,8,8,*,*")]) + [(set_attr "move_type" "move,move,move,load,store") + (set_attr "mode" "TF")]) (define_split [(set (match_operand:MOVE64 0 "nonimmediate_operand") @@ -4303,31 +4310,16 @@ DONE; }) -(define_insn "movv2sf_hardfloat_64bit" - [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") - (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))] - "TARGET_HARD_FLOAT - && TARGET_PAIRED_SINGLE_FLOAT - && TARGET_64BIT - && (register_operand (operands[0], V2SFmode) - || reg_or_0_operand (operands[1], V2SFmode))" - { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) - -(define_insn "movv2sf_hardfloat_32bit" +(define_insn "*movv2sf" [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))] "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT - && !TARGET_64BIT && (register_operand (operands[0], V2SFmode) || reg_or_0_operand (operands[1], V2SFmode))" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "4,8,*,*,*,8,8,8,*,*")]) + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + (set_attr "mode" "DF")]) ;; Extract the high part of a HI/LO value. See mips_hard_regno_mode_ok_p ;; for the reason why we can't just use (reg:GPR HI_REGNUM). @@ -4341,7 +4333,7 @@ UNSPEC_MFHI))] "" { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; } - [(set_attr "type" "mfhilo") + [(set_attr "move_type" "mfhilo") (set_attr "mode" "<GPR:MODE>")]) ;; Set the high part of a HI/LO value, given that the low part has @@ -4354,7 +4346,7 @@ UNSPEC_MTHI))] "" "mthi\t%z1" - [(set_attr "type" "mthilo") + [(set_attr "move_type" "mthilo") (set_attr "mode" "SI")]) ;; Emit a doubleword move in which exactly one of the operands is @@ -4402,7 +4394,7 @@ operands[0] = mips_subword (operands[0], 0); return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "mtc,fpload") + [(set_attr "move_type" "mtc,fpload") (set_attr "mode" "<HALFMODE>")]) ;; Load the high word of operand 0 from operand 1, preserving the value @@ -4417,7 +4409,7 @@ operands[0] = mips_subword (operands[0], 1); return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "mtc,fpload") + [(set_attr "move_type" "mtc,fpload") (set_attr "mode" "<HALFMODE>")]) ;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the @@ -4432,7 +4424,7 @@ operands[1] = mips_subword (operands[1], INTVAL (operands[2])); return mips_output_move (operands[0], operands[1]); } - [(set_attr "type" "mfc,fpstore") + [(set_attr "move_type" "mfc,fpstore") (set_attr "mode" "<HALFMODE>")]) ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the @@ -4444,7 +4436,7 @@ UNSPEC_MTHC1))] "TARGET_HARD_FLOAT && ISA_HAS_MXHC1" "mthc1\t%z1,%0" - [(set_attr "type" "mtc") + [(set_attr "move_type" "mtc") (set_attr "mode" "<HALFMODE>")]) ;; Move high word of operand 1 to operand 0 using mfhc1. @@ -4454,7 +4446,7 @@ UNSPEC_MFHC1))] "TARGET_HARD_FLOAT && ISA_HAS_MXHC1" "mfhc1\t%0,%1" - [(set_attr "type" "mfc") + [(set_attr "move_type" "mfc") (set_attr "mode" "<HALFMODE>")]) ;; Move a constant that satisfies CONST_GP_P into operand 0. @@ -4505,8 +4497,7 @@ "" "" [(set_attr "type" "ghost") - (set_attr "mode" "none") - (set_attr "length" "0")]) + (set_attr "mode" "none")]) ;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol ;; and operand 1 is the __GOTT_INDEX__ symbol. @@ -5493,8 +5484,7 @@ } } [(set_attr "type" "branch") - (set_attr "mode" "none") - (set_attr "length" "8")]) + (set_attr "mode" "none")]) (define_expand "b<code>" [(set (pc) @@ -5746,9 +5736,8 @@ (label_ref (match_operand 0 "" "")))] "TARGET_MIPS16" "b\t%l0" - [(set_attr "type" "branch") - (set_attr "mode" "none") - (set_attr "length" "8")]) + [(set_attr "type" "branch") + (set_attr "mode" "none")]) (define_expand "indirect_jump" [(set (pc) (match_operand 0 "register_operand"))] @@ -5883,8 +5872,7 @@ "" "" [(set_attr "type" "ghost") - (set_attr "mode" "none") - (set_attr "length" "0")]) + (set_attr "mode" "none")]) (define_expand "epilogue" [(const_int 2)] @@ -6070,16 +6058,14 @@ (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))] "TARGET_USE_GOT" "" - [(set_attr "length" "0") - (set_attr "type" "ghost")]) + [(set_attr "type" "ghost")]) (define_insn "update_got_version" [(set (reg:SI GOT_VERSION_REGNUM) (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))] "TARGET_USE_GOT" "" - [(set_attr "length" "0") - (set_attr "type" "ghost")]) + [(set_attr "type" "ghost")]) ;; Sibling calls. All these patterns use jump instructions. @@ -6205,8 +6191,7 @@ mips_restore_gp (); DONE; } - [(set_attr "jal" "indirect,direct") - (set_attr "extended_mips16" "no,yes")]) + [(set_attr "jal" "indirect,direct")]) ;; A pattern for calls that must be made directly. It is used for ;; MIPS16 calls that the linker may need to redirect to a hard-float @@ -6258,8 +6243,7 @@ mips_restore_gp (); DONE; } - [(set_attr "jal" "indirect,direct") - (set_attr "extended_mips16" "no,yes")]) + [(set_attr "jal" "indirect,direct")]) (define_insn "call_value_split" [(set (match_operand 0 "register_operand" "") @@ -6301,8 +6285,7 @@ mips_restore_gp (); DONE; } - [(set_attr "jal" "indirect,direct") - (set_attr "extended_mips16" "no,yes")]) + [(set_attr "jal" "indirect,direct")]) (define_insn "call_value_multiple_split" [(set (match_operand 0 "register_operand" "") diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 2807d08d956..fe38bb01eca 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -241,7 +241,7 @@ mmix_init_expanders (void) static struct machine_function * mmix_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } /* DATA_ALIGNMENT. @@ -1158,7 +1158,7 @@ mmix_encode_section_info (tree decl, rtx rtl, int first) const char *str = XSTR (XEXP (rtl, 0), 0); int len = strlen (str); - char *newstr = alloca (len + 2); + char *newstr = XALLOCAVEC (char, len + 2); newstr[0] = '@'; strcpy (newstr + 1, str); XSTR (XEXP (rtl, 0), 0) = ggc_alloc_string (newstr, len + 1); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 009f5faf10c..0529a86a68c 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -538,7 +538,7 @@ pa_init_builtins (void) static struct machine_function * pa_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (machine_function)); + return GGC_CNEW (machine_function); } /* If FROM is a probable pointer register, mark TO as a probable @@ -7861,7 +7861,7 @@ hppa_encode_label (rtx sym) int len = strlen (str) + 1; char *newstr, *p; - p = newstr = alloca (len + 1); + p = newstr = XALLOCAVEC (char, len + 1); *p++ = '@'; strcpy (p, str); diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 09e0fe507cf..48072988f33 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -201,6 +201,8 @@ /* Define cutoff for using external functions to save floating point. */ #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63) +/* And similarly for general purpose registers. */ +#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32) /* __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. diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h index 9479fc312ca..d8550c86dfb 100644 --- a/gcc/config/rs6000/darwin.h +++ b/gcc/config/rs6000/darwin.h @@ -191,6 +191,8 @@ #undef FP_SAVE_INLINE #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) +#undef GP_SAVE_INLINE +#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32) /* Darwin uses a function call if everything needs to be saved/restored. */ #undef WORLD_SAVE_P diff --git a/gcc/config/rs6000/e500.h b/gcc/config/rs6000/e500.h index ae909952d8b..c874f08f0ad 100644 --- a/gcc/config/rs6000/e500.h +++ b/gcc/config/rs6000/e500.h @@ -19,7 +19,6 @@ #undef TARGET_SPE_ABI #undef TARGET_SPE #undef TARGET_E500 -#undef TARGET_ISEL #undef TARGET_FPRS #undef TARGET_E500_SINGLE #undef TARGET_E500_DOUBLE @@ -28,13 +27,12 @@ #define TARGET_SPE_ABI rs6000_spe_abi #define TARGET_SPE rs6000_spe #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540) -#define TARGET_ISEL rs6000_isel #define TARGET_FPRS (rs6000_float_gprs == 0) #define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1) #define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2) #define CHECK_E500_OPTIONS \ do { \ - if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI || TARGET_ISEL \ + if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI \ || TARGET_E500_SINGLE || TARGET_E500_DOUBLE) \ { \ if (TARGET_ALTIVEC) \ diff --git a/gcc/config/rs6000/e500mc.md b/gcc/config/rs6000/e500mc.md new file mode 100644 index 00000000000..86434f95fe1 --- /dev/null +++ b/gcc/config/rs6000/e500mc.md @@ -0,0 +1,200 @@ +;; Pipeline description for Motorola PowerPC e500mc core. +;; Copyright (C) 2008 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. +;; +;; e500mc 32-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) +;; FP is half clocked, timings of other instructions are as in the e500v2. + +(define_automaton "e500mc_most,e500mc_long,e500mc_retire") +(define_cpu_unit "e500mc_decode_0,e500mc_decode_1" "e500mc_most") +(define_cpu_unit "e500mc_issue_0,e500mc_issue_1" "e500mc_most") +(define_cpu_unit "e500mc_retire_0,e500mc_retire_1" "e500mc_retire") + +;; SU. +(define_cpu_unit "e500mc_su0_stage0,e500mc_su1_stage0" "e500mc_most") + +;; MU. +(define_cpu_unit "e500mc_mu_stage0,e500mc_mu_stage1" "e500mc_most") +(define_cpu_unit "e500mc_mu_stage2,e500mc_mu_stage3" "e500mc_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc_mu_div" "e500mc_long") + +;; LSU. +(define_cpu_unit "e500mc_lsu" "e500mc_most") + +;; FPU. +(define_cpu_unit "e500mc_fpu" "e500mc_most") + +;; Branch unit. +(define_cpu_unit "e500mc_bu" "e500mc_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc_decode_0" "e500mc_most") +(define_cpu_unit "present_e500mc_issue_0" "e500mc_most") +(define_cpu_unit "present_e500mc_retire_0" "e500mc_retire") +(define_cpu_unit "present_e500mc_su0_stage0" "e500mc_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc_decode_0" "e500mc_decode_0") +(presence_set "present_e500mc_issue_0" "e500mc_issue_0") +(presence_set "present_e500mc_retire_0" "e500mc_retire_0") +(presence_set "present_e500mc_su0_stage0" "e500mc_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc_decode" + "e500mc_decode_0|e500mc_decode_1+present_e500mc_decode_0") +(define_reservation "e500mc_issue" + "e500mc_issue_0|e500mc_issue_1+present_e500mc_issue_0") +(define_reservation "e500mc_retire" + "e500mc_retire_0|e500mc_retire_1+present_e500mc_retire_0") +(define_reservation "e500mc_su_stage0" + "e500mc_su0_stage0|e500mc_su1_stage0+present_e500mc_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc_su" 1 + (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\ + delayed_compare,var_delayed_compare,fast_compare,\ + shift,trap,var_shift_rotate,cntlz,exts") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +(define_insn_reservation "e500mc_two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire") + +(define_insn_reservation "e500mc_three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Multiply. +(define_insn_reservation "e500mc_multiply" 4 + (and (eq_attr "type" "imul,imul2,imul3,imul_compare") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_mu_stage0,e500mc_mu_stage1,\ + e500mc_mu_stage2,e500mc_mu_stage3+e500mc_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc_divide" 14 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_mu_stage0+e500mc_mu_div,\ + e500mc_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_bu,e500mc_retire") + +;; CR logical. +(define_insn_reservation "e500mc_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_bu,e500mc_retire") + +;; Mfcr. +(define_insn_reservation "e500mc_mfcr" 1 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Brinc. +(define_insn_reservation "e500mc_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Loads. +(define_insn_reservation "e500mc_load" 3 + (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ + load_l,sync") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +(define_insn_reservation "e500mc_fpload" 4 + (and (eq_attr "type" "fpload,fpload_ux,fpload_u") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing*2,e500mc_retire") + +;; Stores. +(define_insn_reservation "e500mc_store" 3 + (and (eq_attr "type" "store,store_ux,store_u,store_c") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +(define_insn_reservation "e500mc_fpstore" 3 + (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; Simple FP. +(define_insn_reservation "e500mc_simple_float" 8 + (and (eq_attr "type" "fpsimple") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") +; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") + +;; FP. +(define_insn_reservation "e500mc_float" 8 + (and (eq_attr "type" "fp") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") +; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") + +(define_insn_reservation "e500mc_fpcompare" 8 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") + +(define_insn_reservation "e500mc_dmul" 10 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc_sdiv" 36 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*35") + +(define_insn_reservation "e500mc_ddiv" 66 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65") diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 3dd4bf560d7..8e97c79acd2 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -213,6 +213,9 @@ switch (mode) { case TFmode: + if (TARGET_E500_DOUBLE) + return 0; + REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); @@ -912,7 +915,7 @@ rtx elt; int count = XVECLEN (op, 0); - if (count != 55) + if (count != 54) return 0; index = 0; @@ -961,9 +964,8 @@ || GET_MODE (SET_SRC (elt)) != Pmode) return 0; - if (GET_CODE (XVECEXP (op, 0, index++)) != USE - || GET_CODE (XVECEXP (op, 0, index++)) != USE - || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) + if (GET_CODE (XVECEXP (op, 0, index++)) != SET + || GET_CODE (XVECEXP (op, 0, index++)) != SET) return 0; return 1; }) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 68280a5ff9b..4833ad76d91 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -694,6 +694,25 @@ struct processor_costs ppce300c2c3_cost = { 1, /* prefetch streams /*/ }; +/* Instruction costs on PPCE500MC processors. */ +static const +struct processor_costs ppce500mc_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (8), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ +}; + /* Instruction costs on POWER4 and POWER5 processors. */ static const struct processor_costs power4_cost = { @@ -742,7 +761,7 @@ static bool spe_func_has_64bit_regs_p (void); static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int, int, HOST_WIDE_INT); static rtx gen_frame_mem_offset (enum machine_mode, rtx, int); -static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int); +static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int); static unsigned rs6000_hash_constant (rtx); static unsigned toc_hash_function (const void *); static int toc_hash_eq (const void *, const void *); @@ -752,7 +771,7 @@ static bool legitimate_small_data_p (enum machine_mode, rtx); static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int); static struct machine_function * rs6000_init_machine_status (void); static bool rs6000_assemble_integer (rtx, unsigned int, int); -static bool no_global_regs_above (int); +static bool no_global_regs_above (int, bool); #ifdef HAVE_GAS_HIDDEN static void rs6000_assemble_visibility (tree, int); #endif @@ -765,7 +784,13 @@ static void rs6000_eliminate_indexed_memrefs (rtx operands[2]); static const char *rs6000_mangle_type (const_tree); extern const struct attribute_spec rs6000_attribute_table[]; static void rs6000_set_default_type_attributes (tree); +static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool); +static void rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool); +static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, + enum machine_mode, bool, bool, bool); static bool rs6000_reg_live_or_pic_offset_p (int); +static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int); +static void rs6000_restore_saved_cr (rtx, int); static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT); static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT); static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, @@ -1450,6 +1475,7 @@ rs6000_override_options (const char *default_cpu) {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN}, {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, + {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, @@ -1553,10 +1579,12 @@ rs6000_override_options (const char *default_cpu) } } - if (TARGET_E500 && !rs6000_explicit_options.isel) + if ((TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) + && !rs6000_explicit_options.isel) rs6000_isel = 1; - if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3) + if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 + || rs6000_cpu == PROCESSOR_PPCE500MC) { if (TARGET_ALTIVEC) error ("AltiVec not supported in this target"); @@ -1673,9 +1701,9 @@ rs6000_override_options (const char *default_cpu) SUB3TARGET_OVERRIDE_OPTIONS; #endif - if (TARGET_E500) + if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) { - /* The e500 does not have string instructions, and we set + /* The e500 and e500mc do not have string instructions, and we set MASK_STRING above when optimizing for size. */ if ((target_flags & MASK_STRING) != 0) target_flags = target_flags & ~MASK_STRING; @@ -1888,6 +1916,10 @@ rs6000_override_options (const char *default_cpu) rs6000_cost = &ppce300c2c3_cost; break; + case PROCESSOR_PPCE500MC: + rs6000_cost = &ppce500mc_cost; + break; + case PROCESSOR_POWER4: case PROCESSOR_POWER5: rs6000_cost = &power4_cost; @@ -11493,7 +11525,7 @@ rs6000_got_register (rtx value ATTRIBUTE_UNUSED) static struct machine_function * rs6000_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (machine_function)); + return GGC_CNEW (machine_function); } /* These macros test for integers and extract the low-order bits. */ @@ -12370,7 +12402,7 @@ print_operand_address (FILE *file, rtx x) char *newname; name = XSTR (symref, 0); - newname = alloca (strlen (name) + sizeof ("@toc")); + newname = XALLOCAVEC (char, strlen (name) + sizeof ("@toc")); strcpy (newname, name); strcat (newname, "@toc"); XSTR (symref, 0) = newname; @@ -14608,7 +14640,7 @@ rs6000_stack_info (void) { /* Align stack so SPE GPR save area is aligned on a double-word boundary. */ - if (info_ptr->spe_gp_size != 0) + if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0) info_ptr->spe_padding_size = 8 - (-info_ptr->cr_save_offset % 8); else @@ -15263,10 +15295,12 @@ rs6000_emit_stack_tie (void) /* 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. + If COPY_R11, make sure a copy of the old frame is left in r11, + in preference to r12 if COPY_R12. The generated code may use hard register 0 as a temporary. */ static void -rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12) +rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11) { rtx insn; rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); @@ -15315,8 +15349,11 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12) warning (0, "stack limit expression is not supported"); } - if (copy_r12 || ! TARGET_UPDATE) - emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg); + if (copy_r12 || copy_r11 || ! TARGET_UPDATE) + emit_move_insn (copy_r11 + ? gen_rtx_REG (Pmode, 11) + : gen_rtx_REG (Pmode, 12), + stack_reg); if (TARGET_UPDATE) { @@ -15342,7 +15379,9 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12) ? gen_addsi3 (stack_reg, stack_reg, todec) : gen_adddi3 (stack_reg, stack_reg, todec)); emit_move_insn (gen_rtx_MEM (Pmode, stack_reg), - gen_rtx_REG (Pmode, 12)); + copy_r11 + ? gen_rtx_REG (Pmode, 11) + : gen_rtx_REG (Pmode, 12)); } RTX_FRAME_RELATED_P (insn) = 1; @@ -15565,11 +15604,11 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) and cannot use stmw/lmw if there are any in its range. */ static bool -no_global_regs_above (int first_greg) +no_global_regs_above (int first, bool gpr) { int i; - for (i = 0; i < 32 - first_greg; i++) - if (global_regs[first_greg + i]) + for (i = first; i < gpr ? 32 : 64 ; i++) + if (global_regs[i]) return false; return true; } @@ -15578,6 +15617,163 @@ no_global_regs_above (int first_greg) #define TARGET_FIX_AND_CONTINUE 0 #endif +/* It's really GPR 13 and FPR 14, but we need the smaller of the two. */ +#define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO +#define LAST_SAVRES_REGISTER 31 +#define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1) + +static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8]; + +/* Return the symbol for an out-of-line register save/restore routine. + We are saving/restoring GPRs if GPR is true. */ + +static rtx +rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp) +{ + int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32); + rtx sym; + int select = ((savep ? 1 : 0) << 2 + | (gpr + /* On the SPE, we never have any FPRs, but we do have + 32/64-bit versions of the routines. */ + ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0) + : 0) << 1 + | (exitp ? 1: 0)); + + /* Don't generate bogus routine names. */ + gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER); + + sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]; + + if (sym == NULL) + { + char name[30]; + const char *action; + const char *regkind; + const char *exit_suffix; + + action = savep ? "save" : "rest"; + + /* SPE has slightly different names for its routines depending on + whether we are saving 32-bit or 64-bit registers. */ + if (TARGET_SPE_ABI) + { + /* No floating point saves on the SPE. */ + gcc_assert (gpr); + + regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr"; + } + else + regkind = gpr ? "gpr" : "fpr"; + + exit_suffix = exitp ? "_x" : ""; + + sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix); + + sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select] + = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); + } + + return sym; +} + +/* Emit a sequence of insns, including a stack tie if needed, for + resetting the stack pointer. If SAVRES is true, then don't reset the + stack pointer, but move the base of the frame into r11 for use by + out-of-line register restore routines. */ + +static void +rs6000_emit_stack_reset (rs6000_stack_t *info, + rtx sp_reg_rtx, rtx frame_reg_rtx, + int sp_offset, bool savres) +{ + /* This blockage is needed so that sched doesn't decide to move + the sp change before the register restores. */ + if (frame_reg_rtx != sp_reg_rtx + || (TARGET_SPE_ABI + && info->spe_64bit_regs_used != 0 + && info->first_gp_reg_save != 32)) + rs6000_emit_stack_tie (); + + if (frame_reg_rtx != sp_reg_rtx) + { + rs6000_emit_stack_tie (); + if (sp_offset != 0) + emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx, + GEN_INT (sp_offset))); + else if (!savres) + emit_move_insn (sp_reg_rtx, frame_reg_rtx); + } + else if (sp_offset != 0) + { + /* If we are restoring registers out-of-line, we will be using the + "exit" variants of the restore routines, which will reset the + stack for us. But we do need to point r11 into the right place + for those routines. */ + rtx dest_reg = (savres + ? gen_rtx_REG (Pmode, 11) + : sp_reg_rtx); + + emit_insn (TARGET_32BIT + ? gen_addsi3 (dest_reg, sp_reg_rtx, + GEN_INT (sp_offset)) + : gen_adddi3 (dest_reg, sp_reg_rtx, + GEN_INT (sp_offset))); + } +} + +/* Construct a parallel rtx describing the effect of a call to an + out-of-line register save/restore routine. */ + +static rtx +rs6000_make_savres_rtx (rs6000_stack_t *info, + rtx frame_reg_rtx, int save_area_offset, + enum machine_mode reg_mode, + bool savep, bool gpr, bool exitp) +{ + int i; + int offset, start_reg, end_reg, n_regs; + int reg_size = GET_MODE_SIZE (reg_mode); + rtx sym; + rtvec p; + + offset = 0; + start_reg = (gpr + ? info->first_gp_reg_save + : info->first_fp_reg_save); + end_reg = gpr ? 32 : 64; + n_regs = end_reg - start_reg; + p = rtvec_alloc ((exitp ? 4 : 3) + n_regs); + + /* If we're saving registers, then we should never say we're exiting. */ + gcc_assert ((savep && !exitp) || !savep); + + if (exitp) + RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode); + + RTVEC_ELT (p, offset++) + = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65)); + + sym = rs6000_savres_routine_sym (info, savep, gpr, exitp); + RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym); + RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11)); + + for (i = 0; i < end_reg - start_reg; i++) + { + rtx addr, reg, mem; + reg = gen_rtx_REG (reg_mode, start_reg + i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (save_area_offset + reg_size*i)); + mem = gen_frame_mem (reg_mode, addr); + + RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, + savep ? mem : reg, + savep ? reg : mem); + } + + return gen_rtx_PARALLEL (VOIDmode, p); +} + /* Determine whether the gp REG is really used. */ static bool @@ -15592,6 +15788,85 @@ rs6000_reg_live_or_pic_offset_p (int reg) || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))); } +enum { + SAVRES_MULTIPLE = 0x1, + SAVRES_INLINE_FPRS = 0x2, + SAVRES_INLINE_GPRS = 0x4 +}; + +/* Determine the strategy for savings/restoring registers. */ + +static int +rs6000_savres_strategy (rs6000_stack_t *info, bool savep, + int using_static_chain_p, int sibcall) +{ + bool using_multiple_p; + bool common; + bool savres_fprs_inline; + bool savres_gprs_inline; + bool noclobber_global_gprs + = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true); + + using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64 + && (!TARGET_SPE_ABI + || info->spe_64bit_regs_used == 0) + && info->first_gp_reg_save < 31 + && noclobber_global_gprs); + /* Don't bother to try to save things out-of-line if r11 is occupied + by the static chain. It would require too much fiddling and the + static chain is rarely used anyway. */ + common = (using_static_chain_p + || sibcall + || crtl->calls_eh_return + || !info->lr_save_p + || cfun->machine->ra_need_lr + || info->total_size > 32767); + savres_fprs_inline = (common + || info->first_fp_reg_save == 64 + || !no_global_regs_above (info->first_fp_reg_save, + /*gpr=*/false) + || FP_SAVE_INLINE (info->first_fp_reg_save)); + savres_gprs_inline = (common + /* Saving CR interferes with the exit routines + used on the SPE, so just punt here. */ + || (!savep + && TARGET_SPE_ABI + && info->spe_64bit_regs_used != 0 + && info->cr_save_p != 0) + || info->first_gp_reg_save == 32 + || !noclobber_global_gprs + || GP_SAVE_INLINE (info->first_gp_reg_save)); + + if (savep) + /* If we are going to use store multiple, then don't even bother + with the out-of-line routines, since the store-multiple instruction + will always be smaller. */ + savres_gprs_inline = savres_gprs_inline || using_multiple_p; + else + { + /* The situation is more complicated with load multiple. We'd + prefer to use the out-of-line routines for restores, since the + "exit" out-of-line routines can handle the restore of LR and + the frame teardown. But we can only use the out-of-line + routines if we know that we've used store multiple or + out-of-line routines in the prologue, i.e. if we've saved all + the registers from first_gp_reg_save. Otherwise, we risk + loading garbage from the stack. Furthermore, we can only use + the "exit" out-of-line gpr restore if we haven't saved any + fprs. */ + bool saved_all = !savres_gprs_inline || using_multiple_p; + + if (saved_all && info->first_fp_reg_save != 64) + /* We can't use the exit routine; use load multiple if it's + available. */ + savres_gprs_inline = savres_gprs_inline || using_multiple_p; + } + + return (using_multiple_p + | (savres_fprs_inline << 1) + | (savres_gprs_inline << 2)); +} + /* Emit function prologue as insns. */ void @@ -15605,8 +15880,13 @@ rs6000_emit_prologue (void) rtx frame_reg_rtx = sp_reg_rtx; rtx cr_save_rtx = NULL_RTX; rtx insn; + int strategy; int saving_FPRs_inline; + int saving_GPRs_inline; int using_store_multiple; + int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE + && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) + && !call_used_regs[STATIC_CHAIN_REGNUM]); HOST_WIDE_INT sp_offset = 0; if (TARGET_FIX_AND_CONTINUE) @@ -15629,15 +15909,12 @@ rs6000_emit_prologue (void) reg_size = 8; } - using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 - && (!TARGET_SPE_ABI - || info->spe_64bit_regs_used == 0) - && info->first_gp_reg_save < 31 - && no_global_regs_above (info->first_gp_reg_save)); - saving_FPRs_inline = (info->first_fp_reg_save == 64 - || FP_SAVE_INLINE (info->first_fp_reg_save) - || crtl->calls_eh_return - || cfun->machine->ra_need_lr); + strategy = rs6000_savres_strategy (info, /*savep=*/true, + /*static_chain_p=*/using_static_chain_p, + /*sibcall=*/0); + using_store_multiple = strategy & SAVRES_MULTIPLE; + saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS; + saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS; /* For V.4, update stack before we do any saving and set back pointer. */ if (! WORLD_SAVE_P (info) @@ -15645,17 +15922,24 @@ rs6000_emit_prologue (void) && (DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return)) { + bool need_r11 = (TARGET_SPE + ? (!saving_GPRs_inline + && info->spe_64bit_regs_used == 0) + : (!saving_FPRs_inline || !saving_GPRs_inline)); if (info->total_size < 32767) sp_offset = info->total_size; else - frame_reg_rtx = frame_ptr_rtx; + frame_reg_rtx = (need_r11 + ? gen_rtx_REG (Pmode, 11) + : 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 - ))); + )), + need_r11); if (frame_reg_rtx != sp_reg_rtx) rs6000_emit_stack_tie (); } @@ -15832,40 +16116,147 @@ rs6000_emit_prologue (void) } else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) { + rtx par; + + par = rs6000_make_savres_rtx (info, frame_reg_rtx, + info->fp_save_offset + sp_offset, + DFmode, + /*savep=*/true, /*gpr=*/false, + /*exitp=*/false); + insn = emit_insn (par); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); + } + + /* Save GPRs. This is done as a PARALLEL if we are using + the store-multiple instructions. */ + if (!WORLD_SAVE_P (info) + && TARGET_SPE_ABI + && info->spe_64bit_regs_used != 0 + && info->first_gp_reg_save != 32) + { int i; - char rname[30]; - const char *alloc_rname; - rtvec p; - p = rtvec_alloc (2 + 64 - info->first_fp_reg_save); + rtx spe_save_area_ptr; + + /* Determine whether we can address all of the registers that need + to be saved with an offset from the stack pointer that fits in + the small const field for SPE memory instructions. */ + int spe_regs_addressable_via_sp + = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset + + (32 - info->first_gp_reg_save - 1) * reg_size) + && saving_GPRs_inline); + int spe_offset; + + if (spe_regs_addressable_via_sp) + { + spe_save_area_ptr = frame_reg_rtx; + spe_offset = info->spe_gp_save_offset + sp_offset; + } + else + { + /* Make r11 point to the start of the SPE save area. We need + to be careful here if r11 is holding the static chain. If + it is, then temporarily save it in r0. We would use r0 as + our base register here, but using r0 as a base register in + loads and stores means something different from what we + would like. */ + int ool_adjust = (saving_GPRs_inline + ? 0 + : (info->first_gp_reg_save + - (FIRST_SAVRES_REGISTER+1))*8); + HOST_WIDE_INT offset = (info->spe_gp_save_offset + + sp_offset - ool_adjust); + + if (using_static_chain_p) + { + rtx r0 = gen_rtx_REG (Pmode, 0); + gcc_assert (info->first_gp_reg_save > 11); + + emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); + } + + spe_save_area_ptr = gen_rtx_REG (Pmode, 11); + insn = emit_insn (gen_addsi3 (spe_save_area_ptr, + frame_reg_rtx, + GEN_INT (offset))); + /* We need to make sure the move to r11 gets noted for + properly outputting unwind information. */ + if (!saving_GPRs_inline) + rs6000_frame_related (insn, frame_reg_rtx, offset, + NULL_RTX, NULL_RTX); + spe_offset = 0; + } + + if (saving_GPRs_inline) + { + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) + { + rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); + rtx offset, addr, mem; - RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode, - gen_rtx_REG (Pmode, - LR_REGNO)); - sprintf (rname, "%s%d%s", SAVE_FP_PREFIX, - info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); - alloc_rname = ggc_strdup (rname); - 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++) + /* We're doing all this to ensure that the offset fits into + the immediate offset of 'evstdd'. */ + gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); + + offset = GEN_INT (reg_size * i + spe_offset); + addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); + mem = gen_rtx_MEM (V2SImode, addr); + + insn = emit_move_insn (mem, reg); + + rs6000_frame_related (insn, spe_save_area_ptr, + info->spe_gp_save_offset + + sp_offset + reg_size * i, + offset, const0_rtx); + } + } + else { - 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_frame_mem (DFmode, addr); + rtx par; - RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg); + par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), + 0, reg_mode, + /*savep=*/true, /*gpr=*/true, + /*exitp=*/false); + insn = emit_insn (par); + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + NULL_RTX, NULL_RTX); } - insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); + + + /* Move the static chain pointer back. */ + if (using_static_chain_p && !spe_regs_addressable_via_sp) + emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); + } + else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline) + { + rtx par; + + /* Need to adjust r11 if we saved any FPRs. */ + if (info->first_fp_reg_save != 64) + { + rtx r11 = gen_rtx_REG (reg_mode, 11); + rtx offset = GEN_INT (info->total_size + + (-8 * (64-info->first_fp_reg_save))); + rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx + ? sp_reg_rtx : r11); + + emit_insn (TARGET_32BIT + ? gen_addsi3 (r11, ptr_reg, offset) + : gen_adddi3 (r11, ptr_reg, offset)); + } + + par = rs6000_make_savres_rtx (info, frame_reg_rtx, + info->gp_save_offset + sp_offset, + reg_mode, + /*savep=*/true, /*gpr=*/true, + /*exitp=*/false); + insn = emit_insn (par); rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, NULL_RTX, NULL_RTX); } - - /* Save GPRs. This is done as a PARALLEL if we are using - the store-multiple instructions. */ - if (!WORLD_SAVE_P (info) && using_store_multiple) + else if (!WORLD_SAVE_P (info) && using_store_multiple) { rtvec p; int i; @@ -15886,80 +16277,6 @@ rs6000_emit_prologue (void) rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, NULL_RTX, NULL_RTX); } - else if (!WORLD_SAVE_P (info) - && TARGET_SPE_ABI - && info->spe_64bit_regs_used != 0 - && info->first_gp_reg_save != 32) - { - int i; - rtx spe_save_area_ptr; - int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE - && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) - && !call_used_regs[STATIC_CHAIN_REGNUM]); - - /* Determine whether we can address all of the registers that need - to be saved with an offset from the stack pointer that fits in - the small const field for SPE memory instructions. */ - int spe_regs_addressable_via_sp - = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset - + (32 - info->first_gp_reg_save - 1) * reg_size); - int spe_offset; - - if (spe_regs_addressable_via_sp) - { - spe_save_area_ptr = frame_reg_rtx; - spe_offset = info->spe_gp_save_offset + sp_offset; - } - else - { - /* Make r11 point to the start of the SPE save area. We need - to be careful here if r11 is holding the static chain. If - it is, then temporarily save it in r0. We would use r0 as - our base register here, but using r0 as a base register in - loads and stores means something different from what we - would like. */ - if (using_static_chain_p) - { - rtx r0 = gen_rtx_REG (Pmode, 0); - - gcc_assert (info->first_gp_reg_save > 11); - - emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); - } - - spe_save_area_ptr = gen_rtx_REG (Pmode, 11); - emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx, - GEN_INT (info->spe_gp_save_offset + sp_offset))); - - spe_offset = 0; - } - - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - { - rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - rtx offset, addr, mem; - - /* We're doing all this to ensure that the offset fits into - the immediate offset of 'evstdd'. */ - gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); - - offset = GEN_INT (reg_size * i + spe_offset); - addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); - mem = gen_rtx_MEM (V2SImode, addr); - - insn = emit_move_insn (mem, reg); - - rs6000_frame_related (insn, spe_save_area_ptr, - info->spe_gp_save_offset - + sp_offset + reg_size * i, - offset, const0_rtx); - } - - /* Move the static chain pointer back. */ - if (using_static_chain_p && !spe_regs_addressable_via_sp) - emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); - } else if (!WORLD_SAVE_P (info)) { int i; @@ -16059,7 +16376,8 @@ rs6000_emit_prologue (void) (frame_reg_rtx != sp_reg_rtx && ((info->altivec_size != 0) || (info->vrsave_mask != 0) - ))); + )), + FALSE); if (frame_reg_rtx != sp_reg_rtx) rs6000_emit_stack_tie (); } @@ -16215,8 +16533,7 @@ rs6000_output_function_prologue (FILE *file, && !FP_SAVE_INLINE (info->first_fp_reg_save)) fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n", SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX, - RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, - RESTORE_FP_SUFFIX); + RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); /* Write .extern for AIX common mode routines, if needed. */ if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined) @@ -16264,6 +16581,54 @@ rs6000_output_function_prologue (FILE *file, we restore after the pop when possible. */ #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0 +/* Reload CR from REG. */ + +static void +rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple) +{ + int count = 0; + int i; + + if (using_mfcr_multiple) + { + for (i = 0; i < 8; i++) + if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) + count++; + gcc_assert (count); + } + + if (using_mfcr_multiple && count > 1) + { + rtvec p; + int ndx; + + p = rtvec_alloc (count); + + ndx = 0; + for (i = 0; i < 8; i++) + if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) + { + rtvec r = rtvec_alloc (2); + RTVEC_ELT (r, 0) = reg; + RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); + RTVEC_ELT (p, ndx) = + gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), + gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); + ndx++; + } + emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); + gcc_assert (ndx == count); + } + else + for (i = 0; i < 8; i++) + if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) + { + emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, + CR0_REGNO+i), + reg)); + } +} + /* Emit function epilogue as insns. At present, dwarf2out_frame_debug_expr doesn't understand @@ -16275,10 +16640,13 @@ void rs6000_emit_epilogue (int sibcall) { rs6000_stack_t *info; + int restoring_GPRs_inline; int restoring_FPRs_inline; int using_load_multiple; int using_mtcr_multiple; int use_backchain_to_restore_sp; + int restore_lr; + int strategy; int sp_offset = 0; rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); rtx frame_reg_rtx = sp_reg_rtx; @@ -16294,15 +16662,11 @@ rs6000_emit_epilogue (int sibcall) reg_size = 8; } - using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 - && (!TARGET_SPE_ABI - || info->spe_64bit_regs_used == 0) - && info->first_gp_reg_save < 31 - && no_global_regs_above (info->first_gp_reg_save)); - restoring_FPRs_inline = (sibcall - || crtl->calls_eh_return - || info->first_fp_reg_save == 64 - || FP_SAVE_INLINE (info->first_fp_reg_save)); + strategy = rs6000_savres_strategy (info, /*savep=*/false, + /*static_chain_p=*/0, sibcall); + using_load_multiple = strategy & SAVRES_MULTIPLE; + restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS; + restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS; using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601 || rs6000_cpu == PROCESSOR_PPC603 || rs6000_cpu == PROCESSOR_PPC750 @@ -16318,6 +16682,9 @@ rs6000_emit_epilogue (int sibcall) > 32767 || (cfun->calls_alloca && !frame_pointer_needed)); + restore_lr = (info->lr_save_p + && restoring_GPRs_inline + && restoring_FPRs_inline); if (WORLD_SAVE_P (info)) { @@ -16584,8 +16951,9 @@ rs6000_emit_epilogue (int sibcall) emit_insn (generate_set_vrsave (reg, info, 1)); } - /* Get the old lr if we saved it. */ - if (info->lr_save_p) + /* Get the old lr if we saved it. If we are restoring registers + out-of-line, then the out-of-line routines can do this for us. */ + if (restore_lr) { rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx, info->lr_save_offset + sp_offset); @@ -16604,7 +16972,7 @@ rs6000_emit_epilogue (int sibcall) } /* Set LR here to try to overlap restores below. */ - if (info->lr_save_p) + if (restore_lr) emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), gen_rtx_REG (Pmode, 0)); @@ -16640,35 +17008,17 @@ rs6000_emit_epilogue (int sibcall) /* Restore GPRs. This is done as a PARALLEL if we are using the load-multiple instructions. */ - if (using_load_multiple) - { - rtvec p; - p = rtvec_alloc (32 - info->first_gp_reg_save); - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + sp_offset - + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, i) = - gen_rtx_SET (VOIDmode, - gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - mem); - } - emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - } - else if (TARGET_SPE_ABI - && info->spe_64bit_regs_used != 0 - && info->first_gp_reg_save != 32) + if (TARGET_SPE_ABI + && info->spe_64bit_regs_used != 0 + && info->first_gp_reg_save != 32) { /* Determine whether we can address all of the registers that need to be saved with an offset from the stack pointer that fits in the small const field for SPE memory instructions. */ int spe_regs_addressable_via_sp - = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset - + (32 - info->first_gp_reg_save - 1) * reg_size); + = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset + + (32 - info->first_gp_reg_save - 1) * reg_size) + && restoring_GPRs_inline); int spe_offset; if (spe_regs_addressable_via_sp) @@ -16680,10 +17030,17 @@ rs6000_emit_epilogue (int sibcall) not clobbering it when we were saving registers in the prologue. There's no need to worry here because the static chain is passed anew to every function. */ + int ool_adjust = (restoring_GPRs_inline + ? 0 + : (info->first_gp_reg_save + - (FIRST_SAVRES_REGISTER+1))*8); + if (frame_reg_rtx == sp_reg_rtx) frame_reg_rtx = gen_rtx_REG (Pmode, 11); emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, - GEN_INT (info->spe_gp_save_offset + sp_offset))); + GEN_INT (info->spe_gp_save_offset + + sp_offset + - ool_adjust))); /* Keep the invariant that frame_reg_rtx + sp_offset points at the top of the stack frame. */ sp_offset = -info->spe_gp_save_offset; @@ -16691,26 +17048,80 @@ rs6000_emit_epilogue (int sibcall) spe_offset = 0; } - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - { - rtx offset, addr, mem; + if (restoring_GPRs_inline) + { + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) + { + rtx offset, addr, mem; - /* We're doing all this to ensure that the immediate offset - fits into the immediate field of 'evldd'. */ - gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); + /* We're doing all this to ensure that the immediate offset + fits into the immediate field of 'evldd'. */ + gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); - offset = GEN_INT (spe_offset + reg_size * i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); - mem = gen_rtx_MEM (V2SImode, addr); + offset = GEN_INT (spe_offset + reg_size * i); + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); + mem = gen_rtx_MEM (V2SImode, addr); - emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - mem); - } + emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + mem); + } + } + else + { + rtx par; + + par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), + 0, reg_mode, + /*savep=*/false, /*gpr=*/true, + /*exitp=*/true); + emit_jump_insn (par); + + /* We don't want anybody else emitting things after we jumped + back. */ + return; + } } - else - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) + else if (!restoring_GPRs_inline) + { + /* We are jumping to an out-of-line function. */ + bool can_use_exit = info->first_fp_reg_save == 64; + rtx par; + + /* Emit stack reset code if we need it. */ + if (can_use_exit) + rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, + sp_offset, can_use_exit); + else + emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11), + sp_reg_rtx, + GEN_INT (sp_offset - info->fp_size))); + + par = rs6000_make_savres_rtx (info, frame_reg_rtx, + info->gp_save_offset, reg_mode, + /*savep=*/false, /*gpr=*/true, + /*exitp=*/can_use_exit); + + if (can_use_exit) + { + if (info->cr_save_p) + rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), + using_mtcr_multiple); + + emit_jump_insn (par); + + /* We don't want anybody else emitting things after we jumped + back. */ + return; + } + else + emit_insn (par); + } + else if (using_load_multiple) + { + rtvec p; + p = rtvec_alloc (32 - info->first_gp_reg_save); + for (i = 0; i < 32 - info->first_gp_reg_save; i++) { rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (info->gp_save_offset @@ -16718,9 +17129,28 @@ rs6000_emit_epilogue (int sibcall) + reg_size * i)); rtx mem = gen_frame_mem (reg_mode, addr); - emit_move_insn (gen_rtx_REG (reg_mode, - info->first_gp_reg_save + i), mem); + RTVEC_ELT (p, i) = + gen_rtx_SET (VOIDmode, + gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + mem); } + emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); + } + else + { + for (i = 0; i < 32 - info->first_gp_reg_save; i++) + if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) + { + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, + GEN_INT (info->gp_save_offset + + sp_offset + + reg_size * i)); + rtx mem = gen_frame_mem (reg_mode, addr); + + emit_move_insn (gen_rtx_REG (reg_mode, + info->first_gp_reg_save + i), mem); + } + } /* Restore fpr's if we need to do it without calling a function. */ if (restoring_FPRs_inline) @@ -16742,69 +17172,12 @@ rs6000_emit_epilogue (int sibcall) /* If we saved cr, restore it here. Just those that were used. */ if (info->cr_save_p) - { - rtx r12_rtx = gen_rtx_REG (SImode, 12); - int count = 0; - - if (using_mtcr_multiple) - { - for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) - count++; - gcc_assert (count); - } - - if (using_mtcr_multiple && count > 1) - { - rtvec p; - int ndx; - - p = rtvec_alloc (count); - - ndx = 0; - for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (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, ndx) = - gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), - gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); - ndx++; - } - emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - gcc_assert (ndx == count); - } - else - for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) - { - emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, - CR0_REGNO+i), - r12_rtx)); - } - } + rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple); /* If this is V.4, unwind the stack pointer after all of the loads have been done. */ - if (frame_reg_rtx != sp_reg_rtx) - { - /* This blockage is needed so that sched doesn't decide to move - the sp change before the register restores. */ - rs6000_emit_stack_tie (); - if (sp_offset != 0) - emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx, - GEN_INT (sp_offset))); - else - emit_move_insn (sp_reg_rtx, frame_reg_rtx); - } - else if (sp_offset != 0) - emit_insn (TARGET_32BIT - ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, - GEN_INT (sp_offset)) - : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, - GEN_INT (sp_offset))); + rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, + sp_offset, !restoring_FPRs_inline); if (crtl->calls_eh_return) { @@ -16818,30 +17191,30 @@ rs6000_emit_epilogue (int sibcall) { rtvec p; if (! restoring_FPRs_inline) - p = rtvec_alloc (3 + 64 - info->first_fp_reg_save); + p = rtvec_alloc (4 + 64 - info->first_fp_reg_save); else p = rtvec_alloc (2); RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode); - RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, - gen_rtx_REG (Pmode, - LR_REGNO)); + RTVEC_ELT (p, 1) = (restoring_FPRs_inline + ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65)) + : gen_rtx_CLOBBER (VOIDmode, + gen_rtx_REG (Pmode, 65))); /* 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]; - const char *alloc_rname; - - sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX, - info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); - alloc_rname = ggc_strdup (rname); - RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, - gen_rtx_SYMBOL_REF (Pmode, - alloc_rname)); - + rtx sym; + + sym = rs6000_savres_routine_sym (info, + /*savep=*/false, + /*gpr=*/false, + /*exitp=*/true); + RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym); + RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, + gen_rtx_REG (Pmode, 11)); for (i = 0; i < 64 - info->first_fp_reg_save; i++) { rtx addr, mem; @@ -16849,7 +17222,7 @@ rs6000_emit_epilogue (int sibcall) GEN_INT (info->fp_save_offset + 8*i)); mem = gen_frame_mem (DFmode, addr); - RTVEC_ELT (p, i+3) = + RTVEC_ELT (p, i+4) = gen_rtx_SET (VOIDmode, gen_rtx_REG (DFmode, info->first_fp_reg_save + i), mem); @@ -17473,7 +17846,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) toc_hash_table = htab_create_ggc (1021, toc_hash_function, toc_hash_eq, NULL); - h = ggc_alloc (sizeof (*h)); + h = GGC_NEW (struct toc_hash_struct); h->key = x; h->key_mode = mode; h->labelno = labelno; @@ -18661,6 +19034,7 @@ rs6000_issue_rate (void) case CPU_CELL: case CPU_PPCE300C2: case CPU_PPCE300C3: + case CPU_PPCE500MC: return 2; case CPU_RIOS2: case CPU_PPC604: @@ -19531,7 +19905,7 @@ redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail) /* Initialize. */ issue_rate = rs6000_issue_rate (); - group_insns = alloca (issue_rate * sizeof (rtx)); + group_insns = XALLOCAVEC (rtx, issue_rate); for (i = 0; i < issue_rate; i++) { group_insns[i] = 0; @@ -20127,7 +20501,7 @@ rs6000_elf_encode_section_info (tree decl, rtx rtl, int first) { rtx sym_ref = XEXP (rtl, 0); size_t len = strlen (XSTR (sym_ref, 0)); - char *str = alloca (len + 2); + char *str = XALLOCAVEC (char, len + 2); str[0] = '.'; memcpy (str + 1, XSTR (sym_ref, 0), len + 1); XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1); @@ -20426,10 +20800,10 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub) length = strlen (symb); - symbol_name = alloca (length + 32); + symbol_name = XALLOCAVEC (char, length + 32); GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length); - lazy_ptr_name = alloca (length + 32); + lazy_ptr_name = XALLOCAVEC (char, length + 32); GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length); if (flag_pic == 2) @@ -20445,7 +20819,7 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub) fprintf (file, "\t.indirect_symbol %s\n", symbol_name); label++; - local_label_0 = alloca (sizeof ("\"L00000000000$spb\"")); + local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\"")); sprintf (local_label_0, "\"L%011d$spb\"", label); fprintf (file, "\tmflr r0\n"); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 4c225a3f0e7..8a926e43c44 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -133,6 +133,7 @@ %{mcpu=8548: -me500} \ %{mcpu=e300c2: -me300} \ %{mcpu=e300c3: -me300} \ +%{mcpu=e500mc: -me500mc} \ %{maltivec: -maltivec} \ -many" @@ -282,6 +283,7 @@ enum processor_type PROCESSOR_PPC8540, PROCESSOR_PPCE300C2, PROCESSOR_PPCE300C3, + PROCESSOR_PPCE500MC, PROCESSOR_POWER4, PROCESSOR_POWER5, PROCESSOR_POWER6, @@ -400,7 +402,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; #define TARGET_SPE_ABI 0 #define TARGET_SPE 0 #define TARGET_E500 0 -#define TARGET_ISEL 0 +#define TARGET_ISEL rs6000_isel #define TARGET_FPRS 1 #define TARGET_E500_SINGLE 0 #define TARGET_E500_DOUBLE 0 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index e3912c76646..5efde36de8d 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -133,7 +133,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,power4,power5,power6,cell" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell" (const (symbol_ref "rs6000_cpu_attr"))) @@ -167,6 +167,7 @@ (include "7450.md") (include "8540.md") (include "e300c2c3.md") +(include "e500mc.md") (include "power4.md") (include "power5.md") (include "power6.md") @@ -14421,12 +14422,25 @@ "{stm|stmw} %2,%1" [(set_attr "type" "store_ux")]) +(define_insn "*save_gpregs_<mode>" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:P 3 "memory_operand" "=m") + (match_operand:P 4 "gpc_reg_operand" "r"))])] + "" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + (define_insn "*save_fpregs_<mode>" [(match_parallel 0 "any_parallel_operand" [(clobber (reg:P 65)) - (use (match_operand:P 1 "call_operand" "s")) - (set (match_operand:DF 2 "memory_operand" "=m") - (match_operand:DF 3 "gpc_reg_operand" "f"))])] + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:DF 3 "memory_operand" "=m") + (match_operand:DF 4 "gpc_reg_operand" "f"))])] "" "bl %z1" [(set_attr "type" "branch") @@ -14514,15 +14528,43 @@ ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... +(define_insn "*restore_gpregs_<mode>" + [(match_parallel 0 "any_parallel_operand" + [(clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:P 4 "gpc_reg_operand" "=r") + (match_operand:P 5 "memory_operand" "m"))])] + "" + "bl %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_gpregs_<mode>" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:P 4 "gpc_reg_operand" "=r") + (match_operand:P 5 "memory_operand" "m"))])] + "" + "b %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + (define_insn "*return_and_restore_fpregs_<mode>" [(match_parallel 0 "any_parallel_operand" [(return) - (use (reg:P 65)) - (use (match_operand:P 1 "call_operand" "s")) - (set (match_operand:DF 2 "gpc_reg_operand" "=f") - (match_operand:DF 3 "memory_operand" "m"))])] + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:DF 4 "gpc_reg_operand" "=f") + (match_operand:DF 5 "memory_operand" "m"))])] "" - "b %z1") + "b %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) ; This is used in compiling the unwind routines. (define_expand "eh_return" diff --git a/gcc/config/rs6000/spe.md b/gcc/config/rs6000/spe.md index 1b66343bab2..96be255895b 100644 --- a/gcc/config/rs6000/spe.md +++ b/gcc/config/rs6000/spe.md @@ -3138,3 +3138,41 @@ "TARGET_E500" "cror 4*%0+gt,4*%1+gt,4*%2+gt" [(set_attr "type" "cr_logical")]) + +;; Out-of-line prologues and epilogues. +(define_insn "*save_gpregs_spe" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:V2SI 3 "memory_operand" "=m") + (match_operand:V2SI 4 "gpc_reg_operand" "r"))])] + "TARGET_SPE_ABI" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*restore_gpregs_spe" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:V2SI 3 "gpc_reg_operand" "=r") + (match_operand:V2SI 4 "memory_operand" "m"))])] + "TARGET_SPE_ABI" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_gpregs_spe" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:V2SI 3 "gpc_reg_operand" "=r") + (match_operand:V2SI 4 "memory_operand" "m"))])] + "TARGET_SPE_ABI" + "b %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index ef7f969ece4..b94de3bbbf4 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -266,19 +266,27 @@ do { \ #endif /* Define cutoff for using external functions to save floating point. - Currently on V.4, always use inline stores. */ -#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64) + Currently on 64-bit V.4, always use inline stores. When optimizing + for size on 32-bit targets, use external functions when + profitable. */ +#define FP_SAVE_INLINE(FIRST_REG) (optimize_size && !TARGET_64BIT \ + ? ((FIRST_REG) == 62 \ + || (FIRST_REG) == 63) \ + : (FIRST_REG) < 64) +/* And similarly for general purpose registers. */ +#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32 \ + && (TARGET_64BIT || !optimize_size)) /* Put jump tables in read-only memory, rather than in .text. */ #define JUMP_TABLES_IN_TEXT_SECTION 0 /* Prefix and suffix to use to saving floating point. */ #define SAVE_FP_PREFIX "_savefpr_" -#define SAVE_FP_SUFFIX "_l" +#define SAVE_FP_SUFFIX (TARGET_64BIT ? "_l" : "") /* Prefix and suffix to use to restoring floating point. */ #define RESTORE_FP_PREFIX "_restfpr_" -#define RESTORE_FP_SUFFIX "_l" +#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "_l" : "") /* Type used for ptrdiff_t, as a string used in a declaration. */ #define PTRDIFF_TYPE "int" diff --git a/gcc/config/rs6000/t-aix52 b/gcc/config/rs6000/t-aix52 index 37a5d83b828..3b19cbcee44 100644 --- a/gcc/config/rs6000/t-aix52 +++ b/gcc/config/rs6000/t-aix52 @@ -55,3 +55,5 @@ TARGET_LIBGCC2_CFLAGS = -mlong-double-128 # Either 32-bit and 64-bit objects in archives. AR_FLAGS_FOR_TARGET = -X32_64 +# genautomata requires more than 256MB of data +build/genautomata : override LDFLAGS += -Wl,-bmaxdata:0x20000000 diff --git a/gcc/config/rs6000/t-ppccomm b/gcc/config/rs6000/t-ppccomm index 8fc3e71b08e..3645571223f 100644 --- a/gcc/config/rs6000/t-ppccomm +++ b/gcc/config/rs6000/t-ppccomm @@ -3,23 +3,7 @@ LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c # These can't end up in shared libgcc -LIB2FUNCS_STATIC_EXTRA = eabi.S \ - crtsavfpr.S crtresfpr.S \ - crtsavgpr.S crtresgpr.S \ - crtresxfpr.S crtresxgpr.S \ - e500crtres32gpr.S \ - e500crtres64gpr.S \ - e500crtres64gprctr.S \ - e500crtrest32gpr.S \ - e500crtrest64gpr.S \ - e500crtresx32gpr.S \ - e500crtresx64gpr.S \ - e500crtsav32gpr.S \ - e500crtsav64gpr.S \ - e500crtsav64gprctr.S \ - e500crtsavg32gpr.S \ - e500crtsavg64gpr.S \ - e500crtsavg64gprctr.S +LIB2FUNCS_STATIC_EXTRA = eabi.S eabi.S: $(srcdir)/config/rs6000/eabi.asm cat $(srcdir)/config/rs6000/eabi.asm > eabi.S @@ -52,63 +36,6 @@ ncrti.S: $(srcdir)/config/rs6000/sol-ci.asm ncrtn.S: $(srcdir)/config/rs6000/sol-cn.asm cat $(srcdir)/config/rs6000/sol-cn.asm >ncrtn.S -crtsavfpr.S: $(srcdir)/config/rs6000/crtsavfpr.asm - cat $(srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S - -crtresfpr.S: $(srcdir)/config/rs6000/crtresfpr.asm - cat $(srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S - -crtsavgpr.S: $(srcdir)/config/rs6000/crtsavgpr.asm - cat $(srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S - -crtresgpr.S: $(srcdir)/config/rs6000/crtresgpr.asm - cat $(srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S - -crtresxfpr.S: $(srcdir)/config/rs6000/crtresxfpr.asm - cat $(srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S - -crtresxgpr.S: $(srcdir)/config/rs6000/crtresxgpr.asm - cat $(srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S - -e500crtres32gpr.S: $(srcdir)/config/rs6000/e500crtres32gpr.asm - cat $(srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S - -e500crtres64gpr.S: $(srcdir)/config/rs6000/e500crtres64gpr.asm - cat $(srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S - -e500crtres64gprctr.S: $(srcdir)/config/rs6000/e500crtres64gprctr.asm - cat $(srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S - -e500crtrest32gpr.S: $(srcdir)/config/rs6000/e500crtrest32gpr.asm - cat $(srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S - -e500crtrest64gpr.S: $(srcdir)/config/rs6000/e500crtrest64gpr.asm - cat $(srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S - -e500crtresx32gpr.S: $(srcdir)/config/rs6000/e500crtresx32gpr.asm - cat $(srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S - -e500crtresx64gpr.S: $(srcdir)/config/rs6000/e500crtresx64gpr.asm - cat $(srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S - -e500crtsav32gpr.S: $(srcdir)/config/rs6000/e500crtsav32gpr.asm - cat $(srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S - -e500crtsav64gpr.S: $(srcdir)/config/rs6000/e500crtsav64gpr.asm - cat $(srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S - -e500crtsav64gprctr.S: $(srcdir)/config/rs6000/e500crtsav64gprctr.asm - cat $(srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S - -e500crtsavg32gpr.S: $(srcdir)/config/rs6000/e500crtsavg32gpr.asm - cat $(srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S - -e500crtsavg64gpr.S: $(srcdir)/config/rs6000/e500crtsavg64gpr.asm - cat $(srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S - -e500crtsavg64gprctr.S: $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm - cat $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S - # Build multiple copies of ?crt{i,n}.o, one for each target switch. $(T)ecrti$(objext): ecrti.S $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ecrti.S -o $(T)ecrti$(objext) @@ -122,63 +49,6 @@ $(T)ncrti$(objext): ncrti.S $(T)ncrtn$(objext): ncrtn.S $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ncrtn.S -o $(T)ncrtn$(objext) -$(T)crtsavfpr$(objext): crtsavfpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavfpr.S -o $(T)crtsavfpr$(objext) - -$(T)crtresfpr$(objext): crtresfpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresfpr.S -o $(T)crtresfpr$(objext) - -$(T)crtsavgpr$(objext): crtsavgpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavgpr.S -o $(T)crtsavgpr$(objext) - -$(T)crtresgpr$(objext): crtresgpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresgpr.S -o $(T)crtresgpr$(objext) - -$(T)crtresxfpr$(objext): crtresxfpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxfpr.S -o $(T)crtresxfpr$(objext) - -$(T)crtresxgpr$(objext): crtresxgpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxgpr.S -o $(T)crtresxgpr$(objext) - -$(T)e500crtres32gpr$(objext): e500crtres32gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres32gpr.S -o $(T)e500crtres32gpr$(objext) - -$(T)e500crtres64gpr$(objext): e500crtres64gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gpr.S -o $(T)e500crtres64gpr$(objext) - -$(T)e500crtres64gprctr$(objext): e500crtres64gprctr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gprctr.S -o $(T)e500crtres64gprctr$(objext) - -$(T)e500crtrest32gpr$(objext): e500crtrest32gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest32gpr.S -o $(T)e500crtrest32gpr$(objext) - -$(T)e500crtrest64gpr$(objext): e500crtrest64gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest64gpr.S -o $(T)e500crtrest64gpr$(objext) - -$(T)e500crtresx32gpr$(objext): e500crtresx32gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx32gpr.S -o $(T)e500crtresx32gpr$(objext) - -$(T)e500crtresx64gpr$(objext): e500crtresx64gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx64gpr.S -o $(T)e500crtresx64gpr$(objext) - -$(T)e500crtsav32gpr$(objext): e500crtsav32gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav32gpr.S -o $(T)e500crtsav32gpr$(objext) - -$(T)e500crtsav64gpr$(objext): e500crtsav64gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gpr.S -o $(T)e500crtsav64gpr$(objext) - -$(T)e500crtsav64gprctr$(objext): e500crtsav64gprctr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gprctr.S -o $(T)e500crtsav64gprctr$(objext) - -$(T)e500crtsavg32gpr$(objext): e500crtsavg32gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg32gpr.S -o $(T)e500crtsavg32gpr$(objext) - -$(T)e500crtsavg64gpr$(objext): e500crtsavg64gpr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gpr.S -o $(T)e500crtsavg64gpr$(objext) - -$(T)e500crtsavg64gprctr$(objext): e500crtsavg64gprctr.S - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gprctr.S -o $(T)e500crtsavg64gprctr$(objext) - # It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata. CRTSTUFF_T_CFLAGS = -msdata=none # Make sure crt*.o are built with -fPIC even if configured with diff --git a/gcc/config/rs6000/x-linux64 b/gcc/config/rs6000/x-linux64 deleted file mode 100644 index 4371ca30431..00000000000 --- a/gcc/config/rs6000/x-linux64 +++ /dev/null @@ -1,2 +0,0 @@ -# parts of gcc need more than a 64k TOC. -X_CFLAGS = -mminimal-toc diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index ff2edecb223..b9f231729a6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1451,7 +1451,7 @@ s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop) static struct machine_function * s390_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } /* Change optimizations to be performed, depending on the diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index 56c6c477082..4f383da88dd 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -922,7 +922,7 @@ score_block_move_straight (rtx dst, rtx src, HOST_WIDE_INT length) length -= leftover; reg_count = length / UNITS_PER_WORD; - regs = alloca (sizeof (rtx) * reg_count); + regs = XALLOCAVEC (rtx, reg_count); for (i = 0; i < reg_count; i++) regs[i] = gen_reg_rtx (SImode); @@ -1006,7 +1006,7 @@ score_block_move_loop_body (rtx dst_reg, HOST_WIDE_INT dst_align, HOST_WIDE_INT length) { int reg_count = length / UNITS_PER_WORD; - rtx *regs = alloca (sizeof (rtx) * reg_count); + rtx *regs = XALLOCAVEC (rtx, reg_count); int i; bool src_unaligned = (src_align < BITS_PER_WORD); bool dst_unaligned = (dst_align < BITS_PER_WORD); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 009ab3a2bcf..5e6f5748672 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -8848,7 +8848,7 @@ sparc_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED, static struct machine_function * sparc_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } /* Locate some local-dynamic symbol still in use by this function diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 4dd3d7cc0fe..e645adb2281 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -4576,15 +4576,6 @@ spu_builtin_splats (rtx ops[]) constant_to_array (GET_MODE_INNER (mode), ops[1], arr); emit_move_insn (ops[0], array_to_constant (mode, arr)); } - else if (!flag_pic && GET_MODE (ops[0]) == V4SImode && CONSTANT_P (ops[1])) - { - rtvec v = rtvec_alloc (4); - RTVEC_ELT (v, 0) = ops[1]; - RTVEC_ELT (v, 1) = ops[1]; - RTVEC_ELT (v, 2) = ops[1]; - RTVEC_ELT (v, 3) = ops[1]; - emit_move_insn (ops[0], gen_rtx_CONST_VECTOR (mode, v)); - } else { rtx reg = gen_reg_rtx (TImode); @@ -4903,7 +4894,9 @@ spu_expand_vector_init (rtx target, rtx vals) for (i = 0; i < n_elts; ++i) { x = XVECEXP (vals, 0, i); - if (!CONSTANT_P (x)) + if (!(CONST_INT_P (x) + || GET_CODE (x) == CONST_DOUBLE + || GET_CODE (x) == CONST_FIXED)) ++n_var; else { @@ -4940,8 +4933,13 @@ spu_expand_vector_init (rtx target, rtx vals) /* fill empty slots with the first constant, this increases our chance of using splats in the recursive call below. */ for (i = 0; i < n_elts; ++i) - if (!CONSTANT_P (XVECEXP (constant_parts_rtx, 0, i))) - XVECEXP (constant_parts_rtx, 0, i) = first_constant; + { + x = XVECEXP (constant_parts_rtx, 0, i); + if (!(CONST_INT_P (x) + || GET_CODE (x) == CONST_DOUBLE + || GET_CODE (x) == CONST_FIXED)) + XVECEXP (constant_parts_rtx, 0, i) = first_constant; + } spu_expand_vector_init (target, constant_parts_rtx); } @@ -4957,7 +4955,9 @@ spu_expand_vector_init (rtx target, rtx vals) for (i = 0; i < n_elts; ++i) { x = XVECEXP (vals, 0, i); - if (!CONSTANT_P (x)) + if (!(CONST_INT_P (x) + || GET_CODE (x) == CONST_DOUBLE + || GET_CODE (x) == CONST_FIXED)) { if (!register_operand (x, GET_MODE (x))) x = force_reg (GET_MODE (x), x); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index a5ca4635248..6e26d76daad 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -1208,7 +1208,7 @@ xtensa_expand_nonlocal_goto (rtx *operands) static struct machine_function * xtensa_init_machine_status (void) { - return ggc_alloc_cleared (sizeof (struct machine_function)); + return GGC_CNEW (struct machine_function); } |