diff options
Diffstat (limited to 'gnu/egcs/gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gnu/egcs/gcc/config/rs6000/rs6000.md | 142 |
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")]) |