summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-12-04 13:22:31 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-12-04 13:22:31 +0000
commit7b48bf2011b4020c4a5a2d5d4149b03983f72cc2 (patch)
treeb07a064ee6bddbe6ddf73a98a9c131b5ab6a0f5f /gcc/config/rs6000/rs6000.md
parent8cd167a5ad8baf4988e07fcbc9c9cc338c02d3d1 (diff)
downloadgcc-tarball-7b48bf2011b4020c4a5a2d5d4149b03983f72cc2.tar.gz
gcc-5.3.0gcc-5.3.0
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md175
1 files changed, 104 insertions, 71 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0178bf45b0..0e5883c7fc 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