;; 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 Free Software Foundation, Inc.
+;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; 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 2, or (at your
+;; option) any later version.
-;; GNU CC 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.
+;; 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;; `unspec' values used in rs6000.md:
-;; Number Use
-;; 0 frsp for POWER machines
-;; 0/v blockage
-;; 5 used to tie the stack contents and the stack pointer
-;; 6 address of a word pointing to the TOC
-;; 7 address of the TOC (more-or-less)
-;; 8 movsi_got
-;; 9/v eh_reg_restore
-;; 10 fctiwz
-;; 19 movesi_from_cr
-;; 20 movesi_to_cr
+;;
+;; UNSPEC usage
+;;
+
+(define_constants
+ [(UNSPEC_FRSP 0) ; frsp for POWER machines
+ (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)
+ (UNSPEC_MOVSI_GOT 8)
+ (UNSPEC_MV_CR_OV 9) ; move_from_CR_ov_bit
+ (UNSPEC_FCTIWZ 10)
+ (UNSPEC_LD_MPIC 15) ; load_macho_picbase
+ (UNSPEC_MPIC_CORRECT 16) ; macho_correct_pic
+ (UNSPEC_TLSGD 17)
+ (UNSPEC_TLSLD 18)
+ (UNSPEC_MOVESI_FROM_CR 19)
+ (UNSPEC_MOVESI_TO_CR 20)
+ (UNSPEC_TLSDTPREL 21)
+ (UNSPEC_TLSDTPRELHA 22)
+ (UNSPEC_TLSDTPRELLO 23)
+ (UNSPEC_TLSGOTDTPREL 24)
+ (UNSPEC_TLSTPREL 25)
+ (UNSPEC_TLSTPRELHA 26)
+ (UNSPEC_TLSTPRELLO 27)
+ (UNSPEC_TLSGOTTPREL 28)
+ (UNSPEC_TLSTLS 29)
+ ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_constants
+ [(UNSPECV_BLOCK 0)
+ (UNSPECV_EH_RR 9) ; eh_reg_restore
+ ])
\f
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
+(define_attr "type" "integer,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv"
(const_string "integer"))
;; Length (in bytes).
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4"
(const (symbol_ref "rs6000_cpu_attr")))
-; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
-; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
-
-; Load/Store Unit -- pure PowerPC only
-; (POWER and 601 use Integer Unit)
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load,vecload")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,vecstore")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "ppc7450"))
- 3 3)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "mpccore,ppc603,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc7450"))
- 4 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rs64a,ppc604,ppc604e,ppc620,ppc630"))
- 3 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "rios1,ppc601"))
- 0 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc601"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "load,fpload")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-; Integer Unit (RIOS1, PPC601, PPC603, RS64a)
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios1,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc403"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc405"))
- 4 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc405"))
- 3 2)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rios1"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rios1"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rios1"))
- 3 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc601,ppc603"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rs64a"))
- 20 20)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rs64a"))
- 12 12)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rs64a"))
- 8 8)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "rs64a"))
- 34 34)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc403"))
- 33 33)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc405"))
- 35 35)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc601"))
- 36 36)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc603"))
- 37 36)
-
-; RIOS2 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
-; Divide latency varies greatly from 2-11, use 6 as average
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "mpccore"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "mpccore"))
- 6 6)
-
-; PPC604{,e} has two units that perform integer operations
-; and one unit for divide/multiply operations (and move
-; from/to spr).
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604e"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 5 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc620,ppc630"))
- 4 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc620,ppc630"))
- 3 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 7 5)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc604,ppc604e"))
- 20 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc620"))
- 37 36)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc630"))
- 21 20)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "ppc620,ppc630"))
- 37 36)
-
-; PPC7450 has 3 integer units (for most integer insns) and one mul/div
-; unit, which also does CR-logical insns and move to/from SPR.
-; It also has 4 vector units, one for each type of vector instruction.
-; However, we can only dispatch 2 instructions per cycle.
-; We model this as saying that dispatching two of the same type of instruction
-; in a row incurs a single cycle delay.
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc7450"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc7450"))
- 23 23)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 2 [(eq_attr "type" "vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 1 [(eq_attr "type" "!vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "vecperm")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!vecperm")])
-
-; PPC750 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-; CR-logical operations are execute-serialized, that is they don't
-; start (and block the function unit) until all preceding operations
-; have finished. They don't block dispatch of other insns, though.
-; I've imitated this by giving them longer latency.
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc603,ppc750,ppc7400"))
- 3 2)
-
-; compare is done on integer unit, but feeds insns which
-; execute on the branch unit.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "rios1"))
- 4 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "rios1"))
- 5 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 3 1)
-
-; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
-; and a following branch, to reduce mispredicts
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rios2"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 1 1)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios1"))
- 9 1)
-
-; rios1 and rios2 have different fpcompare delays
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios2,ppc630"))
- 5 1)
-
-; on ppc601 and ppc603, fpcompare takes also 2 cycles from
-; the integer unit
-; here we do not define delays, just occupy the unit. The dependencies
-; will be assigned by the fpcompare definition in the fpu.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc601,ppc603"))
- 0 2)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rs64a,ppc601,ppc603,ppc604,ppc604e,ppc620"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc750,ppc7400,ppc7450"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "mpccore"))
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "rios1,rios2,rs64a"))
- 5 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 4 1)
-
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc7450"))
- 2 2)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "rios1,rios2,ppc604"))
- 4 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc604e,ppc620,ppc630,rs64a"))
- 1 1)
-
-; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "jmpreg")
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "branch")
- 1 1)
-
-; Floating Point Unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "rs64a,mpccore"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc601"))
- 4 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620,ppc750,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc7450"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "rs64a"))
- 7 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "mpccore"))
- 5 5)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc601"))
- 5 2)
-
-; is this true?
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc603,ppc750"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "rs64a"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc601,ppc750,ppc7400"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc7450"))
- 21 21)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "mpccore"))
- 10 10)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620"))
- 18 18)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "mpccore"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "rs64a,ppc601,ppc750,ppc604,ppc604e,ppc620,ppc7400"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc7450"))
- 35 35)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc603"))
- 33 33)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-; RIOS2 has two symmetric FPUs.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc630"))
- 3 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios2"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc630"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc630"))
- 21 21)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "rios2"))
- 26 26)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc630"))
- 18 18)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc630"))
- 26 26)
-
-;; Power4
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "power4"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul,lmul")
- (eq_attr "cpu" "power4"))
- 7 6)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "power4"))
- 5 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "power4"))
- 4 3)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "jmpreg,branch")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "power4"))
- 6 1)
-
-; adjust_cost increases the cost of dependent branches,
-; so shave a few cycles off for fpcompare.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "power4"))
- 33 28)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "power4"))
- 40 35)
+(automata_option "ndfa")
+
+(include "rios1.md")
+(include "rios2.md")
+(include "rs64.md")
+(include "mpc.md")
+(include "40x.md")
+(include "440.md")
+(include "603.md")
+(include "6xx.md")
+(include "7xx.md")
+(include "7450.md")
+(include "8540.md")
+(include "power4.md")
\f
;; Start with fixed-point load and store insns. Here we put only the more
"@
lha%U1%X1 %0,%1
extsh %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
"@
lwa%U1%X1 %0,%1
extsw %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
"@
lha%U1%X1 %0,%1
{exts|extsh} %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
{ai.|addic.} %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
{ai.|addic.} %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
(const_int 0)))]
"")
-(define_insn "ffssi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
- (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (clz:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
""
- "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
- [(set_attr "length" "16")])
+ "{cntlz|cntlzw} %0,%1")
+(define_expand "ctzsi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 31) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
+(define_expand "ffssi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 32) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
(define_expand "mulsi3"
[(use (match_operand:SI 0 "gpc_reg_operand" ""))
(use (match_operand:SI 1 "gpc_reg_operand" ""))
(const_string "imul2")]
(const_string "imul")))])
-(define_insn ""
+(define_insn "*mulsi3_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (set (match_operand:SI 3 "register_operand" "")
(mod:SI (match_dup 1) (match_dup 2)))])]
"TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
"
}
}")
-(define_insn ""
+(define_insn "*divmodsi4_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "gpc_reg_operand" "r")))
- (set (match_operand:SI 3 "gpc_reg_operand" "=q")
+ (set (match_operand:SI 3 "register_operand" "=q")
(mod:SI (match_dup 1) (match_dup 2)))]
"TARGET_POWER"
"divs %0,%1,%2"
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
-\f
+
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
(compare:CC
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-
+\f
;; Rotate and shift insns, in all their variants. These support shifts,
;; field inserts and extracts, and various combinations thereof.
(define_expand "insv"
if (which_alternative == 1)
return \"#\";
- /* If the bitfield being tested fits in the upper or lower half of a
+ /* If the bit-field being tested fits in the upper or lower half of a
word, it is possible to use andiu. or andil. to test it. This is
useful because the condition register set-use delay is smaller for
andi[ul]. than for rlinm. This doesn't work when the starting bit
return \"#\";
/* Since we are using the output value, we can't ignore any need for
- a shift. The bitfield must end at the LSB. */
+ a shift. The bit-field must end at the LSB. */
if (start >= 16 && start + size == 32)
{
operands[3] = GEN_INT ((1 << size) - 1);
(define_insn "aux_truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
+ (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
"frsp %0,%1"
[(set_attr "type" "fp")])
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(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_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (SFmode)"
+ "fnmadds %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
+ (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
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
"fnmadds %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
+ (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
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
+ "{fnma|fnmadd} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(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_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (SFmode)"
+ "fnmsubs %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
+ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+ (match_operand:SF 2 "gpc_reg_operand" "f"))))]
+ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
"fnmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")])
"{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
+(define_insn ""
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
+ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+ (match_operand:SF 2 "gpc_reg_operand" "f"))))]
+ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (SFmode)"
+ "{fnms|fnmsub} %0,%1,%2,%3"
+ [(set_attr "type" "fp")])
+
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
(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"))))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (DFmode)"
+ "{fnma|fnmadd} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(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")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (DFmode)"
"{fnma|fnmadd} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
(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"))))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && HONOR_SIGNED_ZEROS (DFmode)"
+ "{fnms|fnmsub} %0,%1,%2,%3"
+ [(set_attr "type" "dmul")])
+
+(define_insn ""
+ [(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"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
+ && ! HONOR_SIGNED_ZEROS (DFmode)"
"{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul")])
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))
- (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "24")])
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "20")])
DONE;
}")
-; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10))
+; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
; rather than (set (subreg:SI (reg)) (fix:SI ...))
; 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"))] 10))]
+ (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+ UNSPEC_FCTIWZ))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
"{fcirz|fctiwz} %0,%1"
[(set_attr "type" "fp")])
"")
;; Twiddles bits to avoid double rounding.
-;; Bits that might be trucated when converting to DFmode are replaced
+;; Bits that might be truncated when converting to DFmode are replaced
;; by a bit that won't be lost at that stage, but is below the SFmode
;; rounding position.
(define_expand "floatdisf2_internal2"
- [(set (match_dup 2) (and:DI (match_operand:DI 0 "" "") (const_int 2047)))
- (set (match_dup 4) (compare:CC (match_dup 2) (const_int 0)))
+ [(parallel [(set (match_dup 4)
+ (compare:CC (and:DI (match_operand:DI 0 "" "")
+ (const_int 2047))
+ (const_int 0)))
+ (set (match_dup 2) (and:DI (match_dup 0) (const_int 2047)))
+ (clobber (match_scratch:CC 7 ""))])
(set (match_dup 3) (ashiftrt:DI (match_dup 0) (const_int 53)))
(set (match_dup 3) (plus:DI (match_dup 3) (const_int 1)))
(set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
addic. %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
addic. %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
(const_int 0)))]
"")
-(define_insn "ffsdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
- (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (clz:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64"
- "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
- [(set_attr "length" "16")])
+ "cntlzd %0,%1")
+
+(define_expand "ctzdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 63) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
+
+(define_expand "ffsdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 64) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
(define_insn "muldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
"mulld %0,%1,%2"
[(set_attr "type" "lmul")])
+(define_insn "*muldi3_internal1"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 "=r,r"))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %3,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 ""))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 3)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
+
+(define_insn "*muldi3_internal2"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %0,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 0)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
(define_insn "smuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
(define_expand "movsi_got"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_operand" "")
- (match_dup 2)] 8))]
+ (match_dup 2)] UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"
{
(define_insn "*movsi_got_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
+ (match_operand:SI 2 "gpc_reg_operand" "b")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"{l|lwz} %0,%a1@got(%2)"
[(set_attr "type" "load")])
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "memory_operand" "")] 8))]
+ (match_operand:SI 2 "memory_operand" "")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4
&& flag_pic == 1
&& (reload_in_progress || reload_completed)"
[(set (match_dup 0) (match_dup 2))
- (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 8))]
+ (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
+ UNSPEC_MOVSI_GOT))]
"")
;; For SI, we special-case integers that can't be loaded in one insn. We
operands2[2] = operands[2];
operands2[3] = gen_rtx_REG (SImode, RS6000_PIC_OFFSET_TABLE_REGNUM);
output_asm_insn (\"{l|lwz} %0,lo16(%2)(%1)\", operands);
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ output_asm_insn (\"{liu|lis} %L0,ha16(%2+4)\", operands);
+ else
/* We cannot rely on ha16(low half)==ha16(high half), alas,
although in practice it almost always is. */
output_asm_insn (\"{cau|addis} %L0,%3,ha16(%2+4)\", operands2);
+#endif
return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\");
}
default:
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*,*")
+ [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
(set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
\f
;; Here is how to move condition codes around. When we store CC data in
;; an integer register or memory, we store just the high-order 4 bits.
"")
(define_insn "*movcc_internal1"
- [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
- (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
+ [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,r,r,r,r,q,cl,r,m")
+ (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,h,r,r,m,r"))]
"register_operand (operands[0], CCmode)
|| register_operand (operands[1], CCmode)"
"@
mfcr %0
mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
mr %0,%1
+ mf%1 %0
+ mt%0 %1
+ mt%0 %1
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
- [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,load,store")
- (set_attr "length" "*,*,12,*,8,*,*,*")])
+ [(set_attr "type" "cr_logical,mtcr,mtcr,mfcr,mfcr,*,mfjmpr,*,mtjmpr,load,store")
+ (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")])
\f
;; For floating-point, we normally deal with the floating-point registers
;; unless -msoft-float is used. The sole exception is that parameter passing
}")
(define_insn "*movsf_hardfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r")
- (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!r,!r")
+ (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,G,Fn"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_HARD_FLOAT && TARGET_FPRS)"
fmr %0,%1
lfs%U1%X1 %0,%1
stfs%U0%X0 %1,%0
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
#
#"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,8")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
- (match_operand:SF 1 "input_operand" "r,m,r,I,L,R,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
+ (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
"@
mr %0,%1
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
{liu|lis} %0,%v1
{cal|la} %0,%a1
#
- #"
- [(set_attr "type" "*,load,store,*,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,8")])
+ #
+ {cror 0,0,0|nop}"
+ [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
\f
(define_expand "movdf"
int endian = (WORDS_BIG_ENDIAN == 0);
long l[2];
REAL_VALUE_TYPE rv;
+#if HOST_BITS_PER_WIDE_INT >= 64
HOST_WIDE_INT val;
+#endif
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
operands[2] = gen_lowpart (DImode, operands[0]);
/* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
#if HOST_BITS_PER_WIDE_INT >= 64
- val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 |
- ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
+ val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
- operands[3] = immed_double_const (val, -(val < 0), DImode);
+ operands[3] = gen_int_mode (val, DImode);
#else
operands[3] = immed_double_const (l[1 - endian], l[endian], DImode);
#endif
;; The "??" is a kludge until we can figure out a more reasonable way
;; of handling these non-offsettable values.
(define_insn "*movdf_hardfloat32"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
return \"\";
}
case 3:
+ return \"fmr %0,%1\";
case 4:
+ return \"lfd%U1%X1 %0,%1\";
case 5:
- return \"#\";
+ return \"stfd%U0%X0 %1,%0\";
case 6:
- return \"fmr %0,%1\";
case 7:
- return \"lfd%U1%X1 %0,%1\";
case 8:
- return \"stfd%U0%X0 %1,%0\";
+ return \"#\";
}
}"
- [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
- (set_attr "length" "8,16,16,8,12,16,*,*,*")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*")
+ (set_attr "length" "8,16,16,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
(set_attr "length" "8,8,8,8,12,16")])
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
mr %0,%1
ld%U1%X1 %0,%1
std%U0%X0 %1,%0
- #
- #
- #
fmr %0,%1
lfd%U1%X1 %0,%1
- stfd%U0%X0 %1,%0"
- [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
- (set_attr "length" "4,4,4,8,12,16,4,4,4")])
+ stfd%U0%X0 %1,%0
+ mt%0 %1
+ mf%1 %0
+ #
+ #
+ #"
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
- (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r")
+ (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))]
"TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
mr %0,%1
+ mt%0 %1
+ mf%1 %0
ld%U1%X1 %0,%1
std%U0%X0 %1,%0
#
#
#"
- [(set_attr "type" "*,load,store,*,*,*")
- (set_attr "length" "*,*,*,8,12,16")])
+ [(set_attr "type" "*,*,*,load,store,*,*,*")
+ (set_attr "length" "4,4,4,4,4,8,12,16")])
\f
(define_expand "movtf"
[(set (match_operand:TF 0 "general_operand" "")
else
return \"fmr %0,%1\;fmr %L0,%L1\";
case 1:
- return \"lfd %0,%1\;lfd %L0,%L1\";
+ return \"lfd %0,%1\;lfd %L0,%Y1\";
case 2:
- return \"stfd %1,%0\;stfd %L1,%L0\";
+ return \"stfd %1,%0\;stfd %L1,%Y0\";
case 3:
case 4:
case 5:
(define_split
[(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "const_double_operand" ""))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- [(set (match_dup 3) (match_dup 1))
- (set (match_dup 0)
- (float_extend:TF (match_dup 3)))]
+ (match_operand:TF 1 "easy_fp_constant" ""))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 6))
+ (set (match_dup 3) (match_dup 7))
+ (set (match_dup 4) (match_dup 8))
+ (set (match_dup 5) (match_dup 9))]
"
{
- operands[2] = operand_subword (operands[1], 0, 0, DFmode);
- operands[3] = gen_reg_rtx (DFmode);
+ long l[4];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+ operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+ operands[4] = operand_subword (operands[0], 2, 0, TFmode);
+ operands[5] = operand_subword (operands[0], 3, 0, TFmode);
+ operands[6] = gen_int_mode (l[0], SImode);
+ operands[7] = gen_int_mode (l[1], SImode);
+ operands[8] = gen_int_mode (l[2], SImode);
+ operands[9] = gen_int_mode (l[3], SImode);
}")
-(define_insn_and_split "extenddftf2"
+(define_split
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
+ (match_operand:TF 1 "easy_fp_constant" ""))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ long l[4];
+ REAL_VALUE_TYPE rv;
+#if HOST_BITS_PER_WIDE_INT >= 64
+ HOST_WIDE_INT val;
+#endif
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = gen_lowpart (DImode, operands[0]);
+ operands[3] = gen_highpart (DImode, operands[0]);
+#if HOST_BITS_PER_WIDE_INT >= 64
+ val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[1]));
+ operands[4] = gen_int_mode (val, DImode);
+
+ val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32
+ | ((HOST_WIDE_INT)(unsigned long)l[3]));
+ operands[5] = gen_int_mode (val, DImode);
+#else
+ operands[4] = immed_double_const (l[1], l[0], DImode);
+ operands[5] = immed_double_const (l[3], l[2], DImode);
+#endif
+}")
+
+(define_insn "extenddftf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
- "#"
- ""
- [(set (match_dup 2) (match_dup 3))]
- "
+ "*
{
- operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1));
- operands[3] = CONST0_RTX (DFmode);
-}")
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"fsub %L0,%L0,%L0\";
+ else
+ return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
+}"
+ [(set_attr "type" "fp")])
-(define_insn_and_split "extendsftf2"
+(define_insn "extendsftf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
- "#"
- ""
- [(set (match_dup 2) (match_dup 3))]
- "
+ "*
{
- operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1));
- operands[3] = CONST0_RTX (SFmode);
-}")
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"fsub %L0,%L0,%L0\";
+ else
+ return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
+}"
+ [(set_attr "type" "fp")])
(define_insn "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))
- (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float:DF (match_dup 1)))
+ (set (match_dup 0)
(float_extend:TF (match_dup 2)))]
"")
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
- (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float:DF (match_dup 1)))
+ (set (match_dup 0)
(float_extend:TF (match_dup 2)))]
"")
(define_insn_and_split "fix_trunctfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))
+ (clobber (match_scratch:DF 2 "=f"))]
"DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
- (set (match_operand:DI 0 "gpc_reg_operand" "")
- (fix:SI (match_dup 2)))]
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
+ (fix:DI (match_dup 2)))]
"")
(define_insn_and_split "fix_trunctfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
+ (clobber (match_scratch:DF 2 "=f"))]
"DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
- (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
(fix:SI (match_dup 2)))]
"")
}
}"
[(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
- (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
+ (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
}")
+(define_split
+ [(set (match_operand:TI 0 "gpc_reg_operand" "")
+ (match_operand:TI 1 "const_double_operand" ""))]
+ "TARGET_POWERPC64"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
+ TImode);
+ operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
+ TImode);
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
+ operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ }
+ else if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
+ operands[5] = operands[1];
+ }
+ else
+ FAIL;
+}")
+
(define_insn "*movdi_internal64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
+ [(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"))]
"TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
mf%1 %0
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
+ [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
(set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
;; immediate value valid for a single instruction hiding in a const_double
case 0:
return \"{stsi|stswi} %1,%P0,16\";
-
case 1:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
-
case 2:
/* Normally copy registers with lowest numbered register copied first.
But copy in the other order if the first register of the output
}
}"
[(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "*,16,16,*,16")])
+ (set_attr "length" "4,16,16,4,16")])
(define_insn "*movti_string"
- [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
- (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
- (clobber (match_scratch:SI 2 "=X,X,X"))]
+ [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
+ (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
"TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
abort ();
case 0:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
-
+ return \"{stsi|stswi} %1,%P0,16\";
case 1:
+ return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
+ case 2:
/* Normally copy registers with lowest numbered register copied first.
But copy in the other order if the first register of the output
is the second, third, or fourth register in the input. */
return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
- case 2:
+ case 3:
+ /* If the address is not used in the output, we can use lsi. Otherwise,
+ fall through to generating four loads. */
+ if (! reg_overlap_mentioned_p (operands[0], operands[1]))
+ return \"{lsi|lswi} %0,%P1,16\";
+ /* ... fall through ... */
+ case 4:
/* If the address register is the same as the register for the lowest-
addressed word, load it last. Similarly for the next two words.
Otherwise load lowest address to highest. */
return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
}
}"
- [(set_attr "type" "store,*,load")
- (set_attr "length" "16,16,16")])
+ [(set_attr "type" "store,store,*,load,load")
+ (set_attr "length" "4,16,16,4,16")])
(define_insn "*movti_ppc64"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
for (i = 0; i < count; i++)
XVECEXP (operands[3], 0, i)
= gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i),
- adjust_address (op1, SImode, i * 4));
+ adjust_address_nv (op1, SImode, i * 4));
}")
-(define_insn ""
+(define_insn "*ldmsi8"
[(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
- (mem:SI (match_operand:SI 2 "gpc_reg_operand" "b")))])]
- "TARGET_STRING"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+ (set (match_operand:SI 8 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 24))))
+ (set (match_operand:SI 9 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
"*
-{
- /* We have to handle the case where the pseudo used to contain the address
- is assigned to one of the output registers. */
- int i, j;
- int words = XVECLEN (operands[0], 0);
- rtx xop[10];
+{ return rs6000_output_load_multiple (operands); }"
+ [(set_attr "type" "load")
+ (set_attr "length" "32")])
- if (XVECLEN (operands[0], 0) == 1)
- return \"{l|lwz} %1,0(%2)\";
+(define_insn "*ldmsi7"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+ (set (match_operand:SI 8 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
+ "*
+{ return rs6000_output_load_multiple (operands); }"
+ [(set_attr "type" "load")
+ (set_attr "length" "32")])
- for (i = 0; i < words; i++)
- if (refers_to_regno_p (REGNO (operands[1]) + i,
- REGNO (operands[1]) + i + 1, operands[2], 0))
- {
- if (i == words-1)
- {
- xop[0] = operands[1];
- xop[1] = operands[2];
- xop[2] = GEN_INT (4 * (words-1));
- output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
- return \"\";
- }
- else if (i == 0)
- {
- xop[0] = operands[1];
- xop[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- xop[2] = GEN_INT (4 * (words-1));
- output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
- return \"\";
- }
- else
- {
- for (j = 0; j < words; j++)
- if (j != i)
- {
- xop[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + j);
- xop[1] = operands[2];
- xop[2] = GEN_INT (j * 4);
- output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
- }
- xop[0] = operands[2];
- xop[1] = GEN_INT (i * 4);
- output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
- return \"\";
- }
- }
+(define_insn "*ldmsi6"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+ (set (match_operand:SI 7 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
+ "*
+{ return rs6000_output_load_multiple (operands); }"
+ [(set_attr "type" "load")
+ (set_attr "length" "32")])
- return \"{lsi|lswi} %1,%2,%N0\";
-}"
+(define_insn "*ldmsi5"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+ (set (match_operand:SI 6 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
+ "*
+{ return rs6000_output_load_multiple (operands); }"
+ [(set_attr "type" "load")
+ (set_attr "length" "32")])
+
+(define_insn "*ldmsi4"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+ (set (match_operand:SI 5 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
+ "*
+{ return rs6000_output_load_multiple (operands); }"
+ [(set_attr "type" "load")
+ (set_attr "length" "32")])
+
+(define_insn "*ldmsi3"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "")
+ (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+ (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+ (set (match_operand:SI 4 "gpc_reg_operand" "")
+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
+ "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
+ "*
+{ return rs6000_output_load_multiple (operands); }"
[(set_attr "type" "load")
(set_attr "length" "32")])
-\f
(define_expand "store_multiple"
[(match_par_dup 3 [(set (match_operand:SI 0 "" "")
(match_operand:SI 1 "" ""))
op0 = replace_equiv_address (operands[0], to);
XVECEXP (operands[3], 0, 0)
- = gen_rtx_SET (VOIDmode, adjust_address (op0, SImode, 0), operands[1]);
+ = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]);
XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
gen_rtx_SCRATCH (SImode));
for (i = 1; i < count; i++)
XVECEXP (operands[3], 0, i + 1)
= gen_rtx_SET (VOIDmode,
- adjust_address (op0, SImode, i * 4),
+ adjust_address_nv (op0, SImode, i * 4),
gen_rtx_REG (SImode, regno + i));
}")
-(define_insn ""
+(define_insn "*store_multiple_power"
[(match_parallel 0 "store_multiple_operation"
[(set (match_operand:SI 1 "indirect_operand" "=Q")
(match_operand:SI 2 "gpc_reg_operand" "r"))
"{stsi|stswi} %2,%P1,%O0"
[(set_attr "type" "store")])
-(define_insn ""
+(define_insn "*stmsi8"
[(match_parallel 0 "store_multiple_operation"
- [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
- (clobber (match_scratch:SI 3 "X"))])]
- "TARGET_STRING && ! TARGET_POWER"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
+ (match_operand:SI 10 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 9"
"{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")])
+(define_insn "*stmsi7"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 8"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi6"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 7"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi5"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 6"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi4"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 5"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi3"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 4"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
\f
;; String/block move insn.
;; Argument 0 is the destination
"@
ldux %3,%0,%2
ldu %3,%2(%0)"
- [(set_attr "type" "load")])
-
-(define_insn "*movdi_update2"
- [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
- (sign_extend:DI
- (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
- (match_operand:DI 2 "gpc_reg_operand" "r")))))
- (set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
- "lwaux %3,%0,%2"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "movdi_update"
[(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
"@
stdux %3,%0,%2
stdu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsi_update1"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- ""
+ "TARGET_UPDATE"
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
+
+(define_insn "*movsi_update2"
+ [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
+ (sign_extend:DI
+ (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
+ (match_operand:DI 2 "gpc_reg_operand" "r")))))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=b")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "lwaux %3,%0,%2"
+ [(set_attr "type" "load_ext_ux")])
(define_insn "movsi_update"
[(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
-(define_insn "*movhi_update"
+(define_insn "*movhi_update1"
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update3"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
"@
lhaux %3,%0,%2
lhau %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ext_ux,load_ext_u")])
(define_insn "*movhi_update4"
[(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
sthux %3,%0,%2
sthu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movqi_update1"
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update3"
[(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
stbux %3,%0,%2
stbu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsf_update1"
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
"@
lfsux %3,%0,%2
lfsu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movsf_update2"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
stfsux %3,%0,%2
stfsu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
(define_insn "*movsf_update3"
[(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movsf_update4"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movdf_update1"
[(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
"@
lfdux %3,%0,%2
lfdu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movdf_update2"
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
"@
stfdux %3,%0,%2
stfdu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
(define_insn "load_toc_aix_si"
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(const_int 0)] 7))
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))
(use (reg:SI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
"*
(define_insn "load_toc_aix_di"
[(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(const_int 0)] 7))
+ (unspec:DI [(const_int 0)] UNSPEC_TOC))
(use (reg:DI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
"*
(define_insn "load_toc_v4_pic_si"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(const_int 0)] 7))]
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
"bl _GLOBAL_OFFSET_TABLE_@local-4"
[(set_attr "type" "branch")
(define_insn "load_toc_v4_PIC_1"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1)] 7)]
+ (unspec [(match_dup 1)] UNSPEC_TOC)]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
- "bl %1\\n%1:"
+ "bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "load_toc_v4_PIC_1b"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)]
+ (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")]
+ UNSPEC_TOCPTR)]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
- "bl %1\\n\\t.long %2-%1+4\\n%1:"
+ "bcl 20,31,%1\\n\\t.long %2-%1+4\\n%1:"
[(set_attr "type" "branch")
(set_attr "length" "8")])
(define_insn "load_toc_v4_PIC_2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+ (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(minus:SI (match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")))))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
(define_insn "load_macho_picbase"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(const_int 0)] 15))]
+ (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
+ UNSPEC_LD_MPIC))]
"(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
- "*
-{
-#if TARGET_MACHO
- char *picbase = machopic_function_base_name ();
- operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
-#endif
- return \"bcl 20,31,%1\\n%1:\";
-}"
+ "bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
(set_attr "length" "4")])
+(define_insn "macho_correct_pic"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
+ (match_operand:SI 3 "immediate_operand" "s")]
+ UNSPEC_MPIC_CORRECT)))]
+ "DEFAULT_ABI == ABI_DARWIN"
+ "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
+ [(set_attr "length" "8")])
+
;; If the TOC is shared over a translation unit, as happens with all
;; the kinds of PIC that we support, we need to restore the TOC
;; pointer only when jumping over units of translation.
+;; On Darwin, we need to reload the picbase.
(define_expand "builtin_setjmp_receiver"
[(use (label_ref (match_operand 0 "" "")))]
"(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
- || (TARGET_TOC && TARGET_MINIMAL_TOC)"
+ || (TARGET_TOC && TARGET_MINIMAL_TOC)
+ || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
"
{
- rs6000_emit_load_toc_table (FALSE);
+#if TARGET_MACHO
+ if (DEFAULT_ABI == ABI_DARWIN)
+ {
+ const char *picbase = machopic_function_base_name ();
+ rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
+ rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+ rtx tmplabrtx;
+ char tmplab[20];
+
+ ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
+ CODE_LABEL_NUMBER (operands[0]));
+ tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (tmplab, -1));
+
+ emit_insn (gen_load_macho_picbase (picreg, tmplabrtx));
+ emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
+ }
+ else
+#endif
+ rs6000_emit_load_toc_table (FALSE);
DONE;
}")
\f
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
operands[0] = XEXP (operands[0], 0);
if (GET_CODE (operands[0]) != SYMBOL_REF
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
|| (INTVAL (operands[2]) & CALL_LONG) != 0)
{
if (INTVAL (operands[2]) & CALL_LONG)
operands[0] = rs6000_longcall_ref (operands[0]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
operands[0] = force_reg (Pmode, operands[0]);
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) != SYMBOL_REF
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
|| (INTVAL (operands[3]) & CALL_LONG) != 0)
{
if (INTVAL (operands[3]) & CALL_LONG)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
operands[0] = force_reg (Pmode, operands[0]);
}")
;; Call to function in current module. No TOC pointer reload needed.
-;; Operand2 is non-zero if we are using the V.4 calling sequence and
+;; Operand2 is nonzero if we are using the V.4 calling sequence and
;; either the function was not prototyped, or it was prototyped as a
;; variable argument function. It is > 0 if FP registers were passed
;; and < 0 if they were not.
;; Call to function which may be in another module. Restore the TOC
;; pointer (r2) after the call unless this is System V.
-;; Operand2 is non-zero if we are using the V.4 calling sequence and
+;; Operand2 is nonzero if we are using the V.4 calling sequence and
;; either the function was not prototyped, or it was prototyped as a
;; variable argument function. It is > 0 if FP registers were passed
;; and < 0 if they were not.
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "(DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
{
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "(DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
{
[(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
- (use (scratch:SI))
+ (use (match_operand 3 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
abort ();
operands[0] = XEXP (operands[0], 0);
+ operands[3] = gen_reg_rtx (SImode);
}")
[(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[2]) & CALL_LONG) == 0"
"*
[(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[3]) & CALL_LONG) == 0"
"*
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
[(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
- (use (scratch:SI))
+ (use (match_operand 4 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
abort ();
operands[1] = XEXP (operands[1], 0);
+ operands[4] = gen_reg_rtx (SImode);
}")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
""
"")
\f
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
""
"{cmp%I2|cmpw%I2} %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
"TARGET_POWERPC64"
"cmpd%I2 %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; If we are comparing a register for equality with a large constant,
;; we can do this with an XOR followed by a compare. But we need a scratch
(match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
""
"{cmpl%I2|cmplw%I2} %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal2"
[(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
(match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
""
"cmpld%I2 %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; The following two insns don't exist as single insns, but if we provide
;; them, we can swap an add and compare, which will enable us to overlap more
(const_int 0)]))]
""
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ [(set_attr "type" "mfcr")
(set_attr "length" "12")])
;; Same as above, but get the OV/ORDERED bit.
(define_insn "move_from_CR_ov_bit"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] 724))]
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
"TARGET_ISEL"
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
- [(set_attr "length" "12")])
+ [(set_attr "type" "mfcr")
+ (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(const_int 0)]))]
"TARGET_POWERPC64"
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ [(set_attr "type" "mfcr")
(set_attr "length" "12")])
(define_insn ""
return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
}"
- [(set_attr "type" "cr_logical")
+ [(set_attr "type" "mfcr")
(set_attr "length" "12")])
(define_insn ""
(const_int 0)]))]
"REGNO (operands[2]) != REGNO (operands[5])"
"%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
(define_peephole
(const_int 0)]))]
"TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
"%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
;; There are some scc insns that can be done directly, without a compare.
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(return)
(pc)))]
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(return)))]
; (eq:SI (reg:CCFP 68) (const_int 0)))
; (const_int 1)))
; which are generated by the branch logic.
+; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_operator"
- [(match_operator:SI 2
+ [(match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)])
- (match_operator:SI 4
+ (match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int 1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
; Why is the constant -1 here, but 1 in the previous pattern?
; Because ~1 has all but the low bit set.
(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
- [(not:SI (match_operator:SI 2
+ [(not:SI (match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)]))
(match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int -1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1
"branch_positive_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])
(const_int 0)))]
"!TARGET_SPE"
"{crnor %E0,%j1,%j1|crnot %E0,%j1}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
;; If we are comparing the result of two comparisons, this can be done
;; using creqv or crxor.
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal2"
[(set (pc)
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal1"
[(set (pc)
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal2"
[(set (pc)
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Similar, but we can use GE since we have a REG_NONNEG.
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal4"
[(set (pc)
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal3"
[(set (pc)
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal4"
[(set (pc)
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Similar but use EQ
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrsi_internal6"
[(set (pc)
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal5"
[(set (pc)
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
(define_insn "*ctrdi_internal6"
[(set (pc)
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "4,12,16")])
;; Now the splitters if we could not allocate the CTR register
(define_insn "movesi_from_cr"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
- (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
+ (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)]
+ UNSPEC_MOVESI_FROM_CR))]
""
"mfcr %0"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mfcr")])
(define_insn "*stmw"
[(match_parallel 0 "stmw_operation"
; not be moved over stores to stack memory.
(define_insn "stack_tie"
[(set (match_operand:BLK 0 "memory_operand" "+m")
- (unspec:BLK [(match_dup 0)] 5))]
+ (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
""
""
[(set_attr "length" "0")])
(define_expand "movsi_to_cr_one"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_dup 2)] 20))]
+ (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
""
"operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
[(set (match_operand:CC 1 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
(match_operand 3 "immediate_operand" "n")]
- 20))])]
+ UNSPEC_MOVESI_TO_CR))])]
""
"*
{
operands[4] = GEN_INT (mask);
return \"mtcrf %4,%2\";
}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
-(define_insn ""
+(define_insn "*mtcrfsi"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand 2 "immediate_operand" "n")] 20))]
+ (match_operand 2 "immediate_operand" "n")]
+ UNSPEC_MOVESI_TO_CR))]
"GET_CODE (operands[0]) == REG
&& CR_REGNO_P (REGNO (operands[0]))
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
"mtcrf %R0,%1"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
; The load-multiple instructions have similar properties.
; Note that "load_multiple" is a name known to the machine-independent
; We can't expand this before we know where the link register is stored.
(define_insn "eh_set_lr_si"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:SI 1 "=&b"))]
"TARGET_32BIT"
"#")
(define_insn "eh_set_lr_di"
- [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:DI 1 "=&b"))]
"TARGET_64BIT"
"#")
(define_split
- [(unspec_volatile [(match_operand 0 "register_operand" "")] 9)
+ [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
(clobber (match_scratch 1 ""))]
"reload_completed"
[(const_int 0)]