From ab6b44cb2201de72cdd17740fd1ad1a557319be3 Mon Sep 17 00:00:00 2001 From: Matthew Fortune Date: Thu, 19 Jan 2017 16:05:59 +0000 Subject: [PATCH] MIPS: PR target/78176 add -mlxc1-sxc1. gcc/ PR target/78176 * config.gcc (supported_defaults): Add lxc1-sxc1. (with_lxc1_sxc1): Add validation. (all_defaults): Add lxc1-sxc1. * config/mips/mips.opt (mlxc1-sxc1): New option. * gcc/config/mips/mips.h (OPTION_DEFAULT_SPECS): Add a default for mlxc1-sxc1. (TARGET_CPU_CPP_BUILTINS): Add builtin_define for __mips_no_lxc1_sxc1. (ISA_HAS_LXC1_SXC1): Gate with mips_lxc1_sxc1. * gcc/doc/invoke.texi (-mlxc1-sxc1): Document the new option. * doc/install.texi (--with-lxc1-sxc1): Document the new option. gcc/testsuite/ * gcc.target/mips/lxc1-sxc1-1.c: New file. * gcc.target/mips/lxc1-sxc1-2.c: Likewise. * gcc.target/mips/mips.exp (mips_option_groups): Add ghost option HAS_LXC1. (mips_option_groups): Add -m[no-]lxc1-sxc1. (mips-dg-init): Detect default -mno-lxc1-sxc1. (mips-dg-options): Handle HAS_LXC1 arch upgrade/downgrade. From-SVN: r244640 --- gcc/ChangeLog | 15 ++++++ gcc/config.gcc | 19 ++++++- gcc/config/mips/mips.h | 8 ++- gcc/config/mips/mips.opt | 4 ++ gcc/doc/install.texi | 19 +++++++ gcc/doc/invoke.texi | 6 +++ gcc/testsuite/ChangeLog | 11 ++++ gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c | 60 +++++++++++++++++++++ gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c | 60 +++++++++++++++++++++ gcc/testsuite/gcc.target/mips/mips.exp | 12 ++++- 10 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c create mode 100644 gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20b703f1fe7..f933e1ad240 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-01-19 Doug Gilmore + + PR target/78176 + * config.gcc (supported_defaults): Add lxc1-sxc1. + (with_lxc1_sxc1): Add validation. + (all_defaults): Add lxc1-sxc1. + * config/mips/mips.opt (mlxc1-sxc1): New option. + * gcc/config/mips/mips.h (OPTION_DEFAULT_SPECS): Add a default for + mlxc1-sxc1. + (TARGET_CPU_CPP_BUILTINS): Add builtin_define for + __mips_no_lxc1_sxc1. + (ISA_HAS_LXC1_SXC1): Gate with mips_lxc1_sxc1. + * gcc/doc/invoke.texi (-mlxc1-sxc1): Document the new option. + * doc/install.texi (--with-lxc1-sxc1): Document the new option. + 2017-01-19 Richard Biener PR tree-optimization/72488 diff --git a/gcc/config.gcc b/gcc/config.gcc index 90308cd4572..dd8c08cfd93 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3940,7 +3940,7 @@ case "${target}" in ;; mips*-*-*) - supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci" + supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci lxc1-sxc1" case ${with_float} in "" | soft | hard) @@ -4063,6 +4063,21 @@ case "${target}" in exit 1 ;; esac + + case ${with_lxc1_sxc1} in + yes) + with_lxc1_sxc1=lxc1-sxc1 + ;; + no) + with_lxc1_sxc1=no-lxc1-sxc1 + ;; + "") + ;; + *) + echo "Unknown lxc1-sxc1 type used in --with-lxc1-sxc1" 1>&2 + exit 1 + ;; + esac ;; nds32*-*-*) @@ -4496,7 +4511,7 @@ case ${target} in esac t= -all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls" +all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls lxc1-sxc1" for option in $all_defaults do eval "val=\$with_"`echo $option | sed s/-/_/g` diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index fbd7011512e..4205589af45 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -637,6 +637,8 @@ struct mips_cpu_info { \ if (TARGET_CACHE_BUILTIN) \ builtin_define ("__GCC_HAVE_BUILTIN_MIPS_CACHE"); \ + if (!ISA_HAS_LXC1_SXC1) \ + builtin_define ("__mips_no_lxc1_sxc1"); \ } \ while (0) @@ -866,7 +868,8 @@ struct mips_cpu_info { {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \ {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \ {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \ - {"synci", "%{!msynci:%{!mno-synci:-m%(VALUE)}}" } + {"synci", "%{!msynci:%{!mno-synci:-m%(VALUE)}}" }, \ + {"lxc1-sxc1", "%{!mlxc1-sxc1:%{!mno-lxc1-sxc1:-m%(VALUE)}}" } \ /* A spec that infers the: -mnan=2008 setting from a -mips argument, @@ -1036,7 +1039,8 @@ struct mips_cpu_info { /* ISA has floating-point indexed load and store instructions (LWXC1, LDXC1, SWXC1 and SDXC1). */ -#define ISA_HAS_LXC1_SXC1 ISA_HAS_FP4 +#define ISA_HAS_LXC1_SXC1 (ISA_HAS_FP4 \ + && mips_lxc1_sxc1) /* ISA has paired-single instructions. */ #define ISA_HAS_PAIRED_SINGLE ((ISA_MIPS64 \ diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 2559649ffc5..75ebafdba26 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -388,6 +388,10 @@ mlra Target Report Var(mips_lra_flag) Init(1) Save Use LRA instead of reload. +mlxc1-sxc1 +Target Report Var(mips_lxc1_sxc1) Init(1) +Use lwxc1/swxc1/ldxc1/sdxc1 instructions where applicable. + mtune= Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value) -mtune=PROCESSOR Optimize the output for PROCESSOR. diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 4793ef85b0d..712b82a1442 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1375,6 +1375,25 @@ On MIPS targets, make @option{-msynci} the default when no On MIPS targets, make @option{-mno-synci} the default when no @option{-msynci} option is passed. This is the default. +@item --with-lxc1-sxc1 +On MIPS targets, make @option{-mlxc1-sxc1} the default when no +@option{-mno-lxc1-sxc1} option is passed. This is the default. + +@item --without-lxc1-sxc1 +On MIPS targets, make @option{-mno-lxc1-sxc1} the default when no +@option{-mlxc1-sxc1} option is passed. The indexed load/store +instructions are not directly a problem but can lead to unexpected +behaviour when deployed in an application intended for a 32-bit address +space but run on a 64-bit processor. The issue is seen because all +known MIPS 64-bit Linux kernels execute o32 and n32 applications +with 64-bit addressing enabled which affects the overflow behaviour +of the indexed addressing mode. GCC will assume that ordinary +32-bit arithmetic overflow behaviour is the same whether performed +as an @code{addu} instruction or as part of the address calculation +in @code{lwxc1} type instructions. This assumption holds true in a +pure 32-bit environment and can hold true in a 64-bit environment if +the address space is accurately set to be 32-bit for o32 and n32. + @item --with-mips-plt On MIPS targets, make use of copy relocations and PLTs. These features are extensions to the traditional diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 82cb1b5751f..a13a450b1ee 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -19932,6 +19932,12 @@ it is unused. This optimization is off by default at all optimization levels. +@item -mlxc1-sxc1 +@itemx -mno-lxc1-sxc1 +@opindex mlxc1-sxc1 +When applicable, enable (disable) the generation of @code{lwxc1}, +@code{swxc1}, @code{ldxc1}, @code{sdxc1} instructions. Enabled by default. + @end table @node MMIX Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e0e0bd5432b..0ba8f93b6a8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2017-01-19 Matthew Fortune + + PR target/78176 + * gcc.target/mips/lxc1-sxc1-1.c: New file. + * gcc.target/mips/lxc1-sxc1-2.c: Likewise. + * gcc.target/mips/mips.exp (mips_option_groups): Add ghost option + HAS_LXC1. + (mips_option_groups): Add -m[no-]lxc1-sxc1. + (mips-dg-init): Detect default -mno-lxc1-sxc1. + (mips-dg-options): Handle HAS_LXC1 arch upgrade/downgrade. + 2017-01-19 Andre Vehreschild PR fortran/70696 diff --git a/gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c new file mode 100644 index 00000000000..f455eb8776a --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c @@ -0,0 +1,60 @@ +/* { dg-options "(HAS_LXC1) -mno-lxc1-sxc1" } */ +/* { dg-final { scan-assembler-not "\tldxc1\t" } } */ +/* { dg-final { scan-assembler-not "\tsdxc1\t" } } */ + +#ifndef __mips_no_lxc1_sxc1 +#error missing definition of __mips_no_lxc1_sxc1 +#endif + +double ldexp(double x, int exp); + +typedef struct +{ + double** rows; +} d_mat_struct; + +typedef d_mat_struct d_mat_t[1]; + +#define d_mat_entry(mat,i,j) (*((mat)->rows[i] + (j))) + +double __attribute__((noinline)) +ldxc1_test (int kappa, int zeros, double ctt, int* expo, d_mat_t r, double* s) +{ + int kappa2 = kappa; + double tmp = 0.0; + + do + { + kappa--; + if (kappa > zeros + 1) + { + tmp = d_mat_entry(r, kappa - 1, kappa - 1) * ctt; + tmp = ldexp(tmp, (expo[kappa - 1] - expo[kappa2])); + } + } + while ((kappa >= zeros + 2) && (s[kappa - 1] <= tmp)); + + return tmp; +} + +#define SIZE 20 + +int main(void) +{ + int kappa = SIZE - 1; + int zeros = 1; + double ctt = 2; + + int expo[SIZE] = {0}; + double s[SIZE] = {0}; + double rows_data[SIZE][SIZE] = {0}; + double* rows[SIZE]; + + for (int i = 0; i < SIZE; i++) + rows[i] = rows_data[i]; + + d_mat_t r = { rows }; + + ldxc1_test(kappa, zeros, ctt, expo, r, s); + return 0; +} diff --git a/gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c new file mode 100644 index 00000000000..dfbf6b5c170 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c @@ -0,0 +1,60 @@ +/* { dg-options "(HAS_LXC1) -mlxc1-sxc1" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler "\tldxc1\t" } } */ + +#ifdef __mips_no_lxc1_sxc1 +#error unexpected definition of __mips_no_lxc1_sxc1 +#endif + +double ldexp(double x, int exp); + +typedef struct +{ + double** rows; +} d_mat_struct; + +typedef d_mat_struct d_mat_t[1]; + +#define d_mat_entry(mat,i,j) (*((mat)->rows[i] + (j))) + +double __attribute__((noinline)) +ldxc1_test (int kappa, int zeros, double ctt, int* expo, d_mat_t r, double* s) +{ + int kappa2 = kappa; + double tmp = 0.0; + + do + { + kappa--; + if (kappa > zeros + 1) + { + tmp = d_mat_entry(r, kappa - 1, kappa - 1) * ctt; + tmp = ldexp(tmp, (expo[kappa - 1] - expo[kappa2])); + } + } + while ((kappa >= zeros + 2) && (s[kappa - 1] <= tmp)); + + return tmp; +} + +#define SIZE 20 + +int main(void) +{ + int kappa = SIZE - 1; + int zeros = 1; + double ctt = 2; + + int expo[SIZE] = {0}; + double s[SIZE] = {0}; + double rows_data[SIZE][SIZE] = {0}; + double* rows[SIZE]; + + for (int i = 0; i < SIZE; i++) + rows[i] = rows_data[i]; + + d_mat_t r = { rows }; + + ldxc1_test(kappa, zeros, ctt, expo, r, s); + return 0; +} diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index b2f4e1824cc..5296a15f616 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -258,6 +258,7 @@ set mips_option_groups { madd "HAS_MADD" maddps "HAS_MADDPS" lsa "(|!)HAS_LSA" + lxc1 "HAS_LXC1" section_start "-Wl,--section-start=.*" frame-header "-mframe-header-opt|-mno-frame-header-opt" stack-protector "-fstack-protector" @@ -282,6 +283,7 @@ foreach option { gpopt local-sdata long-calls + lxc1-sxc1 paired-single plt shared @@ -855,6 +857,12 @@ proc mips-dg-init {} { "-mno-smartmips", #endif + #ifdef __mips_no_lxc1_sxc1 + "-mno-lxc1-sxc1", + #else + "-mlxc1-sxc1" + #endif + #ifdef __mips_synci "-msynci", #else @@ -1173,7 +1181,8 @@ proc mips-dg-options { args } { # # } elseif { $isa < 4 - && [mips_have_test_option_p options "HAS_MOVN"] } { + && ([mips_have_test_option_p options "HAS_LXC1"] + || [mips_have_test_option_p options "HAS_MOVN"]) } { mips_make_test_option options "-mips4" # We need MIPS III or higher for: # @@ -1214,6 +1223,7 @@ proc mips-dg-options { args } { || [mips_have_test_option_p options "-mfp32"] || [mips_have_test_option_p options "-mfix-r10000"] || [mips_have_test_option_p options "NOT_HAS_DMUL"] + || [mips_have_test_option_p options "HAS_LXC1"] || [mips_have_test_option_p options "HAS_MOVN"] || [mips_have_test_option_p options "HAS_MADD"] || [mips_have_test_option_p options "-mpaired-single"] -- 2.30.2