aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md248
1 files changed, 159 insertions, 89 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index b61b77ec431..e9ae2963da5 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3615,7 +3615,7 @@
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
-
+
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
(compare:CC
@@ -3635,7 +3635,7 @@
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-
+
;; Rotate and shift insns, in all their variants. These support shifts,
;; field inserts and extracts, and various combinations thereof.
(define_expand "insv"
@@ -8349,8 +8349,8 @@
"")
(define_insn "*movcc_internal1"
- [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
- (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
+ [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,cl,q,r,r,m")
+ (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,r,r,h,m,r"))]
"register_operand (operands[0], CCmode)
|| register_operand (operands[1], CCmode)"
"@
@@ -8360,10 +8360,13 @@
mfcr %0
mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
mr %0,%1
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
- [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,load,store")
- (set_attr "length" "*,*,12,*,8,*,*,*")])
+ [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,*,mtjmpr,*,load,store")
+ (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")])
;; For floating-point, we normally deal with the floating-point registers
;; unless -msoft-float is used. The sole exception is that parameter passing
@@ -8402,8 +8405,8 @@
}")
(define_insn "*movsf_hardfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r")
- (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!r,!r")
+ (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,G,Fn"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_HARD_FLOAT && TARGET_FPRS)"
@@ -8414,19 +8417,25 @@
fmr %0,%1
lfs%U1%X1 %0,%1
stfs%U0%X0 %1,%0
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
#
#"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,8")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
- (match_operand:SF 1 "input_operand" "r,m,r,I,L,R,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r")
+ (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
"@
mr %0,%1
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
@@ -8434,8 +8443,8 @@
{cal|la} %0,%a1
#
#"
- [(set_attr "type" "*,load,store,*,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,8")])
+ [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
(define_expand "movdf"
@@ -8518,10 +8527,10 @@
operands[2] = gen_lowpart (DImode, operands[0]);
/* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
#if HOST_BITS_PER_WIDE_INT >= 64
- val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 |
- ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
+ val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
- operands[3] = immed_double_const (val, -(val < 0), DImode);
+ operands[3] = gen_int_mode (val, DImode);
#else
operands[3] = immed_double_const (l[1 - endian], l[endian], DImode);
#endif
@@ -8534,8 +8543,8 @@
;; The "??" is a kludge until we can figure out a more reasonable way
;; of handling these non-offsettable values.
(define_insn "*movdf_hardfloat32"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
@@ -8612,19 +8621,19 @@
return \"\";
}
case 3:
+ return \"fmr %0,%1\";
case 4:
+ return \"lfd%U1%X1 %0,%1\";
case 5:
- return \"#\";
+ return \"stfd%U0%X0 %1,%0\";
case 6:
- return \"fmr %0,%1\";
case 7:
- return \"lfd%U1%X1 %0,%1\";
case 8:
- return \"stfd%U0%X0 %1,%0\";
+ return \"#\";
}
}"
- [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
- (set_attr "length" "8,16,16,8,12,16,*,*,*")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*")
+ (set_attr "length" "8,16,16,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
@@ -8668,8 +8677,8 @@
(set_attr "length" "8,8,8,8,12,16")])
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
@@ -8677,30 +8686,34 @@
mr %0,%1
ld%U1%X1 %0,%1
std%U0%X0 %1,%0
- #
- #
- #
fmr %0,%1
lfd%U1%X1 %0,%1
- stfd%U0%X0 %1,%0"
- [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
- (set_attr "length" "4,4,4,8,12,16,4,4,4")])
+ stfd%U0%X0 %1,%0
+ mt%0 %1
+ mf%1 %0
+ #
+ #
+ #"
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r")
+ (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))]
"TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
mr %0,%1
+ mt%0 %1
+ mf%1 %0
ld%U1%X1 %0,%1
std%U0%X0 %1,%0
#
#
#"
- [(set_attr "type" "*,load,store,*,*,*")
- (set_attr "length" "*,*,*,8,12,16")])
+ [(set_attr "type" "*,*,*,load,store,*,*,*")
+ (set_attr "length" "4,4,4,4,4,8,12,16")])
(define_expand "movtf"
[(set (match_operand:TF 0 "general_operand" "")
@@ -8731,9 +8744,9 @@
else
return \"fmr %0,%1\;fmr %L0,%L1\";
case 1:
- return \"lfd %0,%1\;lfd %L0,%L1\";
+ return \"lfd %0,%1\;lfd %L0,%Y1\";
case 2:
- return \"stfd %1,%0\;stfd %L1,%L0\";
+ return \"stfd %1,%0\;stfd %L1,%Y0\";
case 3:
case 4:
case 5:
@@ -8745,45 +8758,100 @@
(define_split
[(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "const_double_operand" ""))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- [(set (match_dup 3) (match_dup 1))
- (set (match_dup 0)
- (float_extend:TF (match_dup 3)))]
+ (match_operand:TF 1 "easy_fp_constant" ""))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 6))
+ (set (match_dup 3) (match_dup 7))
+ (set (match_dup 4) (match_dup 8))
+ (set (match_dup 5) (match_dup 9))]
"
{
- operands[2] = operand_subword (operands[1], 0, 0, DFmode);
- operands[3] = gen_reg_rtx (DFmode);
+ long l[4];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+ operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+ operands[4] = operand_subword (operands[0], 2, 0, TFmode);
+ operands[5] = operand_subword (operands[0], 3, 0, TFmode);
+ operands[6] = gen_int_mode (l[0], SImode);
+ operands[7] = gen_int_mode (l[1], SImode);
+ operands[8] = gen_int_mode (l[2], SImode);
+ operands[9] = gen_int_mode (l[3], SImode);
}")
-(define_insn_and_split "extenddftf2"
+(define_split
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
+ (match_operand:TF 1 "easy_fp_constant" ""))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ long l[4];
+ REAL_VALUE_TYPE rv;
+ HOST_WIDE_INT val;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = gen_lowpart (DImode, operands[0]);
+ operands[3] = gen_highpart (DImode, operands[0]);
+#if HOST_BITS_PER_WIDE_INT >= 64
+ val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[1]));
+ operands[4] = gen_int_mode (val, DImode);
+
+ val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[3]));
+ operands[5] = gen_int_mode (val, DImode);
+#else
+ operands[4] = immed_double_const (l[1], l[0], DImode);
+ operands[5] = immed_double_const (l[3], l[2], DImode);
+#endif
+}")
+
+(define_insn "extenddftf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
- "#"
- ""
- [(set (match_dup 2) (match_dup 3))]
- "
+ "*
{
- operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1));
- operands[3] = CONST0_RTX (DFmode);
-}")
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"fsub %L0,%L0,%L0\";
+ else
+ return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
+}"
+ [(set_attr "type" "fp")])
-(define_insn_and_split "extendsftf2"
+(define_insn "extendsftf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
- "#"
- ""
- [(set (match_dup 2) (match_dup 3))]
- "
+ "*
{
- operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1));
- operands[3] = CONST0_RTX (SFmode);
-}")
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"fsub %L0,%L0,%L0\";
+ else
+ return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
+}"
+ [(set_attr "type" "fp")])
(define_insn "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
@@ -8817,8 +8885,8 @@
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))
- (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float:DF (match_dup 1)))
+ (set (match_dup 0)
(float_extend:TF (match_dup 2)))]
"")
@@ -8831,34 +8899,36 @@
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
- (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float:DF (match_dup 1)))
+ (set (match_dup 0)
(float_extend:TF (match_dup 2)))]
"")
(define_insn_and_split "fix_trunctfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))
+ (clobber (match_scratch:DF 2 "=f"))]
"DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
- (set (match_operand:DI 0 "gpc_reg_operand" "")
- (fix:SI (match_dup 2)))]
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
+ (fix:DI (match_dup 2)))]
"")
(define_insn_and_split "fix_trunctfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
+ (clobber (match_scratch:DF 2 "=f"))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
(fix:SI (match_dup 2)))]
"")
@@ -8962,7 +9032,7 @@
}
}"
[(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
- (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
+ (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -9177,7 +9247,7 @@
}
}"
[(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "*,16,16,*,16")])
+ (set_attr "length" "4,16,16,4,16")])
(define_insn "*movti_string"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
@@ -10219,7 +10289,7 @@
(define_insn "load_toc_v4_PIC_2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+ (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(minus:SI (match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")))))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
@@ -14089,7 +14159,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal2"
[(set (pc)
@@ -14113,7 +14183,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal1"
[(set (pc)
@@ -14137,7 +14207,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal2"
[(set (pc)
@@ -14161,7 +14231,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Similar, but we can use GE since we have a REG_NONNEG.
@@ -14187,7 +14257,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal4"
[(set (pc)
@@ -14211,7 +14281,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal3"
[(set (pc)
@@ -14235,7 +14305,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal4"
[(set (pc)
@@ -14259,7 +14329,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Similar but use EQ
@@ -14285,7 +14355,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal6"
[(set (pc)
@@ -14309,7 +14379,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal5"
[(set (pc)
@@ -14333,7 +14403,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal6"
[(set (pc)
@@ -14357,7 +14427,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Now the splitters if we could not allocate the CTR register