diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2015-12-15 10:44:46 +0100 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2015-12-15 14:41:45 +0100 |
commit | 966a7fddb78c4fad3c2efb46c969308686557ec0 (patch) | |
tree | ed597a56f1ed08195ec07841c5608cf4d2945a47 /gcc/config/rs6000 | |
parent | 7f7da9776a2100eb6e64c142732c89ecc719d45d (diff) |
Merge branches/gcc-5-branch rev 231642.
Change-Id: I58832e31b4e58588e1d0800c3fc09a01f91b6320
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/freebsd64.h | 15 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 24 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 175 |
3 files changed, 132 insertions, 82 deletions
diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h index 9fc929dff56..351ae3c37af 100644 --- a/gcc/config/rs6000/freebsd64.h +++ b/gcc/config/rs6000/freebsd64.h @@ -65,6 +65,13 @@ extern int dot_symbols; #define INVALID_64BIT "-m%s not supported in this configuration" #define INVALID_32BIT INVALID_64BIT +/* Use LINUX64 instead of FREEBSD64 for compat with e.g. sysv4le.h */ +#ifdef LINUX64_DEFAULT_ABI_ELFv2 +#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1) +#else +#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2) +#endif + #undef SUBSUBTARGET_OVERRIDE_OPTIONS #define SUBSUBTARGET_OVERRIDE_OPTIONS \ do \ @@ -84,6 +91,12 @@ extern int dot_symbols; rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ error (INVALID_64BIT, "relocatable"); \ } \ + if (ELFv2_ABI_CHECK) \ + { \ + rs6000_current_abi = ABI_ELFv2; \ + if (dot_symbols) \ + error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \ + } \ if (rs6000_isa_flags & OPTION_MASK_EABI) \ { \ rs6000_isa_flags &= ~OPTION_MASK_EABI; \ @@ -304,7 +317,7 @@ extern int dot_symbols; /* rs6000.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ #undef WCHAR_TYPE -#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int") + #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE 32 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d06e9a8d48e..e17c36ada56 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -30263,13 +30263,15 @@ rs6000_declare_alias (struct symtab_node *n, void *d) if (dollar_inside) { if (data->function_descriptor) fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name); - else - fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); + fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); } if (data->function_descriptor) - fputs ("\t.globl .", data->file); - else - fputs ("\t.globl ", data->file); + { + fputs ("\t.globl .", data->file); + RS6000_OUTPUT_BASENAME (data->file, buffer); + putc ('\n', data->file); + } + fputs ("\t.globl ", data->file); RS6000_OUTPUT_BASENAME (data->file, buffer); putc ('\n', data->file); } @@ -30283,14 +30285,16 @@ rs6000_declare_alias (struct symtab_node *n, void *d) if (dollar_inside) { if (data->function_descriptor) - fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); - else fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name); + fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); } if (data->function_descriptor) - fputs ("\t.lglobl .", data->file); - else - fputs ("\t.lglobl ", data->file); + { + fputs ("\t.lglobl .", data->file); + RS6000_OUTPUT_BASENAME (data->file, buffer); + putc ('\n', data->file); + } + fputs ("\t.lglobl ", data->file); RS6000_OUTPUT_BASENAME (data->file, buffer); putc ('\n', data->file); } diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 0178bf45b00..0e5883c7fc8 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -77,6 +77,7 @@ UNSPEC_FRIN UNSPEC_FRIP UNSPEC_FRIZ + UNSPEC_XSRDPI UNSPEC_LD_MPIC ; load_macho_picbase UNSPEC_RELD_MPIC ; re-load_macho_picbase UNSPEC_MPIC_CORRECT ; macho_correct_pic @@ -438,8 +439,16 @@ ; SF/DF constraint for arithmetic on traditional floating point registers (define_mode_attr Ff [(SF "f") (DF "d")]) -; SF/DF constraint for arithmetic on VSX registers -(define_mode_attr Fv [(SF "wy") (DF "ws")]) +; SF/DF constraint for arithmetic on VSX registers using instructions added in +; ISA 2.06 (power7). This includes instructions that normally target DF mode, +; but are used on SFmode, since internally SFmode values are kept in the DFmode +; format. +(define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")]) + +; SF/DF constraint for arithmetic on VSX registers. This is intended to be +; used for DFmode instructions added in ISA 2.06 (power7) and SFmode +; instructions added in ISA 2.07 (power8) +(define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) ; SF/DF constraint for arithmetic on altivec registers (define_mode_attr Fa [(SF "wu") (DF "wv")]) @@ -5099,9 +5108,9 @@ "") (define_insn "*add<mode>3_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR" "@ fadd<Ftrad> %0,%1,%2 @@ -5117,9 +5126,9 @@ "") (define_insn "*sub<mode>3_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR" "@ fsub<Ftrad> %0,%1,%2 @@ -5135,9 +5144,9 @@ "") (define_insn "*mul<mode>3_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR" "@ fmul<Ftrad> %0,%1,%2 @@ -5153,9 +5162,9 @@ "") (define_insn "*div<mode>3_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU" "@ fdiv<Ftrad> %0,%1,%2 @@ -5164,8 +5173,8 @@ (set_attr "fp_type" "fp_div_<Fs>")]) (define_insn "sqrt<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" "@ @@ -5176,8 +5185,8 @@ ;; Floating point reciprocal approximation (define_insn "fre<Fs>" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] UNSPEC_FRES))] "TARGET_<FFRE>" "@ @@ -5186,8 +5195,8 @@ [(set_attr "type" "fp")]) (define_insn "*rsqrt<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] UNSPEC_RSQRT))] "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" "@ @@ -5198,8 +5207,8 @@ ;; Floating point comparisons (define_insn "*cmp<mode>_fpr" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") - (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))] + (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] "TARGET_<MODE>_FPR" "@ fcmpu %0,%1,%2 @@ -6257,6 +6266,27 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_<Fs>")]) +(define_insn "*xsrdpi<mode>2" + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] + UNSPEC_XSRDPI))] + "TARGET_<MODE>_FPR && TARGET_VSX" + "xsrdpi %x0,%x1" + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_<Fs>")]) + +(define_expand "lround<mode>di2" + [(set (match_dup 2) + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] + UNSPEC_XSRDPI)) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (unspec:DI [(match_dup 2)] + UNSPEC_FCTID))] + "TARGET_<MODE>_FPR && TARGET_VSX" +{ + operands[2] = gen_reg_rtx (<MODE>mode); +}) + ; An UNSPEC is used so we don't have to support SImode in FP registers. (define_insn "stfiwx" [(set (match_operand:SI 0 "memory_operand" "=Z") @@ -8337,8 +8367,8 @@ [(set_attr "length" "20,20,16")]) (define_expand "extenddftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" "")))] + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) @@ -8346,52 +8376,55 @@ { if (TARGET_E500_DOUBLE) emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); + else if (TARGET_VSX) + emit_insn (gen_extenddftf2_vsx (operands[0], operands[1])); else - emit_insn (gen_extenddftf2_fprs (operands[0], operands[1])); + { + rtx zero = gen_reg_rtx (DFmode); + rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); + emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero)); + } DONE; }) -(define_expand "extenddftf2_fprs" - [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" ""))) - (use (match_dup 2))])] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" +;; Allow memory operands for the source to be created by the combiner. +(define_insn_and_split "extenddftf2_fprs" + [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d,&d") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) + (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] + "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (match_dup 2))] { - /* VSX can create 0.0 directly, otherwise let rs6000_emit_move create - the proper constant. */ - if (TARGET_VSX) - operands[2] = CONST0_RTX (DFmode); - else - { - operands[2] = gen_reg_rtx (DFmode); - rs6000_emit_move (operands[2], CONST0_RTX (DFmode), DFmode); - } + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); + + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); + operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); }) -(define_insn_and_split "*extenddftf2_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,ws,d,&d") - (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,md"))) - (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,j,m,d"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" +(define_insn_and_split "extenddftf2_vsx" + [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "ws,m")))] + "TARGET_LONG_DOUBLE_128 && TARGET_VSX && !TARGET_IEEEQUAD" "#" "&& reload_completed" - [(pc)] + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 3) (match_dup 4))] { const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); - emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word), - operands[1]); - emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word), - operands[2]); - DONE; + + operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); + operands[4] = CONST0_RTX (DFmode); }) (define_expand "extendsftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") + [(set (match_operand:TF 0 "gpc_reg_operand" "") (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT @@ -13577,11 +13610,11 @@ "") (define_insn "*fma<mode>4_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") (fma:SFDF - (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0") - (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))] + (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") + (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] "TARGET_<MODE>_FPR" "@ fmadd<Ftrad> %0,%1,%2,%3 @@ -13601,11 +13634,11 @@ "") (define_insn "*fms<mode>4_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") (fma:SFDF - (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0") - (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))] + (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") + (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] "TARGET_<MODE>_FPR" "@ fmsub<Ftrad> %0,%1,%2,%3 @@ -13648,12 +13681,12 @@ "") (define_insn "*nfma<mode>4_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") (neg:SFDF (fma:SFDF - (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0") - (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))] + (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") + (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] "TARGET_<MODE>_FPR" "@ fnmadd<Ftrad> %0,%1,%2,%3 @@ -13674,13 +13707,13 @@ "") (define_insn "*nfmssf4_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") (neg:SFDF (fma:SFDF - (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>") - (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0") + (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") + (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") (neg:SFDF - (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))] + (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] "TARGET_<MODE>_FPR" "@ fnmsub<Ftrad> %0,%1,%2,%3 |