summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/egcs/gcc/config/rs6000/rs6000.md')
-rw-r--r--gnu/egcs/gcc/config/rs6000/rs6000.md142
1 files changed, 102 insertions, 40 deletions
diff --git a/gnu/egcs/gcc/config/rs6000/rs6000.md b/gnu/egcs/gcc/config/rs6000/rs6000.md
index 9b3c4306f77..0211728fa19 100644
--- a/gnu/egcs/gcc/config/rs6000/rs6000.md
+++ b/gnu/egcs/gcc/config/rs6000/rs6000.md
@@ -3042,16 +3042,14 @@
"TARGET_POWER"
"@
sle %0,%1,%2
- {sli|slwi} %0,%1,%h2"
- [(set_attr "length" "8")])
+ {sli|slwi} %0,%1,%h2")
(define_insn "ashlsi3_no_power"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_cint_operand" "ri")))]
"! TARGET_POWER"
- "{sl|slw}%I2 %0,%1,%h2"
- [(set_attr "length" "8")])
+ "{sl|slw}%I2 %0,%1,%h2")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
@@ -5494,12 +5492,12 @@
(define_expand "iordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "reg_or_cint_operand" "")))]
+ (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
"TARGET_POWERPC64"
"
{
if (GET_CODE (operands[2]) == CONST_INT
- && ! logical_operand (operands[2], DImode))
+ && ! logical_u_operand (operands[2], DImode))
{
HOST_WIDE_INT value = INTVAL (operands[2]);
rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
@@ -5510,12 +5508,26 @@
emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
+ else if (GET_CODE (operands[2]) == CONST_DOUBLE
+ && ! logical_u_operand (operands[2], DImode))
+ {
+ HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+ rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+ ? operands[0] : gen_reg_rtx (DImode));
+
+ emit_insn (gen_iordi3 (tmp, operands[1],
+ immed_double_const (value
+ & (~ (HOST_WIDE_INT) 0xffff),
+ 0, DImode)));
+ emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+ DONE;
+ }
}")
(define_insn "*iordi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
- (match_operand:DI 2 "logical_operand" "r,K,J")))]
+ (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
"TARGET_POWERPC64"
"@
or %0,%1,%2
@@ -5549,25 +5561,36 @@
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "non_logical_cint_operand" "")))]
+ (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
"TARGET_POWERPC64"
[(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
"
{
- operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
- operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+ if (GET_CODE (operands[2]) == CONST_DOUBLE)
+ {
+ HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+ operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+ 0, DImode);
+ operands[4] = GEN_INT (value & 0xffff);
+ }
+ else
+ {
+ operands[3] = GEN_INT (INTVAL (operands[2])
+ & (~ (HOST_WIDE_INT) 0xffff));
+ operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+ }
}")
(define_expand "xordi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "reg_or_cint_operand" "")))]
+ (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
"TARGET_POWERPC64"
"
{
if (GET_CODE (operands[2]) == CONST_INT
- && ! logical_operand (operands[2], DImode))
+ && ! logical_u_operand (operands[2], DImode))
{
HOST_WIDE_INT value = INTVAL (operands[2]);
rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
@@ -5578,12 +5601,26 @@
emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
DONE;
}
+ else if (GET_CODE (operands[2]) == CONST_DOUBLE
+ && ! logical_u_operand (operands[2], DImode))
+ {
+ HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+ rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+ ? operands[0] : gen_reg_rtx (DImode));
+
+ emit_insn (gen_xordi3 (tmp, operands[1],
+ immed_double_const (value
+ & (~ (HOST_WIDE_INT) 0xffff),
+ 0, DImode)));
+ emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+ DONE;
+ }
}")
(define_insn "*xordi3_internal1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
- (match_operand:DI 2 "logical_operand" "r,K,J")))]
+ (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
"TARGET_POWERPC64"
"@
xor %0,%1,%2
@@ -5617,14 +5654,25 @@
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:DI 2 "non_logical_cint_operand" "")))]
+ (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
"TARGET_POWERPC64"
[(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
"
{
- operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
- operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+ if (GET_CODE (operands[2]) == CONST_DOUBLE)
+ {
+ HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+ operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+ 0, DImode);
+ operands[4] = GEN_INT (value & 0xffff);
+ }
+ else
+ {
+ operands[3] = GEN_INT (INTVAL (operands[2])
+ & (~ (HOST_WIDE_INT) 0xffff));
+ operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+ }
}")
(define_insn "*eqvdi3_internal1"
@@ -6620,13 +6668,14 @@
(set (match_dup 3) (match_dup 1))]
"
{
+ HOST_WIDE_INT value = INTVAL (operands[1]);
operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0);
operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0);
#if HOST_BITS_PER_WIDE_INT == 32
- operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
+ operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
#else
- operands[4] = GEN_INT ((HOST_WIDE_INT) INTVAL (operands[1]) >> 32);
- operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffffffff);
+ operands[4] = GEN_INT (value >> 32);
+ operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
#endif
}")
@@ -6763,7 +6812,8 @@
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
- "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
+ "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
+ && num_insns_constant (operands[1], DImode) > 1"
[(set (match_dup 0)
(match_dup 2))
(set (match_dup 0)
@@ -6774,29 +6824,40 @@
(match_dup 3)))]
"
{
- HOST_WIDE_INT low;
- HOST_WIDE_INT high;
-
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
- low = CONST_DOUBLE_LOW (operands[1]);
- high = CONST_DOUBLE_HIGH (operands[1]);
+ operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
+ operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]),
+ 0, DImode);
}
else
-#if HOST_BITS_PER_WIDE_INT == 32
- {
- low = INTVAL (operands[1]);
- high = (low < 0) ? ~0 : 0;
- }
-#else
{
- low = INTVAL (operands[1]) & 0xffffffff;
- high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
+ HOST_WIDE_INT value = INTVAL (operands[1]);
+ operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
+ operands[3] = immed_double_const (value, 0, DImode);
}
-#endif
+}")
- operands[2] = GEN_INT (high);
- operands[3] = GEN_INT (low);
+(define_split
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (match_operand:DI 1 "const_int_operand" ""))]
+ "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
+ && num_insns_constant (operands[1], DImode) > 1"
+ [(set (match_dup 0)
+ (match_dup 2))
+ (set (match_dup 0)
+ (ashift:DI (match_dup 0)
+ (const_int 32)))
+ (set (match_dup 0)
+ (ior:DI (match_dup 0)
+ (match_dup 3)))]
+ "
+{
+#if HOST_BITS_PER_WIDE_INT != 32
+ HOST_WIDE_INT value = INTVAL (operands[1]);
+ operands[2] = GEN_INT (value >> 32);
+ operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
+#endif
}")
(define_insn ""
@@ -7804,7 +7865,8 @@
rs6000_output_load_toc_table (asm_out_file, 30);
return \"\";
}"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load")
+ (set_attr "length" "24")])
;; A function pointer under AIX is a pointer to a data area whose first word
;; contains the actual address of the function, whose second word contains a
@@ -8784,7 +8846,7 @@
(define_insn ""
[(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
+ (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
""
"{cmpl%I2|cmplw%I2} %0,%1,%W2"
[(set_attr "type" "compare")])
@@ -8792,7 +8854,7 @@
(define_insn ""
[(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
(compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
- (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
+ (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
""
"cmpld%I2 %0,%1,%W2"
[(set_attr "type" "compare")])
@@ -9161,7 +9223,7 @@
(lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
(const_int 31)))
(clobber (match_scratch:SI 2 "=&r"))]
- "! TARGET_POWER"
+ "! TARGET_POWER && ! TARGET_POWERPC64"
"{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
[(set_attr "length" "8")])