Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:PowerPC
gcc43
ibm311554-ltoc-r160772:160773
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ibm311554-ltoc-r160772:160773 of Package gcc43
2010-06-15 Alan Modra <amodra@gmail.com> * doc/invoke.texi: Add mcmodel to powerpc options. * configure.ac: Add HAVE_LD_LARGE_TOC test. * configure: Regenerate. * config.in: Regenerate. * config/rs6000/linux64.opt (mcmodel): New. * config/rs6000/linux64.h (TARGET_USES_LINUX64_OPT): Define. (TARGET_CMODEL): Define. (SUBSUBTARGET_OVERRIDE_OPTIONS): Check user -mcmodel choice, select CMODEL_MEDIUM default. * config/rs6000/rs6000.h (enum rs6000_cmodel): New. (TARGET_CMODEL): Define default. * config/rs6000/rs6000.c (cmodel): New variable. (rs6000_explicit_options): Add cmodel field. (rs6000_handle_option): Handle -mcmodel. (create_TOC_reference): Add largetoc_reg param. Generate high, lo_sum rtl for CMODEL_MEDIUM and CMODEL_LARGE. Update all callers. (rs6000_legitimize_reload_address): Handle new toc references. (print_operand_address): Handle legitimate_constant_pool_address_p match before lo_sum. (rs6000_eliminate_indexed_memrefs): Tidy. (rs6000_emit_move): Tweak threshold for inlining constants. Keep rs6000_emit_allocate_stack large stack frame offsets loaded into r0 inline. (rs6000_generate_compare <cmptf_internal2>): One more clobber. (tocrel_base, tocrel_offset): New variables. (toc_relative_expr_p): Set them here. (print_operand_address): Skip over any offset on constant pool address. (rs6000_output_addr_const_extra): Print tocrel_offset before @toc. (rs6000_mode_dependent_address <LO_SUM>): False for new toc refs. (offsettable_ok_by_alignment): New function. (rs6000_emit_move): Address suitably aligned local symbol_refs relative to the toc pointer for -mcmodel=medium. (legitimate_constant_pool_address_p): Make param const_rtx. Add strict param. Allow lo_sum version of addressing. Verify reg used for -mminimal-toc and -mcmodel != small. Update all callers. * config/rs6000/constraints.md: Update for above change. * config/rs6000/predicates.md: Likewise. * config/rs6000/rs6000.md (tls_gd_aix): Generate -mcmodel=medium/large code. (tls_gd): Split for -mcmodel=medium/large. (tls_gd_high, tls_gd_low): New. (tls_ld_aix, tls_ld, tls_ld_high, tls_ld_low): Similarly. (tls_got_dtprel, tls_got_dtprel_high, tls_got_dtprel_low): Similarly. (tls_got_tprel, tls_got_tprel_high, tls_got_tprel_low): Similarly. (largetoc_high, largetoc_low): New. (cmptf_internal2): Add clobber. * config/rs6000/rs6000-protos.h: Update. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/doc/invoke.texi 2011-04-15 15:22:49.000000000 +0200 @@ -680,6 +680,7 @@ See RS/6000 and PowerPC Options. @emph{RS/6000 and PowerPC Options} @gccoptlist{-mcpu=@var{cpu-type} @gol -mtune=@var{cpu-type} @gol +-mcmodel=@var{code-model} @gol -mpower -mno-power -mpower2 -mno-power2 @gol -mpowerpc -mpowerpc64 -mno-powerpc @gol -maltivec -mno-altivec @gol @@ -13030,6 +13031,22 @@ precision and FRE instruction for double cannot generate user-visible traps, and the domain values not include Infinities, denormals or zero denominator. +@item -mcmodel=small +@opindex mcmodel=small +Generate PowerPC64 code for the small model: The TOC is limited to +64k. + +@item -mcmodel=medium +@opindex mcmodel=medium +Generate PowerPC64 code for the medium model: The TOC and other static +data may be up to a total of 4G in size. + +@item -mcmodel=large +@opindex mcmodel=large +Generate PowerPC64 code for the large model: The TOC may be up to 4G +in size. Other data and code is only limited by the 64-bit address +space. + @item -maltivec @itemx -mno-altivec @opindex maltivec Index: gcc/config.in =================================================================== --- gcc/config.in.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config.in 2011-04-15 15:22:49.000000000 +0200 @@ -1013,6 +1013,12 @@ #endif +/* Define if your PowerPC64 linker supports a large TOC. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_LARGE_TOC +#endif + + /* Define if your PowerPC64 linker only needs function descriptor syms. */ #ifndef USED_FOR_TARGET #undef HAVE_LD_NO_DOT_SYMS Index: gcc/configure.ac =================================================================== --- gcc/configure.ac.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/configure.ac 2011-04-15 15:22:49.000000000 +0200 @@ -3446,6 +3446,36 @@ EOF AC_DEFINE(HAVE_LD_NO_DOT_SYMS, 1, [Define if your PowerPC64 linker only needs function descriptor syms.]) fi + + AC_CACHE_CHECK(linker large toc support, + gcc_cv_ld_large_toc, + [gcc_cv_ld_large_toc=no + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then + gcc_cv_ld_large_toc=yes + fi + elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then + cat > conftest.s <<EOF + .section ".tbss","awT",@nobits + .align 3 +ie0: .space 8 + .global _start + .text +_start: + addis 9,13,ie0@got@tprel@ha + ld 9,ie0@got@tprel@l(9) +EOF + if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -melf64ppc --no-toc-sort -o conftest conftest.o > /dev/null 2>&1; then + gcc_cv_ld_large_toc=yes + fi + rm -f conftest conftest.o conftest.s + fi + ]) + if test x"$gcc_cv_ld_large_toc" = xyes; then + AC_DEFINE(HAVE_LD_LARGE_TOC, 1, + [Define if your PowerPC64 linker supports a large TOC.]) + fi ;; esac Index: gcc/configure =================================================================== --- gcc/configure.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/configure 2011-04-15 15:22:49.000000000 +0200 @@ -22792,6 +22792,45 @@ cat >>confdefs.h <<\_ACEOF _ACEOF fi + + echo "$as_me:$LINENO: checking linker large toc support" >&5 +echo $ECHO_N "checking linker large toc support... $ECHO_C" >&6 +if test "${gcc_cv_ld_large_toc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_ld_large_toc=no + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then + gcc_cv_ld_large_toc=yes + fi + elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then + cat > conftest.s <<EOF + .section ".tbss","awT",@nobits + .align 3 +ie0: .space 8 + .global _start + .text +_start: + addis 9,13,ie0@got@tprel@ha + ld 9,ie0@got@tprel@l(9) +EOF + if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -melf64ppc --no-toc-sort -o conftest conftest.o > /dev/null 2>&1; then + gcc_cv_ld_large_toc=yes + fi + rm -f conftest conftest.o conftest.s + fi + +fi +echo "$as_me:$LINENO: result: $gcc_cv_ld_large_toc" >&5 +echo "${ECHO_T}$gcc_cv_ld_large_toc" >&6 + if test x"$gcc_cv_ld_large_toc" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LD_LARGE_TOC 1 +_ACEOF + + fi ;; esac Index: gcc/config/rs6000/constraints.md =================================================================== --- gcc/config/rs6000/constraints.md.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/constraints.md 2011-04-15 15:22:49.000000000 +0200 @@ -166,7 +166,7 @@ usually better to use @samp{m} or @samp{ (define_constraint "R" "AIX TOC entry" - (match_test "legitimate_constant_pool_address_p (op)")) + (match_test "legitimate_constant_pool_address_p (op, false)")) ;; General constraints Index: gcc/config/rs6000/predicates.md =================================================================== --- gcc/config/rs6000/predicates.md.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/predicates.md 2011-04-15 15:22:49.000000000 +0200 @@ -837,7 +837,7 @@ return 1; /* A SYMBOL_REF referring to the TOC is valid. */ - if (legitimate_constant_pool_address_p (op)) + if (legitimate_constant_pool_address_p (op, false)) return 1; /* A constant pool expression (relative to the TOC) is valid */ Index: gcc/config/rs6000/linux64.opt =================================================================== --- gcc/config/rs6000/linux64.opt.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/linux64.opt 2011-04-15 15:22:49.000000000 +0200 @@ -22,3 +22,7 @@ mprofile-kernel Target Report Var(TARGET_PROFILE_KERNEL) Call mcount for profiling before a function prologue + +mcmodel= +Target RejectNegative Joined +Select code model Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/rs6000-protos.h 2011-04-15 15:22:49.000000000 +0200 @@ -39,7 +39,7 @@ extern int small_data_operand (rtx, enum extern bool toc_relative_expr_p (rtx); extern bool invalid_e500_subreg (rtx, enum machine_mode); extern void validate_condition_mode (enum rtx_code, enum machine_mode); -extern bool legitimate_constant_pool_address_p (rtx); +extern bool legitimate_constant_pool_address_p (const_rtx, bool); extern bool legitimate_indirect_address_p (rtx, int); extern bool legitimate_indexed_address_p (rtx, int); extern bool avoiding_indexed_address_p (enum machine_mode); @@ -114,7 +114,7 @@ extern void output_toc (FILE *, rtx, int extern void rs6000_initialize_trampoline (rtx, rtx, rtx); extern rtx rs6000_longcall_ref (rtx); extern void rs6000_fatal_bad_address (rtx); -extern rtx create_TOC_reference (rtx); +extern rtx create_TOC_reference (rtx, rtx); extern void rs6000_split_multireg_move (rtx, rtx); extern void rs6000_emit_move (rtx, rtx, enum machine_mode); extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode); Index: gcc/config/rs6000/linux64.h =================================================================== --- gcc/config/rs6000/linux64.h.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/linux64.h 2011-04-15 15:22:49.000000000 +0200 @@ -56,6 +56,16 @@ extern int dot_symbols; #define DOT_SYMBOLS dot_symbols #endif +#define TARGET_USES_LINUX64_OPT 1 +#ifdef HAVE_LD_LARGE_TOC +extern enum rs6000_cmodel cmodel; +#undef TARGET_CMODEL +#define TARGET_CMODEL cmodel +#define SET_CMODEL(opt) cmodel = opt +#else +#define SET_CMODEL(opt) +#endif + #undef PROCESSOR_DEFAULT #define PROCESSOR_DEFAULT PROCESSOR_POWER6 #undef PROCESSOR_DEFAULT64 @@ -107,6 +117,23 @@ extern int dot_symbols; target_flags |= MASK_POWERPC64; \ error ("-m64 requires a PowerPC64 cpu"); \ } \ + if ((target_flags_explicit & MASK_MINIMAL_TOC) != 0) \ + { \ + if (rs6000_explicit_options.cmodel \ + && cmodel != CMODEL_SMALL) \ + error ("-mcmodel incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + else \ + { \ + if (!rs6000_explicit_options.cmodel) \ + SET_CMODEL (CMODEL_MEDIUM); \ + if (cmodel != CMODEL_SMALL) \ + { \ + TARGET_NO_FP_IN_TOC = 0; \ + TARGET_NO_SUM_IN_TOC = 0; \ + } \ + } \ } \ else \ { \ @@ -117,6 +144,11 @@ extern int dot_symbols; SET_PROFILE_KERNEL (0); \ error (INVALID_32BIT, "profile-kernel"); \ } \ + if (rs6000_explicit_options.cmodel) \ + { \ + SET_CMODEL (CMODEL_SMALL); \ + error (INVALID_32BIT, "cmodel"); \ + } \ } \ } \ while (0) Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/rs6000.c 2011-04-15 15:22:49.000000000 +0200 @@ -283,6 +283,9 @@ static GTY(()) section *toc_section; /* String from -malign-XXXXX. */ int rs6000_alignment_flags; +/* Code model for 64-bit linux. */ +enum rs6000_cmodel cmodel; + /* True for any options that were explicitly set. */ static struct { bool aix_struct_ret; /* True if -maix-struct-ret was used. */ @@ -294,6 +297,7 @@ static struct { bool long_double; /* True if -mlong-double- was used. */ bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */ bool vrsave; /* True if -mvrsave was used. */ + bool cmodel; /* True if -mcmodel was used. */ } rs6000_explicit_options; struct builtin_description @@ -3153,6 +3157,22 @@ rs6000_handle_option (size_t code, const break; #endif +#if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT) + case OPT_mcmodel_: + if (strcmp (arg, "small") == 0) + cmodel = CMODEL_SMALL; + else if (strcmp (arg, "medium") == 0) + cmodel = CMODEL_MEDIUM; + else if (strcmp (arg, "large") == 0) + cmodel = CMODEL_LARGE; + else + { + error ("invalid option for -mcmodel: '%s'", arg); + return false; + } + rs6000_explicit_options.cmodel = true; +#endif + #ifdef TARGET_USES_AIX64_OPT case OPT_maix64: #else @@ -4594,26 +4614,29 @@ constant_pool_expr_p (rtx op) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode)); } +static rtx tocrel_base, tocrel_offset; + bool toc_relative_expr_p (rtx op) { - rtx base, offset; - if (GET_CODE (op) != CONST) return false; - split_const (op, &base, &offset); - return (GET_CODE (base) == UNSPEC - && XINT (base, 1) == UNSPEC_TOCREL); + split_const (op, &tocrel_base, &tocrel_offset); + return (GET_CODE (tocrel_base) == UNSPEC + && XINT (tocrel_base, 1) == UNSPEC_TOCREL); } bool -legitimate_constant_pool_address_p (rtx x) +legitimate_constant_pool_address_p (const_rtx x, bool strict) { return (TARGET_TOC - && GET_CODE (x) == PLUS + && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM) && GET_CODE (XEXP (x, 0)) == REG - && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER) + && (REGNO (XEXP (x, 0)) == TOC_REGISTER + || ((TARGET_MINIMAL_TOC + || TARGET_CMODEL != CMODEL_SMALL) + && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))) && toc_relative_expr_p (XEXP (x, 1))); } @@ -4642,7 +4665,7 @@ rs6000_legitimate_offset_address_p (enum return false; if (!reg_offset_addressing_ok_p (mode)) return virtual_stack_registers_memory_p (x); - if (legitimate_constant_pool_address_p (x)) + if (legitimate_constant_pool_address_p (x, strict)) return true; if (GET_CODE (XEXP (x, 1)) != CONST_INT) return false; @@ -4990,7 +5013,8 @@ rs6000_legitimize_address (rtx x, rtx ol && constant_pool_expr_p (x) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode)) { - return create_TOC_reference (x); + rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX; + return create_TOC_reference (x, reg); } else return x; @@ -5360,6 +5384,24 @@ rs6000_legitimize_reload_address (rtx x, } #endif + if (TARGET_CMODEL != CMODEL_SMALL + && GET_CODE (x) == LO_SUM + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG + && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER + && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (x, 1)) == CONST + && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC + && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL + && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1))) + { + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, + opnum, (enum reload_type) type); + *win = 1; + return x; + } + /* Force ld/std non-word aligned offset into base register by wrapping in offset 0. */ if (GET_CODE (x) == PLUS @@ -5485,7 +5527,11 @@ rs6000_legitimize_reload_address (rtx x, && constant_pool_expr_p (x) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode)) { - x = create_TOC_reference (x); + x = create_TOC_reference (x, NULL_RTX); + if (TARGET_CMODEL != CMODEL_SMALL) + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, + opnum, (enum reload_type) type); *win = 1; return x; } @@ -5568,7 +5614,7 @@ rs6000_legitimate_address_p (enum machin return 1; if (reg_offset_p && legitimate_small_data_p (mode, x)) return 1; - if (reg_offset_p && legitimate_constant_pool_address_p (x)) + if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict)) return 1; /* If not REG_OK_STRICT (before reload) let pass any stack offset. */ if (! reg_ok_strict @@ -5668,7 +5714,9 @@ rs6000_mode_dependent_address (rtx addr) break; case LO_SUM: - return true; + /* Anything in the constant pool is sufficiently aligned that + all bytes have the same high part address. */ + return !legitimate_constant_pool_address_p (addr, false); /* Auto-increment cases are now treated generically in recog.c. */ case PRE_MODIFY: @@ -6010,23 +6058,54 @@ rs6000_emit_set_long_const (rtx dest, HO static void rs6000_eliminate_indexed_memrefs (rtx operands[2]) { + if (reload_in_progress) + return; + if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) != REG - && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0)) - && ! reload_in_progress) + && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false)) operands[0] = replace_equiv_address (operands[0], copy_addr_to_reg (XEXP (operands[0], 0))); if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) != REG - && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0)) - && ! reload_in_progress) + && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false)) operands[1] = replace_equiv_address (operands[1], copy_addr_to_reg (XEXP (operands[1], 0))); } +/* Return true if memory accesses to DECL are known to never straddle + a 32k boundary. */ + +static bool +offsettable_ok_by_alignment (tree decl) +{ + unsigned HOST_WIDE_INT dsize; + + /* Presume any compiler generated symbol_ref is suitably aligned. */ + if (!decl) + return true; + + if (TREE_CODE (decl) != VAR_DECL + && TREE_CODE (decl) != PARM_DECL + && TREE_CODE (decl) != RESULT_DECL + && TREE_CODE (decl) != FIELD_DECL) + return true; + + if (!host_integerp (DECL_SIZE_UNIT (decl), 1)) + return false; + + dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1); + if (dsize <= 1) + return true; + if (dsize > 32768) + return false; + + return DECL_ALIGN_UNIT (decl) >= dsize; +} + /* Emit a move from SOURCE to DEST in mode MODE. */ void rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) @@ -6366,25 +6445,43 @@ rs6000_emit_move (rtx dest, rtx source, /* If this is a SYMBOL_REF that refers to a constant pool entry, and we have put it in the TOC, we just need to make a TOC-relative reference to it. */ - if (TARGET_TOC - && GET_CODE (operands[1]) == SYMBOL_REF - && constant_pool_expr_p (operands[1]) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), - get_pool_mode (operands[1]))) + if ((TARGET_TOC + && GET_CODE (operands[1]) == SYMBOL_REF + && constant_pool_expr_p (operands[1]) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), + get_pool_mode (operands[1]))) + || (TARGET_CMODEL == CMODEL_MEDIUM + && GET_CODE (operands[1]) == SYMBOL_REF + && !CONSTANT_POOL_ADDRESS_P (operands[1]) + && SYMBOL_REF_LOCAL_P (operands[1]) + && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1])))) { - operands[1] = create_TOC_reference (operands[1]); + rtx reg = NULL_RTX; + if (TARGET_CMODEL != CMODEL_SMALL) + { + if (can_create_pseudo_p ()) + reg = gen_reg_rtx (Pmode); + else + reg = operands[0]; + } + operands[1] = create_TOC_reference (operands[1], reg); } else if (mode == Pmode && CONSTANT_P (operands[1]) && ((GET_CODE (operands[1]) != CONST_INT && ! easy_fp_constant (operands[1], mode)) || (GET_CODE (operands[1]) == CONST_INT - && num_insns_constant (operands[1], mode) > 2) + && (num_insns_constant (operands[1], mode) + > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2))) || (GET_CODE (operands[0]) == REG && FP_REGNO_P (REGNO (operands[0])))) && GET_CODE (operands[1]) != HIGH - && ! legitimate_constant_pool_address_p (operands[1]) - && ! toc_relative_expr_p (operands[1])) + && ! legitimate_constant_pool_address_p (operands[1], false) + && ! toc_relative_expr_p (operands[1]) + && (TARGET_CMODEL == CMODEL_SMALL + || can_create_pseudo_p () + || (REG_P (operands[0]) + && INT_REG_OK_FOR_BASE_P (operands[0], true)))) { #if TARGET_MACHO @@ -6430,9 +6527,17 @@ rs6000_emit_move (rtx dest, rtx source, get_pool_constant (XEXP (operands[1], 0)), get_pool_mode (XEXP (operands[1], 0)))) { - operands[1] - = gen_const_mem (mode, - create_TOC_reference (XEXP (operands[1], 0))); + rtx tocref; + rtx reg = NULL_RTX; + if (TARGET_CMODEL != CMODEL_SMALL) + { + if (can_create_pseudo_p ()) + reg = gen_reg_rtx (Pmode); + else + reg = operands[0]; + } + tocref = create_TOC_reference (XEXP (operands[1], 0), reg); + operands[1] = gen_const_mem (mode, tocref); set_mem_alias_set (operands[1], get_TOC_alias_set ()); } } @@ -14716,14 +14821,6 @@ print_operand_address (FILE *file, rtx x else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)", INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]); -#if TARGET_ELF - else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG - && CONSTANT_P (XEXP (x, 1))) - { - output_addr_const (file, XEXP (x, 1)); - fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); - } -#endif #if TARGET_MACHO else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG && CONSTANT_P (XEXP (x, 1))) @@ -14733,11 +14830,29 @@ print_operand_address (FILE *file, rtx x fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); } #endif - else if (legitimate_constant_pool_address_p (x)) + else if (legitimate_constant_pool_address_p (x, true)) + { + /* This hack along with a corresponding hack in + rs6000_output_addr_const_extra arranges to output addends + where the assembler expects to find them. eg. + (lo_sum (reg 9) + . (const (plus (unspec [symbol_ref ("x") tocrel]) 8))) + without this hack would be output as "x@toc+8@l(9)". We + want "x+8@toc@l(9)". */ + output_addr_const (file, tocrel_base); + if (GET_CODE (x) == LO_SUM) + fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); + else + fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]); + } +#if TARGET_ELF + else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG + && CONSTANT_P (XEXP (x, 1))) { output_addr_const (file, XEXP (x, 1)); - fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]); + fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); } +#endif else gcc_unreachable (); } @@ -14751,9 +14866,14 @@ rs6000_output_addr_const_extra (FILE *fi switch (XINT (x, 1)) { case UNSPEC_TOCREL: - x = XVECEXP (x, 0, 0); - gcc_assert (GET_CODE (x) == SYMBOL_REF); - output_addr_const (file, x); + gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF); + output_addr_const (file, XVECEXP (x, 0, 0)); + if (x == tocrel_base && tocrel_offset != const0_rtx) + { + if (INTVAL (tocrel_offset) >= 0) + fprintf (file, "+"); + output_addr_const (file, tocrel_offset); + } if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC)) { putc ('-', file); @@ -15098,7 +15218,7 @@ rs6000_generate_compare (enum rtx_code c && !TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128) emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (9, + gen_rtvec (10, gen_rtx_SET (VOIDmode, compare_result, gen_rtx_COMPARE (comp_mode, @@ -15111,7 +15231,8 @@ rs6000_generate_compare (enum rtx_code c gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode))))); + gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), + gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode))))); else if (GET_CODE (rs6000_compare_op1) == UNSPEC && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST) { @@ -17567,8 +17688,10 @@ uses_TOC (void) #endif rtx -create_TOC_reference (rtx symbol) +create_TOC_reference (rtx symbol, rtx largetoc_reg) { + rtx tocrel, tocreg; + if (TARGET_DEBUG_ADDR) { if (GET_CODE (symbol) == SYMBOL_REF) @@ -17584,10 +17707,23 @@ create_TOC_reference (rtx symbol) if (!can_create_pseudo_p ()) df_set_regs_ever_live (TOC_REGISTER, true); - return gen_rtx_PLUS (Pmode, - gen_rtx_REG (Pmode, TOC_REGISTER), - gen_rtx_CONST (Pmode, - gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL))); + + tocrel = gen_rtx_CONST (Pmode, + gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), + UNSPEC_TOCREL)); + tocreg = gen_rtx_REG (Pmode, TOC_REGISTER); + if (TARGET_CMODEL != CMODEL_SMALL) + { + rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel)); + if (largetoc_reg != NULL) + { + emit_move_insn (largetoc_reg, hi); + hi = largetoc_reg; + } + return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel)); + } + else + return gen_rtx_PLUS (Pmode, tocreg, tocrel); } /* If _Unwind_* has been called from within the same module, Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h.orig 2011-04-15 15:22:37.000000000 +0200 +++ gcc/config/rs6000/rs6000.h 2011-04-15 15:22:49.000000000 +0200 @@ -282,6 +282,20 @@ extern const char *host_detect_local_cpu #define TARGET_SECURE_PLT 0 #endif +/* Code model for 64-bit linux. + small: 16-bit toc offsets. + medium: 32-bit toc offsets, static data and code within 2G of TOC pointer. + large: 32-bit toc offsets, no limit on static data and code. */ +enum rs6000_cmodel { + CMODEL_SMALL, + CMODEL_MEDIUM, + CMODEL_LARGE +}; + +#ifndef TARGET_CMODEL +#define TARGET_CMODEL CMODEL_SMALL +#endif + #define TARGET_32BIT (! TARGET_64BIT) #ifndef HAVE_AS_TLS Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md.orig 2011-04-15 15:22:38.000000000 +0200 +++ gcc/config/rs6000/rs6000.md 2011-04-15 15:22:49.000000000 +0200 @@ -11033,7 +11033,12 @@ UNSPEC_TLSGD) (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" - "addi %0,%1,%2@got@tlsgd\;bl %z3\;%." +{ + if (TARGET_CMODEL != CMODEL_SMALL) + return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;bl %z3\;%."; + else + return "addi %0,%1,%2@got@tlsgd\;bl %z3\;%."; +} "&& TARGET_TLS_MARKERS" [(set (match_dup 0) (unspec:TLSmode [(match_dup 1) @@ -11046,7 +11051,10 @@ (clobber (reg:SI LR_REGNO))])] "" [(set_attr "type" "two") - (set_attr "length" "12")]) + (set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 16) + (const_int 12)))]) (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") @@ -11082,13 +11090,47 @@ [(set_attr "type" "two") (set_attr "length" "8")]) -(define_insn "*tls_gd<TLSmode:tls_abi_suffix>" +(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD))] "HAVE_AS_TLS && TARGET_TLS_MARKERS" "addi %0,%1,%2@got@tlsgd" + "&& TARGET_CMODEL != CMODEL_SMALL" + [(set (match_dup 3) + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))) + (set (match_dup 0) + (lo_sum:TLSmode (match_dup 3) + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))] + " +{ + operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); +}" + [(set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD))))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" + "addis %0,%1,%2@got@tlsgd@ha" + [(set_attr "length" "4")]) + +(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD)))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" + "addi %0,%1,%2@got@tlsgd@l" [(set_attr "length" "4")]) (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" @@ -11131,7 +11173,12 @@ UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" - "addi %0,%1,%&@got@tlsld\;bl %z2\;%." +{ + if (TARGET_CMODEL != CMODEL_SMALL) + return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;bl %z2\;%."; + else + return "addi %0,%1,%&@got@tlsld\;bl %z2\;%."; +} "&& TARGET_TLS_MARKERS" [(set (match_dup 0) (unspec:TLSmode [(match_dup 1)] @@ -11142,7 +11189,11 @@ (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))])] "" - [(set_attr "length" "12")]) + [(set_attr "type" "two") + (set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 16) + (const_int 12)))]) (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") @@ -11175,12 +11226,44 @@ "" [(set_attr "length" "8")]) -(define_insn "*tls_ld<TLSmode:tls_abi_suffix>" +(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] UNSPEC_TLSLD))] "HAVE_AS_TLS && TARGET_TLS_MARKERS" "addi %0,%1,%&@got@tlsld" + "&& TARGET_CMODEL != CMODEL_SMALL" + [(set (match_dup 2) + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))) + (set (match_dup 0) + (lo_sum:TLSmode (match_dup 2) + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] + " +{ + operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); +}" + [(set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" + "addis %0,%1,%&@got@tlsld@ha" + [(set_attr "length" "4")]) + +(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" + "addi %0,%1,%&@got@tlsld@l" [(set_attr "length" "4")]) (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" @@ -11237,13 +11320,48 @@ "HAVE_AS_TLS" "addi %0,%1,%2@dtprel@l") -(define_insn "tls_got_dtprel_<TLSmode:tls_abi_suffix>" +(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGOTDTPREL))] "HAVE_AS_TLS" - "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)") + "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" + "&& TARGET_CMODEL != CMODEL_SMALL" + [(set (match_dup 3) + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))) + (set (match_dup 0) + (lo_sum:TLSmode (match_dup 3) + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))] + " +{ + operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); +}" + [(set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL))))] + "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" + "addis %0,%1,%2@got@dtprel@ha" + [(set_attr "length" "4")]) + +(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL)))] + "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" + "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" + [(set_attr "length" "4")]) (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") @@ -11272,13 +11390,48 @@ ;; "b" output constraint here and on tls_tls input to support linker tls ;; optimization. The linker may edit the instructions emitted by a ;; tls_got_tprel/tls_tls pair to addis,addi. -(define_insn "tls_got_tprel_<TLSmode:tls_abi_suffix>" +(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGOTTPREL))] "HAVE_AS_TLS" - "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)") + "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" + "&& TARGET_CMODEL != CMODEL_SMALL" + [(set (match_dup 3) + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))) + (set (match_dup 0) + (lo_sum:TLSmode (match_dup 3) + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))] + " +{ + operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); +}" + [(set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL))))] + "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" + "addis %0,%1,%2@got@tprel@ha" + [(set_attr "length" "4")]) + +(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL)))] + "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" + "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" + [(set_attr "length" "4")]) (define_insn "tls_tls_<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") @@ -11287,7 +11440,6 @@ UNSPEC_TLSTLS))] "HAVE_AS_TLS" "add %0,%1,%2@tls") - ;; Next come insns related to the calling sequence. ;; @@ -11575,6 +11727,21 @@ "@ {cal|la} %0,%2@l(%1) {ai|addic} %0,%1,%K2") + +;; Largetoc support +(define_insn "largetoc_high" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b") + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (high:DI (match_operand:DI 2 "" ""))))] + "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" + "{cau|addis} %0,%1,%2@ha") + +(define_insn "largetoc_low" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (match_operand:DI 2 "" "")))] + "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" + "{cal %0,%2@l(%1)|addi %0,%1,%2@l}") ;; A function pointer under AIX is a pointer to a data area whose first word ;; contains the actual address of the function, whose second word contains a @@ -13013,26 +13180,27 @@ (clobber (match_scratch:DF 7 "=d")) (clobber (match_scratch:DF 8 "=d")) (clobber (match_scratch:DF 9 "=d")) - (clobber (match_scratch:DF 10 "=d"))] + (clobber (match_scratch:DF 10 "=d")) + (clobber (match_scratch:GPR 11 "=b"))] "!TARGET_IEEEQUAD && TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" - [(set (match_dup 3) (match_dup 13)) - (set (match_dup 4) (match_dup 14)) + [(set (match_dup 3) (match_dup 14)) + (set (match_dup 4) (match_dup 15)) (set (match_dup 9) (abs:DF (match_dup 5))) (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) - (label_ref (match_dup 11)) + (label_ref (match_dup 12)) (pc))) (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) - (set (pc) (label_ref (match_dup 12))) - (match_dup 11) + (set (pc) (label_ref (match_dup 13))) + (match_dup 12) (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) - (match_dup 12)] + (match_dup 13)] { REAL_VALUE_TYPE rv; const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; @@ -13042,22 +13210,23 @@ operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word); operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word); - operands[11] = gen_label_rtx (); operands[12] = gen_label_rtx (); + operands[13] = gen_label_rtx (); real_inf (&rv); - operands[13] = force_const_mem (DFmode, - CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); operands[14] = force_const_mem (DFmode, + CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); + operands[15] = force_const_mem (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst0, DFmode)); if (TARGET_TOC) { - operands[13] = gen_const_mem (DFmode, - create_TOC_reference (XEXP (operands[13], 0))); - operands[14] = gen_const_mem (DFmode, - create_TOC_reference (XEXP (operands[14], 0))); - set_mem_alias_set (operands[13], get_TOC_alias_set ()); + rtx tocref; + tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); + operands[14] = gen_const_mem (DFmode, tocref); + tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); + operands[15] = gen_const_mem (DFmode, tocref); set_mem_alias_set (operands[14], get_TOC_alias_set ()); + set_mem_alias_set (operands[15], get_TOC_alias_set ()); } })
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor