diff options
Diffstat (limited to 'gcc/config')
41 files changed, 677 insertions, 513 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 1e0a346e553..9ddf43eda5e 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -2462,10 +2462,10 @@ break; } /* Fall through. */ - case UNGE: + case UNLT: std::swap (operands[2], operands[3]); /* Fall through. */ - case UNLE: + case UNGT: case GT: comparison = gen_aarch64_cmgt<mode>; break; @@ -2476,10 +2476,10 @@ break; } /* Fall through. */ - case UNGT: + case UNLE: std::swap (operands[2], operands[3]); /* Fall through. */ - case UNLT: + case UNGE: case GE: comparison = gen_aarch64_cmge<mode>; break; @@ -2502,21 +2502,35 @@ case UNGT: case UNLE: case UNLT: - case NE: - /* FCM returns false for lanes which are unordered, so if we use - the inverse of the comparison we actually want to emit, then - invert the result, we will end up with the correct result. - Note that a NE NaN and NaN NE b are true for all a, b. - - Our transformations are: - a UNGE b -> !(b GT a) - a UNGT b -> !(b GE a) - a UNLE b -> !(a GT b) - a UNLT b -> !(a GE b) - a NE b -> !(a EQ b) */ - gcc_assert (comparison != NULL); - emit_insn (comparison (operands[0], operands[2], operands[3])); - emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0])); + { + /* All of the above must not raise any FP exceptions. Thus we first + check each operand for NaNs and force any elements containing NaN to + zero before using them in the compare. + Example: UN<cc> (a, b) -> UNORDERED (a, b) | + (cm<cc> (isnan (a) ? 0.0 : a, + isnan (b) ? 0.0 : b)) + We use the following transformations for doing the comparisions: + a UNGE b -> a GE b + a UNGT b -> a GT b + a UNLE b -> b GE a + a UNLT b -> b GT a. */ + + rtx tmp0 = gen_reg_rtx (<V_cmp_result>mode); + rtx tmp1 = gen_reg_rtx (<V_cmp_result>mode); + rtx tmp2 = gen_reg_rtx (<V_cmp_result>mode); + emit_insn (gen_aarch64_cmeq<mode> (tmp0, operands[2], operands[2])); + emit_insn (gen_aarch64_cmeq<mode> (tmp1, operands[3], operands[3])); + emit_insn (gen_and<v_cmp_result>3 (tmp2, tmp0, tmp1)); + emit_insn (gen_and<v_cmp_result>3 (tmp0, tmp0, + lowpart_subreg (<V_cmp_result>mode, operands[2], <MODE>mode))); + emit_insn (gen_and<v_cmp_result>3 (tmp1, tmp1, + lowpart_subreg (<V_cmp_result>mode, operands[3], <MODE>mode))); + gcc_assert (comparison != NULL); + emit_insn (comparison (operands[0], + lowpart_subreg (<MODE>mode, tmp0, <V_cmp_result>mode), + lowpart_subreg (<MODE>mode, tmp1, <V_cmp_result>mode))); + emit_insn (gen_orn<v_cmp_result>3 (operands[0], tmp2, operands[0])); + } break; case LT: @@ -2524,25 +2538,19 @@ case GT: case GE: case EQ: + case NE: /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ. As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are: a GE b -> a GE b a GT b -> a GT b a LE b -> b GE a a LT b -> b GT a - a EQ b -> a EQ b */ + a EQ b -> a EQ b + a NE b -> ~(a EQ b) */ gcc_assert (comparison != NULL); emit_insn (comparison (operands[0], operands[2], operands[3])); - break; - - case UNEQ: - /* We first check (a > b || b > a) which is !UNEQ, inverting - this result will then give us (a == b || a UNORDERED b). */ - emit_insn (gen_aarch64_cmgt<mode> (operands[0], - operands[2], operands[3])); - emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[3], operands[2])); - emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp)); - emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0])); + if (code == NE) + emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0])); break; case LTGT: @@ -2554,21 +2562,22 @@ emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp)); break; - case UNORDERED: - /* Operands are ORDERED iff (a > b || b >= a), so we can compute - UNORDERED as !ORDERED. */ - emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[2], operands[3])); - emit_insn (gen_aarch64_cmge<mode> (operands[0], - operands[3], operands[2])); - emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp)); - emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0])); - break; - case ORDERED: - emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[2], operands[3])); - emit_insn (gen_aarch64_cmge<mode> (operands[0], - operands[3], operands[2])); - emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp)); + case UNORDERED: + case UNEQ: + /* cmeq (a, a) & cmeq (b, b). */ + emit_insn (gen_aarch64_cmeq<mode> (operands[0], + operands[2], operands[2])); + emit_insn (gen_aarch64_cmeq<mode> (tmp, operands[3], operands[3])); + emit_insn (gen_and<v_cmp_result>3 (operands[0], operands[0], tmp)); + + if (code == UNORDERED) + emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0])); + else if (code == UNEQ) + { + emit_insn (gen_aarch64_cmeq<mode> (tmp, operands[2], operands[3])); + emit_insn (gen_orn<v_cmp_result>3 (operands[0], operands[0], tmp)); + } break; default: diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 2bd3c5e069f..974f0f8b1a3 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8610,17 +8610,6 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts) if (opts->x_pcrelative_literal_loads == 1) aarch64_pcrelative_literal_loads = true; - /* This is PR70113. When building the Linux kernel with - CONFIG_ARM64_ERRATUM_843419, support for relocations - R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADR_PREL_PG_HI21_NC is - removed from the kernel to avoid loading objects with possibly - offending sequences. Without -mpc-relative-literal-loads we would - generate such relocations, preventing the kernel build from - succeeding. */ - if (opts->x_pcrelative_literal_loads == 2 - && TARGET_FIX_ERR_A53_843419) - aarch64_pcrelative_literal_loads = true; - /* In the tiny memory model it makes no sense to disallow PC relative literal pool loads. */ if (aarch64_cmodel == AARCH64_CMODEL_TINY diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 51368e29f2d..4c4e144587e 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3093,7 +3093,8 @@ (define_insn_and_split "*compare_cstore<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (EQL:GPI (match_operand:GPI 1 "register_operand" "r") - (match_operand:GPI 2 "aarch64_imm24" "n")))] + (match_operand:GPI 2 "aarch64_imm24" "n"))) + (clobber (reg:CC CC_REGNUM))] "!aarch64_move_imm (INTVAL (operands[2]), <MODE>mode) && !aarch64_plus_operand (operands[2], <MODE>mode) && !reload_completed" diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index cbf28bcffa9..0c0d3bce42b 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -7750,13 +7750,13 @@ alpha_expand_prologue (void) int probed; for (probed = 4096; probed < probed_size; probed += 8192) - emit_insn (gen_probe_stack (GEN_INT (-probed))); + emit_insn (gen_stack_probe_internal (GEN_INT (-probed))); /* We only have to do this probe if we aren't saving registers or if we are probing beyond the frame because of -fstack-check. */ if ((sa_size == 0 && probed_size > probed - 4096) || flag_stack_check || flag_stack_clash_protection) - emit_insn (gen_probe_stack (GEN_INT (-probed_size))); + emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size))); } if (frame_size != 0) diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 97838a5083a..14c18656d82 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -4915,7 +4915,7 @@ ;; Subroutine of stack space allocation. Perform a stack probe. -(define_expand "probe_stack" +(define_expand "stack_probe_internal" [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))] "" { @@ -4950,12 +4950,14 @@ int probed = 4096; - emit_insn (gen_probe_stack (GEN_INT (- probed))); + emit_insn (gen_stack_probe_internal (GEN_INT (- probed))); while (probed + 8192 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); + emit_insn (gen_stack_probe_internal + (GEN_INT (- (probed += 8192)))); if (probed + 4096 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1])))); + emit_insn (gen_stack_probe_internal + (GEN_INT (- INTVAL(operands[1])))); } operands[1] = GEN_INT (- INTVAL (operands[1])); diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c index 792b688f66c..d3b67184362 100644 --- a/gcc/config/arm/arm-builtins.c +++ b/gcc/config/arm/arm-builtins.c @@ -2576,7 +2576,7 @@ arm_expand_builtin (tree exp, icode = CODE_FOR_set_fpscr; arg0 = CALL_EXPR_ARG (exp, 0); op0 = expand_normal (arg0); - pat = GEN_FCN (icode) (op0); + pat = GEN_FCN (icode) (force_reg (SImode, op0)); } emit_insn (pat); return target; @@ -2584,7 +2584,9 @@ arm_expand_builtin (tree exp, case ARM_BUILTIN_CMSE_NONSECURE_CALLER: target = gen_reg_rtx (SImode); op0 = arm_return_addr (0, NULL_RTX); - emit_insn (gen_addsi3 (target, op0, const1_rtx)); + emit_insn (gen_andsi3 (target, op0, const1_rtx)); + op1 = gen_rtx_EQ (SImode, target, const0_rtx); + emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx)); return target; case ARM_BUILTIN_TEXTRMSB: diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 80cb52744ae..5651fb7da4b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -19097,6 +19097,11 @@ arm_r3_live_at_start_p (void) static int arm_compute_static_chain_stack_bytes (void) { + /* Once the value is updated from the init value of -1, do not + re-compute. */ + if (cfun->machine->static_chain_stack_bytes != -1) + return cfun->machine->static_chain_stack_bytes; + /* See the defining assertion in arm_expand_prologue. */ if (IS_NESTED (arm_current_func_type ()) && ((TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) @@ -21396,6 +21401,11 @@ arm_expand_prologue (void) emit_insn (gen_movsi (stack_pointer_rtx, r1)); } + /* Let's compute the static_chain_stack_bytes required and store it. Right + now the value must the -1 as stored by arm_init_machine_status (). */ + cfun->machine->static_chain_stack_bytes + = arm_compute_static_chain_stack_bytes (); + /* The static chain register is the same as the IP register. If it is clobbered when creating the frame, we need to save and restore it. */ clobber_ip = IS_NESTED (func_type) @@ -24545,6 +24555,7 @@ arm_init_machine_status (void) #if ARM_FT_UNKNOWN != 0 machine->func_type = ARM_FT_UNKNOWN; #endif + machine->static_chain_stack_bytes = -1; return machine; } @@ -26858,7 +26869,10 @@ static bool arm_array_mode_supported_p (machine_mode mode, unsigned HOST_WIDE_INT nelems) { - if (TARGET_NEON + /* We don't want to enable interleaved loads and stores for BYTES_BIG_ENDIAN + for now, as the lane-swapping logic needs to be extended in the expanders. + See PR target/82518. */ + if (TARGET_NEON && !BYTES_BIG_ENDIAN && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)) && (nelems >= 2 && nelems <= 4)) return true; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 25953f53bd6..68a6fa56c7c 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1420,6 +1420,9 @@ typedef struct GTY(()) machine_function machine_mode thumb1_cc_mode; /* Set to 1 after arm_reorg has started. */ int after_arm_reorg; + /* The number of bytes used to store the static chain register on the + stack, above the stack frame. */ + int static_chain_stack_bytes; } machine_function; #endif diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f9365cde504..ad5f3874bc7 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4498,16 +4498,13 @@ (set_attr "type" "load1")]) (define_insn "unaligned_loadhis" - [(set (match_operand:SI 0 "s_register_operand" "=l,r") + [(set (match_operand:SI 0 "s_register_operand" "=r") (sign_extend:SI - (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")] + (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")] UNSPEC_UNALIGNED_LOAD)))] "unaligned_access" "ldrsh%?\t%0, %1\t@ unaligned" - [(set_attr "arch" "t2,any") - (set_attr "length" "2,4") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "yes,no") + [(set_attr "predicable" "yes") (set_attr "type" "load_byte")]) (define_insn "unaligned_loadhiu" diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h index 8fde2736a2a..427647fb981 100644 --- a/gcc/config/arm/arm_cmse.h +++ b/gcc/config/arm/arm_cmse.h @@ -35,7 +35,6 @@ extern "C" { #if __ARM_FEATURE_CMSE & 1 #include <stddef.h> -#include <stdint.h> #ifdef __ARM_BIG_ENDIAN @@ -174,9 +173,9 @@ cmse_nonsecure_caller (void) #define CMSE_MPU_NONSECURE 16 #define CMSE_NONSECURE 18 -#define cmse_nsfptr_create(p) ((typeof ((p))) ((intptr_t) (p) & ~1)) +#define cmse_nsfptr_create(p) ((__typeof__ ((p))) ((__INTPTR_TYPE__) (p) & ~1)) -#define cmse_is_nsfptr(p) (!((intptr_t) (p) & 1)) +#define cmse_is_nsfptr(p) (!((__INTPTR_TYPE__) (p) & 1)) #endif /* __ARM_FEATURE_CMSE & 2 */ @@ -188,7 +187,7 @@ __extension__ void * cmse_check_address_range (void *, size_t, int); #define cmse_check_pointed_object(p, f) \ - ((typeof ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f))) + ((__typeof__ ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f))) #endif /* __ARM_FEATURE_CMSE & 1 */ diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index cacc1f9198a..5ddef4956f5 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1143,12 +1143,12 @@ ) (define_insn_and_split "ashldi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?&r, ?w,w") - (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r, 0w,w") - (match_operand:SI 2 "general_operand" "rUm, i, r, i, i,rUm,i"))) - (clobber (match_scratch:SI 3 "= X, X,?&r, X, X, X,X")) - (clobber (match_scratch:SI 4 "= X, X,?&r, X, X, X,X")) - (clobber (match_scratch:DI 5 "=&w, X, X, X, X, &w,X")) + [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r, ?w,?w") + (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r, 0w, w") + (match_operand:SI 2 "general_operand" "rUm, i, r, i, i,rUm, i"))) + (clobber (match_scratch:SI 3 "= X, X, &r, X, X, X, X")) + (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X, X")) + (clobber (match_scratch:DI 5 "=&w, X, X, X, X, &w, X")) (clobber (reg:CC_C CC_REGNUM))] "TARGET_NEON" "#" @@ -1243,7 +1243,7 @@ ;; ashrdi3_neon ;; lshrdi3_neon (define_insn_and_split "<shift>di3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?&r,?w,?w") + [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r,?w,?w") (RSHIFTS:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r,0w, w") (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, i, r, i"))) (clobber (match_scratch:SI 3 "=2r, X, &r, X, X,2r, X")) diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 3dfa8c3b00b..c7705ca3c21 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -153,6 +153,9 @@ FIXME: DRIVER_SELF_SPECS has changed. #define FIRST_PSEUDO_REGISTER 36 +#define GENERAL_REGNO_P(N) IN_RANGE (N, 2, 31) +#define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X))) + #define FIXED_REGISTERS {\ 1,1,/* r0 r1 */\ 0,0,/* r2 r3 */\ diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 3a6dec2b0c0..ee5a1c420c7 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -3362,6 +3362,8 @@ (match_operand:HI 1 "reg_or_0_operand"))] "optimize && reload_completed + && GENERAL_REG_P (operands[0]) + && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1])) && (!AVR_HAVE_MOVW || const0_rtx == operands[1])" [(set (match_dup 2) (match_dup 3)) diff --git a/gcc/config/i386/avx512vlintrin.h b/gcc/config/i386/avx512vlintrin.h index f62f641188e..301713ba907 100644 --- a/gcc/config/i386/avx512vlintrin.h +++ b/gcc/config/i386/avx512vlintrin.h @@ -9099,6 +9099,17 @@ _mm_maskz_mul_epi32 (__mmask8 __M, __m128i __X, __m128i __Y) extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutexvar_epi64 (__m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_permvardi256_mask ((__v4di) __Y, + (__v4di) __X, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutexvar_epi64 (__m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { @@ -9163,6 +9174,17 @@ _mm_maskz_mul_epu32 (__mmask8 __M, __m128i __X, __m128i __Y) extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutexvar_epi32 (__m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_permvarsi256_mask ((__v8si) __Y, + (__v8si) __X, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutexvar_epi32 (__m256i __W, __mmask8 __M, __m256i __X, __m256i __Y) { @@ -9751,6 +9773,17 @@ _mm_cmple_epi64_mask (__m128i __X, __m128i __Y) #ifdef __OPTIMIZE__ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_permutex_epi64 (__m256i __X, const int __I) +{ + return (__m256i) __builtin_ia32_permdi256_mask ((__v4di) __X, + __I, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_permutex_epi64 (__m256i __W, __mmask8 __M, __m256i __X, const int __I) { @@ -12367,6 +12400,13 @@ _mm256_permutex_pd (__m256d __X, const int __M) _mm256_undefined_pd (), \ (__mmask8)-1)) +#define _mm256_permutex_epi64(X, I) \ + ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), \ + (int)(I), \ + (__v4di)(__m256i) \ + (_mm256_setzero_si256 ()),\ + (__mmask8) -1)) + #define _mm256_maskz_permutex_epi64(M, X, I) \ ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), \ (int)(I), \ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 88411ca0c59..761c0c28c36 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -12033,19 +12033,23 @@ ix86_setup_frame_addresses (void) labels in call and return thunks. */ static int indirectlabelno; -/* True if call and return thunk functions are needed. */ +/* True if call thunk function is needed. */ static bool indirect_thunk_needed = false; -/* True if call and return thunk functions with the BND prefix are - needed. */ +/* True if call thunk function with the BND prefix is needed. */ static bool indirect_thunk_bnd_needed = false; /* Bit masks of integer registers, which contain branch target, used - by call and return thunks functions. */ + by call thunk functions. */ static int indirect_thunks_used; /* Bit masks of integer registers, which contain branch target, used - by call and return thunks functions with the BND prefix. */ + by call thunk functions with the BND prefix. */ static int indirect_thunks_bnd_used; +/* True if return thunk function is needed. */ +static bool indirect_return_needed = false; +/* True if return thunk function with the BND prefix is needed. */ +static bool indirect_return_bnd_needed = false; + /* True if return thunk function via CX is needed. */ static bool indirect_return_via_cx; /* True if return thunk function via CX with the BND prefix is @@ -12192,16 +12196,18 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno) /* Output a funtion with a call and return thunk for indirect branch. If BND_P is true, the BND prefix is needed. If REGNO != INVALID_REGNUM, the function address is in REGNO. Otherwise, the function address is - on the top of stack. */ + on the top of stack. Thunk is used for function return if RET_P is + true. */ static void -output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) +output_indirect_thunk_function (bool need_bnd_p, unsigned int regno, + bool ret_p) { char name[32]; tree decl; /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ - indirect_thunk_name (name, regno, need_bnd_p, false); + indirect_thunk_name (name, regno, need_bnd_p, ret_p); decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name), build_function_type_list (void_type_node, NULL_TREE)); @@ -12244,50 +12250,6 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) ASM_OUTPUT_LABEL (asm_out_file, name); } - /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or - __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd. */ - bool need_alias; - if (regno == INVALID_REGNUM) - need_alias = true; - else if (regno == CX_REG) - { - if (need_bnd_p) - need_alias = indirect_return_via_cx_bnd; - else - need_alias = indirect_return_via_cx; - } - else - need_alias = false; - - if (need_alias) - { - char alias[32]; - - indirect_thunk_name (alias, regno, need_bnd_p, true); -#if TARGET_MACHO - if (TARGET_MACHO) - { - fputs ("\t.weak_definition\t", asm_out_file); - assemble_name (asm_out_file, alias); - fputs ("\n\t.private_extern\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - ASM_OUTPUT_LABEL (asm_out_file, alias); - } -#else - ASM_OUTPUT_DEF (asm_out_file, alias, name); - if (USE_HIDDEN_LINKONCE) - { - fputs ("\t.globl\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - fputs ("\t.hidden\t", asm_out_file); - assemble_name (asm_out_file, alias); - putc ('\n', asm_out_file); - } -#endif - } - DECL_INITIAL (decl) = make_node (BLOCK); current_function_decl = decl; allocate_struct_function (decl, false); @@ -12334,19 +12296,29 @@ ix86_code_end (void) rtx xops[2]; unsigned int regno; + if (indirect_return_needed) + output_indirect_thunk_function (false, INVALID_REGNUM, true); + if (indirect_return_bnd_needed) + output_indirect_thunk_function (true, INVALID_REGNUM, true); + + if (indirect_return_via_cx) + output_indirect_thunk_function (false, CX_REG, true); + if (indirect_return_via_cx_bnd) + output_indirect_thunk_function (true, CX_REG, true); + if (indirect_thunk_needed) - output_indirect_thunk_function (false, INVALID_REGNUM); + output_indirect_thunk_function (false, INVALID_REGNUM, false); if (indirect_thunk_bnd_needed) - output_indirect_thunk_function (true, INVALID_REGNUM); + output_indirect_thunk_function (true, INVALID_REGNUM, false); for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) { unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; if ((indirect_thunks_used & (1 << i))) - output_indirect_thunk_function (false, regno); + output_indirect_thunk_function (false, regno, false); if ((indirect_thunks_bnd_used & (1 << i))) - output_indirect_thunk_function (true, regno); + output_indirect_thunk_function (true, regno, false); } for (regno = AX_REG; regno <= SP_REG; regno++) @@ -12355,10 +12327,10 @@ ix86_code_end (void) tree decl; if ((indirect_thunks_used & (1 << regno))) - output_indirect_thunk_function (false, regno); + output_indirect_thunk_function (false, regno, false); if ((indirect_thunks_bnd_used & (1 << regno))) - output_indirect_thunk_function (true, regno); + output_indirect_thunk_function (true, regno, false); if (!(pic_labels_used & (1 << regno))) continue; @@ -20061,72 +20033,36 @@ emit_i387_cw_initialization (int mode) emit_insn (gen_x86_fnstcw_1 (stored_mode)); emit_move_insn (reg, copy_rtx (stored_mode)); - if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL - || optimize_insn_for_size_p ()) - { - switch (mode) - { - case I387_CW_TRUNC: - /* round toward zero (truncate) */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00))); - slot = SLOT_CW_TRUNC; - break; - - case I387_CW_FLOOR: - /* round down toward -oo */ - emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400))); - slot = SLOT_CW_FLOOR; - break; - - case I387_CW_CEIL: - /* round up toward +oo */ - emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800))); - slot = SLOT_CW_CEIL; - break; - - case I387_CW_MASK_PM: - /* mask precision exception for nearbyint() */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); - slot = SLOT_CW_MASK_PM; - break; - - default: - gcc_unreachable (); - } - } - else + switch (mode) { - switch (mode) - { - case I387_CW_TRUNC: - /* round toward zero (truncate) */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0xc))); - slot = SLOT_CW_TRUNC; - break; + case I387_CW_TRUNC: + /* round toward zero (truncate) */ + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00))); + slot = SLOT_CW_TRUNC; + break; - case I387_CW_FLOOR: - /* round down toward -oo */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0x4))); - slot = SLOT_CW_FLOOR; - break; + case I387_CW_FLOOR: + /* round down toward -oo */ + emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400))); + slot = SLOT_CW_FLOOR; + break; - case I387_CW_CEIL: - /* round up toward +oo */ - emit_insn (gen_insvsi_1 (reg, GEN_INT (0x8))); - slot = SLOT_CW_CEIL; - break; + case I387_CW_CEIL: + /* round up toward +oo */ + emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800))); + slot = SLOT_CW_CEIL; + break; - case I387_CW_MASK_PM: - /* mask precision exception for nearbyint() */ - emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); - slot = SLOT_CW_MASK_PM; - break; + case I387_CW_MASK_PM: + /* mask precision exception for nearbyint() */ + emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020))); + slot = SLOT_CW_MASK_PM; + break; - default: - gcc_unreachable (); - } + default: + gcc_unreachable (); } gcc_assert (slot < MAX_386_STACK_LOCALS); @@ -29403,12 +29339,12 @@ ix86_output_function_return (bool long_p) true); if (need_bnd_p) { - indirect_thunk_bnd_needed |= need_thunk; + indirect_return_bnd_needed |= need_thunk; fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); } else { - indirect_thunk_needed |= need_thunk; + indirect_return_needed |= need_thunk; fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); } } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 10abb165bd9..c5dae5ffe7d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -739,7 +739,7 @@ (if_then_else (match_operand 1 "constant_call_address_operand") (const_string "none") (const_string "load")) - (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1") + (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1") (match_operand 1 "memory_operand")) (const_string "both") (and (match_operand 0 "memory_operand") @@ -750,7 +750,7 @@ (match_operand 1 "memory_operand") (const_string "load") (and (eq_attr "type" - "!alu1,negnot,ishift1, + "!alu1,negnot,ishift1,rotate1, imov,imovx,icmp,test,bitmanip, fmov,fcmp,fsgn, sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, @@ -6685,6 +6685,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*add<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (plus:SWI + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" + "adc{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*addsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6701,6 +6715,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "*addsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)]) + (match_operand:SI 1 "register_operand" "0")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "adc{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + ;; There is no point to generate ADCX instruction. ADC is shorter and faster. (define_insn "addcarry<mode>" @@ -6741,6 +6769,20 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*sub<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)" + "sbb{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*subsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6758,6 +6800,21 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "*subsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (minus:SI + (match_operand:SI 1 "register_operand" "0") + (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)])))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "sbb{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + (define_insn "subborrow<mode>" [(set (reg:CCC FLAGS_REG) (compare:CCC @@ -9916,7 +9973,7 @@ { switch (get_attr_type (insn)) { - case TYPE_ALU: + case TYPE_ALU1: gcc_assert (operands[1] == const1_rtx); return "add{b}\t%0, %0"; @@ -9932,12 +9989,12 @@ (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") (match_operand 0 "register_operand")) (match_operand 1 "const1_operand")) - (const_string "alu") + (const_string "alu1") ] (const_string "ishift1"))) (set (attr "length_immediate") (if_then_else - (ior (eq_attr "type" "alu") + (ior (eq_attr "type" "alu1") (and (eq_attr "type" "ishift1") (and (match_operand 1 "const1_operand") (ior (match_test "TARGET_SHIFT1") @@ -11730,6 +11787,7 @@ "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_overlap_mentioned_p (operands[3], operands[4]) && ! reg_set_p (operands[3], operands[4]) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) @@ -11776,6 +11834,7 @@ "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_overlap_mentioned_p (operands[3], operands[4]) && ! reg_set_p (operands[3], operands[4]) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) @@ -15536,7 +15595,8 @@ "(TARGET_USE_FANCY_MATH_387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) - && flag_unsafe_math_optimizations) + && flag_unsafe_math_optimizations + && (flag_fp_int_builtin_inexact || !flag_trapping_math)) || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && !flag_trapping_math && !flag_rounding_math)" { diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 80cda39bacf..c8c3a5045b7 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1134,11 +1134,8 @@ operands[2])); } else if (memory_operand (operands[1], DImode)) - { - rtx tmp = gen_reg_rtx (V2DImode); - emit_insn (gen_vec_concatv2di (tmp, operands[1], const0_rtx)); - emit_move_insn (operands[0], gen_lowpart (V4SImode, tmp)); - } + emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]), + operands[1], const0_rtx)); else gcc_unreachable (); DONE; @@ -4398,7 +4395,7 @@ (match_operand:VF_128 1 "register_operand" "v") (const_int 1)))] "TARGET_AVX512F && TARGET_64BIT" - "vcvtusi2<ssescalarmodesuffix>\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}" + "vcvtusi2<ssescalarmodesuffix>{q}\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}" [(set_attr "type" "sseicvt") (set_attr "prefix" "evex") (set_attr "mode" "<ssescalarmode>")]) @@ -8883,14 +8880,14 @@ ;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_loadhpd" [(set (match_operand:V2DF 0 "nonimmediate_operand" - "=x,v,x,v,o,o ,o") + "=x,v,x,v ,o,o ,o") (vec_concat:V2DF (vec_select:DF (match_operand:V2DF 1 "nonimmediate_operand" - " 0,v,0,v,0,0 ,0") + " 0,v,0,v ,0,0 ,0") (parallel [(const_int 0)])) (match_operand:DF 2 "nonimmediate_operand" - " m,m,x,v,x,*f,r")))] + " m,m,x,Yv,x,*f,r")))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ movhpd\t{%2, %0|%0, %2} @@ -9938,11 +9935,11 @@ && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" "@ p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2} - vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}" + vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" [(set_attr "isa" "noavx,avx") (set_attr "type" "sseiadd") (set_attr "prefix_data16" "1,*") - (set_attr "prefix" "<mask_prefix3>") + (set_attr "prefix" "orig,vex") (set_attr "mode" "<sseinsnmode>")]) (define_insn "*<plusminus_insn><mode>3_mask" @@ -10683,11 +10680,14 @@ (const_string "0"))) (set_attr "mode" "<sseinsnmode>")]) +(define_mode_attr vshift_count + [(V32HI "v") (V16HI "Yv") (V8HI "Yv")]) + (define_insn "<shift_insn><mode>3<mask_name>" [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,v") (any_lshift:VI2_AVX2_AVX512BW (match_operand:VI2_AVX2_AVX512BW 1 "register_operand" "0,v") - (match_operand:DI 2 "nonmemory_operand" "xN,vN")))] + (match_operand:DI 2 "nonmemory_operand" "xN,<vshift_count>N")))] "TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>" "@ p<vshift><ssemodesuffix>\t{%2, %0|%0, %2} @@ -10706,7 +10706,7 @@ [(set (match_operand:VI48_AVX2 0 "register_operand" "=x,x,v") (any_lshift:VI48_AVX2 (match_operand:VI48_AVX2 1 "register_operand" "0,x,v") - (match_operand:DI 2 "nonmemory_operand" "xN,xN,vN")))] + (match_operand:DI 2 "nonmemory_operand" "xN,xN,YvN")))] "TARGET_SSE2 && <mask_mode512bit_condition>" "@ p<vshift><ssemodesuffix>\t{%2, %0|%0, %2} @@ -11822,7 +11822,7 @@ (eq_attr "mode" "TI")) (const_string "1") (const_string "*"))) - (set_attr "prefix" "<mask_prefix3>") + (set_attr "prefix" "orig,vex") (set (attr "mode") (cond [(and (match_test "<MODE_SIZE> == 16") (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 70a8f0de245..af2c4a23dfe 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -2008,6 +2008,9 @@ static void nvptx_assemble_decl_begin (FILE *file, const char *name, const char *section, const_tree type, HOST_WIDE_INT size, unsigned align) { + bool atype = (TREE_CODE (type) == ARRAY_TYPE) + && (TYPE_DOMAIN (type) == NULL_TREE); + while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); @@ -2047,6 +2050,8 @@ nvptx_assemble_decl_begin (FILE *file, const char *name, const char *section, /* We make everything an array, to simplify any initialization emission. */ fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]", init_frag.remaining); + else if (atype) + fprintf (file, "[]"); } /* Called when the initializer for a decl has been completely output through diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index e6ac34acec9..9368d4504a8 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -1725,9 +1725,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) } else emit_move_insn (scratch_reg, XEXP (op1, 0)); - emit_insn (gen_rtx_SET (operand0, - replace_equiv_address (op1, scratch_reg))); - return 1; + op1 = replace_equiv_address (op1, scratch_reg); } } else if ((!INT14_OK_STRICT && symbolic_memory_operand (op1, VOIDmode)) @@ -1737,10 +1735,10 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) /* Load memory address into SCRATCH_REG. */ scratch_reg = force_mode (word_mode, scratch_reg); emit_move_insn (scratch_reg, XEXP (op1, 0)); - emit_insn (gen_rtx_SET (operand0, - replace_equiv_address (op1, scratch_reg))); - return 1; + op1 = replace_equiv_address (op1, scratch_reg); } + emit_insn (gen_rtx_SET (operand0, op1)); + return 1; } else if (scratch_reg && FP_REG_P (operand1) @@ -1778,9 +1776,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) } else emit_move_insn (scratch_reg, XEXP (op0, 0)); - emit_insn (gen_rtx_SET (replace_equiv_address (op0, scratch_reg), - operand1)); - return 1; + op0 = replace_equiv_address (op0, scratch_reg); } } else if ((!INT14_OK_STRICT && symbolic_memory_operand (op0, VOIDmode)) @@ -1790,10 +1786,10 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) /* Load memory address into SCRATCH_REG. */ scratch_reg = force_mode (word_mode, scratch_reg); emit_move_insn (scratch_reg, XEXP (op0, 0)); - emit_insn (gen_rtx_SET (replace_equiv_address (op0, scratch_reg), - operand1)); - return 1; + op0 = replace_equiv_address (op0, scratch_reg); } + emit_insn (gen_rtx_SET (op0, operand1)); + return 1; } /* Handle secondary reloads for loads of FP registers from constant expressions by forcing the constant into memory. For the most part, diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 65df53e54b0..dd37dd3ad8d 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1153,8 +1153,18 @@ do { \ PREFIX is the class of label and NUM is the number within the class. This is suitable for output with `assemble_name'. */ -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%c$%s%04ld", (PREFIX)[0], (PREFIX) + 1, (long)(NUM)) +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + do \ + { \ + char *__p; \ + (LABEL)[0] = '*'; \ + (LABEL)[1] = (PREFIX)[0]; \ + (LABEL)[2] = '$'; \ + __p = stpcpy (&(LABEL)[3], &(PREFIX)[1]); \ + sprint_ul (__p, (unsigned long) (NUM)); \ + } \ + while (0) + /* Output the definition of a compiler-generated label named NAME. */ @@ -1193,14 +1203,14 @@ do { \ /* This is how to output an element of a case-vector that is absolute. */ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.word L$%04d\n", VALUE) + fprintf (FILE, "\t.word L$%d\n", VALUE) /* This is how to output an element of a case-vector that is relative. Since we always place jump tables in the text section, the difference is absolute and requires no relocation. */ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - fprintf (FILE, "\t.word L$%04d-L$%04d\n", VALUE, REL) + fprintf (FILE, "\t.word L$%d-L$%d\n", VALUE, REL) /* This is how to output an absolute case-vector. */ diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index e786d104b1f..01657fdf838 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2536,24 +2536,40 @@ xoperands[0] = operands[0]; xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); - output_asm_insn (\"mfia %0\", xoperands); - - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + && !LABEL_REF_NONLOCAL_P (operands[1])) + { + xoperands[2] = gen_label_rtx (); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", + CODE_LABEL_NUMBER (xoperands[2])); + output_asm_insn (\"mfia %0\", xoperands); + + /* If we're trying to load the address of a label that happens to be + close, then we can use a shorter sequence. */ + if (INSN_ADDRESSES_SET_P () + && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) + - INSN_ADDRESSES (INSN_UID (insn))) < 8100) + output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + else + { + output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); + output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + } + } else { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + /* Load using linkage table. */ + if (TARGET_64BIT) + { + output_asm_insn (\"addil LT%%%1,%%r27\", xoperands); + output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands); + } + else + { + output_asm_insn (\"addil LT%%%1,%%r19\", xoperands); + output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands); + } } return \"\"; }" @@ -2570,25 +2586,33 @@ xoperands[0] = operands[0]; xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - output_asm_insn (\"bl .+8,%0\", xoperands); - output_asm_insn (\"depi 0,31,2,%0\", xoperands); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); - - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + && !LABEL_REF_NONLOCAL_P (operands[1])) + { + xoperands[2] = gen_label_rtx (); + output_asm_insn (\"bl .+8,%0\", xoperands); + output_asm_insn (\"depi 0,31,2,%0\", xoperands); + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", + CODE_LABEL_NUMBER (xoperands[2])); + + /* If we're trying to load the address of a label that happens to be + close, then we can use a shorter sequence. */ + if (INSN_ADDRESSES_SET_P () + && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) + - INSN_ADDRESSES (INSN_UID (insn))) < 8100) + output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); + else + { + output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); + output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + } + } else { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); + /* Load using linkage table. */ + output_asm_insn (\"addil LT%%%1,%%r19\", xoperands); + output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands); } return \"\"; }" diff --git a/gcc/config/pa/pa64-hpux.h b/gcc/config/pa/pa64-hpux.h index 8b7a42be3b5..5b21482602d 100644 --- a/gcc/config/pa/pa64-hpux.h +++ b/gcc/config/pa/pa64-hpux.h @@ -245,8 +245,18 @@ do { \ /* We need to use the HP style for internal labels. */ #undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ - sprintf (LABEL, "*%c$%s%04ld", (PREFIX)[0], (PREFIX) + 1, (long)(NUM)) +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + do \ + { \ + char *__p; \ + (LABEL)[0] = '*'; \ + (LABEL)[1] = (PREFIX)[0]; \ + (LABEL)[2] = '$'; \ + __p = stpcpy (&(LABEL)[3], &(PREFIX)[1]); \ + sprint_ul (__p, (unsigned long) (NUM)); \ + } \ + while (0) + #else /* USING_ELFOS_H */ diff --git a/gcc/config/riscv/t-rtems b/gcc/config/riscv/t-rtems new file mode 100644 index 00000000000..41f5927fc87 --- /dev/null +++ b/gcc/config/riscv/t-rtems @@ -0,0 +1,25 @@ +MULTILIB_OPTIONS = +MULTILIB_DIRNAMES = + +MULTILIB_OPTIONS += march=rv32i/march=rv32im/march=rv32imafd/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv64imafd/march=rv64imac/march=rv64imafdc +MULTILIB_DIRNAMES += rv32i rv32im rv32imafd rv32iac rv32imac rv32imafc rv64imafd rv64imac rv64imafdc + +MULTILIB_OPTIONS += mabi=ilp32/mabi=ilp32f/mabi=ilp32d/mabi=lp64/mabi=lp64d +MULTILIB_DIRNAMES += ilp32 ilp32f ilp32d lp64 lp64d + +MULTILIB_OPTIONS += mcmodel=medany +MULTILIB_DIRNAMES += medany + +MULTILIB_REQUIRED = +MULTILIB_REQUIRED += march=rv32i/mabi=ilp32 +MULTILIB_REQUIRED += march=rv32im/mabi=ilp32 +MULTILIB_REQUIRED += march=rv32imafd/mabi=ilp32d +MULTILIB_REQUIRED += march=rv32iac/mabi=ilp32 +MULTILIB_REQUIRED += march=rv32imac/mabi=ilp32 +MULTILIB_REQUIRED += march=rv32imafc/mabi=ilp32f +MULTILIB_REQUIRED += march=rv64imafd/mabi=lp64d +MULTILIB_REQUIRED += march=rv64imafd/mabi=lp64d/mcmodel=medany +MULTILIB_REQUIRED += march=rv64imac/mabi=lp64 +MULTILIB_REQUIRED += march=rv64imac/mabi=lp64/mcmodel=medany +MULTILIB_REQUIRED += march=rv64imafdc/mabi=lp64d +MULTILIB_REQUIRED += march=rv64imafdc/mabi=lp64d/mcmodel=medany diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h index 3011a87becf..e04c3a50a9e 100644 --- a/gcc/config/rs6000/altivec.h +++ b/gcc/config/rs6000/altivec.h @@ -398,8 +398,6 @@ #define vec_vctzd __builtin_vec_vctzd #define vec_vctzh __builtin_vec_vctzh #define vec_vctzw __builtin_vec_vctzw -#define vec_vextract4b __builtin_vec_vextract4b -#define vec_vinsert4b __builtin_vec_vinsert4b #define vec_extract4b __builtin_vec_extract4b #define vec_insert4b __builtin_vec_insert4b #define vec_vprtyb __builtin_vec_vprtyb diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 53c6eb81154..32dfa8f999a 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -2615,39 +2615,49 @@ "lvx %0,%y1" [(set_attr "type" "vecload")]) -; The next two patterns embody what lvx should usually look like. -(define_insn "altivec_lvx_<mode>_2op" - [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") - (match_operand:DI 2 "register_operand" "r")) - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_64BIT" - "lvx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_<mode>_1op" - [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_64BIT" - "lvx %0,0,%1" - [(set_attr "type" "vecload")]) +; The following patterns embody what lvx should usually look like. +(define_expand "altivec_lvx_<VM2:mode>" + [(set (match_operand:VM2 0 "register_operand") + (match_operand:VM2 1 "altivec_indexed_or_indirect_operand"))] + "TARGET_ALTIVEC" +{ + rtx addr = XEXP (operand1, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + rtx op1 = XEXP (addr, 0); + rtx op2 = XEXP (addr, 1); + if (TARGET_64BIT) + emit_insn (gen_altivec_lvx_<VM2:mode>_2op_di (operand0, op1, op2)); + else + emit_insn (gen_altivec_lvx_<VM2:mode>_2op_si (operand0, op1, op2)); + } + else + { + if (TARGET_64BIT) + emit_insn (gen_altivec_lvx_<VM2:mode>_1op_di (operand0, addr)); + else + emit_insn (gen_altivec_lvx_<VM2:mode>_1op_si (operand0, addr)); + } + DONE; +}) -; 32-bit versions of the above. -(define_insn "altivec_lvx_<mode>_2op_si" +; The next two patterns embody what lvx should usually look like. +(define_insn "altivec_lvx_<VM2:mode>_2op_<P:mptrsize>" [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_32BIT" + (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") + (match_operand:P 2 "register_operand" "r")) + (const_int -16))))] + "TARGET_ALTIVEC" "lvx %0,%1,%2" [(set_attr "type" "vecload")]) -(define_insn "altivec_lvx_<mode>_1op_si" +(define_insn "altivec_lvx_<VM2:mode>_1op_<P:mptrsize>" [(set (match_operand:VM2 0 "register_operand" "=v") - (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") - (const_int -16))))] - "TARGET_ALTIVEC && TARGET_32BIT" + (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") + (const_int -16))))] + "TARGET_ALTIVEC" "lvx %0,0,%1" [(set_attr "type" "vecload")]) @@ -2663,39 +2673,49 @@ "stvx %1,%y0" [(set_attr "type" "vecstore")]) -; The next two patterns embody what stvx should usually look like. -(define_insn "altivec_stvx_<mode>_2op" - [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") - (match_operand:DI 2 "register_operand" "r")) - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_64BIT" - "stvx %0,%1,%2" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_<mode>_1op" - [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_64BIT" - "stvx %0,0,%1" - [(set_attr "type" "vecstore")]) +; The following patterns embody what stvx should usually look like. +(define_expand "altivec_stvx_<VM2:mode>" + [(set (match_operand:VM2 1 "altivec_indexed_or_indirect_operand") + (match_operand:VM2 0 "register_operand"))] + "TARGET_ALTIVEC" +{ + rtx addr = XEXP (operand1, 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + rtx op1 = XEXP (addr, 0); + rtx op2 = XEXP (addr, 1); + if (TARGET_64BIT) + emit_insn (gen_altivec_stvx_<VM2:mode>_2op_di (operand0, op1, op2)); + else + emit_insn (gen_altivec_stvx_<VM2:mode>_2op_si (operand0, op1, op2)); + } + else + { + if (TARGET_64BIT) + emit_insn (gen_altivec_stvx_<VM2:mode>_1op_di (operand0, addr)); + else + emit_insn (gen_altivec_stvx_<VM2:mode>_1op_si (operand0, addr)); + } + DONE; +}) -; 32-bit versions of the above. -(define_insn "altivec_stvx_<mode>_2op_si" - [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_32BIT" +; The next two patterns embody what stvx should usually look like. +(define_insn "altivec_stvx_<VM2:mode>_2op_<P:mptrsize>" + [(set (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") + (match_operand:P 2 "register_operand" "r")) + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC" "stvx %0,%1,%2" [(set_attr "type" "vecstore")]) -(define_insn "altivec_stvx_<mode>_1op_si" - [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") - (const_int -16))) - (match_operand:VM2 0 "register_operand" "v"))] - "TARGET_ALTIVEC && TARGET_32BIT" +(define_insn "altivec_stvx_<VM2:mode>_1op_<P:mptrsize>" + [(set (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC" "stvx %0,0,%1" [(set_attr "type" "vecstore")]) diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 46ae21a6120..2cc07c6b5ae 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -1,5 +1,5 @@ /* Builtin functions for rs6000/powerpc. - Copyright (C) 2009-2017 Free Software Foundation, Inc. + Copyright (C) 2009-2018 Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) This file is part of GCC. @@ -659,6 +659,14 @@ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +#define BU_P7_POWERPC64_MISC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_POPCNTD /* MASK */ \ + | RS6000_BTM_POWERPC64, \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ /* Miscellaneous builtins for instructions added in ISA 2.07. These instructions do require the ISA 2.07 vector support, but they aren't vector @@ -2034,8 +2042,6 @@ BU_P9V_AV_2 (VEXTUWRX, "vextuwrx", CONST, vextuwrx) /* Insert/extract 4 byte word into a vector. */ BU_P9V_VSX_2 (VEXTRACT4B, "vextract4b", CONST, vextract4b) -BU_P9V_VSX_3 (VINSERT4B, "vinsert4b", CONST, vinsert4b) -BU_P9V_VSX_3 (VINSERT4B_DI, "vinsert4b_di", CONST, vinsert4b_di) BU_P9V_VSX_3 (INSERT4B, "insert4b", CONST, insert4b) BU_P9V_VSX_2 (EXTRACT4B, "extract4b", CONST, extract4b) @@ -2090,7 +2096,6 @@ BU_P9V_OVERLOAD_2 (EXTRACT4B, "extract4b") /* ISA 3.0 Vector scalar overloaded 3 argument functions */ BU_P9V_OVERLOAD_3 (STXVL, "stxvl") -BU_P9V_OVERLOAD_3 (VINSERT4B, "vinsert4b") BU_P9V_OVERLOAD_3 (INSERT4B, "insert4b") /* Overloaded CMPNE support was implemented prior to Power 9, @@ -2107,13 +2112,9 @@ BU_P9V_OVERLOAD_1 (VCTZLSBB, "vctzlsbb") /* 2 argument extended divide functions added in ISA 2.06. */ BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si) -BU_P7_MISC_2 (DIVWEO, "divweo", CONST, diveo_si) BU_P7_MISC_2 (DIVWEU, "divweu", CONST, diveu_si) -BU_P7_MISC_2 (DIVWEUO, "divweuo", CONST, diveuo_si) -BU_P7_MISC_2 (DIVDE, "divde", CONST, dive_di) -BU_P7_MISC_2 (DIVDEO, "divdeo", CONST, diveo_di) -BU_P7_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di) -BU_P7_MISC_2 (DIVDEUO, "divdeuo", CONST, diveuo_di) +BU_P7_POWERPC64_MISC_2 (DIVDE, "divde", CONST, dive_di) +BU_P7_POWERPC64_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di) /* 1 argument DFP (decimal floating point) functions added in ISA 2.05. */ BU_DFP_MISC_1 (DXEX, "dxex", CONST, dfp_dxex_dd) diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index c3134fce60d..516db05da8f 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -2393,7 +2393,7 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKSDUS, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKSDUS, + { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKUDUS, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, { ALTIVEC_BUILTIN_VEC_VPKSWUS, ALTIVEC_BUILTIN_VPKSWUS, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, @@ -5109,27 +5109,6 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { P9V_BUILTIN_VEC_INSERT4B, P9V_BUILTIN_INSERT4B, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, - RS6000_BTI_V16QI, RS6000_BTI_V4SI, - RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, - RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTSI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_V16QI, RS6000_BTI_INTDI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI, - RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTDI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, - { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, { P8V_BUILTIN_VEC_VADDECUQ, P8V_BUILTIN_VADDECUQ, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, @@ -6096,6 +6075,15 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); stmt = build_indirect_ref (loc, stmt, RO_NULL); + /* PR83660: We mark this as having side effects so that + downstream in fold_build_cleanup_point_expr () it will get a + CLEANUP_POINT_EXPR. If it does not we can run into an ICE + later in gimplify_cleanup_point_expr (). Potentially this + causes missed optimization because the actually is no side + effect. */ + if (c_dialect_cxx ()) + TREE_SIDE_EFFECTS (stmt) = 1; + return stmt; } diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 86e410e4bdf..dcb483dea51 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991-2017 Free Software Foundation, Inc. + Copyright (C) 1991-2018 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -1372,6 +1372,7 @@ static rtx rs6000_debug_legitimize_reload_address (rtx, machine_mode, int, int, int, int *); static bool rs6000_mode_dependent_address (const_rtx); static bool rs6000_debug_mode_dependent_address (const_rtx); +static bool rs6000_offsettable_memref_p (rtx, machine_mode, bool); static enum reg_class rs6000_secondary_reload_class (enum reg_class, machine_mode, rtx); static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, @@ -3890,6 +3891,7 @@ rs6000_builtin_mask_calculate (void) | ((TARGET_P9_MISC) ? RS6000_BTM_P9_MISC : 0) | ((TARGET_MODULO) ? RS6000_BTM_MODULO : 0) | ((TARGET_64BIT) ? RS6000_BTM_64BIT : 0) + | ((TARGET_POWERPC64) ? RS6000_BTM_POWERPC64 : 0) | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0) | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) @@ -8563,10 +8565,15 @@ mem_operand_gpr (rtx op, machine_mode mode) int extra; rtx addr = XEXP (op, 0); - /* Don't allow altivec type addresses like (mem (and (plus ...))). - See PR target/84279. */ + /* PR85755: Allow PRE_INC and PRE_DEC addresses. */ + if (TARGET_UPDATE + && (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC) + && mode_supports_pre_incdec_p (mode) + && legitimate_indirect_address_p (XEXP (addr, 0), false)) + return true; - if (GET_CODE (addr) == AND) + /* Don't allow non-offsettable addresses. See PRs 83969 and 84279. */ + if (!rs6000_offsettable_memref_p (op, mode, false)) return false; op = address_offset (addr); @@ -10339,7 +10346,7 @@ rs6000_find_base_term (rtx op) in 32-bit mode, that the recog predicate rejects. */ static bool -rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode) +rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode, bool strict) { bool worst_case; @@ -10347,7 +10354,7 @@ rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode) return false; /* First mimic offsettable_memref_p. */ - if (offsettable_address_p (true, GET_MODE (op), XEXP (op, 0))) + if (offsettable_address_p (strict, GET_MODE (op), XEXP (op, 0))) return true; /* offsettable_address_p invokes rs6000_mode_dependent_address, but @@ -10361,7 +10368,7 @@ rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode) worst_case = ((TARGET_POWERPC64 && GET_MODE_CLASS (reg_mode) == MODE_INT) || GET_MODE_SIZE (reg_mode) == 4); return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), - true, worst_case); + strict, worst_case); } /* Determine the reassociation width to be used in reassociate_bb. @@ -14117,6 +14124,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), 3, dest_addr, addr, size_int (rsize * 4)); + TREE_ADDRESSABLE (tmp) = 1; gimplify_and_add (copy, pre_p); addr = dest_addr; @@ -15098,12 +15106,12 @@ altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk) /* For LVX, express the RTL accurately by ANDing the address with -16. LVXL and LVE*X expand to use UNSPECs to hide their special behavior, so the raw address is fine. */ - if (icode == CODE_FOR_altivec_lvx_v2df_2op - || icode == CODE_FOR_altivec_lvx_v2di_2op - || icode == CODE_FOR_altivec_lvx_v4sf_2op - || icode == CODE_FOR_altivec_lvx_v4si_2op - || icode == CODE_FOR_altivec_lvx_v8hi_2op - || icode == CODE_FOR_altivec_lvx_v16qi_2op) + if (icode == CODE_FOR_altivec_lvx_v2df + || icode == CODE_FOR_altivec_lvx_v2di + || icode == CODE_FOR_altivec_lvx_v4sf + || icode == CODE_FOR_altivec_lvx_v4si + || icode == CODE_FOR_altivec_lvx_v8hi + || icode == CODE_FOR_altivec_lvx_v16qi) { rtx rawaddr; if (op0 == const0_rtx) @@ -15289,12 +15297,12 @@ altivec_expand_stv_builtin (enum insn_code icode, tree exp) /* For STVX, express the RTL accurately by ANDing the address with -16. STVXL and STVE*X expand to use UNSPECs to hide their special behavior, so the raw address is fine. */ - if (icode == CODE_FOR_altivec_stvx_v2df_2op - || icode == CODE_FOR_altivec_stvx_v2di_2op - || icode == CODE_FOR_altivec_stvx_v4sf_2op - || icode == CODE_FOR_altivec_stvx_v4si_2op - || icode == CODE_FOR_altivec_stvx_v8hi_2op - || icode == CODE_FOR_altivec_stvx_v16qi_2op) + if (icode == CODE_FOR_altivec_stvx_v2df + || icode == CODE_FOR_altivec_stvx_v2di + || icode == CODE_FOR_altivec_stvx_v4sf + || icode == CODE_FOR_altivec_stvx_v4si + || icode == CODE_FOR_altivec_stvx_v8hi + || icode == CODE_FOR_altivec_stvx_v16qi) { if (op1 == const0_rtx) rawaddr = op2; @@ -16195,18 +16203,18 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) switch (fcode) { case ALTIVEC_BUILTIN_STVX_V2DF: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df, exp); case ALTIVEC_BUILTIN_STVX_V2DI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di, exp); case ALTIVEC_BUILTIN_STVX_V4SF: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf, exp); case ALTIVEC_BUILTIN_STVX: case ALTIVEC_BUILTIN_STVX_V4SI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp); case ALTIVEC_BUILTIN_STVX_V8HI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi, exp); case ALTIVEC_BUILTIN_STVX_V16QI: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi_2op, exp); + return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi, exp); case ALTIVEC_BUILTIN_STVEBX: return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp); case ALTIVEC_BUILTIN_STVEHX: @@ -16400,9 +16408,6 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) } break; - case P9V_BUILTIN_VINSERT4B: - case P9V_BUILTIN_VINSERT4B_DI: - case P9V_BUILTIN_VEC_VINSERT4B: case P9V_BUILTIN_VEC_INSERT4B: arg2 = CALL_EXPR_ARG (exp, 2); STRIP_NOPS (arg2); @@ -16413,7 +16418,7 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) if (TREE_CODE (arg2) != INTEGER_CST || TREE_INT_CST_LOW (arg2) > 12) { - error ("third argument to vec_vinsert4b must be 0..12"); + error ("third argument to vec_insert4b must be 0..12"); return expand_call (exp, target, false); } break; @@ -16473,23 +16478,23 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp) return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v16qi, exp, target, false); case ALTIVEC_BUILTIN_LVX_V2DF: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df, exp, target, false); case ALTIVEC_BUILTIN_LVX_V2DI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di, exp, target, false); case ALTIVEC_BUILTIN_LVX_V4SF: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf, exp, target, false); case ALTIVEC_BUILTIN_LVX: case ALTIVEC_BUILTIN_LVX_V4SI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si, exp, target, false); case ALTIVEC_BUILTIN_LVX_V8HI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi, exp, target, false); case ALTIVEC_BUILTIN_LVX_V16QI: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi_2op, + return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi, exp, target, false); case ALTIVEC_BUILTIN_LVLX: return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx, @@ -17053,6 +17058,11 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode) error ("Builtin function %s requires the -mhard-float option", name); else if ((fnmask & RS6000_BTM_FLOAT128) != 0) error ("Builtin function %s requires the -mfloat128 option", name); + else if ((fnmask & (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64)) + == (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64)) + error ("builtin function %qs requires the %qs (or newer), and " + "%qs or %qs options", + name, "-mcpu=power7", "-m64", "-mpowerpc64"); else error ("Builtin function %s is not supported with the current options", name); @@ -18817,9 +18827,7 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0, case CRYPTO_BUILTIN_VPMSUM: case MISC_BUILTIN_ADDG6S: case MISC_BUILTIN_DIVWEU: - case MISC_BUILTIN_DIVWEUO: case MISC_BUILTIN_DIVDEU: - case MISC_BUILTIN_DIVDEUO: h.uns_p[0] = 1; h.uns_p[1] = 1; h.uns_p[2] = 1; @@ -23280,7 +23288,7 @@ rs6000_output_move_128bit (rtx operands[]) } else if (TARGET_ALTIVEC && src_vmx_p - && altivec_indexed_or_indirect_operand (src, mode)) + && altivec_indexed_or_indirect_operand (dest, mode)) return "stvx %1,%y0"; else if (TARGET_VSX && src_vsx_p) @@ -26558,7 +26566,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) emit_insn (gen_add3_insn (breg, breg, delta_rtx)); src = replace_equiv_address (src, breg); } - else if (! rs6000_offsettable_memref_p (src, reg_mode)) + else if (! rs6000_offsettable_memref_p (src, reg_mode, true)) { if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY) { @@ -26625,7 +26633,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) emit_insn (gen_add3_insn (breg, breg, delta_rtx)); dst = replace_equiv_address (dst, breg); } - else if (!rs6000_offsettable_memref_p (dst, reg_mode) + else if (!rs6000_offsettable_memref_p (dst, reg_mode, true) && GET_CODE (XEXP (dst, 0)) != LO_SUM) { if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY) @@ -26664,7 +26672,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) } } else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) - gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode)); + gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode, true)); } for (i = 0; i < nregs; i++) @@ -35886,6 +35894,11 @@ rs6000_elf_in_small_data_p (const_tree decl) } else { + /* If we are told not to put readonly data in sdata, then don't. */ + if (TREE_READONLY (decl) && rs6000_sdata != SDATA_EABI + && !rs6000_readonly_in_sdata) + return false; + HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl)); if (size > 0 @@ -39423,6 +39436,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] = { "hard-dfp", RS6000_BTM_DFP, false, false }, { "hard-float", RS6000_BTM_HARD_FLOAT, false, false }, { "long-double-128", RS6000_BTM_LDBL128, false, false }, + { "powerpc64", RS6000_BTM_POWERPC64, false, false }, { "float128", RS6000_BTM_FLOAT128, false, false }, }; @@ -42160,6 +42174,7 @@ rtx_is_swappable_p (rtx op, unsigned int *special) case UNSPEC_VPERM_UNS: case UNSPEC_VPERMHI: case UNSPEC_VPERMSI: + case UNSPEC_VPERMXOR: case UNSPEC_VPKPX: case UNSPEC_VSLDOI: case UNSPEC_VSLO: diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3780a49d902..ba234fda718 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992-2017 Free Software Foundation, Inc. + Copyright (C) 1992-2018 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -110,7 +110,8 @@ /* Common ASM definitions used by ASM_SPEC among the various targets for handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to provide the default assembler options if the user uses -mcpu=native, so if - you make changes here, make them also there. */ + you make changes here, make them also there. PR63177: Do not pass -mpower8 + to the assembler if -mpower9-vector was also used. */ #define ASM_CPU_SPEC \ "%{!mcpu*: \ %{mpowerpc64*: -mppc64} \ @@ -124,7 +125,7 @@ %{mcpu=power6: %(asm_cpu_power6) -maltivec} \ %{mcpu=power6x: %(asm_cpu_power6) -maltivec} \ %{mcpu=power7: %(asm_cpu_power7)} \ -%{mcpu=power8: %(asm_cpu_power8)} \ +%{mcpu=power8: %{!mpower9-vector: %(asm_cpu_power8)}} \ %{mcpu=power9: %(asm_cpu_power9)} \ %{mcpu=a2: -ma2} \ %{mcpu=powerpc: -mppc} \ @@ -173,6 +174,7 @@ %{maltivec: -maltivec} \ %{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \ %{mpower8-vector|mcrypto|mdirect-move|mhtm: %{!mcpu*: %(asm_cpu_power8)}} \ +%{mpower9-vector: %{!mcpu*|mcpu=power8: %(asm_cpu_power9)}} \ -many" #define CPP_DEFAULT_SPEC "" @@ -2735,6 +2737,7 @@ extern int frame_pointer_needed; #define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ #define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */ #define RS6000_BTM_64BIT MASK_64BIT /* 64-bit addressing. */ +#define RS6000_BTM_POWERPC64 MASK_POWERPC64 /* 64-bit registers. */ #define RS6000_BTM_FLOAT128 MASK_FLOAT128_TYPE /* IEEE 128-bit float. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ @@ -2754,6 +2757,7 @@ extern int frame_pointer_needed; | RS6000_BTM_DFP \ | RS6000_BTM_HARD_FLOAT \ | RS6000_BTM_LDBL128 \ + | RS6000_BTM_POWERPC64 \ | RS6000_BTM_FLOAT128) /* Define builtin enum index. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 138b0c7e995..80f29e5b97d 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,5 +1,5 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990-2017 Free Software Foundation, Inc. +;; Copyright (C) 1990-2018 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GCC. @@ -135,9 +135,7 @@ UNSPEC_CDTBCD UNSPEC_CBCDTD UNSPEC_DIVE - UNSPEC_DIVEO UNSPEC_DIVEU - UNSPEC_DIVEUO UNSPEC_UNPACK_128BIT UNSPEC_PACK_128BIT UNSPEC_LSQ @@ -8642,14 +8640,14 @@ ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX (define_insn "*movdi_internal64" [(set (match_operand:DI 0 "nonimmediate_operand" - "=Y, r, r, r, r, r, + "=YZ, r, r, r, r, r, ^m, ^d, ^d, ^wY, $Z, $wb, $wv, ^wi, *wo, *wo, *wv, *wi, *wi, *wv, *wv, r, *h, *h, ?*r, ?*wg, ?*r, ?*wj") (match_operand:DI 1 "input_operand" - "r, Y, r, I, L, nF, + "r, YZ, r, I, L, nF, d, m, d, wb, wv, wY, Z, wi, Oj, wM, OjwM, Oj, wM, wS, wB, *h, r, 0, @@ -14449,14 +14447,10 @@ (set_attr "length" "4")]) (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE - UNSPEC_DIVEO - UNSPEC_DIVEU - UNSPEC_DIVEUO]) + UNSPEC_DIVEU]) (define_int_attr div_extend [(UNSPEC_DIVE "e") - (UNSPEC_DIVEO "eo") - (UNSPEC_DIVEU "eu") - (UNSPEC_DIVEUO "euo")]) + (UNSPEC_DIVEU "eu")]) (define_insn "div<div_extend>_<mode>" [(set (match_operand:GPR 0 "register_operand" "=r") @@ -14535,16 +14529,14 @@ (set_attr "length" "4")]) (define_insn_and_split "pack<mode>" - [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") + [(set (match_operand:FMOVE128 0 "register_operand" "=&d") (unspec:FMOVE128 - [(match_operand:<FP128_64> 1 "register_operand" "0,d") - (match_operand:<FP128_64> 2 "register_operand" "d,d")] + [(match_operand:<FP128_64> 1 "register_operand" "d") + (match_operand:<FP128_64> 2 "register_operand" "d")] UNSPEC_PACK_128BIT))] "FLOAT128_2REG_P (<MODE>mode)" - "@ - fmr %L0,%2 - #" - "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" + "#" + "&& reload_completed" [(set (match_dup 3) (match_dup 1)) (set (match_dup 4) (match_dup 2))] { @@ -14557,8 +14549,8 @@ operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); } - [(set_attr "type" "fpsimple,fp") - (set_attr "length" "4,8")]) + [(set_attr "type" "fp") + (set_attr "length" "8")]) (define_insn "unpack<mode>" [(set (match_operand:DI 0 "register_operand" "=d,d") diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt index 423300b8148..1492871da7d 100644 --- a/gcc/config/rs6000/sysv4.opt +++ b/gcc/config/rs6000/sysv4.opt @@ -27,6 +27,10 @@ msdata= Target RejectNegative Joined Var(rs6000_sdata_name) Select method for sdata handling. +mreadonly-in-sdata +Target Report Var(rs6000_readonly_in_sdata) Init(1) Save +Allow readonly data in sdata. + mtls-size= Target RejectNegative Joined Var(rs6000_tls_size) Enum(rs6000_tls_size) Specify bit size of immediate TLS offsets. diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index ea8169fabe0..a9ec9a9981a 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -180,12 +180,7 @@ operands[1] = rs6000_address_for_altivec (operands[1]); rtx and_op = XEXP (operands[1], 0); gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_lvx_<mode>_2op (operands[0], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_lvx_<mode>_1op (operands[0], operands[1])); + emit_insn (gen_altivec_lvx_<mode> (operands[0], operands[1])); DONE; } }") @@ -203,12 +198,7 @@ operands[0] = rs6000_address_for_altivec (operands[0]); rtx and_op = XEXP (operands[0], 0); gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_stvx_<mode>_2op (operands[1], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_stvx_<mode>_1op (operands[1], operands[0])); + emit_insn (gen_altivec_stvx_<mode> (operands[1], operands[0])); DONE; } }") diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index c00238bf7a3..37d768fe570 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -157,6 +157,22 @@ (TF "wp") (KF "wq")]) +;; A mode attribute to disparage use of GPR registers, except for scalar +;; interger modes. +(define_mode_attr ??r [(V16QI "??r") + (V8HI "??r") + (V4SI "??r") + (V4SF "??r") + (V2DI "??r") + (V2DF "??r") + (DI "r") + (DF "??r") + (SF "??r") + (V1TI "??r") + (TI "r") + (TF "??r") + (KF "??r")]) + ;; Same size integer type for floating point data (define_mode_attr VSi [(V4SF "v4si") (V2DF "v2di") @@ -961,7 +977,7 @@ (define_insn "*vsx_mov<mode>_64bit" [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=ZwO, <VSa>, <VSa>, r, we, ?wQ, - ?&r, ??r, ??Y, ??r, wo, v, + ?&r, ??r, ??Y, <??r>, wo, v, ?<VSa>, *r, v, ??r, wZ, v") (match_operand:VSX_M 1 "input_operand" @@ -990,7 +1006,7 @@ ;; LVX (VMX) STVX (VMX) (define_insn "*vsx_mov<mode>_32bit" [(set (match_operand:VSX_M 0 "nonimmediate_operand" - "=ZwO, <VSa>, <VSa>, ??r, ??Y, ??r, + "=ZwO, <VSa>, <VSa>, ??r, ??Y, <??r>, wo, v, ?<VSa>, *r, v, ??r, wZ, v") @@ -3930,7 +3946,7 @@ (match_operand:DI 2 "register_operand" "+r")] UNSPEC_STXVL))] "TARGET_P9_VECTOR && TARGET_64BIT" - "sldi %2,%2\;stxvl %x0,%1,%2" + "sldi %2,%2,56\;stxvl %x0,%1,%2" [(set_attr "length" "8") (set_attr "type" "vecstore")]) @@ -4084,7 +4100,7 @@ ;; Vector insert/extract word at arbitrary byte values. Note, the little ;; endian version needs to adjust the byte number, and the V4SI element in -;; vinsert4b. +;; insert4b. (define_insn "extract4b" [(set (match_operand:V2DI 0 "vsx_register_operand") (unspec:V2DI [(match_operand:V16QI 1 "vsx_register_operand" "wa") @@ -4164,56 +4180,6 @@ } [(set_attr "type" "vecperm")]) -(define_expand "vinsert4b" - [(set (match_operand:V16QI 0 "vsx_register_operand") - (unspec:V16QI [(match_operand:V4SI 1 "vsx_register_operand") - (match_operand:V16QI 2 "vsx_register_operand") - (match_operand:QI 3 "const_0_to_12_operand")] - UNSPEC_XXINSERTW))] - "TARGET_P9_VECTOR" -{ - if (!VECTOR_ELT_ORDER_BIG) - { - rtx op1 = operands[1]; - rtx v4si_tmp = gen_reg_rtx (V4SImode); - emit_insn (gen_vsx_xxpermdi_v4si_be (v4si_tmp, op1, op1, const1_rtx)); - operands[1] = v4si_tmp; - operands[3] = GEN_INT (12 - INTVAL (operands[3])); - } -}) - -(define_insn "*vinsert4b_internal" - [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa") - (unspec:V16QI [(match_operand:V4SI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "0") - (match_operand:QI 3 "const_0_to_12_operand" "n")] - UNSPEC_XXINSERTW))] - "TARGET_P9_VECTOR" - "xxinsertw %x0,%x1,%3" - [(set_attr "type" "vecperm")]) - -(define_expand "vinsert4b_di" - [(set (match_operand:V16QI 0 "vsx_register_operand") - (unspec:V16QI [(match_operand:DI 1 "vsx_register_operand") - (match_operand:V16QI 2 "vsx_register_operand") - (match_operand:QI 3 "const_0_to_12_operand")] - UNSPEC_XXINSERTW))] - "TARGET_P9_VECTOR" -{ - if (!VECTOR_ELT_ORDER_BIG) - operands[3] = GEN_INT (12 - INTVAL (operands[3])); -}) - -(define_insn "*vinsert4b_di_internal" - [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa") - (unspec:V16QI [(match_operand:DI 1 "vsx_register_operand" "wj") - (match_operand:V16QI 2 "vsx_register_operand" "0") - (match_operand:QI 3 "const_0_to_12_operand" "n")] - UNSPEC_XXINSERTW))] - "TARGET_P9_VECTOR" - "xxinsertw %x0,%x1,%3" - [(set_attr "type" "vecperm")]) - ;; Support for ISA 3.0 vector byte reverse diff --git a/gcc/config/rtems.h b/gcc/config/rtems.h index 439199d4cbb..35026efa2c7 100644 --- a/gcc/config/rtems.h +++ b/gcc/config/rtems.h @@ -48,3 +48,7 @@ -latomic -lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}" #define TARGET_POSIX_IO + +/* Prefer int for int32_t (see stdint-newlib.h). */ +#undef STDINT_LONG32 +#define STDINT_LONG32 (INT_TYPE_SIZE != 32 && LONG_TYPE_SIZE == 32) diff --git a/gcc/config/s390/s390-builtin-types.def b/gcc/config/s390/s390-builtin-types.def index b7f33030eb9..915b050b2fb 100644 --- a/gcc/config/s390/s390-builtin-types.def +++ b/gcc/config/s390/s390-builtin-types.def @@ -124,6 +124,7 @@ DEF_OPAQUE_VECTOR_TYPE (BT_OUV4SI, BT_UINT, 4) DEF_OPAQUE_VECTOR_TYPE (BT_BV4SI, BT_BINT, 4) DEF_FN_TYPE_0 (BT_FN_INT, BT_INT) DEF_FN_TYPE_0 (BT_FN_UINT, BT_UINT) +DEF_FN_TYPE_0 (BT_FN_VOID, BT_VOID) DEF_FN_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT) DEF_FN_TYPE_1 (BT_FN_INT_VOIDPTR, BT_INT, BT_VOIDPTR) DEF_FN_TYPE_1 (BT_FN_OV4SI_INT, BT_OV4SI, BT_INT) diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def index 9046cb08f94..c2f278dc9c3 100644 --- a/gcc/config/s390/s390-builtins.def +++ b/gcc/config/s390/s390-builtins.def @@ -294,7 +294,7 @@ flags: Flags applying to all its variants should be mentioned in the OB_DEF line instead. */ -B_DEF (tbeginc, tbeginc, 0, B_HTM, 0, BT_FN_INT) +B_DEF (tbeginc, tbeginc, 0, B_HTM, 0, BT_FN_VOID) B_DEF (tbegin, tbegin, returns_twice_attr, B_HTM, 0, BT_FN_INT_VOIDPTR) B_DEF (tbegin_nofloat, tbegin_nofloat, returns_twice_attr, B_HTM, 0, BT_FN_INT_VOIDPTR) B_DEF (tbegin_retry, tbegin_retry, returns_twice_attr, B_HTM, 0, BT_FN_INT_VOIDPTR_INT) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 5b3a7cefd3d..3a850342ea7 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -16173,7 +16173,7 @@ s390_output_indirect_thunk_function (unsigned int regno, bool z10_p) Stopping in the thunk: backtrace will point to the thunk target is if it was interrupted by a signal. For a call this means that the call chain will be: caller->callee->thunk */ - if (flag_asynchronous_unwind_tables) + if (flag_asynchronous_unwind_tables && flag_dwarf2_cfi_asm) { fputs ("\t.cfi_signal_frame\n", asm_out_file); fprintf (asm_out_file, "\t.cfi_return_column %d\n", regno); diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 68e3876f51d..f204204b435 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -205,7 +205,7 @@ enum processor_flags #define OPTION_DEFAULT_SPECS \ { "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" }, \ { "arch", "%{!march=*:-march=%(VALUE)}" }, \ - { "tune", "%{!mtune=*:-mtune=%(VALUE)}" } + { "tune", "%{!mtune=*:%{!march=*:-mtune=%(VALUE)}}" } #ifdef __s390__ extern const char *s390_host_detect_local_cpu (int argc, const char **argv); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b28d1570990..af56ddd8432 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -2188,7 +2188,7 @@ sparc_expand_move (machine_mode mode, rtx *operands) } } - /* Fixup TLS cases. */ + /* Fix up TLS cases. */ if (TARGET_HAVE_TLS && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) @@ -2197,15 +2197,20 @@ sparc_expand_move (machine_mode mode, rtx *operands) return false; } - /* Fixup PIC cases. */ + /* Fix up PIC cases. */ if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases. */ - if (GET_CODE (operands[1]) == LABEL_REF - && can_use_mov_pic_label_ref (operands[1])) + if ((GET_CODE (operands[1]) == LABEL_REF + && can_use_mov_pic_label_ref (operands[1])) + || (GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT + && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0)))) { if (mode == SImode) { @@ -2215,7 +2220,6 @@ sparc_expand_move (machine_mode mode, rtx *operands) if (mode == DImode) { - gcc_assert (TARGET_ARCH64); emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); return true; } @@ -4216,10 +4220,11 @@ int pic_address_needs_scratch (rtx x) { /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + && !SMALL_INT (XEXP (XEXP (x, 0), 1))) return 1; return 0; @@ -4667,16 +4672,15 @@ sparc_legitimize_tls_address (rtx addr) static rtx sparc_legitimize_pic_address (rtx orig, rtx reg) { - bool gotdata_op = false; - if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig))) { + bool gotdata_op = false; rtx pic_ref, address; rtx_insn *insn; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4687,8 +4691,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) /* If not during reload, allocate another temp reg here for loading in the address, so that these instructions can be optimized properly. */ - rtx temp_reg = (! can_create_pseudo_p () - ? reg : gen_reg_rtx (Pmode)); + rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg; /* Must put the SYMBOL_REF inside an UNSPEC here so that cse won't get confused into thinking that these two instructions @@ -4704,6 +4707,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) emit_insn (gen_movsi_high_pic (temp_reg, orig)); emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } + address = temp_reg; gotdata_op = true; } @@ -4744,7 +4748,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) return orig; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4853,7 +4857,11 @@ sparc_delegitimize_address (rtx x) && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL) { x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0); - gcc_assert (GET_CODE (x) == LABEL_REF); + gcc_assert (GET_CODE (x) == LABEL_REF + || (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)); } return x; diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 4ddbe56fbf4..55d41ef8dc7 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1758,7 +1758,7 @@ (define_expand "movsi_pic_label_ref" [(set (match_dup 3) (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:SI (match_dup 3) (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1784,7 +1784,7 @@ (define_insn "*movsi_high_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1792,7 +1792,7 @@ (define_insn "*movsi_lo_sum_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") @@ -1896,7 +1896,7 @@ visl") (define_expand "movdi_pic_label_ref" [(set (match_dup 3) (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:DI (match_dup 3) (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1922,7 +1922,7 @@ visl") (define_insn "*movdi_high_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1930,7 +1930,7 @@ visl") (define_insn "*movdi_lo_sum_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "") (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index d5596e25d82..0eba10b742c 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -38,6 +38,7 @@ (UNSPEC_MEMW 11) (UNSPEC_LSETUP_START 12) (UNSPEC_LSETUP_END 13) + (UNSPEC_FRAME_BLOCKAGE 14) (UNSPECV_SET_FP 1) (UNSPECV_ENTRY 2) @@ -1676,6 +1677,32 @@ ;; Miscellaneous instructions. +;; In windowed ABI stack pointer adjustment must happen before any access +;; to the space allocated on stack is allowed, otherwise register spill +;; area may be clobbered. That's what frame blockage is supposed to enforce. + +(define_expand "allocate_stack" + [(set (match_operand 0 "nonimmed_operand") + (minus (reg A1_REG) (match_operand 1 "add_operand"))) + (set (reg A1_REG) + (minus (reg A1_REG) (match_dup 1)))] + "TARGET_WINDOWED_ABI" +{ + if (CONST_INT_P (operands[1])) + { + rtx neg_op0 = GEN_INT (-INTVAL (operands[1])); + emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0)); + } + else + { + emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, + operands[1])); + } + emit_move_insn (operands[0], virtual_stack_dynamic_rtx); + emit_insn (gen_frame_blockage ()); + DONE; +}) + (define_expand "prologue" [(const_int 0)] "" @@ -1767,6 +1794,25 @@ [(set_attr "length" "0") (set_attr "type" "nop")]) +;; Do not schedule instructions accessing memory before this point. + +(define_expand "frame_blockage" + [(set (match_dup 0) + (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] + "" +{ + operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[0]) = 1; + operands[1] = stack_pointer_rtx; +}) + +(define_insn "*frame_blockage" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] + "" + "" + [(set_attr "length" "0")]) + (define_insn "trap" [(trap_if (const_int 1) (const_int 0))] "" |