diff options
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/constraints.md | 16 | ||||
-rw-r--r-- | gcc/config/rs6000/dfp.md | 235 | ||||
-rw-r--r-- | gcc/config/rs6000/power4.md | 154 | ||||
-rw-r--r-- | gcc/config/rs6000/power5.md | 83 | ||||
-rw-r--r-- | gcc/config/rs6000/ppc-asm.h | 28 | ||||
-rw-r--r-- | gcc/config/rs6000/ppu_intrinsics.h | 42 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 220 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 38 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 580 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.opt | 12 | ||||
-rw-r--r-- | gcc/config/rs6000/t-rs6000 | 20 | ||||
-rw-r--r-- | gcc/config/rs6000/vector.md | 2 |
13 files changed, 779 insertions, 660 deletions
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index 17c2350cfba..7b99094d738 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -1,5 +1,5 @@ ;; Constraint definitions for RS6000 -;; Copyright (C) 2006, 2007 Free Software Foundation, Inc. +;; Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; @@ -135,8 +135,17 @@ ;; Memory constraints +(define_memory_constraint "es" + "A ``stable'' memory operand; that is, one which does not include any +automodification of the base register. Unlike @samp{m}, this constraint +can be used in @code{asm} statements that might access the operand +several times, or that might not access it at all." + (and (match_code "mem") + (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC"))) + (define_memory_constraint "Q" - "Memory operand that is just an offset from a reg" + "Memory operand that is an offset from a register (it is usually better +to use @samp{m} or @samp{es} in @code{asm} statements)" (and (match_code "mem") (match_test "GET_CODE (XEXP (op, 0)) == REG"))) @@ -145,7 +154,8 @@ (match_operand 0 "word_offset_memref_operand")) (define_memory_constraint "Z" - "Indexed or indirect memory operand" + "Memory operand that is an indexed or indirect from a register (it is +usually better to use @samp{m} or @samp{es} in @code{asm} statements)" (match_operand 0 "indexed_or_indirect_operand")) ;; Address constraints diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md index 377023b0491..5ffe7fcffc7 100644 --- a/gcc/config/rs6000/dfp.md +++ b/gcc/config/rs6000/dfp.md @@ -1,5 +1,5 @@ ;; Decimal Floating Point (DFP) patterns. -;; Copyright (C) 2007, 2008 +;; Copyright (C) 2007, 2008, 2010 ;; Free Software Foundation, Inc. ;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner ;; (bergner@vnet.ibm.com). @@ -105,7 +105,7 @@ (define_insn "movsd_store" [(set (match_operand:DD 0 "nonimmediate_operand" "=m") - (unspec:DD [(match_operand:SD 1 "input_operand" "f")] + (unspec:DD [(match_operand:SD 1 "input_operand" "d")] UNSPEC_MOVSD_STORE))] "(gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], SDmode)) @@ -128,15 +128,15 @@ ;; Hardware support for decimal floating point operations. (define_insn "extendsddd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))] "TARGET_DFP" "dctdp %0,%1" [(set_attr "type" "fp")]) (define_expand "extendsdtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" { rtx tmp = gen_reg_rtx (DDmode); @@ -147,7 +147,7 @@ (define_insn "truncddsd2" [(set (match_operand:SD 0 "gpc_reg_operand" "=f") - (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "f")))] + (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drsp %0,%1" [(set_attr "type" "fp")]) @@ -159,8 +159,8 @@ "") (define_insn "*negdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (neg:DD (match_operand:DD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fneg %0,%1" [(set_attr "type" "fp")]) @@ -172,15 +172,15 @@ "") (define_insn "*absdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (abs:DD (match_operand:DD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "*nabsdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (neg:DD (abs:DD (match_operand:DF 1 "gpc_reg_operand" "f"))))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -281,8 +281,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdd_hardfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,m,r,f,m,f,G,H,F"))] + [(set (match_operand:DD 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r") + (match_operand:DD 1 "input_operand" "r,m,r,d,m,d,G,H,F"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], DDmode))" @@ -293,71 +293,9 @@ default: gcc_unreachable (); case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register - of operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; case 1: - if (rs6000_offsettable_memref_p (operands[1]) - || (GET_CODE (operands[1]) == MEM - && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM - || GET_CODE (XEXP (operands[1], 0)) == PRE_INC - || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))) - { - /* If the low-address word is used in the address, we must load - it last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is - known to be dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - } - else - { - rtx addreg; - - addreg = find_addr_reg (XEXP (operands[1], 0)); - if (refers_to_regno_p (REGNO (operands[0]), - REGNO (operands[0]) + 1, - operands[1], 0)) - { - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"{lx|lwzx} %0,%1\"; - } - else - { - output_asm_insn (\"{lx|lwzx} %0,%1\", operands); - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"\"; - } - } case 2: - if (rs6000_offsettable_memref_p (operands[0]) - || (GET_CODE (operands[0]) == MEM - && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM - || GET_CODE (XEXP (operands[0], 0)) == PRE_INC - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))) - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - else - { - rtx addreg; - - addreg = find_addr_reg (XEXP (operands[0], 0)); - output_asm_insn (\"{stx|stwx} %1,%0\", operands); - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{stx|stwx} %L1,%0\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"\"; - } + return \"#\"; case 3: return \"fmr %0,%1\"; case 4: @@ -379,46 +317,15 @@ "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], DDmode))" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load - it last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is - known to be dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - case 3: - case 4: - case 5: - return \"#\"; - } -}" + "#" [(set_attr "type" "two,load,store,*,*,*") (set_attr "length" "8,8,8,8,12,16")]) ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdd_hardfloat64_mfpgpr" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f") - (match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))] + [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d") + (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))] "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], DDmode))" @@ -443,8 +350,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdd_hardfloat64" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))] + [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r") + (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))] "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], DDmode))" @@ -490,8 +397,8 @@ "") (define_insn "*negtd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fneg %0,%1" [(set_attr "type" "fp")]) @@ -503,15 +410,15 @@ "") (define_insn "*abstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (abs:TD (match_operand:TD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "*nabstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (neg:TD (abs:TD (match_operand:DF 1 "gpc_reg_operand" "f"))))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -526,8 +433,8 @@ ; otherwise reload, given m->f, will try to pick f->f and reload it, ; which doesn't make progress. Likewise r->Y must be before r->r. (define_insn_and_split "*movtd_internal" - [(set (match_operand:TD 0 "nonimmediate_operand" "=o,f,f,r,Y,r") - (match_operand:TD 1 "input_operand" "f,o,f,YGHF,r,r"))] + [(set (match_operand:TD 0 "nonimmediate_operand" "=o,d,d,r,Y,r") + (match_operand:TD 1 "input_operand" "d,o,d,YGHF,r,r"))] "TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], TDmode) || gpc_reg_operand (operands[1], TDmode))" @@ -540,8 +447,8 @@ ;; Hardware support for decimal floating point operations. (define_insn "extendddtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctqpq %0,%1" [(set_attr "type" "fp")]) @@ -552,96 +459,96 @@ ;; that the result is the first of the pair receiving the result of drdpq. (define_insn "trunctddd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "f"))) - (clobber (match_scratch:TD 2 "=f"))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d"))) + (clobber (match_scratch:TD 2 "=d"))] "TARGET_DFP" "drdpq %2,%1\;fmr %0,%2" [(set_attr "type" "fp")]) (define_insn "adddd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%f") - (match_operand:DD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dadd %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "addtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%f") - (match_operand:TD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "daddq %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "subdd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (minus:DD (match_operand:DD 1 "gpc_reg_operand" "f") - (match_operand:DD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dsub %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "subtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (minus:TD (match_operand:TD 1 "gpc_reg_operand" "f") - (match_operand:TD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dsubq %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "muldd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%f") - (match_operand:DD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dmul %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "multd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%f") - (match_operand:TD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dmulq %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "divdd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (div:DD (match_operand:DD 1 "gpc_reg_operand" "f") - (match_operand:DD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (div:DD (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "ddiv %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "divtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (div:TD (match_operand:TD 1 "gpc_reg_operand" "f") - (match_operand:TD 2 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (div:TD (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "ddivq %0,%1,%2" [(set_attr "type" "fp")]) (define_insn "*cmpdd_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "f") - (match_operand:DD 2 "gpc_reg_operand" "f")))] + (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) (define_insn "*cmptd_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "f") - (match_operand:TD 2 "gpc_reg_operand" "f")))] + (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcmpuq %0,%1,%2" [(set_attr "type" "fpcompare")]) (define_insn "floatditd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (float:TD (match_operand:DI 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcffixq %0,%1" [(set_attr "type" "fp")]) @@ -650,8 +557,8 @@ ;; This is the first stage of converting it to an integer type. (define_insn "ftruncdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=f") - (fix:DD (match_operand:DD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drintn. 0,%0,%1,1" [(set_attr "type" "fp")]) @@ -660,8 +567,8 @@ ;; This is the second stage of converting decimal float to integer type. (define_insn "fixdddi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (fix:DI (match_operand:DD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctfix %0,%1" [(set_attr "type" "fp")]) @@ -670,8 +577,8 @@ ;; This is the first stage of converting it to an integer type. (define_insn "ftrunctd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=f") - (fix:TD (match_operand:TD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drintnq. 0,%0,%1,1" [(set_attr "type" "fp")]) @@ -680,8 +587,8 @@ ;; This is the second stage of converting decimal float to integer type. (define_insn "fixtddi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (fix:DI (match_operand:TD 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctfixq %0,%1" [(set_attr "type" "fp")]) diff --git a/gcc/config/rs6000/power4.md b/gcc/config/rs6000/power4.md index 7b5b6ea2dbd..60dbffd58c9 100644 --- a/gcc/config/rs6000/power4.md +++ b/gcc/config/rs6000/power4.md @@ -41,21 +41,18 @@ |(du4_power4,lsu1_power4)") (define_reservation "lsuq_power4" - "(du1_power4+du2_power4,lsu1_power4+iu2_power4)\ - |(du2_power4+du3_power4,lsu2_power4+iu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4+iu1_power4)") + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))\ + +(nothing,iu2_power4|nothing,iu1_power4)") (define_reservation "iq_power4" - "(du1_power4,iu1_power4)\ - |(du2_power4,iu2_power4)\ - |(du3_power4,iu2_power4)\ - |(du4_power4,iu1_power4)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4|iu2_power4)") (define_reservation "fpq_power4" - "(du1_power4,fpu1_power4)\ - |(du2_power4,fpu2_power4)\ - |(du3_power4,fpu2_power4)\ - |(du4_power4,fpu1_power4)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4|fpu2_power4)") (define_reservation "vq_power4" "(du1_power4,vec_power4)\ @@ -86,9 +83,11 @@ (define_insn_reservation "power4-load-ext" 5 (and (eq_attr "type" "load_ext") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,lsu1_power4,nothing,nothing,iu2_power4)\ - |(du2_power4+du3_power4,lsu2_power4,nothing,nothing,iu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4,nothing,nothing,iu1_power4)") + "(du1_power4+du2_power4,lsu1_power4\ + |du2_power4+du3_power4,lsu2_power4\ + |du3_power4+du4_power4,lsu2_power4),\ + nothing,nothing,\ + (iu2_power4|iu1_power4)") (define_insn_reservation "power4-load-ext-update" 5 (and (eq_attr "type" "load_ext_u") @@ -131,18 +130,23 @@ (define_insn_reservation "power4-store" 12 (and (eq_attr "type" "store") (eq_attr "cpu" "power4")) - "(du1_power4,lsu1_power4,iu1_power4)\ - |(du2_power4,lsu2_power4,iu2_power4)\ - |(du3_power4,lsu2_power4,iu2_power4)\ - |(du4_power4,lsu1_power4,iu1_power4)") + "((du1_power4,lsu1_power4)\ + |(du2_power4,lsu2_power4)\ + |(du3_power4,lsu2_power4)\ + |(du4_power4,lsu1_power4)),\ + (iu1_power4|iu2_power4)") (define_insn_reservation "power4-store-update" 12 (and (eq_attr "type" "store_u") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,lsu1_power4+iu2_power4,iu1_power4)\ - |(du2_power4+du3_power4,lsu2_power4+iu2_power4,iu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4+iu1_power4,iu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4,iu1_power4,iu2_power4)") + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))+\ + ((nothing,iu2_power4,iu1_power4)\ + |(nothing,iu2_power4,iu2_power4)\ + |(nothing,iu1_power4,iu2_power4)\ + |(nothing,iu1_power4,iu2_power4))") (define_insn_reservation "power4-store-update-indexed" 12 (and (eq_attr "type" "store_ux") @@ -153,17 +157,19 @@ (define_insn_reservation "power4-fpstore" 12 (and (eq_attr "type" "fpstore") (eq_attr "cpu" "power4")) - "(du1_power4,lsu1_power4,fpu1_power4)\ - |(du2_power4,lsu2_power4,fpu2_power4)\ - |(du3_power4,lsu2_power4,fpu2_power4)\ - |(du4_power4,lsu1_power4,fpu1_power4)") + "((du1_power4,lsu1_power4)\ + |(du2_power4,lsu2_power4)\ + |(du3_power4,lsu2_power4)\ + |(du4_power4,lsu1_power4)),\ + (fpu1_power4|fpu2_power4)") (define_insn_reservation "power4-fpstore-update" 12 (and (eq_attr "type" "fpstore_u,fpstore_ux") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,lsu1_power4+iu2_power4,fpu1_power4)\ - |(du2_power4+du3_power4,lsu2_power4+iu2_power4,fpu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4+iu1_power4,fpu2_power4)") + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))\ + +(nothing,(iu1_power4|iu2_power4),(fpu1_power4|fpu2_power4))") (define_insn_reservation "power4-vecstore" 12 (and (eq_attr "type" "vecstore") @@ -176,8 +182,7 @@ (define_insn_reservation "power4-llsc" 11 (and (eq_attr "type" "load_l,store_c,sync") (eq_attr "cpu" "power4")) - "du1_power4+du2_power4+du3_power4+du4_power4,\ - lsu1_power4") + "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") ; Integer latency is 2 cycles @@ -190,29 +195,32 @@ (define_insn_reservation "power4-two" 2 (and (eq_attr "type" "two") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,iu1_power4,nothing,iu2_power4)\ - |(du2_power4+du3_power4,iu2_power4,nothing,iu2_power4)\ - |(du3_power4+du4_power4,iu2_power4,nothing,iu1_power4)\ - |(du4_power4+du1_power4,iu1_power4,nothing,iu1_power4)") + "((du1_power4+du2_power4)\ + |(du2_power4+du3_power4)\ + |(du3_power4+du4_power4)\ + |(du4_power4+du1_power4)),\ + ((iu1_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu1_power4)\ + |(iu1_power4,nothing,iu1_power4))") (define_insn_reservation "power4-three" 2 (and (eq_attr "type" "three") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4+du3_power4,\ - iu1_power4,nothing,iu2_power4,nothing,iu2_power4)\ - |(du2_power4+du3_power4+du4_power4,\ - iu2_power4,nothing,iu2_power4,nothing,iu1_power4)\ - |(du3_power4+du4_power4+du1_power4,\ - iu2_power4,nothing,iu1_power4,nothing,iu1_power4)\ - |(du4_power4+du1_power4+du2_power4,\ - iu1_power4,nothing,iu2_power4,nothing,iu2_power4)") + "(du1_power4+du2_power4+du3_power4|du2_power4+du3_power4+du4_power4\ + |du3_power4+du4_power4+du1_power4|du4_power4+du1_power4+du2_power4),\ + ((iu1_power4,nothing,iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4,nothing,iu1_power4)\ + |(iu2_power4,nothing,iu1_power4,nothing,iu1_power4)\ + |(iu1_power4,nothing,iu2_power4,nothing,iu2_power4))") (define_insn_reservation "power4-insert" 4 (and (eq_attr "type" "insert_word") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,iu1_power4,nothing,iu2_power4)\ - |(du2_power4+du3_power4,iu2_power4,nothing,iu2_power4)\ - |(du3_power4+du4_power4,iu2_power4,nothing,iu1_power4)") + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu1_power4))") (define_insn_reservation "power4-cmp" 3 (and (eq_attr "type" "cmp,fast_compare") @@ -222,53 +230,50 @@ (define_insn_reservation "power4-compare" 2 (and (eq_attr "type" "compare,delayed_compare,var_delayed_compare") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,iu1_power4,iu2_power4)\ - |(du2_power4+du3_power4,iu2_power4,iu2_power4)\ - |(du3_power4+du4_power4,iu2_power4,iu1_power4)") + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4,iu2_power4)\ + |(iu2_power4,iu2_power4)\ + |(iu2_power4,iu1_power4))") (define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-lmul-cmp" 7 (and (eq_attr "type" "lmul_compare") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,iu1_power4*6,iu2_power4)\ - |(du2_power4+du3_power4,iu2_power4*6,iu2_power4)\ - |(du3_power4+du4_power4,iu2_power4*6,iu1_power4)") + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4*6,iu2_power4)\ + |(iu2_power4*6,iu2_power4)\ + |(iu2_power4*6,iu1_power4))") (define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-imul-cmp" 5 (and (eq_attr "type" "imul_compare") (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4,iu1_power4*4,iu2_power4)\ - |(du2_power4+du3_power4,iu2_power4*4,iu2_power4)\ - |(du3_power4+du4_power4,iu2_power4*4,iu1_power4)") + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4*4,iu2_power4)\ + |(iu2_power4*4,iu2_power4)\ + |(iu2_power4*4,iu1_power4))") (define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-lmul" 7 (and (eq_attr "type" "lmul") (eq_attr "cpu" "power4")) - "(du1_power4,iu1_power4*6)\ - |(du2_power4,iu2_power4*6)\ - |(du3_power4,iu2_power4*6)\ - |(du4_power4,iu1_power4*6)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*6|iu2_power4*6)") (define_insn_reservation "power4-imul" 5 (and (eq_attr "type" "imul") (eq_attr "cpu" "power4")) - "(du1_power4,iu1_power4*4)\ - |(du2_power4,iu2_power4*4)\ - |(du3_power4,iu2_power4*4)\ - |(du4_power4,iu1_power4*4)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*4|iu2_power4*4)") (define_insn_reservation "power4-imul3" 4 (and (eq_attr "type" "imul2,imul3") (eq_attr "cpu" "power4")) - "(du1_power4,iu1_power4*3)\ - |(du2_power4,iu2_power4*3)\ - |(du3_power4,iu2_power4*3)\ - |(du4_power4,iu1_power4*3)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*3|iu2_power4*3)") ; SPR move only executes in first IU. @@ -347,24 +352,19 @@ (define_insn_reservation "power4-sdiv" 33 (and (eq_attr "type" "sdiv,ddiv") (eq_attr "cpu" "power4")) - "(du1_power4,fpu1_power4*28)\ - |(du2_power4,fpu2_power4*28)\ - |(du3_power4,fpu2_power4*28)\ - |(du4_power4,fpu1_power4*28)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4*28|fpu2_power4*28)") (define_insn_reservation "power4-sqrt" 40 (and (eq_attr "type" "ssqrt,dsqrt") (eq_attr "cpu" "power4")) - "(du1_power4,fpu1_power4*35)\ - |(du2_power4,fpu2_power4*35)\ - |(du3_power4,fpu2_power4*35)\ - |(du4_power4,fpu2_power4*35)") + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4*35|fpu2_power4*35)") (define_insn_reservation "power4-isync" 2 (and (eq_attr "type" "isync") (eq_attr "cpu" "power4")) - "du1_power4+du2_power4+du3_power4+du4_power4,\ - lsu1_power4") + "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") ; VMX diff --git a/gcc/config/rs6000/power5.md b/gcc/config/rs6000/power5.md index cc96b2b036b..b6db0931219 100644 --- a/gcc/config/rs6000/power5.md +++ b/gcc/config/rs6000/power5.md @@ -40,16 +40,12 @@ |(du4_power5,lsu1_power5)") (define_reservation "iq_power5" - "(du1_power5,iu1_power5)\ - |(du2_power5,iu2_power5)\ - |(du3_power5,iu2_power5)\ - |(du4_power5,iu1_power5)") + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (iu1_power5|iu2_power5)") (define_reservation "fpq_power5" - "(du1_power5,fpu1_power5)\ - |(du2_power5,fpu2_power5)\ - |(du3_power5,fpu2_power5)\ - |(du4_power5,fpu1_power5)") + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5|fpu2_power5)") ; Dispatch slots are allocated in order conforming to program order. (absence_set "du1_power5" "du2_power5,du3_power5,du4_power5,du5_power5") @@ -105,10 +101,11 @@ (define_insn_reservation "power5-store" 12 (and (eq_attr "type" "store") (eq_attr "cpu" "power5")) - "(du1_power5,lsu1_power5,iu1_power5)\ - |(du2_power5,lsu2_power5,iu2_power5)\ - |(du3_power5,lsu2_power5,iu2_power5)\ - |(du4_power5,lsu1_power5,iu1_power5)") + "((du1_power5,lsu1_power5)\ + |(du2_power5,lsu2_power5)\ + |(du3_power5,lsu2_power5)\ + |(du4_power5,lsu1_power5)),\ + (iu1_power5|iu2_power5)") (define_insn_reservation "power5-store-update" 12 (and (eq_attr "type" "store_u") @@ -124,10 +121,11 @@ (define_insn_reservation "power5-fpstore" 12 (and (eq_attr "type" "fpstore") (eq_attr "cpu" "power5")) - "(du1_power5,lsu1_power5,fpu1_power5)\ - |(du2_power5,lsu2_power5,fpu2_power5)\ - |(du3_power5,lsu2_power5,fpu2_power5)\ - |(du4_power5,lsu1_power5,fpu1_power5)") + "((du1_power5,lsu1_power5)\ + |(du2_power5,lsu2_power5)\ + |(du3_power5,lsu2_power5)\ + |(du4_power5,lsu1_power5)),\ + (fpu1_power5|fpu2_power5)") (define_insn_reservation "power5-fpstore-update" 12 (and (eq_attr "type" "fpstore_u,fpstore_ux") @@ -151,22 +149,24 @@ (define_insn_reservation "power5-two" 2 (and (eq_attr "type" "two") (eq_attr "cpu" "power5")) - "(du1_power5+du2_power5,iu1_power5,nothing,iu2_power5)\ - |(du2_power5+du3_power5,iu2_power5,nothing,iu2_power5)\ - |(du3_power5+du4_power5,iu2_power5,nothing,iu1_power5)\ - |(du4_power5+du1_power5,iu1_power5,nothing,iu1_power5)") + "((du1_power5+du2_power5)\ + |(du2_power5+du3_power5)\ + |(du3_power5+du4_power5)\ + |(du4_power5+du1_power5)),\ + ((iu1_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu1_power5)\ + |(iu1_power5,nothing,iu1_power5))") (define_insn_reservation "power5-three" 2 (and (eq_attr "type" "three") (eq_attr "cpu" "power5")) - "(du1_power5+du2_power5+du3_power5,\ - iu1_power5,nothing,iu2_power5,nothing,iu2_power5)\ - |(du2_power5+du3_power5+du4_power5,\ - iu2_power5,nothing,iu2_power5,nothing,iu1_power5)\ - |(du3_power5+du4_power5+du1_power5,\ - iu2_power5,nothing,iu1_power5,nothing,iu1_power5)\ - |(du4_power5+du1_power5+du2_power5,\ - iu1_power5,nothing,iu2_power5,nothing,iu2_power5)") + "(du1_power5+du2_power5+du3_power5|du2_power5+du3_power5+du4_power5\ + |du3_power5+du4_power5+du1_power5|du4_power5+du1_power5+du2_power5),\ + ((iu1_power5,nothing,iu2_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu2_power5,nothing,iu1_power5)\ + |(iu2_power5,nothing,iu1_power5,nothing,iu1_power5)\ + |(iu1_power5,nothing,iu2_power5,nothing,iu2_power5))") (define_insn_reservation "power5-insert" 4 (and (eq_attr "type" "insert_word") @@ -202,26 +202,17 @@ (define_insn_reservation "power5-lmul" 7 (and (eq_attr "type" "lmul") (eq_attr "cpu" "power5")) - "(du1_power5,iu1_power5*6)\ - |(du2_power5,iu2_power5*6)\ - |(du3_power5,iu2_power5*6)\ - |(du4_power5,iu1_power5*6)") + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*6|iu2_power5*6)") (define_insn_reservation "power5-imul" 5 (and (eq_attr "type" "imul") (eq_attr "cpu" "power5")) - "(du1_power5,iu1_power5*4)\ - |(du2_power5,iu2_power5*4)\ - |(du3_power5,iu2_power5*4)\ - |(du4_power5,iu1_power5*4)") + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*4|iu2_power5*4)") (define_insn_reservation "power5-imul3" 4 (and (eq_attr "type" "imul2,imul3") (eq_attr "cpu" "power5")) - "(du1_power5,iu1_power5*3)\ - |(du2_power5,iu2_power5*3)\ - |(du3_power5,iu2_power5*3)\ - |(du4_power5,iu1_power5*3)") + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*3|iu2_power5*3)") ; SPR move only executes in first IU. @@ -300,18 +291,14 @@ (define_insn_reservation "power5-sdiv" 33 (and (eq_attr "type" "sdiv,ddiv") (eq_attr "cpu" "power5")) - "(du1_power5,fpu1_power5*28)\ - |(du2_power5,fpu2_power5*28)\ - |(du3_power5,fpu2_power5*28)\ - |(du4_power5,fpu1_power5*28)") + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5*28|fpu2_power5*28)") (define_insn_reservation "power5-sqrt" 40 (and (eq_attr "type" "ssqrt,dsqrt") (eq_attr "cpu" "power5")) - "(du1_power5,fpu1_power5*35)\ - |(du2_power5,fpu2_power5*35)\ - |(du3_power5,fpu2_power5*35)\ - |(du4_power5,fpu2_power5*35)") + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5*35|fpu2_power5*35)") (define_insn_reservation "power5-isync" 2 (and (eq_attr "type" "isync") diff --git a/gcc/config/rs6000/ppc-asm.h b/gcc/config/rs6000/ppc-asm.h index d32d1f127f4..c963eb98abb 100644 --- a/gcc/config/rs6000/ppc-asm.h +++ b/gcc/config/rs6000/ppc-asm.h @@ -1,4 +1,28 @@ -/* PowerPC asm definitions for GNU C. */ +/* PowerPC asm definitions for GNU C. + +Copyright (C) 2002, 2003, 2008, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + /* Under winnt, 1) gas supports the following as names and 2) in particular defining "toc" breaks the FUNC_START macro as ".toc" becomes ".2" */ @@ -328,7 +352,7 @@ GLUE(.L,name): \ #endif #endif -#if defined __linux__ +#if defined __linux__ && !defined __powerpc64__ .section .note.GNU-stack .previous #endif diff --git a/gcc/config/rs6000/ppu_intrinsics.h b/gcc/config/rs6000/ppu_intrinsics.h index 2acb32db963..0950f33aa55 100644 --- a/gcc/config/rs6000/ppu_intrinsics.h +++ b/gcc/config/rs6000/ppu_intrinsics.h @@ -385,11 +385,11 @@ typedef int __V4SI __attribute__((vector_size(16))); #define __mffs() __extension__ \ ({double result; \ - __asm__ volatile ("mffs %0" : "=f" (result)); \ + __asm__ volatile ("mffs %0" : "=d" (result)); \ result; }) #define __mtfsf(mask,value) \ - __asm__ volatile ("mtfsf %0,%1" : : "n" (mask), "f" ((double) (value))) + __asm__ volatile ("mtfsf %0,%1" : : "n" (mask), "d" ((double) (value))) #define __mtfsfi(bits,field) \ __asm__ volatile ("mtfsfi %0,%1" : : "n" (bits), "n" (field)) @@ -400,8 +400,8 @@ typedef int __V4SI __attribute__((vector_size(16))); #define __setflm(v) __extension__ \ ({double result; \ __asm__ volatile ("mffs %0\n\tmtfsf 255,%1" \ - : "=&f" (result) \ - : "f" ((double) (v))); \ + : "=&d" (result) \ + : "d" ((double) (v))); \ result; }) /* __builtin_fabs may perform unnecessary rounding. */ @@ -416,7 +416,7 @@ static __inline__ double __fabs(double x) { double r; - __asm__("fabs %0,%1" : "=f"(r) : "f"(x)); + __asm__("fabs %0,%1" : "=d"(r) : "d"(x)); return r; } @@ -434,7 +434,7 @@ static __inline__ double __fnabs(double x) { double r; - __asm__("fnabs %0,%1" : "=f"(r) : "f"(x)); + __asm__("fnabs %0,%1" : "=d"(r) : "d"(x)); return r; } @@ -453,7 +453,7 @@ static __inline__ double __fmadd(double x, double y, double z) { double r; - __asm__("fmadd %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); + __asm__("fmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); return r; } @@ -463,7 +463,7 @@ static __inline__ double __fmsub(double x, double y, double z) { double r; - __asm__("fmsub %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); + __asm__("fmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); return r; } @@ -473,7 +473,7 @@ static __inline__ double __fnmadd(double x, double y, double z) { double r; - __asm__("fnmadd %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); + __asm__("fnmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); return r; } @@ -483,7 +483,7 @@ static __inline__ double __fnmsub(double x, double y, double z) { double r; - __asm__("fnmsub %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); + __asm__("fnmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); return r; } @@ -533,7 +533,7 @@ static __inline__ double __fsel(double x, double y, double z) { double r; - __asm__("fsel %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); + __asm__("fsel %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); return r; } @@ -552,7 +552,7 @@ static __inline__ double __frsqrte(double x) { double r; - __asm__("frsqrte %0,%1" : "=f" (r) : "f" (x)); + __asm__("frsqrte %0,%1" : "=d" (r) : "d" (x)); return r; } @@ -570,7 +570,7 @@ static __inline__ double __fsqrt(double x) { double r; - __asm__("fsqrt %0,%1" : "=f"(r) : "f"(x)); + __asm__("fsqrt %0,%1" : "=d"(r) : "d"(x)); return r; } @@ -588,7 +588,7 @@ static __inline__ double __fmul(double a, double b) { double d; - __asm__ ("fmul %0,%1,%2" : "=f" (d) : "f" (a), "f" (b)); + __asm__ ("fmul %0,%1,%2" : "=d" (d) : "d" (a), "d" (b)); return d; } @@ -597,7 +597,7 @@ static __inline__ float __fmuls (float a, float b) { float d; - __asm__ ("fmuls %0,%1,%2" : "=f" (d) : "f" (a), "f" (b)); + __asm__ ("fmuls %0,%1,%2" : "=d" (d) : "f" (a), "f" (b)); return d; } @@ -606,7 +606,7 @@ static __inline__ float __frsp (float a) { float d; - __asm__ ("frsp %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("frsp %0,%1" : "=d" (d) : "f" (a)); return d; } @@ -615,7 +615,7 @@ static __inline__ double __fcfid (long long a) { double d; - __asm__ ("fcfid %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("fcfid %0,%1" : "=d" (d) : "d" (a)); return d; } @@ -624,7 +624,7 @@ static __inline__ long long __fctid (double a) { long long d; - __asm__ ("fctid %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("fctid %0,%1" : "=d" (d) : "d" (a)); return d; } @@ -633,7 +633,7 @@ static __inline__ long long __fctidz (double a) { long long d; - __asm__ ("fctidz %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("fctidz %0,%1" : "=d" (d) : "d" (a)); return d; } @@ -642,7 +642,7 @@ static __inline__ int __fctiw (double a) { unsigned long long d; - __asm__ ("fctiw %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("fctiw %0,%1" : "=d" (d) : "d" (a)); return (int) d; } @@ -651,7 +651,7 @@ static __inline__ int __fctiwz (double a) { long long d; - __asm__ ("fctiwz %0,%1" : "=f" (d) : "f" (a)); + __asm__ ("fctiwz %0,%1" : "=d" (d) : "d" (a)); return (int) d; } diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 7d4254caab2..6110e3544a0 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -415,9 +415,7 @@ ;; Return 1 if the operand is an offsettable memory operand. (define_predicate "offsettable_mem_operand" (and (match_operand 0 "memory_operand") - (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC - && GET_CODE (XEXP (op, 0)) != PRE_DEC - && GET_CODE (XEXP (op, 0)) != PRE_MODIFY"))) + (match_test "offsettable_nonstrict_memref_p (op)"))) ;; Return 1 if the operand is a memory operand with an address divisible by 4 (define_predicate "word_offset_memref_operand" @@ -894,6 +892,11 @@ GET_MODE (XEXP (op, 0))), 1")))) +(define_predicate "rs6000_cbranch_operator" + (if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS") + (match_operand 0 "ordered_comparison_operator") + (match_operand 0 "comparison_operator"))) + ;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- ;; it must be a positive comparison. (define_predicate "scc_comparison_operator" diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index dce1aea7f45..3936af9a109 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -920,7 +920,7 @@ static void rs6000_elf_encode_section_info (tree, rtx, int) ATTRIBUTE_UNUSED; #endif static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx); -static void rs6000_expand_to_rtl_hook (void); +static void rs6000_alloc_sdmode_stack_slot (void); static void rs6000_instantiate_decls (void); #if TARGET_XCOFF static void rs6000_xcoff_asm_output_anchor (rtx); @@ -980,6 +980,10 @@ static tree rs6000_builtin_mul_widen_even (tree); static tree rs6000_builtin_mul_widen_odd (tree); static tree rs6000_builtin_conversion (enum tree_code, tree); static tree rs6000_builtin_vec_perm (tree, tree *); +static bool rs6000_builtin_support_vector_misalignment (enum + machine_mode, + const_tree, + int, bool); static void def_builtin (int, const char *, tree, int); static bool rs6000_vector_alignment_reachable (const_tree, bool); @@ -1237,9 +1241,6 @@ static const char alt_reg_names[][8] = #endif #ifndef TARGET_PROFILE_KERNEL #define TARGET_PROFILE_KERNEL 0 -#define SET_PROFILE_KERNEL(N) -#else -#define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N) #endif /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ @@ -1348,7 +1349,9 @@ static const char alt_reg_names[][8] = #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm - +#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT +#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ + rs6000_builtin_support_vector_misalignment #undef TARGET_VECTOR_ALIGNMENT_REACHABLE #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable @@ -1494,7 +1497,7 @@ static const char alt_reg_names[][8] = #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal #undef TARGET_EXPAND_TO_RTL_HOOK -#define TARGET_EXPAND_TO_RTL_HOOK rs6000_expand_to_rtl_hook +#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot #undef TARGET_INSTANTIATE_DECLS #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls @@ -2356,8 +2359,7 @@ rs6000_override_options (const char *default_cpu) } } - /* Add some warnings for VSX. Enable -maltivec unless the user explicitly - used -mno-altivec */ + /* Add some warnings for VSX. */ if (TARGET_VSX) { const char *msg = NULL; @@ -2378,14 +2380,20 @@ rs6000_override_options (const char *default_cpu) msg = N_("-mvsx used with little endian code"); else if (TARGET_AVOID_XFORM > 0) msg = N_("-mvsx needs indexed addressing"); + else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC)) + { + if (target_flags_explicit & MASK_VSX) + msg = N_("-mvsx and -mno-altivec are incompatible"); + else + msg = N_("-mno-altivec disables vsx"); + } if (msg) { warning (0, msg); target_flags &= ~ MASK_VSX; } - else if (TARGET_VSX && !TARGET_ALTIVEC - && (target_flags_explicit & MASK_ALTIVEC) == 0) + else if (TARGET_VSX && !TARGET_ALTIVEC) target_flags |= MASK_ALTIVEC; } @@ -2572,7 +2580,8 @@ rs6000_override_options (const char *default_cpu) else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load")) rs6000_sched_costly_dep = store_to_load_dep_costly; else - rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str); + rs6000_sched_costly_dep = ((enum rs6000_dependence_cost) + atoi (rs6000_sched_costly_dep_str)); } /* Handle -minsert-sched-nops option. */ @@ -2588,7 +2597,8 @@ rs6000_override_options (const char *default_cpu) else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact")) rs6000_sched_insert_nops = sched_finish_regroup_exact; else - rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str); + rs6000_sched_insert_nops = ((enum rs6000_nop_insertion) + atoi (rs6000_sched_insert_nops_str)); } #ifdef TARGET_REGNAMES @@ -2953,6 +2963,36 @@ rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_pac } } +/* Return true if the vector misalignment factor is supported by the + target. */ +bool +rs6000_builtin_support_vector_misalignment (enum machine_mode mode, + const_tree type, + int misalignment, + bool is_packed) +{ + if (TARGET_VSX) + { + /* Return if movmisalign pattern is not supported for this mode. */ + if (optab_handler (movmisalign_optab, mode)->insn_code == + CODE_FOR_nothing) + return false; + + if (misalignment == -1) + { + /* misalignment factor is unknown at compile time but we know + it's word aligned. */ + if (rs6000_vector_alignment_reachable (type, is_packed)) + return true; + return false; + } + /* VSX supports word-aligned vector. */ + if (misalignment % 4 == 0) + return true; + } + return false; +} + /* Implement targetm.vectorize.builtin_vec_perm. */ tree rs6000_builtin_vec_perm (tree type, tree *mask_element_type) @@ -3312,6 +3352,11 @@ rs6000_handle_option (size_t code, const char *arg, int value) rs6000_explicit_options.aix_struct_ret = true; break; + case OPT_mvrsave: + rs6000_explicit_options.vrsave = true; + TARGET_ALTIVEC_VRSAVE = value; + break; + case OPT_mvrsave_: rs6000_explicit_options.vrsave = true; rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE)); @@ -4552,6 +4597,9 @@ darwin_rs6000_special_round_type_align (tree type, unsigned int computed, field = TREE_CHAIN (field); if (! field) break; + /* A packed field does not contribute any extra alignment. */ + if (DECL_PACKED (field)) + return align; type = TREE_TYPE (field); while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); @@ -4950,6 +4998,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, if (model != 0) return rs6000_legitimize_tls_address (x, model); } + switch (mode) { case DFmode: @@ -5790,7 +5839,15 @@ rs6000_mode_dependent_address (rtx addr) switch (GET_CODE (addr)) { case PLUS: - if (GET_CODE (XEXP (addr, 1)) == CONST_INT) + /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx + is considered a legitimate address before reload, so there + are no offset restrictions in that case. Note that this + condition is safe in strict mode because any address involving + virtual_stack_vars_rtx or arg_pointer_rtx would already have + been rejected as illegitimate. */ + if (XEXP (addr, 0) != virtual_stack_vars_rtx + && XEXP (addr, 0) != arg_pointer_rtx + && GET_CODE (XEXP (addr, 1)) == CONST_INT) { unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1)); return val + 12 + 0x8000 >= 0x10000; @@ -6504,14 +6561,6 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) && ! legitimate_constant_pool_address_p (operands[1]) && ! toc_relative_expr_p (operands[1])) { - /* Emit a USE operation so that the constant isn't deleted if - expensive optimizations are turned on because nobody - references it. This should only be done for operands that - contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set. - This should not be done for operands that contain LABEL_REFs. - For now, we just handle the obvious case. */ - if (GET_CODE (operands[1]) != LABEL_REF) - emit_use (operands[1]); #if TARGET_MACHO /* Darwin uses a special PIC legitimizer. */ @@ -10151,8 +10200,8 @@ altivec_expand_vec_set_builtin (tree exp) mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); gcc_assert (VECTOR_MODE_P (tmode)); - op0 = expand_expr (arg0, NULL_RTX, tmode, 0); - op1 = expand_expr (arg1, NULL_RTX, mode1, 0); + op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL); + op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL); elt = get_element_number (TREE_TYPE (arg0), arg2); if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode) @@ -13101,6 +13150,7 @@ rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) case PARM_DECL: case FIELD_DECL: case RESULT_DECL: + case SSA_NAME: case REAL_CST: case INDIRECT_REF: case ALIGN_INDIRECT_REF: @@ -13556,13 +13606,11 @@ rs6000_ira_cover_classes (void) return (TARGET_VSX) ? cover_vsx : cover_pre_vsx; } -/* Scan the trees looking for certain types. - - Allocate a 64-bit stack slot to be used for copying SDmode values through if - this function has any SDmode references. */ +/* Allocate a 64-bit stack slot to be used for copying SDmode + values through if this function has any SDmode references. */ static void -rs6000_expand_to_rtl_hook (void) +rs6000_alloc_sdmode_stack_slot (void) { tree t; basic_block bb; @@ -13570,7 +13618,6 @@ rs6000_expand_to_rtl_hook (void) gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX); - /* Check for SDmode being used. */ FOR_EACH_BB (bb) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { @@ -16553,6 +16600,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) int i; int j = -1; bool used_update = false; + rtx restore_basereg = NULL_RTX; if (MEM_P (src) && INT_REGNO_P (reg)) { @@ -16571,10 +16619,27 @@ rs6000_split_multireg_move (rtx dst, rtx src) } else if (! rs6000_offsettable_memref_p (src)) { - rtx basereg; - basereg = gen_rtx_REG (Pmode, reg); - emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0))); - src = replace_equiv_address (src, basereg); + if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY) + { + rtx basereg = XEXP (XEXP (src, 0), 0); + if (TARGET_UPDATE) + { + rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0); + emit_insn (gen_rtx_SET (VOIDmode, ndst, + gen_rtx_MEM (reg_mode, XEXP (src, 0)))); + used_update = true; + } + else + emit_insn (gen_rtx_SET (VOIDmode, basereg, + XEXP (XEXP (src, 0), 1))); + src = replace_equiv_address (src, basereg); + } + else + { + rtx basereg = gen_rtx_REG (Pmode, reg); + emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0))); + src = replace_equiv_address (src, basereg); + } } breg = XEXP (src, 0); @@ -16588,8 +16653,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) && REGNO (breg) < REGNO (dst) + nregs) j = REGNO (breg) - REGNO (dst); } - - if (GET_CODE (dst) == MEM && INT_REGNO_P (reg)) + else if (MEM_P (dst) && INT_REGNO_P (reg)) { rtx breg; @@ -16619,7 +16683,44 @@ rs6000_split_multireg_move (rtx dst, rtx src) emit_insn (gen_add3_insn (breg, breg, delta_rtx)); dst = replace_equiv_address (dst, breg); } - else + else if (!rs6000_offsettable_memref_p (dst) + && GET_CODE (XEXP (dst, 0)) != LO_SUM) + { + if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY) + { + rtx basereg = XEXP (XEXP (dst, 0), 0); + if (TARGET_UPDATE) + { + rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); + emit_insn (gen_rtx_SET (VOIDmode, + gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc)); + used_update = true; + } + else + emit_insn (gen_rtx_SET (VOIDmode, basereg, + XEXP (XEXP (dst, 0), 1))); + dst = replace_equiv_address (dst, basereg); + } + else + { + rtx basereg = XEXP (XEXP (dst, 0), 0); + rtx offsetreg = XEXP (XEXP (dst, 0), 1); + gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS + && REG_P (basereg) + && REG_P (offsetreg) + && REGNO (basereg) != REGNO (offsetreg)); + if (REGNO (basereg) == 0) + { + rtx tmp = offsetreg; + offsetreg = basereg; + basereg = tmp; + } + emit_insn (gen_add3_insn (basereg, basereg, offsetreg)); + restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg); + dst = replace_equiv_address (dst, basereg); + } + } + else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) gcc_assert (rs6000_offsettable_memref_p (dst)); } @@ -16641,6 +16742,8 @@ rs6000_split_multireg_move (rtx dst, rtx src) simplify_gen_subreg (reg_mode, src, mode, j * reg_mode_size))); } + if (restore_basereg != NULL_RTX) + emit_insn (restore_basereg); } } @@ -20622,7 +20725,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) h->key_mode = mode; h->labelno = labelno; - found = htab_find_slot (toc_hash_table, h, 1); + found = htab_find_slot (toc_hash_table, h, INSERT); if (*found == NULL) *found = h; else /* This is indeed a duplicate. @@ -21044,7 +21147,8 @@ output_profile_hook (int labelno ATTRIBUTE_UNUSED) # define NO_PROFILE_COUNTERS 0 #endif if (NO_PROFILE_COUNTERS) - emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0); + emit_library_call (init_one_libfunc (RS6000_MCOUNT), + LCT_NORMAL, VOIDmode, 0); else { char buf[30]; @@ -21055,8 +21159,8 @@ output_profile_hook (int labelno ATTRIBUTE_UNUSED) label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf)); fun = gen_rtx_SYMBOL_REF (Pmode, label_name); - emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1, - fun, Pmode); + emit_library_call (init_one_libfunc (RS6000_MCOUNT), + LCT_NORMAL, VOIDmode, 1, fun, Pmode); } } else if (DEFAULT_ABI == ABI_DARWIN) @@ -21075,7 +21179,7 @@ output_profile_hook (int labelno ATTRIBUTE_UNUSED) caller_addr_regno = 0; #endif emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name), - 0, VOIDmode, 1, + LCT_NORMAL, VOIDmode, 1, gen_rtx_REG (Pmode, caller_addr_regno), Pmode); } } @@ -21204,9 +21308,7 @@ static int load_store_pendulum; instructions to issue in this cycle. */ static int -rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED, - int verbose ATTRIBUTE_UNUSED, - rtx insn, int more) +rs6000_variable_issue_1 (rtx insn, int more) { last_scheduled_insn = insn; if (GET_CODE (PATTERN (insn)) == USE @@ -21245,6 +21347,15 @@ rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED, return cached_can_issue_more; } +static int +rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more) +{ + int r = rs6000_variable_issue_1 (insn, more); + if (verbose) + fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r); + return r; +} + /* Adjust the cost of a scheduling dependency. Return the new cost of a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ @@ -23983,15 +24094,6 @@ rs6000_elf_asm_out_destructor (rtx symbol, int priority) assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); } -#ifdef HAVE_LD_OVERLAPPING_OPD -/* If the linker supports overlapping .opd entries and we know this function - doesn't ever use r11 passed to it, we can overlap the fd_aux function - descriptor field with next function descriptor's fd_func field. */ -# define OVERLAPPING_OPD (cfun->static_chain_decl == NULL) -#else -# define OVERLAPPING_OPD 0 -#endif - void rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) { @@ -24001,8 +24103,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) ASM_OUTPUT_LABEL (file, name); fputs (DOUBLE_INT_ASM_OP, file); rs6000_output_function_entry (file, name); - fprintf (file, ",.TOC.@tocbase%s\n\t.previous\n", - OVERLAPPING_OPD ? "" : ",0"); + fputs (",.TOC.@tocbase,0\n\t.previous\n", file); if (DOT_SYMBOLS) { fputs ("\t.size\t", file); @@ -24074,13 +24175,6 @@ rs6000_elf_end_indicate_exec_stack (void) { if (TARGET_32BIT) file_end_indicate_exec_stack (); - else - { - int saved_trampolines_created = trampolines_created; - trampolines_created = 0; - file_end_indicate_exec_stack (); - trampolines_created = saved_trampolines_created; - } } #endif @@ -25411,7 +25505,7 @@ rs6000_init_dwarf_reg_sizes_extra (tree address) { int i; enum machine_mode mode = TYPE_MODE (char_type_node); - rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0); + rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL); rtx mem = gen_rtx_MEM (BLKmode, addr); rtx value = gen_int_mode (4, mode); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 035efc03ebf..6a005f68cac 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -279,6 +279,15 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define TARGET_LWSYNC_INSTRUCTION 0 #endif +/* Define TARGET_TLS_MARKERS if the target assembler does not support + arg markers for __tls_get_addr calls. */ +#ifndef HAVE_AS_TLS_MARKERS +#undef TARGET_TLS_MARKERS +#define TARGET_TLS_MARKERS 0 +#else +#define TARGET_TLS_MARKERS tls_markers +#endif + #ifndef TARGET_SECURE_PLT #define TARGET_SECURE_PLT 0 #endif @@ -707,14 +716,7 @@ extern unsigned rs6000_pointer_size; local store. TYPE is the data type, and ALIGN is the alignment that the object would ordinarily have. */ #define LOCAL_ALIGNMENT(TYPE, ALIGN) \ - (((TARGET_ALTIVEC || TARGET_VSX) \ - && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \ - (TARGET_E500_DOUBLE \ - && TYPE_MODE (TYPE) == DFmode) ? 64 : \ - ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \ - && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \ - && TREE_CODE (TYPE) == VECTOR_TYPE \ - && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) ? 64 : ALIGN) + DATA_ALIGNMENT (TYPE, ALIGN) /* Alignment of field after `int : 0' in a structure. */ #define EMPTY_FIELD_BOUNDARY 32 @@ -753,14 +755,18 @@ extern unsigned rs6000_pointer_size; /* Make arrays of chars word-aligned for the same reasons. Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to 64 bits. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \ - || TARGET_PAIRED_FLOAT) ? 64 : 128) \ - : (TARGET_E500_DOUBLE \ - && TYPE_MODE (TYPE) == DFmode) ? 64 \ - : TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) +#define DATA_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == VECTOR_TYPE \ + ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \ + || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \ + ? 64 : 128) \ + : ((TARGET_E500_DOUBLE \ + && TREE_CODE (TYPE) == REAL_TYPE \ + && TYPE_MODE (TYPE) == DFmode) \ + ? 64 \ + : (TREE_CODE (TYPE) == ARRAY_TYPE \ + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ + && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))) /* Nonzero if move instructions will actually fail to work when given unaligned data. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 155ae1742b6..d8bb2ee8974 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,6 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 ;; Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) @@ -55,6 +55,7 @@ (define_constants [(UNSPEC_FRSP 0) ; frsp for POWER machines + (UNSPEC_PROBE_STACK 4) ; probe stack memory reference (UNSPEC_TIE 5) ; tie stack contents and stack pointer (UNSPEC_TOCPTR 6) ; address of a word pointing to the TOC (UNSPEC_TOC 7) ; address of the TOC (more-or-less) @@ -215,6 +216,9 @@ (DD "TARGET_DFP") (TD "TARGET_DFP")]) +; These modes do not fit in integer registers in 32-bit mode. +(define_mode_iterator DIFD [DI DF DD]) + ; Various instructions that come in SI and DI forms. ; A generic w/d attribute, for things like cmpw/cmpd. (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")]) @@ -5577,7 +5581,7 @@ "") (define_insn_and_split "*extendsfdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f") + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d") (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ @@ -5600,7 +5604,7 @@ (define_insn "*truncdfsf2_fpr" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] + (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frsp %0,%1" [(set_attr "type" "fp")]) @@ -5807,7 +5811,7 @@ (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT" "fnmadds %0,%1,%2,%3" [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -5848,7 +5852,7 @@ (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT" "fnmsubs %0,%1,%2,%3" [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -6085,7 +6089,7 @@ (define_insn "*fseldfsf4" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f") + (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d") (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] @@ -6100,8 +6104,8 @@ "") (define_insn "*negdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "fneg %0,%1" @@ -6114,16 +6118,16 @@ "") (define_insn "*absdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "*nabsdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "fnabs %0,%1" @@ -6137,9 +6141,9 @@ "") (define_insn "*adddf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "{fa|fadd} %0,%1,%2" @@ -6154,9 +6158,9 @@ "") (define_insn "*subdf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (minus:DF (match_operand:DF 1 "gpc_reg_operand" "d") + (match_operand:DF 2 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "{fs|fsub} %0,%1,%2" @@ -6171,9 +6175,9 @@ "") (define_insn "*muldf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "{fm|fmul} %0,%1,%2" @@ -6190,18 +6194,18 @@ "") (define_insn "*divdf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (div:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (div:DF (match_operand:DF 1 "gpc_reg_operand" "d") + (match_operand:DF 2 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU && !VECTOR_UNIT_VSX_P (DFmode)" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) (define_expand "recipdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d") + (match_operand:DF 2 "gpc_reg_operand" "d")] UNSPEC_FRES))] "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_POPCNTB && !optimize_size && flag_finite_math_only && !flag_trapping_math" @@ -6211,8 +6215,8 @@ }) (define_expand "fred" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))] "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only" "") @@ -6224,10 +6228,10 @@ [(set_attr "type" "fp")]) (define_insn "*fmadddf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")) + (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && VECTOR_UNIT_NONE_P (DFmode)" "{fma|fmadd} %0,%1,%2,%3" @@ -6235,10 +6239,10 @@ (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "*fmsubdf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")) + (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && VECTOR_UNIT_NONE_P (DFmode)" "{fms|fmsub} %0,%1,%2,%3" @@ -6246,21 +6250,21 @@ (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "*fnmadddf4_fpr_1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f"))))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")) + (match_operand:DF 3 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" + && VECTOR_UNIT_NONE_P (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "*fnmadddf4_fpr_2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")) - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")) + (match_operand:DF 2 "gpc_reg_operand" "d")) + (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" @@ -6268,21 +6272,21 @@ (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "*fnmsubdf4_fpr_1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f")) - (match_operand:DF 3 "gpc_reg_operand" "f"))))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d")) + (match_operand:DF 3 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT - && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" + && VECTOR_UNIT_NONE_P (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "*fnmsubdf4_fpr_2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (minus:DF (match_operand:DF 3 "gpc_reg_operand" "f") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") - (match_operand:DF 2 "gpc_reg_operand" "f"))))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (minus:DF (match_operand:DF 3 "gpc_reg_operand" "d") + (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") + (match_operand:DF 2 "gpc_reg_operand" "d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" @@ -6297,8 +6301,8 @@ "") (define_insn "*sqrtdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" @@ -6357,21 +6361,21 @@ }") (define_insn "*fseldfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f") + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d") (match_operand:DF 4 "zero_fp_constant" "F")) - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] + (match_operand:DF 2 "gpc_reg_operand" "d") + (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) (define_insn "*fselsfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 4 "zero_fp_constant" "F")) - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] + (match_operand:DF 2 "gpc_reg_operand" "d") + (match_operand:DF 3 "gpc_reg_operand" "d")))] "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -6439,16 +6443,16 @@ }") (define_insn_and_split "*floatsidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") + [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "f")) + (use (match_operand:DF 3 "gpc_reg_operand" "d")) (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" + "" [(pc)] " { @@ -6507,15 +6511,15 @@ }") (define_insn_and_split "*floatunssidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") + [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "f")) + (use (match_operand:DF 3 "gpc_reg_operand" "d")) (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))] + (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" + "" [(pc)] " { @@ -6576,13 +6580,13 @@ (define_insn_and_split "*fix_truncdfsi2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d")) (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))" + "" [(pc)] " { @@ -6599,8 +6603,8 @@ (define_insn_and_split "fix_truncdfsi2_internal_gfxopt" [(set (match_operand:SI 0 "memory_operand" "=Z") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))] + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_PPC_GFXOPT" @@ -6617,8 +6621,8 @@ (define_insn_and_split "fix_truncdfsi2_mfpgpr" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d")) (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))] "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" @@ -6635,8 +6639,8 @@ ; because the first makes it clear that operand 0 is not live ; before the instruction. (define_insn "fctiwz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))] UNSPEC_FCTIWZ))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" @@ -6644,8 +6648,8 @@ [(set_attr "type" "fp")]) (define_expand "btruncdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))] "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "") @@ -6671,8 +6675,8 @@ "") (define_insn "*ceildf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))] "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "frip %0,%1" @@ -6692,8 +6696,8 @@ "") (define_insn "*floordf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))] "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "frim %0,%1" @@ -6708,8 +6712,8 @@ ;; No VSX equivalent to frin (define_insn "rounddf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))] "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frin %0,%1" [(set_attr "type" "fp")]) @@ -6730,7 +6734,7 @@ ; 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") - (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")] + (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")] UNSPEC_STFIWX))] "TARGET_PPC_GFXOPT" "stfiwx %1,%y0" @@ -6750,8 +6754,8 @@ "") (define_insn "*floatdidf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" @@ -6772,10 +6776,11 @@ "") (define_insn "*fix_truncdfdi2_fpr" - [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r") - (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" + [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") + (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS + && !VECTOR_UNIT_VSX_P (DFmode)" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -6802,8 +6807,8 @@ ;; from double rounding. (define_insn_and_split "floatdisf2_internal1" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r"))) - (clobber (match_scratch:DF 2 "=f"))] + (float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r"))) + (clobber (match_scratch:DF 2 "=d"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "#" "&& reload_completed" @@ -7220,7 +7225,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) @@ -8747,8 +8752,8 @@ (define_insn "*movsi_internal1" [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h") (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))] - "gpc_reg_operand (operands[0], SImode) - || gpc_reg_operand (operands[1], SImode)" + "!TARGET_SINGLE_FPU && + (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" "@ mr %0,%1 {cal|la} %0,%a1 @@ -8766,6 +8771,30 @@ [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*") (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) +(define_insn "*movsi_internal1_single" + [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h,m,*f") + (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0,f,m"))] + "TARGET_SINGLE_FPU && + (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" + "@ + mr %0,%1 + {cal|la} %0,%a1 + {l%U1%X1|lwz%U1%X1} %0,%1 + {st%U0%X0|stw%U0%X0} %1,%0 + {lil|li} %0,%1 + {liu|lis} %0,%v1 + # + {cal|la} %0,%a1 + mf%1 %0 + mt%0 %1 + mt%0 %1 + mt%0 %1 + {cror 0,0,0|nop} + stfs%U0%X0 %1, %0 + lfs%U1%X1 %0, %1" + [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4,4")]) + ;; Split a load of a large constant into the appropriate two-insn ;; sequence. @@ -9077,8 +9106,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,ws,?wa,ws,?wa,Z,?Z,f,f,m,wa,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,f,m,f,j,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,d,m,d,j,G,H,F"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -9089,73 +9118,9 @@ default: gcc_unreachable (); case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register - of operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; case 1: - if (rs6000_offsettable_memref_p (operands[1]) - || (GET_CODE (operands[1]) == MEM - && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM - || GET_CODE (XEXP (operands[1], 0)) == PRE_INC - || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC - || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY))) - { - /* If the low-address word is used in the address, we must load - it last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is - known to be dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\"; - } - else - { - rtx addreg; - - addreg = find_addr_reg (XEXP (operands[1], 0)); - if (refers_to_regno_p (REGNO (operands[0]), - REGNO (operands[0]) + 1, - operands[1], 0)) - { - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"{l%X1|lwz%X1} %0,%1\"; - } - else - { - output_asm_insn (\"{l%X1|lwz%X1} %0,%1\", operands); - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"\"; - } - } case 2: - if (rs6000_offsettable_memref_p (operands[0]) - || (GET_CODE (operands[0]) == MEM - && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM - || GET_CODE (XEXP (operands[0], 0)) == PRE_INC - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC - || GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY))) - return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\"; - else - { - rtx addreg; - - addreg = find_addr_reg (XEXP (operands[0], 0)); - output_asm_insn (\"{st%X0|stw%X0} %1,%0\", operands); - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{st%X0|stw%X0} %L1,%0\", operands); - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"\"; - } + return \"#\"; case 3: case 4: return \"xxlor %x0,%x1,%x1\"; @@ -9186,50 +9151,19 @@ [(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"))] "! TARGET_POWERPC64 - && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) + && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load - it last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is - known to be dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\"; - case 2: - return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\"; - case 3: - case 4: - case 5: - return \"#\"; - } -}" + "#" [(set_attr "type" "two,load,store,*,*,*") (set_attr "length" "8,8,8,8,12,16")]) ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64_mfpgpr" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,f,f,m,wa,*c*l,!r,*h,!r,!r,!r,r,f") - (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,f,m,f,j,r,h,0,G,H,F,f,r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r,r,d") + (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,r"))] "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) @@ -9262,8 +9196,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,f,f,m,wa,*c*l,!r,*h,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,f,m,f,j,r,h,0,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F"))] "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) @@ -9320,8 +9254,8 @@ ; otherwise reload, given m->f, will try to pick f->f and reload it, ; which doesn't make progress. Likewise r->Y must be before r->r. (define_insn_and_split "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r") - (match_operand:TF 1 "input_operand" "f,o,f,YGHF,r,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,d,r,Y,r") + (match_operand:TF 1 "input_operand" "d,o,d,YGHF,r,r"))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 && (gpc_reg_operand (operands[0], TFmode) @@ -9375,9 +9309,9 @@ }) (define_insn_and_split "*extenddftf2_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r") - (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF"))) - (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,&d,r") + (float_extend:TF (match_operand:DF 1 "input_operand" "dr,md,md,rmGHF"))) + (use (match_operand:DF 2 "zero_reg_mem_operand" "rd,m,d,n"))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" @@ -9418,8 +9352,8 @@ "") (define_insn_and_split "trunctfdf2_internal1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))] "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "@ @@ -9434,8 +9368,8 @@ [(set_attr "type" "fp")]) (define_insn "trunctfdf2_internal2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))] "!TARGET_IEEEQUAD && TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" @@ -9460,8 +9394,8 @@ (define_insn_and_split "trunctfsf2_fprs" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f"))) - (clobber (match_scratch:DF 2 "=f"))] + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d"))) + (clobber (match_scratch:DF 2 "=d"))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_LONG_DOUBLE_128" @@ -9490,10 +9424,10 @@ ; fadd, but rounding towards zero. ; This is probably not the optimal code sequence. (define_insn "fix_trunc_helper" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")] UNSPEC_FIX_TRUNC_TF)) - (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))] + (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" [(set_attr "type" "fp") @@ -9534,15 +9468,15 @@ (define_insn_and_split "*fix_trunctfsi2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DF 2 "gpc_reg_operand" "=f")) - (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f")) - (clobber (match_operand:DI 4 "gpc_reg_operand" "=f")) + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d"))) + (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) + (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) + (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "#" - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))" + "" [(pc)] { rtx lowword; @@ -9567,8 +9501,8 @@ "") (define_insn "negtf2_internal" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TF 0 "gpc_reg_operand" "=d") + (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "* @@ -9633,8 +9567,8 @@ ; List r->r after r->"o<>", otherwise reload will try to reload a ; non-offsettable address by using r->r which won't make progress. (define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r") - (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))] + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r") + (match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF"))] "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -9670,16 +9604,16 @@ }") (define_split - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "") - (match_operand:DI 1 "input_operand" ""))] + [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "") + (match_operand:DIFD 1 "input_operand" ""))] "reload_completed && !TARGET_POWERPC64 && gpr_or_gpr_p (operands[0], operands[1])" [(pc)] { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_insn "*movdi_mfpgpr" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f") - (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,r,*d") + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,*d,r"))] "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -9703,8 +9637,8 @@ (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")]) (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h") - (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h") + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0"))] "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -9870,7 +9804,7 @@ || gpc_reg_operand (operands[1], TImode))) && VECTOR_MEM_NONE_P (TImode)" "#" - [(set_attr "type" "*,load,store")]) + [(set_attr "type" "*,store,load")]) (define_split [(set (match_operand:TI 0 "gpc_reg_operand" "") @@ -10899,7 +10833,7 @@ [(set_attr "type" "store_ux,store_u")]) (define_insn "*movdf_update1" - [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f") + [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") @@ -10915,7 +10849,7 @@ (define_insn "*movdf_update2" [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:DF 3 "gpc_reg_operand" "f,f")) + (match_operand:DF 3 "gpc_reg_operand" "d,d")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE @@ -11004,7 +10938,7 @@ (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) -(define_insn "tls_gd_aix<TLSmode:tls_abi_suffix>" +(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) (match_operand 4 "" "g"))) @@ -11014,10 +10948,21 @@ (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" "addi %0,%1,%2@got@tlsgd\;bl %z3\;%." + "&& TARGET_TLS_MARKERS" + [(set (match_dup 0) + (unspec:TLSmode [(match_dup 1) + (match_dup 2)] + UNSPEC_TLSGD)) + (parallel [(set (match_dup 0) + (call (mem:TLSmode (match_dup 3)) + (match_dup 4))) + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))])] + "" [(set_attr "type" "two") (set_attr "length" "12")]) -(define_insn "tls_gd_sysv<TLSmode:tls_sysv_suffix>" +(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) (match_operand 4 "" "g"))) @@ -11037,10 +10982,62 @@ else return "addi %0,%1,%2@got@tlsgd\;bl %z3"; } + "&& TARGET_TLS_MARKERS" + [(set (match_dup 0) + (unspec:TLSmode [(match_dup 1) + (match_dup 2)] + UNSPEC_TLSGD)) + (parallel [(set (match_dup 0) + (call (mem:TLSmode (match_dup 3)) + (match_dup 4))) + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))])] + "" [(set_attr "type" "two") (set_attr "length" "8")]) -(define_insn "tls_ld_aix<TLSmode:tls_abi_suffix>" +(define_insn "*tls_gd<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS" + "addi %0,%1,%2@got@tlsgd" + [(set_attr "length" "4")]) + +(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" + "bl %z1(%3@tlsgd)\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" +{ + if (flag_pic) + { + if (TARGET_SECURE_PLT && flag_pic == 2) + return "bl %z1+32768(%3@tlsgd)@plt"; + return "bl %z1(%3@tlsgd)@plt"; + } + return "bl %z1(%3@tlsgd)"; +} + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) (match_operand 3 "" "g"))) @@ -11049,9 +11046,19 @@ (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" "addi %0,%1,%&@got@tlsld\;bl %z2\;%." + "&& TARGET_TLS_MARKERS" + [(set (match_dup 0) + (unspec:TLSmode [(match_dup 1)] + UNSPEC_TLSLD)) + (parallel [(set (match_dup 0) + (call (mem:TLSmode (match_dup 2)) + (match_dup 3))) + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))])] + "" [(set_attr "length" "12")]) -(define_insn "tls_ld_sysv<TLSmode:tls_sysv_suffix>" +(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) (match_operand 3 "" "g"))) @@ -11070,8 +11077,56 @@ else return "addi %0,%1,%&@got@tlsld\;bl %z2"; } + "&& TARGET_TLS_MARKERS" + [(set (match_dup 0) + (unspec:TLSmode [(match_dup 1)] + UNSPEC_TLSLD)) + (parallel [(set (match_dup 0) + (call (mem:TLSmode (match_dup 2)) + (match_dup 3))) + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))])] + "" [(set_attr "length" "8")]) +(define_insn "*tls_ld<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] + UNSPEC_TLSLD))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS" + "addi %0,%1,%&@got@tlsld" + [(set_attr "length" "4")]) + +(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" + "bl %z1(%&@tlsld)\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" +{ + if (flag_pic) + { + if (TARGET_SECURE_PLT && flag_pic == 2) + return "bl %z1+32768(%&@tlsld)@plt"; + return "bl %z1(%&@tlsld)@plt"; + } + return "bl %z1(%&@tlsld)"; +} + [(set_attr "type" "branch") + (set_attr "length" "4")]) + (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") @@ -12377,6 +12432,14 @@ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] "" "") + +(define_insn "probe_stack" + [(set (match_operand 0 "memory_operand" "=m") + (unspec [(const_int 0)] UNSPEC_PROBE_STACK))] + "" + "{st%U0%X0|stw%U0%X0} 0,%0" + [(set_attr "type" "store") + (set_attr "length" "4")]) ;; Compare insns are next. Note that the RS/6000 has two types of compares, ;; signed & unsigned, and one type of branch. @@ -12680,6 +12743,7 @@ (match_operand 2 "" "")] "" { + rtx test, op0, op1; #ifdef TARGET_THREAD_SSP_OFFSET rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); @@ -12843,8 +12907,8 @@ (define_insn "*cmpdf_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f")))] + (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d") + (match_operand:DF 2 "gpc_reg_operand" "d")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !VECTOR_UNIT_VSX_P (DFmode)" "fcmpu %0,%1,%2" @@ -12853,8 +12917,8 @@ ;; Only need to compare second words if first words equal (define_insn "*cmptf_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") - (match_operand:TF 2 "gpc_reg_operand" "f")))] + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d") + (match_operand:TF 2 "gpc_reg_operand" "d")))] "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" @@ -12863,16 +12927,16 @@ (define_insn_and_split "*cmptf_internal2" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") - (match_operand:TF 2 "gpc_reg_operand" "f"))) - (clobber (match_scratch:DF 3 "=f")) - (clobber (match_scratch:DF 4 "=f")) - (clobber (match_scratch:DF 5 "=f")) - (clobber (match_scratch:DF 6 "=f")) - (clobber (match_scratch:DF 7 "=f")) - (clobber (match_scratch:DF 8 "=f")) - (clobber (match_scratch:DF 9 "=f")) - (clobber (match_scratch:DF 10 "=f"))] + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d") + (match_operand:TF 2 "gpc_reg_operand" "d"))) + (clobber (match_scratch:DF 3 "=d")) + (clobber (match_scratch:DF 4 "=d")) + (clobber (match_scratch:DF 5 "=d")) + (clobber (match_scratch:DF 6 "=d")) + (clobber (match_scratch:DF 7 "=d")) + (clobber (match_scratch:DF 8 "=d")) + (clobber (match_scratch:DF 9 "=d")) + (clobber (match_scratch:DF 10 "=d"))] "!TARGET_IEEEQUAD && TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "#" @@ -12890,7 +12954,7 @@ (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) - (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4))) + (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) (match_dup 12)] { REAL_VALUE_TYPE rv; @@ -15348,7 +15412,7 @@ (use (match_operand:P 1 "symbol_ref_operand" "s")) (use (match_operand:P 2 "gpc_reg_operand" "r")) (set (match_operand:DF 3 "memory_operand" "=m") - (match_operand:DF 4 "gpc_reg_operand" "f"))])] + (match_operand:DF 4 "gpc_reg_operand" "d"))])] "" "bl %1" [(set_attr "type" "branch") @@ -15468,7 +15532,7 @@ (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (match_operand:P 3 "gpc_reg_operand" "r")) - (set (match_operand:DF 4 "gpc_reg_operand" "=f") + (set (match_operand:DF 4 "gpc_reg_operand" "=d") (match_operand:DF 5 "memory_operand" "m"))])] "" "b %2" diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index ce429e8f92d..63f0f8c1582 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -171,12 +171,16 @@ mfused-madd Target Report Var(TARGET_FUSED_MADD) Init(1) Generate fused multiply/add instructions -msched-prolog -Target Report Var(TARGET_SCHED_PROLOG) Init(1) -Schedule the start and end of the procedure +mtls-markers +Target Report Var(tls_markers) Init(1) +Mark __tls_get_addr calls with argument info msched-epilog -Target Undocumented Var(TARGET_SCHED_PROLOG) VarExists +Target Undocumented Var(TARGET_SCHED_PROLOG) Init(1) + +msched-prolog +Target Report Var(TARGET_SCHED_PROLOG) VarExists +Schedule the start and end of the procedure maix-struct-return Target Report RejectNegative Var(aix_struct_return) diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000 index d60b616e52d..0aac270e8a0 100644 --- a/gcc/config/rs6000/t-rs6000 +++ b/gcc/config/rs6000/t-rs6000 @@ -1,4 +1,23 @@ # General rules that all rs6000/ targets must have. +# +# Copyright (C) 1995, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2008, 2009 +# Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. TM_H += $(srcdir)/config/rs6000/rs6000-builtin.def @@ -38,6 +57,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \ $(srcdir)/config/rs6000/power7.md \ $(srcdir)/config/rs6000/cell.md \ $(srcdir)/config/rs6000/xfpu.md \ + $(srcdir)/config/rs6000/a2.md \ $(srcdir)/config/rs6000/predicates.md \ $(srcdir)/config/rs6000/constraints.md \ $(srcdir)/config/rs6000/darwin.md \ diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index bcfb9fb9777..7f927f103d2 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -3,7 +3,7 @@ ;; expander, and the actual vector instructions will be in altivec.md and ;; vsx.md -;; Copyright (C) 2009 +;; Copyright (C) 2009, 2010 ;; Free Software Foundation, Inc. ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> |