X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=gcc%2Fconfig%2Frs6000%2Frs6000.md;h=43931b247ab016cfb5ba72f730feba878b05302e;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=55612be09328a4429bdcb01d0057f4aa2646a6c4;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 55612be0..43931b24 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,47 +1,129 @@ ;; 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, 2004, 2005, 2006, 2007, 2008, 2009 +;; 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 3, 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 COPYING3. If not see +;; . ;;- 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 +;; +;; REGNOS +;; + +(define_constants + [(MQ_REGNO 64) + (LR_REGNO 65) + (CTR_REGNO 66) + (CR0_REGNO 68) + (CR1_REGNO 69) + (CR2_REGNO 70) + (CR3_REGNO 71) + (CR4_REGNO 72) + (CR5_REGNO 73) + (CR6_REGNO 74) + (CR7_REGNO 75) + (MAX_CR_REGNO 75) + (XER_REGNO 76) + (FIRST_ALTIVEC_REGNO 77) + (LAST_ALTIVEC_REGNO 108) + (VRSAVE_REGNO 109) + (VSCR_REGNO 110) + (SPE_ACC_REGNO 111) + (SPEFSCR_REGNO 112) + (SFP_REGNO 113) + ]) + +;; +;; 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_FRIM 11) + (UNSPEC_FRIN 12) + (UNSPEC_FRIP 13) + (UNSPEC_FRIZ 14) + (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_FIX_TRUNC_TF 30) ; fadd, rounding towards zero + (UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit + (UNSPEC_STFIWX 32) + (UNSPEC_POPCNTB 33) + (UNSPEC_FRES 34) + (UNSPEC_SP_SET 35) + (UNSPEC_SP_TEST 36) + (UNSPEC_SYNC 37) + (UNSPEC_LWSYNC 38) + (UNSPEC_ISYNC 39) + (UNSPEC_SYNC_OP 40) + (UNSPEC_ATOMIC 41) + (UNSPEC_CMPXCHG 42) + (UNSPEC_XCHG 43) + (UNSPEC_AND 44) + (UNSPEC_DLMZB 45) + (UNSPEC_DLMZB_CR 46) + (UNSPEC_DLMZB_STRLEN 47) + (UNSPEC_RSQRT 48) + (UNSPEC_TOCREL 49) + (UNSPEC_MACHOPIC_OFFSET 50) + ]) + +;; +;; UNSPEC_VOLATILE usage +;; + +(define_constants + [(UNSPECV_BLOCK 0) + (UNSPECV_LL 1) ; load-locked + (UNSPECV_SC 2) ; store-conditional + (UNSPECV_EH_RR 9) ; eh_reg_restore + ]) ;; 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,two,three,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,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr" (const_string "integer")) +;; Define floating point instruction sub-types for use with Xfpu.md +(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) + ;; Length (in bytes). -; '(pc)' in the following doesn't include the instruction itself; it is +; '(pc)' in the following doesn't include the instruction itself; it is ; calculated as if the instruction had zero size. (define_attr "length" "" (if_then_else (eq_attr "type" "branch") @@ -56,732 +138,120 @@ ;; 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" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell" (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,ppc604,ppc604e,ppc620,ppc630")) - 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,ppc630")) - 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") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppc630")) - 3 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "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) + +;; If this instruction is microcoded on the CELL processor +; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded +(define_attr "cell_micro" "not,conditional,always" + (if_then_else (eq_attr "type" "compare,delayed_compare,imul_compare,lmul_compare,load_ext,load_ext_ux,var_shift_rotate,var_delayed_compare") + (const_string "always") + (const_string "not"))) + +(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 "e300c2c3.md") +(include "e500mc.md") +(include "power4.md") +(include "power5.md") +(include "power6.md") +(include "cell.md") +(include "xfpu.md") + +(include "predicates.md") +(include "constraints.md") + +(include "darwin.md") + + +;; Mode iterators + +; This mode iterator allows :GPR to be used to indicate the allowable size +; of whole values in GPRs. +(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) + +; Any supported integer mode. +(define_mode_iterator INT [QI HI SI DI TI]) + +; Any supported integer mode that fits in one register. +(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) + +; extend modes for DImode +(define_mode_iterator QHSI [QI HI SI]) + +; SImode or DImode, even if DImode doesn't fit in GPRs. +(define_mode_iterator SDI [SI DI]) + +; The size of a pointer. Also, the size of the value that a record-condition +; (one with a '.') will compare. +(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) + +; Any hardware-supported floating-point mode +(define_mode_iterator FP [ + (SF "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)") + (DF "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)") + (TF "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128") + (DD "TARGET_DFP") + (TD "TARGET_DFP")]) + +; Various instructions that come in SI and DI forms. +; A generic w/d attribute, for things like cmpw/cmpd. +(define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")]) + +; DImode bits +(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) ;; Start with fixed-point load and store insns. Here we put only the more ;; complex forms. Basic data transfer is done later. -(define_expand "zero_extendqidi2" +(define_expand "zero_extenddi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))] + (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))] "TARGET_POWERPC64" "") -(define_insn "" +(define_insn "*zero_extenddi2_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] + (zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))] "TARGET_POWERPC64" "@ - lbz%U1%X1 %0,%1 - rldicl %0,%1,0,56" + lz%U1%X1 %0,%1 + rldicl %0,%1,0," [(set_attr "type" "load,*")]) -(define_insn "" +(define_insn "*zero_extenddi2_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) + (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ - rldicl. %2,%1,0,56 + rldicl. %2,%1,0, #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 2 ""))] "TARGET_POWERPC64 && reload_completed" @@ -792,22 +262,22 @@ (const_int 0)))] "") -(define_insn "" +(define_insn "*zero_extenddi2_internal3" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) + (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ - rldicl. %0,%1,0,56 + rldicl. %0,%1,0, #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") (zero_extend:DI (match_dup 1)))] @@ -823,14 +293,15 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))] "TARGET_POWERPC64" - "extsb %0,%1") + "extsb %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsb. %2,%1 #" @@ -838,7 +309,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 2 ""))] @@ -856,7 +327,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsb. %0,%1 #" @@ -864,7 +335,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") @@ -877,73 +348,6 @@ (const_int 0)))] "") -(define_expand "zero_extendhidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lhz%U1%X1 %0,%1 - rldicl %0,%1,0,48" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - rldicl. %2,%1,0,48 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - rldicl. %0,%1,0,48 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - (define_expand "extendhidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] @@ -953,18 +357,25 @@ (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && rs6000_gen_cell_microcode" "@ lha%U1%X1 %0,%1 extsh %0,%1" - [(set_attr "type" "load,*")]) + [(set_attr "type" "load_ext,exts")]) + +(define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))] + "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" + "extsh %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsh. %2,%1 #" @@ -972,7 +383,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 2 ""))] @@ -990,7 +401,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsh. %0,%1 #" @@ -998,7 +409,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") @@ -1011,73 +422,6 @@ (const_int 0)))] "") -(define_expand "zero_extendsidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - lwz%U1%X1 %0,%1 - rldicl %0,%1,0,32" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" - "@ - rldicl. %2,%1,0,32 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" - "@ - rldicl. %0,%1,0,32 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - (define_expand "extendsidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] @@ -1087,18 +431,25 @@ (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && rs6000_gen_cell_microcode" "@ lwa%U1%X1 %0,%1 extsw %0,%1" - [(set_attr "type" "load,*")]) + [(set_attr "type" "load_ext,exts")]) + +(define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))] + "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" + "extsw %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsw. %2,%1 #" @@ -1106,7 +457,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 2 ""))] @@ -1124,7 +475,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ extsw. %0,%1 #" @@ -1132,7 +483,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") @@ -1173,7 +524,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] @@ -1199,7 +550,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1231,7 +582,8 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))] "TARGET_POWERPC" - "extsb %0,%1") + "extsb %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -1246,7 +598,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] @@ -1272,7 +624,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1339,7 +691,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:HI 2 ""))] @@ -1365,7 +717,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "") @@ -1397,7 +749,8 @@ [(set (match_operand:HI 0 "gpc_reg_operand" "=r") (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))] "TARGET_POWERPC" - "extsb %0,%1") + "extsb %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -1412,7 +765,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:HI 2 ""))] @@ -1438,7 +791,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "") @@ -1507,7 +860,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] @@ -1533,7 +886,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1555,11 +908,18 @@ (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "" + "rs6000_gen_cell_microcode" "@ lha%U1%X1 %0,%1 {exts|extsh} %0,%1" - [(set_attr "type" "load,*")]) + [(set_attr "type" "load_ext,exts")]) + +(define_insn "" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))] + "!rs6000_gen_cell_microcode" + "{exts|extsh} %0,%1" + [(set_attr "type" "exts")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -1574,7 +934,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] @@ -1599,8 +959,539 @@ [(set_attr "type" "compare") (set_attr "length" "4,8")]) +;; IBM 405, 440 and 464 half-word multiplication operations. + +(define_insn "*macchwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_dup 2) + (const_int 16)) + (sign_extend:SI + (match_dup 1))) + (match_dup 4)))] + "TARGET_MULHW" + "macchw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*macchw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "macchw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*macchwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_dup 2) + (const_int 16)) + (zero_extend:SI + (match_dup 1))) + (match_dup 4)))] + "TARGET_MULHW" + "macchwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*macchwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "macchwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*machhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_dup 1) + (const_int 16)) + (ashiftrt:SI + (match_dup 2) + (const_int 16))) + (match_dup 4)))] + "TARGET_MULHW" + "machhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*machhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "machhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*machhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_dup 1) + (const_int 16)) + (lshiftrt:SI + (match_dup 2) + (const_int 16))) + (match_dup 4)))] + "TARGET_MULHW" + "machhwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*machhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "machhwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*maclhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (sign_extend:SI + (match_dup 1)) + (sign_extend:SI + (match_dup 2))) + (match_dup 4)))] + "TARGET_MULHW" + "maclhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*maclhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "maclhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*maclhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (zero_extend:SI + (match_dup 1)) + (zero_extend:SI + (match_dup 2))) + (match_dup 4)))] + "TARGET_MULHW" + "maclhwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*maclhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "maclhwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmacchwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r")))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_dup 4) + (mult:SI (ashiftrt:SI + (match_dup 2) + (const_int 16)) + (sign_extend:SI + (match_dup 1)))))] + "TARGET_MULHW" + "nmacchw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmacchw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r")))))] + "TARGET_MULHW" + "nmacchw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmachhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_dup 4) + (mult:SI (ashiftrt:SI + (match_dup 1) + (const_int 16)) + (ashiftrt:SI + (match_dup 2) + (const_int 16)))))] + "TARGET_MULHW" + "nmachhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmachhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)))))] + "TARGET_MULHW" + "nmachhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmaclhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r")))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_dup 4) + (mult:SI (sign_extend:SI + (match_dup 1)) + (sign_extend:SI + (match_dup 2)))))] + "TARGET_MULHW" + "nmaclhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*nmaclhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") + (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r")))))] + "TARGET_MULHW" + "nmaclhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulchwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (ashiftrt:SI + (match_dup 2) + (const_int 16)) + (sign_extend:SI + (match_dup 1))))] + "TARGET_MULHW" + "mulchw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulchw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))))] + "TARGET_MULHW" + "mulchw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulchwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (lshiftrt:SI + (match_dup 2) + (const_int 16)) + (zero_extend:SI + (match_dup 1))))] + "TARGET_MULHW" + "mulchwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulchwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))))] + "TARGET_MULHW" + "mulchwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulhhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (ashiftrt:SI + (match_dup 1) + (const_int 16)) + (ashiftrt:SI + (match_dup 2) + (const_int 16))))] + "TARGET_MULHW" + "mulhhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulhhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))))] + "TARGET_MULHW" + "mulhhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulhhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (lshiftrt:SI + (match_dup 1) + (const_int 16)) + (lshiftrt:SI + (match_dup 2) + (const_int 16))))] + "TARGET_MULHW" + "mulhhwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mulhhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))))] + "TARGET_MULHW" + "mulhhwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mullhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (sign_extend:SI + (match_dup 1)) + (sign_extend:SI + (match_dup 2))))] + "TARGET_MULHW" + "mullhw. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mullhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))))] + "TARGET_MULHW" + "mullhw %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mullhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (zero_extend:SI + (match_dup 1)) + (zero_extend:SI + (match_dup 2))))] + "TARGET_MULHW" + "mullhwu. %0, %1, %2" + [(set_attr "type" "imul3")]) + +(define_insn "*mullhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))))] + "TARGET_MULHW" + "mullhwu %0, %1, %2" + [(set_attr "type" "imul3")]) + +;; IBM 405, 440 and 464 string-search dlmzb instruction support. +(define_insn "dlmzb" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_DLMZB_CR)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (unspec:SI [(match_dup 1) + (match_dup 2)] + UNSPEC_DLMZB))] + "TARGET_DLMZB" + "dlmzb. %0, %1, %2") + +(define_expand "strlensi" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (unspec:SI [(match_operand:BLK 1 "general_operand" "") + (match_operand:QI 2 "const_int_operand" "") + (match_operand 3 "const_int_operand" "")] + UNSPEC_DLMZB_STRLEN)) + (clobber (match_scratch:CC 4 "=x"))] + "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" +{ + rtx result = operands[0]; + rtx src = operands[1]; + rtx search_char = operands[2]; + rtx align = operands[3]; + rtx addr, scratch_string, word1, word2, scratch_dlmzb; + rtx loop_label, end_label, mem, cr0, cond; + if (search_char != const0_rtx + || GET_CODE (align) != CONST_INT + || INTVAL (align) < 8) + FAIL; + word1 = gen_reg_rtx (SImode); + word2 = gen_reg_rtx (SImode); + scratch_dlmzb = gen_reg_rtx (SImode); + scratch_string = gen_reg_rtx (Pmode); + loop_label = gen_label_rtx (); + end_label = gen_label_rtx (); + addr = force_reg (Pmode, XEXP (src, 0)); + emit_move_insn (scratch_string, addr); + emit_label (loop_label); + mem = change_address (src, SImode, scratch_string); + emit_move_insn (word1, mem); + emit_move_insn (word2, adjust_address (mem, SImode, 4)); + cr0 = gen_rtx_REG (CCmode, CR0_REGNO); + emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); + cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); + emit_jump_insn (gen_rtx_SET (VOIDmode, + pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + cond, + gen_rtx_LABEL_REF + (VOIDmode, + end_label), + pc_rtx))); + emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); + emit_jump_insn (gen_rtx_SET (VOIDmode, + pc_rtx, + gen_rtx_LABEL_REF (VOIDmode, loop_label))); + emit_barrier (); + emit_label (end_label); + emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); + emit_insn (gen_subsi3 (result, scratch_string, addr)); + emit_insn (gen_subsi3 (result, result, const1_rtx)); + DONE; +}) + (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1615,39 +1506,47 @@ ;; Fixed-point arithmetic insns. -;; Discourage ai/addic because of carry but provide it in an alternative -;; allowing register zero as source. -(define_expand "addsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_arith_cint_operand" "")))] +(define_expand "add3" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "") + (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] "" - " { - if (GET_CODE (operands[2]) == CONST_INT - && ! add_operand (operands[2], SImode)) + if (mode == DImode && ! TARGET_POWERPC64) { - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - + if (non_short_cint_operand (operands[2], DImode)) + FAIL; + } + else if (GET_CODE (operands[2]) == CONST_INT + && ! add_operand (operands[2], mode)) + { + rtx tmp = ((!can_create_pseudo_p () + || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (mode)); + HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; + HOST_WIDE_INT rest = trunc_int_for_mode (val - low, mode); + + if (mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) + FAIL; /* The ordering here is important for the prolog expander. When space is allocated from the stack, adding 'low' first may produce a temporary deallocation (which would be bad). */ - emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (rest))); - emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low))); + emit_insn (gen_add3 (tmp, operands[1], GEN_INT (rest))); + emit_insn (gen_add3 (operands[0], tmp, GEN_INT (low))); DONE; } -}") +}) -(define_insn "*addsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b") - (match_operand:SI 2 "add_operand" "r,I,I,L")))] - "" +;; Discourage ai/addic because of carry but provide it in an alternative +;; allowing register zero as source. +(define_insn "*add3_internal1" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r") + (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b") + (match_operand:GPR 2 "add_operand" "r,I,I,L")))] + "!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))" "@ {cax|add} %0,%1,%2 {cal %0,%2(%1)|addi %0,%1,%2} @@ -1663,64 +1562,64 @@ "{cau|addis} %0,%1,ha16(%2)" [(set_attr "length" "4")]) -(define_insn "*addsi3_internal2" +(define_insn "*add3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I")) + (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:P 2 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "! TARGET_POWERPC64" + (clobber (match_scratch:P 3 "=r,r,r,r"))] + "" "@ {cax.|add.} %3,%1,%2 {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 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) + (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "reg_or_short_operand" "")) (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + (clobber (match_scratch:GPR 3 ""))] + "reload_completed" [(set (match_dup 3) - (plus:SI (match_dup 1) + (plus:GPR (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*addsi3_internal3" +(define_insn "*add3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I")) + (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:P 2 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (plus:SI (match_dup 1) - (match_dup 2)))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") + (plus:P (match_dup 1) + (match_dup 2)))] + "" "@ {cax.|add.} %0,%1,%2 {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 [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) + (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "") + (match_operand:P 2 "reg_or_short_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") + (plus:P (match_dup 1) (match_dup 2)))] + "reload_completed" [(set (match_dup 0) - (plus:SI (match_dup 1) - (match_dup 2))) + (plus:P (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] @@ -1731,34 +1630,43 @@ ;; add should be last in case the result gets used in an address. (define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_add_cint_operand" "")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "non_add_cint_operand" "")))] "" - [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] -" + [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) + (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] { HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; + HOST_WIDE_INT rest = trunc_int_for_mode (val - low, mode); - operands[3] = GEN_INT (rest); operands[4] = GEN_INT (low); -}") + if (mode == SImode || satisfies_constraint_L (GEN_INT (rest))) + operands[3] = GEN_INT (rest); + else if (can_create_pseudo_p ()) + { + operands[3] = gen_reg_rtx (DImode); + emit_move_insn (operands[3], operands[2]); + emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); + DONE; + } + else + FAIL; +}) -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] +(define_insn "one_cmpl2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] "" "nor %0,%1,%1") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "! TARGET_POWERPC64" + (clobber (match_scratch:P 2 "=r,r"))] + "" "@ nor. %2,%1,%1 #" @@ -1766,13 +1674,13 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "")) (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWERPC64 && reload_completed" + (clobber (match_scratch:P 2 ""))] + "reload_completed" [(set (match_dup 2) - (not:SI (match_dup 1))) + (not:P (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] @@ -1780,11 +1688,11 @@ (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (not:SI (match_dup 1)))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (not:P (match_dup 1)))] + "" "@ nor. %0,%1,%1 #" @@ -1792,14 +1700,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (not:SI (match_dup 1)))] - "! TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") + (not:P (match_dup 1)))] + "reload_completed" [(set (match_dup 0) - (not:SI (match_dup 1))) + (not:P (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] @@ -1813,9 +1721,9 @@ "{sf%I1|subf%I1c} %0,%2,%1") (define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I") - (match_operand:SI 2 "gpc_reg_operand" "r,r")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] "TARGET_POWERPC" "@ subf %0,%2,%1 @@ -1836,26 +1744,26 @@ (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWERPC && ! TARGET_POWERPC64" + (clobber (match_scratch:P 3 "=r,r"))] + "TARGET_POWERPC" "@ subf. %3,%2,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) + (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "") + (match_operand:P 2 "gpc_reg_operand" "")) (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + (clobber (match_scratch:P 3 ""))] + "reload_completed" [(set (match_dup 3) - (minus:SI (match_dup 1) + (minus:P (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) @@ -1878,47 +1786,47 @@ (define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")) + (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (minus:SI (match_dup 1) + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (minus:P (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC && ! TARGET_POWERPC64" + "TARGET_POWERPC" "@ subf. %0,%2,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) + (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "") + (match_operand:P 2 "gpc_reg_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_dup 1) + (set (match_operand:P 0 "gpc_reg_operand" "") + (minus:P (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) - (minus:SI (match_dup 1) + (minus:P (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_expand "subsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (minus:SI (match_operand:SI 1 "reg_or_short_operand" "") - (match_operand:SI 2 "reg_or_arith_cint_operand" "")))] +(define_expand "sub3" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "") + (match_operand:SDI 2 "reg_or_sub_cint_operand" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT) { - emit_insn (gen_addsi3 (operands[0], operands[1], - negate_rtx (SImode, operands[2]))); + emit_insn (gen_add3 (operands[0], operands[1], + negate_rtx (mode, operands[2]))); DONE; } }") @@ -1936,9 +1844,18 @@ (minus:SI (match_dup 2) (match_dup 1)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " -{ operands[3] = gen_reg_rtx (SImode); }") +{ + if (TARGET_ISEL) + { + operands[2] = force_reg (SImode, operands[2]); + rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); + DONE; + } + + operands[3] = gen_reg_rtx (SImode); +}") (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1961,9 +1878,17 @@ (minus:SI (match_dup 2) (match_dup 1)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " -{ operands[3] = gen_reg_rtx (SImode); }") +{ + if (TARGET_ISEL) + { + operands[2] = force_reg (SImode, operands[2]); + rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); + DONE; + } + operands[3] = gen_reg_rtx (SImode); +}") (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1988,9 +1913,14 @@ (minus:SI (match_dup 4) (match_dup 3)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " { + if (TARGET_ISEL) + { + rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]); + DONE; + } operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); operands[5] = GEN_INT (-2147483647 - 1); @@ -2006,9 +1936,14 @@ (minus:SI (match_dup 4) (match_dup 3)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " { + if (TARGET_ISEL) + { + rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]); + DONE; + } operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); operands[5] = GEN_INT (-2147483647 - 1); @@ -2107,37 +2042,50 @@ "" " { - if (! TARGET_POWER) + if (TARGET_ISEL) + { + emit_insn (gen_abssi2_isel (operands[0], operands[1])); + DONE; + } + else if (! TARGET_POWER) { emit_insn (gen_abssi2_nopower (operands[0], operands[1])); DONE; } }") -(define_insn "abssi2_power" +(define_insn "*abssi2_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] "TARGET_POWER" "abs %0,%1") -(define_insn "abssi2_nopower" +(define_insn_and_split "abssi2_isel" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (clobber (match_scratch:SI 2 "=&b")) + (clobber (match_scratch:CC 3 "=y"))] + "TARGET_ISEL" + "#" + "&& reload_completed" + [(set (match_dup 2) (neg:SI (match_dup 1))) + (set (match_dup 3) + (compare:CC (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (if_then_else:SI (ge (match_dup 3) + (const_int 0)) + (match_dup 1) + (match_dup 2)))] + "") + +(define_insn_and_split "abssi2_nopower" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) + (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "! TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" ""))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWER && reload_completed" + "! TARGET_POWER && ! TARGET_ISEL" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))] @@ -2149,55 +2097,50 @@ "TARGET_POWER" "nabs %0,%1") -(define_insn "*nabs_no_power" +(define_insn_and_split "*nabs_nopower" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:SI 2 "=&r,&r"))] "! TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWER && reload_completed" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))] "") -(define_insn "negsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] +(define_expand "neg2" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] + "" + "") + +(define_insn "*neg2_internal" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] "" "neg %0,%1") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "! TARGET_POWERPC64" + (clobber (match_scratch:P 2 "=r,r"))] + "" "@ neg. %2,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) + (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "")) (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWERPC64 && reload_completed" + (clobber (match_scratch:P 2 ""))] + "reload_completed" [(set (match_dup 2) - (neg:SI (match_dup 1))) + (neg:P (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] @@ -2205,37 +2148,123 @@ (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (match_dup 1)))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (neg:P (match_dup 1)))] + "" "@ neg. %0,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "")) + (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (neg:SI (match_dup 1)))] - "! TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") + (neg:P (match_dup 1)))] + "reload_completed" [(set (match_dup 0) - (neg:SI (match_dup 1))) + (neg:P (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (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 "clz2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (clz:GPR (match_operand:GPR 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|cntlz} %0,%1" + [(set_attr "type" "cntlz")]) + +(define_expand "ctz2" + [(set (match_dup 2) + (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) + (parallel [(set (match_dup 3) (and:GPR (match_dup 1) + (match_dup 2))) + (clobber (scratch:CC))]) + (set (match_dup 4) (clz:GPR (match_dup 3))) + (set (match_operand:GPR 0 "gpc_reg_operand" "") + (minus:GPR (match_dup 5) (match_dup 4)))] + "" + { + operands[2] = gen_reg_rtx (mode); + operands[3] = gen_reg_rtx (mode); + operands[4] = gen_reg_rtx (mode); + operands[5] = GEN_INT (GET_MODE_BITSIZE (mode) - 1); + }) + +(define_expand "ffs2" + [(set (match_dup 2) + (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) + (parallel [(set (match_dup 3) (and:GPR (match_dup 1) + (match_dup 2))) + (clobber (scratch:CC))]) + (set (match_dup 4) (clz:GPR (match_dup 3))) + (set (match_operand:GPR 0 "gpc_reg_operand" "") + (minus:GPR (match_dup 5) (match_dup 4)))] + "" + { + operands[2] = gen_reg_rtx (mode); + operands[3] = gen_reg_rtx (mode); + operands[4] = gen_reg_rtx (mode); + operands[5] = GEN_INT (GET_MODE_BITSIZE (mode)); + }) + +(define_insn "popcntb2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] + UNSPEC_POPCNTB))] + "TARGET_POPCNTB" + "popcntb %0,%1") + +(define_expand "popcount2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] + "TARGET_POPCNTB" + { + rs6000_emit_popcount (operands[0], operands[1]); + DONE; + }) + +(define_expand "parity2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] + "TARGET_POPCNTB" + { + rs6000_emit_parity (operands[0], operands[1]); + DONE; + }) + +(define_insn "bswapsi2" + [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r") + (bswap:SI (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))] + "" + "@ + {lbrx|lwbrx} %0,%y1 + {stbrx|stwbrx} %1,%y0 + #" + [(set_attr "length" "4,4,12")]) + +(define_split + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))] + "reload_completed" + [(set (match_dup 0) + (rotate:SI (match_dup 1) (const_int 8))) + (set (zero_extract:SI (match_dup 0) + (const_int 8) + (const_int 0)) + (match_dup 1)) + (set (zero_extract:SI (match_dup 0) + (const_int 8) + (const_int 16)) + (rotate:SI (match_dup 1) + (const_int 16)))] + "") (define_expand "mulsi3" [(use (match_operand:SI 0 "gpc_reg_operand" "")) @@ -2260,10 +2289,10 @@ "@ {muls|mullw} %0,%1,%2 {muli|mulli} %0,%1,%2" - [(set (attr "type") + [(set (attr "type") (cond [(match_operand:SI 2 "s8bit_cint_operand" "") (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") + (match_operand:SI 2 "short_cint_operand" "") (const_string "imul2")] (const_string "imul")))]) @@ -2275,14 +2304,14 @@ "@ {muls|mullw} %0,%1,%2 {muli|mulli} %0,%1,%2" - [(set (attr "type") + [(set (attr "type") (cond [(match_operand:SI 2 "s8bit_cint_operand" "") (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") + (match_operand:SI 2 "short_cint_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")) @@ -2293,7 +2322,7 @@ "@ {muls.|mullw.} %3,%1,%2 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "imul_compare") (set_attr "length" "4,8")]) (define_split @@ -2312,7 +2341,7 @@ (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")) @@ -2322,11 +2351,11 @@ "@ {muls.|mullw.} %3,%1,%2 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "imul_compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) @@ -2339,7 +2368,7 @@ (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")) @@ -2351,7 +2380,7 @@ "@ {muls.|mullw.} %0,%1,%2 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "imul_compare") (set_attr "length" "4,8")]) (define_split @@ -2371,7 +2400,7 @@ (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")) @@ -2382,11 +2411,11 @@ "@ {muls.|mullw.} %0,%1,%2 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "imul_compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) @@ -2408,7 +2437,7 @@ [(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)" " @@ -2424,20 +2453,20 @@ } }") -(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" [(set_attr "type" "idiv")]) -(define_expand "udivsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")))] +(define_expand "udiv3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "gpc_reg_operand" "")))] "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)" " { @@ -2466,21 +2495,25 @@ [(set_attr "type" "idiv")]) (define_insn "*udivsi3_no_mq" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")))] "TARGET_POWERPC && ! TARGET_POWER" - "divwu %0,%1,%2" - [(set_attr "type" "idiv")]) + "divu %0,%1,%2" + [(set (attr "type") + (cond [(match_operand:SI 0 "" "") + (const_string "idiv")] + (const_string "ldiv")))]) + ;; For powers of two we can do srai/aze for divide and then adjust for ;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be ;; used; for PowerPC, force operands into register and do a normal divide; ;; for AIX common-mode, use quoss call on register operands. -(define_expand "divsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] +(define_expand "div3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "reg_or_cint_operand" "")))] "" " { @@ -2490,7 +2523,7 @@ ; else if (TARGET_POWERPC) { - operands[2] = force_reg (SImode, operands[2]); + operands[2] = force_reg (mode, operands[2]); if (TARGET_POWER) { emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2])); @@ -2518,18 +2551,21 @@ "divw %0,%1,%2" [(set_attr "type" "idiv")]) -(define_insn "*divsi3_no_mq" - [(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")))] +(define_insn "*div3_no_mq" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")))] "TARGET_POWERPC && ! TARGET_POWER" - "divw %0,%1,%2" - [(set_attr "type" "idiv")]) + "div %0,%1,%2" + [(set (attr "type") + (cond [(match_operand:SI 0 "" "") + (const_string "idiv")] + (const_string "ldiv")))]) -(define_expand "modsi3" - [(use (match_operand:SI 0 "gpc_reg_operand" "")) - (use (match_operand:SI 1 "gpc_reg_operand" "")) - (use (match_operand:SI 2 "reg_or_cint_operand" ""))] +(define_expand "mod3" + [(use (match_operand:GPR 0 "gpc_reg_operand" "")) + (use (match_operand:GPR 1 "gpc_reg_operand" "")) + (use (match_operand:GPR 2 "reg_or_cint_operand" ""))] "" " { @@ -2538,49 +2574,52 @@ rtx temp2; if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) < 0 + || INTVAL (operands[2]) <= 0 || (i = exact_log2 (INTVAL (operands[2]))) < 0) FAIL; - temp1 = gen_reg_rtx (SImode); - temp2 = gen_reg_rtx (SImode); + temp1 = gen_reg_rtx (mode); + temp2 = gen_reg_rtx (mode); - emit_insn (gen_divsi3 (temp1, operands[1], operands[2])); - emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i))); - emit_insn (gen_subsi3 (operands[0], operands[1], temp2)); + emit_insn (gen_div3 (temp1, operands[1], operands[2])); + emit_insn (gen_ashl3 (temp2, temp1, GEN_INT (i))); + emit_insn (gen_sub3 (operands[0], operands[1], temp2)); DONE; }") (define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "exact_log2_cint_operand" "N")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "exact_log2_cint_operand" "N")))] "" - "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0" - [(set_attr "length" "8")]) + "{srai|srai} %0,%1,%p2\;{aze|addze} %0,%0" + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "exact_log2_cint_operand" "N,N")) + (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "exact_log2_cint_operand" "N,N")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] + (clobber (match_scratch:P 3 "=r,r"))] "" "@ - {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3 + {srai|srai} %3,%1,%p2\;{aze.|addze.} %3,%3 #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12") + (set_attr "cell_micro" "not")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "exact_log2_cint_operand" "")) + (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "exact_log2_cint_operand" + "")) (const_int 0))) - (clobber (match_scratch:SI 3 ""))] + (clobber (match_scratch:GPR 3 ""))] "reload_completed" [(set (match_dup 3) - (div:SI (match_dup 1) (match_dup 2))) + (div: (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] @@ -2588,28 +2627,30 @@ (define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "exact_log2_cint_operand" "N,N")) + (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "exact_log2_cint_operand" "N,N")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (div:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (div:P (match_dup 1) (match_dup 2)))] "" "@ - {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0 + {srai|srai} %0,%1,%p2\;{aze.|addze.} %0,%0 #" [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + (set_attr "length" "8,12") + (set_attr "cell_micro" "not")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "exact_log2_cint_operand" "")) + (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "exact_log2_cint_operand" + "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (div:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:GPR 0 "gpc_reg_operand" "") + (div:GPR (match_dup 1) (match_dup 2)))] "reload_completed" [(set (match_dup 0) - (div:SI (match_dup 1) (match_dup 2))) + (div: (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] @@ -2727,7 +2768,7 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3)) (sign_extend:DI (reg:SI 4))) (const_int 32)))) - (clobber (match_scratch:SI 0 "=l"))] + (clobber (reg:SI LR_REGNO))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __mulh" [(set_attr "type" "imul")]) @@ -2736,7 +2777,7 @@ [(set (reg:DI 3) (mult:DI (sign_extend:DI (reg:SI 3)) (sign_extend:DI (reg:SI 4)))) - (clobber (match_scratch:SI 0 "=l")) + (clobber (reg:SI LR_REGNO)) (clobber (reg:SI 0))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __mull" @@ -2747,7 +2788,7 @@ (div:SI (reg:SI 3) (reg:SI 4))) (set (reg:SI 4) (mod:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) + (clobber (reg:SI LR_REGNO)) (clobber (reg:SI 0))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __divss" @@ -2758,10 +2799,10 @@ (udiv:SI (reg:SI 3) (reg:SI 4))) (set (reg:SI 4) (umod:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) + (clobber (reg:SI LR_REGNO)) (clobber (reg:SI 0)) - (clobber (match_scratch:CC 1 "=x")) - (clobber (reg:CC 69))] + (clobber (match_scratch:CC 0 "=x")) + (clobber (reg:CC CR1_REGNO))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __divus" [(set_attr "type" "idiv")]) @@ -2769,7 +2810,7 @@ (define_insn "quoss_call" [(set (reg:SI 3) (div:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l"))] + (clobber (reg:SI LR_REGNO))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __quoss" [(set_attr "type" "idiv")]) @@ -2777,10 +2818,10 @@ (define_insn "quous_call" [(set (reg:SI 3) (udiv:SI (reg:SI 3) (reg:SI 4))) - (clobber (match_scratch:SI 0 "=l")) + (clobber (reg:SI LR_REGNO)) (clobber (reg:SI 0)) - (clobber (match_scratch:CC 1 "=x")) - (clobber (reg:CC 69))] + (clobber (match_scratch:CC 0 "=x")) + (clobber (reg:CC CR1_REGNO))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __quous" [(set_attr "type" "idiv")]) @@ -2791,30 +2832,60 @@ ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all ;; those rotate-and-mask operations. Thus, the AND insns come first. -(define_insn "andsi3" +(define_expand "andsi3" + [(parallel + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "and_operand" ""))) + (clobber (match_scratch:CC 3 ""))])] + "" + "") + +(define_insn "andsi3_mc" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") (match_operand:SI 2 "and_operand" "?r,T,K,L"))) (clobber (match_scratch:CC 3 "=X,X,x,x"))] - "" + "rs6000_gen_cell_microcode" "@ and %0,%1,%2 {rlinm|rlwinm} %0,%1,0,%m2,%M2 {andil.|andi.} %0,%1,%b2 - {andiu.|andis.} %0,%1,%u2") + {andiu.|andis.} %0,%1,%u2" + [(set_attr "type" "*,*,compare,compare")]) + +(define_insn "andsi3_nomc" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "and_operand" "?r,T"))) + (clobber (match_scratch:CC 3 "=X,X"))] + "!rs6000_gen_cell_microcode" + "@ + and %0,%1,%2 + {rlinm|rlwinm} %0,%1,0,%m2,%M2") + +(define_insn "andsi3_internal0_nomc" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "and_operand" "?r,T")))] + "!rs6000_gen_cell_microcode" + "@ + and %0,%1,%2 + {rlinm|rlwinm} %0,%1,0,%m2,%M2") + ;; Note to set cr's other than cr0 we do the and immediate and then -;; the test again -- this avoids a mcrf which on the higher end +;; the test again -- this avoids a mfcr which on the higher end ;; machines causes an execution serialization -(define_insn "*andsi3_internal2" +(define_insn "*andsi3_internal2_mc" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r")) (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "! TARGET_POWERPC64" + "TARGET_32BIT && rs6000_gen_cell_microcode" "@ and. %3,%1,%2 {andil.|andi.} %3,%1,%b2 @@ -2827,33 +2898,73 @@ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") (set_attr "length" "4,4,4,4,8,8,8,8")]) +(define_insn "*andsi3_internal3_mc" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + (const_int 0))) + (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r")) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] + "TARGET_64BIT && rs6000_gen_cell_microcode" + "@ + # + {andil.|andi.} %3,%1,%b2 + {andiu.|andis.} %3,%1,%u2 + {rlinm.|rlwinm.} %3,%1,0,%m2,%M2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") + (set_attr "length" "8,4,4,4,8,8,8,8")]) + (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "and_operand" "")) (const_int 0))) - (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:GPR 3 "")) (clobber (match_scratch:CC 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(parallel [(set (match_dup 3) - (and:SI (match_dup 1) - (match_dup 2))) + (and: (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*andsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") +;; We don't have a 32 bit "and. rt,ra,rb" for ppc64. cr is set from the +;; whole 64 bit reg, and we don't know what is in the high 32 bits. + +(define_split + [(set (match_operand:CC 0 "cc_reg_operand" "") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 3) + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") + +(define_insn "*andsi3_internal4" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "! TARGET_POWERPC64" + "TARGET_32BIT && rs6000_gen_cell_microcode" "@ and. %0,%1,%2 {andil.|andi.} %0,%1,%b2 @@ -2866,8 +2977,30 @@ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") (set_attr "length" "4,4,4,4,8,8,8,8")]) +(define_insn "*andsi3_internal5_mc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] + "TARGET_64BIT && rs6000_gen_cell_microcode" + "@ + # + {andil.|andi.} %0,%1,%b2 + {andiu.|andis.} %0,%1,%u2 + {rlinm.|rlwinm.} %0,%1,0,%m2,%M2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") + (set_attr "length" "8,4,4,4,8,8,8,8")]) + (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "and_operand" "")) (const_int 0))) @@ -2875,7 +3008,26 @@ (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" + [(parallel [(set (match_dup 0) + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +(define_split + [(set (match_operand:CC 3 "cc_reg_operand" "") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) @@ -2885,6 +3037,30 @@ (const_int 0)))] "") +;; Handle the PowerPC64 rlwinm corner case + +(define_insn_and_split "*andsi3_internal6" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "mask_operand_wrap" "i")))] + "TARGET_POWERPC64" + "#" + "TARGET_POWERPC64" + [(set (match_dup 0) + (and:SI (rotate:SI (match_dup 1) (match_dup 3)) + (match_dup 4))) + (set (match_dup 0) + (rotate:SI (match_dup 0) (match_dup 5)))] + " +{ + int mb = extract_MB (operands[2]); + int me = extract_ME (operands[2]); + operands[3] = GEN_INT (me + 1); + operands[5] = GEN_INT (32 - (me + 1)); + operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); +}" + [(set_attr "length" "8")]) + (define_expand "iorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -2896,7 +3072,8 @@ && ! logical_operand (operands[2], SImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + rtx tmp = ((!can_create_pseudo_p () + || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (SImode)); emit_insn (gen_iorsi3 (tmp, operands[1], @@ -2917,7 +3094,8 @@ && ! logical_operand (operands[2], SImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + rtx tmp = ((!can_create_pseudo_p () + || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (SImode)); emit_insn (gen_xorsi3 (tmp, operands[1], @@ -2945,7 +3123,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %3,%1,%2 #" @@ -2953,13 +3131,13 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")]) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) @@ -2974,7 +3152,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %0,%1,%2 #" @@ -2982,21 +3160,21 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 4))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) (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 @@ -3011,11 +3189,11 @@ { rtx i; i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = gen_rtx (GET_CODE (operands[3]), SImode, - operands[1], i); + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, + operands[1], i); i = GEN_INT (INTVAL (operands[2]) & 0xffff); - operands[5] = gen_rtx (GET_CODE (operands[3]), SImode, - operands[0], i); + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, + operands[0], i); }") (define_insn "*boolcsi3_internal1" @@ -3033,7 +3211,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %3,%2,%1 #" @@ -3041,13 +3219,13 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (match_operand:SI 2 "gpc_reg_operand" "")]) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) @@ -3062,7 +3240,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %0,%2,%1 #" @@ -3070,14 +3248,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (match_operand:SI 2 "gpc_reg_operand" "")]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 4))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) @@ -3099,7 +3277,7 @@ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %3,%1,%2 #" @@ -3107,13 +3285,13 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) @@ -3128,7 +3306,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ %q4. %0,%1,%2 #" @@ -3136,14 +3314,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 4))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) @@ -3321,7 +3499,7 @@ #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) - + (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC @@ -3341,7 +3519,7 @@ (compare:CC (match_dup 0) (const_int 0)))] "") - + ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" @@ -3354,9 +3532,12 @@ { /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the - compiler if the address of the structure is taken later. */ + compiler if the address of the structure is taken later. Likewise, do + not handle invalid E500 subregs. */ if (GET_CODE (operands[0]) == SUBREG - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD + || ((TARGET_E500_DOUBLE || TARGET_SPE) + && invalid_e500_subreg (operands[0], GET_MODE (operands[0]))))) FAIL; if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode) @@ -3380,13 +3561,14 @@ operands[4] = GEN_INT (32 - start - size); operands[1] = GEN_INT (start + size - 1); return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") +}" + [(set_attr "type" "insert_word")]) (define_insn "*insvsi_internal1" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) - (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r") + (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_operand:SI 4 "const_int_operand" "i")))] "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" "* @@ -3398,7 +3580,8 @@ operands[4] = GEN_INT (shift - start - size); operands[1] = GEN_INT (start + size - 1); return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") +}" + [(set_attr "type" "insert_word")]) (define_insn "*insvsi_internal2" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3416,7 +3599,8 @@ operands[4] = GEN_INT (32 - shift - start - size); operands[1] = GEN_INT (start + size - 1); return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") +}" + [(set_attr "type" "insert_word")]) (define_insn "*insvsi_internal3" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3434,7 +3618,8 @@ operands[4] = GEN_INT (32 - shift - start - size); operands[1] = GEN_INT (start + size - 1); return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; -}") +}" + [(set_attr "type" "insert_word")]) (define_insn "*insvsi_internal4" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3455,7 +3640,47 @@ operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size); operands[1] = GEN_INT (insert_start + insert_size - 1); return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\"; -}") +}" + [(set_attr "type" "insert_word")]) + +;; combine patterns for rlwimi +(define_insn "*insvsi_internal5" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (match_operand:SI 1 "mask_operand" "i")) + (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:SI 5 "mask_operand" "i"))))] + "TARGET_POWERPC && INTVAL(operands[1]) == ~INTVAL(operands[5])" + "* +{ + int me = extract_ME(operands[5]); + int mb = extract_MB(operands[5]); + operands[4] = GEN_INT(32 - INTVAL(operands[2])); + operands[2] = GEN_INT(mb); + operands[1] = GEN_INT(me); + return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; +}" + [(set_attr "type" "insert_word")]) + +(define_insn "*insvsi_internal6" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:SI 5 "mask_operand" "i")) + (and:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (match_operand:SI 1 "mask_operand" "i"))))] + "TARGET_POWERPC && INTVAL(operands[1]) == ~INTVAL(operands[5])" + "* +{ + int me = extract_ME(operands[5]); + int mb = extract_MB(operands[5]); + operands[4] = GEN_INT(32 - INTVAL(operands[2])); + operands[2] = GEN_INT(mb); + operands[1] = GEN_INT(me); + return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; +}" + [(set_attr "type" "insert_word")]) (define_insn "insvdi" [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") @@ -3470,6 +3695,47 @@ operands[1] = GEN_INT (64 - start - size); return \"rldimi %0,%3,%H1,%H2\"; +}" + [(set_attr "type" "insert_dword")]) + +(define_insn "*insvdi_internal2" + [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") + (match_operand:SI 1 "const_int_operand" "i") + (match_operand:SI 2 "const_int_operand" "i")) + (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r") + (match_operand:SI 4 "const_int_operand" "i")))] + "TARGET_POWERPC64 + && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])" + "* +{ + int shift = INTVAL (operands[4]) & 63; + int start = (INTVAL (operands[2]) & 63) - 32; + int size = INTVAL (operands[1]) & 63; + + operands[4] = GEN_INT (64 - shift - start - size); + operands[2] = GEN_INT (start); + operands[1] = GEN_INT (start + size - 1); + return \"rlwimi %0,%3,%h4,%h2,%h1\"; +}") + +(define_insn "*insvdi_internal3" + [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") + (match_operand:SI 1 "const_int_operand" "i") + (match_operand:SI 2 "const_int_operand" "i")) + (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r") + (match_operand:SI 4 "const_int_operand" "i")))] + "TARGET_POWERPC64 + && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])" + "* +{ + int shift = INTVAL (operands[4]) & 63; + int start = (INTVAL (operands[2]) & 63) - 32; + int size = INTVAL (operands[1]) & 63; + + operands[4] = GEN_INT (64 - shift - start - size); + operands[2] = GEN_INT (start); + operands[1] = GEN_INT (start + size - 1); + return \"rlwimi %0,%3,%h4,%h2,%h1\"; }") (define_expand "extzv" @@ -3519,7 +3785,7 @@ (match_operand:SI 3 "const_int_operand" "i,i")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64" + "" "* { int start = INTVAL (operands[3]) & 31; @@ -3529,7 +3795,7 @@ 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 @@ -3551,17 +3817,17 @@ operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\"; }" - [(set_attr "type" "compare") + [(set_attr "type" "delayed_compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) @@ -3578,7 +3844,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "* { int start = INTVAL (operands[3]) & 31; @@ -3588,9 +3854,11 @@ if (which_alternative == 1) return \"#\"; + /* Since we are using the output value, we can't ignore any need for + a shift. The bit-field must end at the LSB. */ if (start >= 16 && start + size == 32) { - operands[3] = GEN_INT ((1 << (32 - start)) - 1); + operands[3] = GEN_INT ((1 << size) - 1); return \"{andil.|andi.} %0,%1,%3\"; } @@ -3604,14 +3872,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) (set (match_dup 4) @@ -3645,7 +3913,7 @@ (match_operand:SI 3 "const_int_operand" "i")) (const_int 0))) (clobber (match_scratch:DI 4 "=r"))] - "TARGET_POWERPC64" + "TARGET_64BIT && rs6000_gen_cell_microcode" "* { int start = INTVAL (operands[3]) & 63; @@ -3657,7 +3925,8 @@ operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl. %4,%1,%3,%2\"; -}") +}" + [(set_attr "type" "compare")]) (define_insn "*extzvdi_internal2" [(set (match_operand:CC 4 "gpc_reg_operand" "=x") @@ -3667,7 +3936,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r") (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))] - "TARGET_POWERPC64" + "TARGET_64BIT && rs6000_gen_cell_microcode" "* { int start = INTVAL (operands[3]) & 63; @@ -3679,35 +3948,41 @@ operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl. %0,%1,%3,%2\"; -}") +}" + [(set_attr "type" "compare")]) (define_insn "rotlsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") + "@ + {rlnm|rlwnm} %0,%1,%2,0xffffffff + {rlinm|rlwinm} %0,%1,%h2,0xffffffff" + [(set_attr "type" "var_shift_rotate,integer")]) (define_insn "*rotlsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC64" + (clobber (match_scratch:SI 3 "=r,r,r,r"))] + "" "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff + {rlnm.|rlwnm.} %3,%1,%2,0xffffffff + {rlinm.|rlwinm.} %3,%1,%h2,0xffffffff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 3) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) @@ -3716,27 +3991,29 @@ "") (define_insn "*rotlsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (rotate:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" + "" "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff + {rlnm.|rlwnm.} %0,%1,%2,0xffffffff + {rlinm.|rlwinm.} %0,%1,%h2,0xffffffff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (rotate:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) @@ -3745,37 +4022,42 @@ "") (define_insn "*rotlsi3_internal4" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) - (match_operand:SI 3 "mask_operand" "T")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")) + (match_operand:SI 3 "mask_operand" "n,n")))] "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") + "@ + {rlnm|rlwnm} %0,%1,%2,%m3,%M3 + {rlinm|rlwinm} %0,%1,%h2,%m3,%M3" + [(set_attr "type" "var_shift_rotate,integer")]) (define_insn "*rotlsi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "T,T")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) + (match_operand:SI 3 "mask_operand" "n,n,n,n")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64" + (clobber (match_scratch:SI 4 "=r,r,r,r"))] + "" "@ - {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3 + {rlnm.|rlwnm.} %4,%1,%2,%m3,%M3 + {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) @@ -3786,23 +4068,25 @@ "") (define_insn "*rotlsi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "T,T")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) + (match_operand:SI 3 "mask_operand" "n,n,n,n")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3 + {rlnm.|rlwnm.} %0,%1,%2,%m3,%M3 + {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) @@ -3810,7 +4094,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -3825,25 +4109,31 @@ (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff") + "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff" + [(set (attr "cell_micro") + (if_then_else (match_operand:SI 2 "const_int_operand" "") + (const_string "not") + (const_string "always")))]) (define_insn "*rotlsi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (zero_extend:SI (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] + (clobber (match_scratch:SI 3 "=r,r,r,r"))] "" "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff + {rlnm.|rlwnm.} %3,%1,%2,0xff + {rlinm.|rlwinm.} %3,%1,%h2,0xff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:QI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -3861,23 +4151,25 @@ "") (define_insn "*rotlsi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (zero_extend:SI (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff + {rlnm.|rlwnm.} %0,%1,%2,0xff + {rlinm.|rlwinm.} %0,%1,%h2,0xff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:QI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -3894,31 +4186,37 @@ "") (define_insn "*rotlsi3_internal10" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))] "" - "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") + "@ + {rlnm|rlwnm} %0,%1,%2,0xffff + {rlinm|rlwinm} %0,%1,%h2,0xffff" + [(set_attr "type" "var_shift_rotate,integer")]) + (define_insn "*rotlsi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] + (clobber (match_scratch:SI 3 "=r,r,r,r"))] "" "@ - {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff + {rlnm.|rlwnm.} %3,%1,%2,0xffff + {rlinm.|rlwinm.} %3,%1,%h2,0xffff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:HI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -3936,23 +4234,25 @@ "") (define_insn "*rotlsi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" "@ - {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff + {rlnm.|rlwnm.} %0,%1,%2,0xffff + {rlinm.|rlwinm.} %0,%1,%h2,0xffff + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:HI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -3996,11 +4296,14 @@ {sli|slwi} %0,%1,%h2") (define_insn "ashlsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "! TARGET_POWER" - "{sl|slw}%I2 %0,%1,%h2") + "@ + {sl|slw} %0,%1,%2 + {sli|slwi} %0,%1,%h2" + [(set_attr "type" "var_shift_rotate,shift")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") @@ -4035,17 +4338,19 @@ "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWER && ! TARGET_POWERPC64" + (clobber (match_scratch:SI 3 "=r,r,r,r"))] + "! TARGET_POWER && TARGET_32BIT" "@ - {sl|slw}%I2. %3,%1,%h2 + {sl.|slw.} %3,%1,%2 + {sli.|slwi.} %3,%1,%h2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") @@ -4053,7 +4358,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + "! TARGET_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 3) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) @@ -4096,18 +4401,20 @@ "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (ashift:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER && ! TARGET_POWERPC64" + "! TARGET_POWER && TARGET_32BIT" "@ - {sl|slw}%I2. %0,%1,%h2 + {sl.|slw.} %0,%1,%2 + {sli.|slwi.} %0,%1,%h2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") @@ -4116,7 +4423,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ashift:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + "! TARGET_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) @@ -4124,11 +4431,11 @@ (const_int 0)))] "") -(define_insn "" +(define_insn "rlwinm" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")))] + (match_operand:SI 3 "mask_operand" "n")))] "includes_lshift_p (operands[2], operands[3])" "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3") @@ -4137,10 +4444,10 @@ (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" + "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 #" @@ -4148,14 +4455,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "")) (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + "includes_lshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 4) (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -4169,11 +4476,11 @@ (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" + "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 #" @@ -4181,7 +4488,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "")) @@ -4189,7 +4496,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + "includes_lshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 0) (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -4225,13 +4532,15 @@ {s%A2i|s%A2wi} %0,%1,%h2") (define_insn "lshrsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))] "! TARGET_POWER" "@ mr %0,%1 - {sr|srw}%I2 %0,%1,%h2") + {sr|srw} %0,%1,%2 + {sri|srwi} %0,%1,%h2" + [(set_attr "type" "integer,var_shift_rotate,shift")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y") @@ -4268,19 +4577,21 @@ "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=X,r,X,r"))] - "! TARGET_POWER && ! TARGET_POWERPC64" + (clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))] + "! TARGET_POWER && TARGET_32BIT" "@ mr. %1,%1 - {sr|srw}%I2. %3,%1,%h2 + {sr.|srw.} %3,%1,%2 + {sri.|srwi.} %3,%1,%h2 + # # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,4,8,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") @@ -4288,7 +4599,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + "! TARGET_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 3) (lshiftrt:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) @@ -4333,20 +4644,22 @@ "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y") + (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r") (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER && ! TARGET_POWERPC64" + "! TARGET_POWER && TARGET_32BIT" "@ mr. %0,%1 - {sr|srw}%I2. %0,%1,%h2 + {sr.|srw.} %0,%1,%2 + {sri.|srwi.} %0,%1,%h2 + # # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,4,8,8,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") @@ -4355,7 +4668,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed" + "! TARGET_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) @@ -4367,7 +4680,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")))] + (match_operand:SI 3 "mask_operand" "n")))] "includes_rshift_p (operands[2], operands[3])" "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3") @@ -4376,10 +4689,10 @@ (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" + "includes_rshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3 #" @@ -4387,14 +4700,14 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "")) (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + "includes_rshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 4) (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -4408,11 +4721,11 @@ (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" + "includes_rshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3 #" @@ -4420,7 +4733,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "")) @@ -4428,7 +4741,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + "includes_rshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 0) (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -4462,7 +4775,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:QI @@ -4498,7 +4811,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:QI @@ -4541,7 +4854,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:HI @@ -4577,7 +4890,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (zero_extend:SI (subreg:HI @@ -4644,14 +4957,18 @@ "TARGET_POWER" "@ srea %0,%1,%2 - {srai|srawi} %0,%1,%h2") + {srai|srawi} %0,%1,%h2" + [(set_attr "type" "shift")]) (define_insn "ashrsi3_no_power" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "! TARGET_POWER" - "{sra|sraw}%I2 %0,%1,%h2") + "@ + {sra|sraw} %0,%1,%2 + {srai|srawi} %0,%1,%h2" + [(set_attr "type" "var_shift_rotate,shift")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") @@ -4686,20 +5003,22 @@ "") (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] + (clobber (match_scratch:SI 3 "=r,r,r,r"))] "! TARGET_POWER" "@ - {sra|sraw}%I2. %3,%1,%h2 + {sra.|sraw.} %3,%1,%2 + {srai.|srawi.} %3,%1,%h2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) @@ -4747,21 +5066,23 @@ "") (define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (ashiftrt:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER" "@ - {sra|sraw}%I2. %0,%1,%h2 + {sra.|sraw.} %0,%1,%2 + {srai.|srawi.} %0,%1,%h2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) @@ -4791,51 +5112,78 @@ ;; this case, we just lose precision that we would have otherwise gotten but ;; is not guaranteed. Perhaps this should be tightened up at some point. -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" - "* +(define_expand "extendsfdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") + +(define_insn_and_split "*extendsfdf2_fpr" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f") + (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "@ + # + fmr %0,%1 + lfs%U1%X1 %0,%1" + "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" + [(const_int 0)] { - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"\"; - else - return \"fmr %0,%1\"; -}" - [(set_attr "type" "fp")]) + emit_note (NOTE_INSN_DELETED); + DONE; +} + [(set_attr "type" "fp,fp,fpload")]) + +(define_expand "truncdfsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") -(define_insn "truncdfsf2" +(define_insn "*truncdfsf2_fpr" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frsp %0,%1" [(set_attr "type" "fp")]) (define_insn "aux_truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + (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")]) -(define_insn "negsf2" +(define_expand "negsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" + "") + +(define_insn "*negsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fneg %0,%1" [(set_attr "type" "fp")]) -(define_insn "abssf2" +(define_expand "abssf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" + "") + +(define_insn "*abssf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -4843,22 +5191,23 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fadds %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) @@ -4866,22 +5215,23 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fsubs %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) @@ -4889,22 +5239,23 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "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_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fmuls %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_mul_s")]) (define_insn "" [(set (match_operand:SF 0 "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_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul")]) @@ -4912,14 +5263,15 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (div:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fdivs %0,%1,%2" [(set_attr "type" "sdiv")]) @@ -4927,25 +5279,47 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) +(define_expand "recipsf3" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f") + (match_operand:SF 2 "gpc_reg_operand" "f")] + UNSPEC_FRES))] + "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT && !optimize_size + && flag_finite_math_only && !flag_trapping_math" +{ + rs6000_emit_swdivsf (operands[0], operands[1], operands[2]); + DONE; +}) + +(define_insn "fres" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] + "TARGET_PPC_GFXOPT && flag_finite_math_only" + "fres %0,%1" + [(set_attr "type" "fp")]) + (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -4954,16 +5328,18 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -4972,16 +5348,39 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) + +(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_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (SFmode)" + "fnmadds %0,%1,%2,%3" + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "{fnma|fnmadd} %0,%1,%2,%3" + [(set_attr "type" "dmul")]) + +(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")]) @@ -4990,59 +5389,143 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) + +(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 + && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" + "fnmsubs %0,%1,%2,%3" + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "{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" "dmul")]) (define_expand "sqrtsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" + "(TARGET_PPC_GPOPT || TARGET_POWER2 || TARGET_XILINX_FPU) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT + && !TARGET_SIMPLE_FPU" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT" + "(TARGET_PPC_GPOPT || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT + && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fsqrts %0,%1" [(set_attr "type" "ssqrt")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_POWER2 && TARGET_HARD_FLOAT" + "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) +(define_expand "rsqrtsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] + UNSPEC_RSQRT))] + "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT && !optimize_size + && flag_finite_math_only && !flag_trapping_math" +{ + rs6000_emit_swrsqrtsf (operands[0], operands[1]); + DONE; +}) + +(define_insn "*rsqrt_internal1" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] + UNSPEC_RSQRT))] + "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" + "frsqrte %0,%1" + [(set_attr "type" "fp")]) + +(define_expand "copysignsf3" + [(set (match_dup 3) + (abs:SF (match_operand:SF 1 "gpc_reg_operand" ""))) + (set (match_dup 4) + (neg:SF (abs:SF (match_dup 1)))) + (set (match_operand:SF 0 "gpc_reg_operand" "") + (if_then_else:SF (ge (match_operand:SF 2 "gpc_reg_operand" "") + (match_dup 5)) + (match_dup 3) + (match_dup 4)))] + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT + && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)" + { + operands[3] = gen_reg_rtx (SFmode); + operands[4] = gen_reg_rtx (SFmode); + operands[5] = CONST0_RTX (SFmode); + }) + +(define_expand "copysigndf3" + [(set (match_dup 3) + (abs:DF (match_operand:DF 1 "gpc_reg_operand" ""))) + (set (match_dup 4) + (neg:DF (abs:DF (match_dup 1)))) + (set (match_operand:DF 0 "gpc_reg_operand" "") + (if_then_else:DF (ge (match_operand:DF 2 "gpc_reg_operand" "") + (match_dup 5)) + (match_dup 3) + (match_dup 4)))] + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)" + { + operands[3] = gen_reg_rtx (DFmode); + operands[4] = gen_reg_rtx (DFmode); + operands[5] = CONST0_RTX (DFmode); + }) + ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a ;; fsel instruction and some auxiliary computations. Then we just have a ;; single DEFINE_INSN for fsel and the define_splits to make them if made by ;; combine. -(define_expand "maxsf3" +(define_expand "smaxsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") -(define_expand "minsf3" +(define_expand "sminsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5050,20 +5533,69 @@ (match_operator:SF 3 "min_max_operator" [(match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" [(const_int 0)] " -{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), +{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1], operands[2]); DONE; }") +(define_expand "movsicc" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (if_then_else:SI (match_operand 1 "comparison_operator" "") + (match_operand:SI 2 "gpc_reg_operand" "") + (match_operand:SI 3 "gpc_reg_operand" "")))] + "TARGET_ISEL" + " +{ + if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) + DONE; + else + FAIL; +}") + +;; We use the BASE_REGS for the isel input operands because, if rA is +;; 0, the value of 0 is placed in rD upon truth. Similarly for rB +;; because we may switch the operands and rB may end up being rA. +;; +;; We need 2 patterns: an unsigned and a signed pattern. We could +;; leave out the mode in operand 4 and use one pattern, but reload can +;; change the mode underneath our feet and then gets confused trying +;; to reload the value. +(define_insn "isel_signed" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI + (match_operator 1 "comparison_operator" + [(match_operand:CC 4 "cc_reg_operand" "y") + (const_int 0)]) + (match_operand:SI 2 "gpc_reg_operand" "b") + (match_operand:SI 3 "gpc_reg_operand" "b")))] + "TARGET_ISEL" + "* +{ return output_isel (operands); }" + [(set_attr "length" "4")]) + +(define_insn "isel_unsigned" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI + (match_operator 1 "comparison_operator" + [(match_operand:CCUNS 4 "cc_reg_operand" "y") + (const_int 0)]) + (match_operand:SI 2 "gpc_reg_operand" "b") + (match_operand:SI 3 "gpc_reg_operand" "b")))] + "TARGET_ISEL" + "* +{ return output_isel (operands); }" + [(set_attr "length" "4")]) + (define_expand "movsfcc" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (match_operand 1 "comparison_operator" "") (match_operand:SF 2 "gpc_reg_operand" "") (match_operand:SF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5078,7 +5610,7 @@ (match_operand:SF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5088,125 +5620,220 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) -(define_insn "negdf2" +(define_expand "negdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") + +(define_insn "*negdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fneg %0,%1" [(set_attr "type" "fp")]) -(define_insn "absdf2" +(define_expand "absdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") + +(define_insn "*absdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fabs %0,%1" [(set_attr "type" "fp")]) -(define_insn "" +(define_insn "*nabsdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fnabs %0,%1" [(set_attr "type" "fp")]) -(define_insn "adddf3" +(define_expand "adddf3" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (plus:DF (match_operand:DF 1 "gpc_reg_operand" "") + (match_operand:DF 2 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") + +(define_insn "*adddf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fa|fadd} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) + +(define_expand "subdf3" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (minus:DF (match_operand:DF 1 "gpc_reg_operand" "") + (match_operand:DF 2 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") -(define_insn "subdf3" +(define_insn "*subdf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fs|fsub} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) -(define_insn "muldf3" +(define_expand "muldf3" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (mult:DF (match_operand:DF 1 "gpc_reg_operand" "") + (match_operand:DF 2 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" + "") + +(define_insn "*muldf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fm|fmul} %0,%1,%2" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_mul_d")]) -(define_insn "divdf3" +(define_expand "divdf3" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (div:DF (match_operand:DF 1 "gpc_reg_operand" "") + (match_operand:DF 2 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) + && !TARGET_SIMPLE_FPU" + "") + +(define_insn "*divdf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (div:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) +(define_expand "recipdf3" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f") + (match_operand:DF 2 "gpc_reg_operand" "f")] + UNSPEC_FRES))] + "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_POPCNTB && !optimize_size + && flag_finite_math_only && !flag_trapping_math" +{ + rs6000_emit_swdivdf (operands[0], operands[1], operands[2]); + DONE; +}) + +(define_insn "fred" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] + "TARGET_POPCNTB && flag_finite_math_only" + "fre %0,%1" + [(set_attr "type" "fp")]) + (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fma|fmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fms|fmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT + && HONOR_SIGNED_ZEROS (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) + +(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 && TARGET_DOUBLE_FLOAT + && ! HONOR_SIGNED_ZEROS (DFmode)" + "{fnma|fnmadd} %0,%1,%2,%3" + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT + && HONOR_SIGNED_ZEROS (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) + +(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 && TARGET_DOUBLE_FLOAT + && ! HONOR_SIGNED_ZEROS (DFmode)" + "{fnms|fnmsub} %0,%1,%2,%3" + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "sqrtdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" + "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) ;; The conditional move instructions allow us to perform max and min -;; operations even when +;; operations even when -(define_expand "maxdf3" +(define_expand "smaxdf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") -(define_expand "mindf3" +(define_expand "smindf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5214,10 +5841,11 @@ (match_operator:DF 3 "min_max_operator" [(match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" [(const_int 0)] " -{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), +{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1], operands[2]); DONE; }") @@ -5227,7 +5855,7 @@ (if_then_else:DF (match_operand 1 "comparison_operator" "") (match_operand:DF 2 "gpc_reg_operand" "") (match_operand:DF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5242,7 +5870,7 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:DF 2 "gpc_reg_operand" "f") (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5252,12 +5880,24 @@ (match_operand:SF 4 "zero_fp_constant" "F")) (match_operand:DF 2 "gpc_reg_operand" "f") (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) ;; Conversions to and from floating-point. +(define_expand "fixuns_truncsfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" + "") + +(define_expand "fix_truncsfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" + "") + ; For each of these conversions, there is a define_expand, a define_insn ; with a '#' template, and a define_split (with C code). The idea is ; to allow constant folding with the template of the define_insn, @@ -5271,74 +5911,68 @@ (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))])] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { + if (TARGET_E500_DOUBLE) + { + emit_insn (gen_spe_floatsidf2 (operands[0], operands[1])); + DONE; + } if (TARGET_POWERPC64) { - rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); - rtx t1 = gen_reg_rtx (DImode); - rtx t2 = gen_reg_rtx (DImode); - emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2)); + rtx x = convert_to_mode (DImode, operands[1], 0); + emit_insn (gen_floatdidf2 (operands[0], x)); DONE; } operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode)); + operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); operands[5] = gen_reg_rtx (DFmode); operands[6] = gen_reg_rtx (SImode); }") -(define_insn "*floatsidf2_internal" +(define_insn_and_split "*floatsidf2_internal" [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (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"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) + (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 && TARGET_DOUBLE_FLOAT" "#" - [(set_attr "length" "24")]) - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "")) - (clobber (match_operand:SI 6 "gpc_reg_operand" ""))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "")) - (clobber (match_operand:SI 6 "gpc_reg_operand" ""))] + "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" + [(pc)] " { rtx lowword, highword; - if (GET_CODE (operands[4]) != MEM) - abort(); - highword = XEXP (operands[4], 0); - lowword = plus_constant (highword, 4); + gcc_assert (MEM_P (operands[4])); + highword = adjust_address (operands[4], SImode, 0); + lowword = adjust_address (operands[4], SImode, 4); if (! WORDS_BIG_ENDIAN) { rtx tmp; tmp = highword; highword = lowword; lowword = tmp; } - emit_insn (gen_xorsi3 (operands[6], operands[1], + emit_insn (gen_xorsi3 (operands[6], operands[1], GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); - emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[6]); - emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]); + emit_move_insn (lowword, operands[6]); + emit_move_insn (highword, operands[2]); emit_move_insn (operands[5], operands[4]); emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); DONE; -}") +}" + [(set_attr "length" "24")]) + +(define_expand "floatunssisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" + "") (define_expand "floatunssidf2" [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -5347,170 +5981,314 @@ (use (match_dup 3)) (clobber (match_dup 4)) (clobber (match_dup 5))])] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { + if (TARGET_E500_DOUBLE) + { + emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1])); + DONE; + } if (TARGET_POWERPC64) { - rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); - rtx t1 = gen_reg_rtx (DImode); - rtx t2 = gen_reg_rtx (DImode); - emit_insn (gen_floatunssidf_ppc64 (operands[0], operands[1], mem, - t1, t2)); + rtx x = convert_to_mode (DImode, operands[1], 1); + emit_insn (gen_floatdidf2 (operands[0], x)); DONE; } operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode)); + operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); operands[5] = gen_reg_rtx (DFmode); }") -(define_insn "*floatunssidf2_internal" +(define_insn_and_split "*floatunssidf2_internal" [(set (match_operand:DF 0 "gpc_reg_operand" "=&f") (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:DF 3 "gpc_reg_operand" "f")) - (clobber (match_operand:DF 4 "memory_operand" "=o")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) + (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))] + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" - [(set_attr "length" "20")]) - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) - (clobber (match_operand:DF 5 "gpc_reg_operand" ""))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (use (match_operand:SI 2 "gpc_reg_operand" "")) - (use (match_operand:DF 3 "gpc_reg_operand" "")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) - (clobber (match_operand:DF 5 "gpc_reg_operand" ""))] + "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" + [(pc)] " { rtx lowword, highword; - if (GET_CODE (operands[4]) != MEM) - abort(); - highword = XEXP (operands[4], 0); - lowword = plus_constant (highword, 4); + gcc_assert (MEM_P (operands[4])); + highword = adjust_address (operands[4], SImode, 0); + lowword = adjust_address (operands[4], SImode, 4); if (! WORDS_BIG_ENDIAN) { rtx tmp; tmp = highword; highword = lowword; lowword = tmp; } - emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[1]); - emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]); + emit_move_insn (lowword, operands[1]); + emit_move_insn (highword, operands[2]); emit_move_insn (operands[5], operands[4]); emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); DONE; -}") +}" + [(set_attr "length" "20")]) (define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") + [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "") (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_dup 2)) (clobber (match_dup 3))])] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + "(TARGET_POWER2 || TARGET_POWERPC) + && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { + if (TARGET_E500_DOUBLE) + { + emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1])); + DONE; + } operands[2] = gen_reg_rtx (DImode); + if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && gpc_reg_operand(operands[0], GET_MODE (operands[0]))) + { + operands[3] = gen_reg_rtx (DImode); + emit_insn (gen_fix_truncdfsi2_mfpgpr (operands[0], operands[1], + operands[2], operands[3])); + DONE; + } + if (TARGET_PPC_GFXOPT) + { + rtx orig_dest = operands[0]; + if (! memory_operand (orig_dest, GET_MODE (orig_dest))) + operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0); + emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1], + operands[2])); + if (operands[0] != orig_dest) + emit_move_insn (orig_dest, operands[0]); + DONE; + } operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); }") -(define_insn "*fix_truncdfsi2_internal" +(define_insn_and_split "*fix_truncdfsi2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=*f")) - (clobber (match_operand:DI 3 "memory_operand" "=o"))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) + (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))] + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "#" - [(set_attr "length" "16")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] + "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))" + [(pc)] " { rtx lowword; - if (GET_CODE (operands[3]) != MEM) - abort(); - lowword = XEXP (operands[3], 0); - if (WORDS_BIG_ENDIAN) - lowword = plus_constant (lowword, 4); + gcc_assert (MEM_P (operands[3])); + lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); emit_insn (gen_fctiwz (operands[2], operands[1])); emit_move_insn (operands[3], operands[2]); - emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword)); + emit_move_insn (operands[0], lowword); DONE; -}") +}" + [(set_attr "length" "16")]) + +(define_insn_and_split "fix_truncdfsi2_internal_gfxopt" + [(set (match_operand:SI 0 "memory_operand" "=Z") + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))] + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT + && TARGET_PPC_GFXOPT" + "#" + "&& 1" + [(pc)] + " +{ + emit_insn (gen_fctiwz (operands[2], operands[1])); + emit_insn (gen_stfiwx (operands[0], operands[2])); + DONE; +}" + [(set_attr "length" "16")]) + +(define_insn_and_split "fix_truncdfsi2_mfpgpr" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) + (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))] + "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" + "#" + "&& 1" + [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ)) + (set (match_dup 3) (match_dup 2)) + (set (match_dup 0) (subreg:SI (match_dup 3) 4))] + "" + [(set_attr "length" "12")]) -; 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))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + [(set (match_operand:DI 0 "gpc_reg_operand" "=f") + (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] + UNSPEC_FCTIWZ))] + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) -(define_insn "floatdidf2" +(define_insn "btruncdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float:DF (match_operand:DI 1 "gpc_reg_operand" "*f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" - "fcfid %0,%1" + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "friz %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "btruncsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + "friz %0,%1" [(set_attr "type" "fp")]) -(define_insn_and_split "floatsidf_ppc64" +(define_insn "ceildf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (clobber (match_operand:DI 2 "memory_operand" "=o")) - (clobber (match_operand:DI 3 "gpc_reg_operand" "=r")) - (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" - "#" - "" - [(set (match_dup 3) (sign_extend:DI (match_dup 1))) - (set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 2)) - (set (match_dup 0) (float:DF (match_dup 4)))] - "") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "frip %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "ceilsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + "frip %0,%1" + [(set_attr "type" "fp")]) -(define_insn_and_split "floatunssidf_ppc64" +(define_insn "floordf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (clobber (match_operand:DI 2 "memory_operand" "=o")) - (clobber (match_operand:DI 3 "gpc_reg_operand" "=r")) - (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" - "#" - "" - [(set (match_dup 3) (zero_extend:DI (match_dup 1))) - (set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 2)) - (set (match_dup 0) (float:DF (match_dup 4)))] + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "frim %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "floorsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + "frim %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "rounddf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "frin %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "roundsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + "frin %0,%1" + [(set_attr "type" "fp")]) + +; An UNSPEC is used so we don't have to support SImode in FP registers. +(define_insn "stfiwx" + [(set (match_operand:SI 0 "memory_operand" "=Z") + (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")] + UNSPEC_STFIWX))] + "TARGET_PPC_GFXOPT" + "stfiwx %1,%y0" + [(set_attr "type" "fpstore")]) + +(define_expand "floatsisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS" "") +(define_insn "floatdidf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))] + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" + "fcfid %0,%1" + [(set_attr "type" "fp")]) + (define_insn "fix_truncdfdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") + [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "fctidz %0,%1" [(set_attr "type" "fp")]) + +(define_expand "floatdisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " + " +{ + rtx val = operands[1]; + if (!flag_unsafe_math_optimizations) + { + rtx label = gen_label_rtx (); + val = gen_reg_rtx (DImode); + emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); + emit_label (label); + } + emit_insn (gen_floatdisf2_internal1 (operands[0], val)); + DONE; +}") + +;; This is not IEEE compliant if rounding mode is "round to nearest". +;; If the DI->DF conversion is inexact, then it's possible to suffer +;; from double rounding. +(define_insn_and_split "floatdisf2_internal1" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r"))) + (clobber (match_scratch:DF 2 "=f"))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" + "#" + "&& reload_completed" + [(set (match_dup 2) + (float:DF (match_dup 1))) + (set (match_dup 0) + (float_truncate:SF (match_dup 2)))] + "") + +;; Twiddles bits to avoid double rounding. +;; 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 3) (ashiftrt:DI (match_operand:DI 1 "" "") + (const_int 53))) + (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1) + (const_int 2047))) + (clobber (scratch:CC))]) + (set (match_dup 3) (plus:DI (match_dup 3) + (const_int 1))) + (set (match_dup 0) (plus:DI (match_dup 0) + (const_int 2047))) + (set (match_dup 4) (compare:CCUNS (match_dup 3) + (const_int 2))) + (set (match_dup 0) (ior:DI (match_dup 0) + (match_dup 1))) + (parallel [(set (match_dup 0) (and:DI (match_dup 0) + (const_int -2048))) + (clobber (scratch:CC))]) + (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) + (label_ref (match_operand:DI 2 "" "")) + (pc))) + (set (match_dup 0) (match_dup 1))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" + " +{ + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (CCUNSmode); +}") ;; Define the DImode operations that can be done in a small number ;; of instructions. The & constraints are to prevent the register @@ -5534,7 +6312,8 @@ ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\" : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\"; }" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "*subdi3_noppc64" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r") @@ -5552,7 +6331,8 @@ ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\" : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\"; }" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "*negdi2_noppc64" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") @@ -5564,7 +6344,8 @@ ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\" : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\"; }" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_expand "mulsidi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -5707,9 +6488,9 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) + (match_operand:SI 1 "gpc_reg_operand" "")) (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 2 "gpc_reg_operand" ""))) (const_int 32))))] "" " @@ -5837,1437 +6618,1203 @@ "@ {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2" - [(set_attr "length" "8")]) - -;; PowerPC64 DImode operations. + [(set_attr "type" "shift") + (set_attr "length" "8")]) -(define_expand "adddi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_add_cint64_operand" "")))] - "" - " +(define_insn "ashrdi3_no_power" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") + (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "M,i")))] + "TARGET_32BIT && !TARGET_POWERPC64 && !TARGET_POWER && WORDS_BIG_ENDIAN" + "@ + {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 + {sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2" + [(set_attr "type" "two,three") + (set_attr "length" "8,12")]) + +(define_insn "*ashrdisi3_noppc64" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 32)) 4))] + "TARGET_32BIT && !TARGET_POWERPC64" + "* { - if (! TARGET_POWERPC64) - { - if (non_short_cint_operand (operands[2], DImode)) - FAIL; - } + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"\"; else - if (GET_CODE (operands[2]) == CONST_INT - && ! add_operand (operands[2], DImode)) - { - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode); - - if (!CONST_OK_FOR_LETTER_P (rest, 'L')) - FAIL; - - /* The ordering here is important for the prolog expander. - When space is allocated from the stack, adding 'low' first may - produce a temporary deallocation (which would be bad). */ - emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (rest))); - emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low))); - DONE; - } -}") + return \"mr %0,%1\"; +}" + [(set_attr "length" "4")]) -;; Discourage ai/addic because of carry but provide it in an alternative -;; allowing register zero as source. + +;; PowerPC64 DImode operations. + +(define_insn_and_split "absdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) + (clobber (match_scratch:DI 2 "=&r,&r"))] + "TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) + (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) + (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] + "") + +(define_insn_and_split "*nabsdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) + (clobber (match_scratch:DI 2 "=&r,&r"))] + "TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) + (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) + (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))] + "") -(define_insn "*adddi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b") - (match_operand:DI 2 "add_operand" "r,I,I,L")))] +(define_insn "muldi3" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "reg_or_short_operand" "r,I")))] "TARGET_POWERPC64" "@ - add %0,%1,%2 - addi %0,%1,%2 - addic %0,%1,%2 - addis %0,%1,%v2") + mulld %0,%1,%2 + mulli %0,%1,%2" + [(set (attr "type") + (cond [(match_operand:SI 2 "s8bit_cint_operand" "") + (const_string "imul3") + (match_operand:SI 2 "short_cint_operand" "") + (const_string "imul2")] + (const_string "lmul")))]) -(define_insn "*adddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) +(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,r,r"))] + (clobber (match_scratch:DI 3 "=r,r"))] "TARGET_POWERPC64" "@ - add. %3,%1,%2 - addic. %3,%1,%2 - # + mulld. %3,%1,%2 #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "lmul_compare") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_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) - (plus:DI (match_dup 1) (match_dup 2))) + (mult:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*adddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")) +(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,r,r") - (plus:DI (match_dup 1) (match_dup 2)))] + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (mult:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" "@ - add. %0,%1,%2 - addic. %0,%1,%2 - # + mulld. %0,%1,%2 #" - [(set_attr "type" "compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "lmul_compare") + (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) + [(set (match_operand:CC 3 "cc_reg_not_micro_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" "") - (plus:DI (match_dup 1) (match_dup 2)))] + (mult:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (plus:DI (match_dup 1) (match_dup 2))) + (mult:DI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -;; Split an add that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. Note that the low-order -;; add should be last in case the result gets used in an address. - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_add_cint_operand" "")))] +(define_insn "smuldi3_highpart" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (truncate:DI + (lshiftrt:TI (mult:TI (sign_extend:TI + (match_operand:DI 1 "gpc_reg_operand" "%r")) + (sign_extend:TI + (match_operand:DI 2 "gpc_reg_operand" "r"))) + (const_int 64))))] "TARGET_POWERPC64" - [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] -" -{ - HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode); - - operands[4] = GEN_INT (low); - if (CONST_OK_FOR_LETTER_P (rest, 'L')) - operands[3] = GEN_INT (rest); - else if (! no_new_pseudos) - { - operands[3] = gen_reg_rtx (DImode); - emit_move_insn (operands[3], operands[2]); - emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); - DONE; - } - else - FAIL; -}") + "mulhd %0,%1,%2" + [(set_attr "type" "lmul")]) -(define_insn "one_cmpldi2" +(define_insn "umuldi3_highpart" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] + (truncate:DI + (lshiftrt:TI (mult:TI (zero_extend:TI + (match_operand:DI 1 "gpc_reg_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "gpc_reg_operand" "r"))) + (const_int 64))))] "TARGET_POWERPC64" - "nor %0,%1,%1") + "mulhdu %0,%1,%2" + [(set_attr "type" "lmul")]) -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] +(define_insn "rotldi3" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i")))] "TARGET_POWERPC64" "@ - nor. %2,%1,%1 + rldcl %0,%1,%2,0 + rldicl %0,%1,%H2,0" + [(set_attr "type" "var_shift_rotate,integer")]) + +(define_insn "*rotldi3_internal2" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" + "@ + rldcl. %3,%1,%2,0 + rldicl. %3,%1,%H2,0 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) (const_int 0))) - (clobber (match_scratch:DI 2 ""))] + (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (not:DI (match_dup 1))) + [(set (match_dup 3) + (rotate:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) - (compare:CC (match_dup 2) + (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) +(define_insn "*rotldi3_internal3" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (not:DI (match_dup 1)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (rotate:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT" "@ - nor. %0,%1,%1 + rldcl. %0,%1,%2,0 + rldicl. %0,%1,%H2,0 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (not:DI (match_dup 1)))] + (rotate:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (not:DI (match_dup 1))) - (set (match_dup 2) + (rotate:DI (match_dup 1) (match_dup 2))) + (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "" +(define_insn "*rotldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I") - (match_operand:DI 2 "gpc_reg_operand" "r,r")))] + (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i")) + (match_operand:DI 3 "mask64_operand" "n,n")))] "TARGET_POWERPC64" "@ - subf %0,%2,%1 - subfic %0,%2,%1") + rldc%B3 %0,%1,%2,%S3 + rldic%B3 %0,%1,%H2,%S3" + [(set_attr "type" "var_shift_rotate,integer")]) -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) +(define_insn "*rotldi3_internal5" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) + (match_operand:DI 3 "mask64_operand" "n,n,n,n")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:DI 4 "=r,r,r,r"))] + "TARGET_64BIT" "@ - subf. %3,%2,%1 + rldc%B3. %4,%1,%2,%S3 + rldic%B3. %4,%1,%H2,%S3 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) (const_int 0))) - (clobber (match_scratch:DI 3 ""))] + (clobber (match_scratch:DI 4 ""))] "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (minus:DI (match_dup 1) (match_dup 2))) + [(set (match_dup 4) + (and:DI (rotate:DI (match_dup 1) + (match_dup 2)) + (match_dup 3))) (set (match_dup 0) - (compare:CC (match_dup 3) + (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) +(define_insn "*rotldi3_internal6" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) + (match_operand:DI 3 "mask64_operand" "n,n,n,n")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (minus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT" "@ - subf. %0,%2,%1 + rldc%B3. %0,%1,%2,%S3 + rldic%B3. %0,%1,%H2,%S3 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (minus:DI (match_dup 1) (match_dup 2)))] + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (minus:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_expand "subdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "") - (match_operand:DI 2 "reg_or_sub_cint64_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_adddi3 (operands[0], operands[1], - negate_rtx (DImode, operands[2]))); - DONE; - } -}") - -(define_insn "absdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) - (clobber (match_scratch:DI 2 "=&r,&r"))] +(define_insn "*rotldi3_internal7" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%2,%0" - [(set_attr "length" "12")]) + "@ + rldcl %0,%1,%2,56 + rldicl %0,%1,%H2,56" + [(set_attr "type" "var_shift_rotate,integer")]) + +(define_insn "*rotldi3_internal8" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" + "@ + rldcl. %3,%1,%2,56 + rldicl. %3,%1,%H2,56 + # + #" + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_scratch:DI 2 ""))] + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) - (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] + [(set (match_dup 3) + (zero_extend:DI (subreg:QI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] "") -(define_insn "*nabsdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) - (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%0,%2" - [(set_attr "length" "12")]) +(define_insn "*rotldi3_internal9" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT" + "@ + rldcl. %0,%1,%2,56 + rldicl. %0,%1,%H2,56 + # + #" + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))) - (clobber (match_scratch:DI 2 ""))] + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) - (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))] - "") - -(define_expand "negdi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))] - "" + [(set (match_dup 0) + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] "") -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] +(define_insn "*rotldi3_internal10" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] "TARGET_POWERPC64" - "neg %0,%1") + "@ + rldcl %0,%1,%2,48 + rldicl %0,%1,%H2,48" + [(set_attr "type" "var_shift_rotate,integer")]) -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) +(define_insn "*rotldi3_internal11" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" "@ - neg. %2,%1 + rldcl. %3,%1,%2,48 + rldicl. %3,%1,%H2,48 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) - (clobber (match_scratch:DI 2 ""))] + (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (neg:DI (match_dup 1))) + [(set (match_dup 3) + (zero_extend:DI (subreg:HI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) (set (match_dup 0) - (compare:CC (match_dup 2) + (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) +(define_insn "*rotldi3_internal12" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (neg:DI (match_dup 1)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT" "@ - neg. %0,%1 + rldcl. %0,%1,%2,48 + rldicl. %0,%1,%H2,48 + # #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (match_dup 1)))] + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (neg:DI (match_dup 1))) - (set (match_dup 2) + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) (compare:CC (match_dup 0) (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")))] - "TARGET_POWERPC64" - "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64" - [(set_attr "length" "16")]) - -(define_insn "muldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] +(define_insn "*rotldi3_internal13" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] "TARGET_POWERPC64" - "mulld %0,%1,%2" - [(set_attr "type" "lmul")]) + "@ + rldcl %0,%1,%2,32 + rldicl %0,%1,%H2,32" + [(set_attr "type" "var_shift_rotate,integer")]) -(define_insn "smuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (sign_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (sign_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhd %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (zero_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhdu %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_expand "divdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 0 - && exact_log2 (INTVAL (operands[2])) >= 0) - ; - else - operands[2] = force_reg (DImode, operands[2]); -}") - -(define_expand "moddi3" - [(use (match_operand:DI 0 "gpc_reg_operand" "")) - (use (match_operand:DI 1 "gpc_reg_operand" "")) - (use (match_operand:DI 2 "reg_or_cint_operand" ""))] - "TARGET_POWERPC64" - " -{ - int i; - rtx temp1; - rtx temp2; - - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 0 - || (i = exact_log2 (INTVAL (operands[2]))) < 0) - FAIL; - - temp1 = gen_reg_rtx (DImode); - temp2 = gen_reg_rtx (DImode); - - emit_insn (gen_divdi3 (temp1, operands[1], operands[2])); - emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i))); - emit_insn (gen_subdi3 (operands[0], operands[1], temp2)); - DONE; -}") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "exact_log2_cint_operand" "N")))] - "TARGET_POWERPC64" - "sradi %0,%1,%p2\;addze %0,%0" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "exact_log2_cint_operand" "N,N")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - sradi %3,%1,%p2\;addze. %3,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) +(define_insn "*rotldi3_internal14" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" + "@ + rldcl. %3,%1,%2,32 + rldicl. %3,%1,%H2,32 + # + #" + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "exact_log2_cint_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) - (div:DI (match_dup 1) (match_dup 2))) + (zero_extend:DI (subreg:SI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "exact_log2_cint_operand" "N,N")) +(define_insn "*rotldi3_internal15" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (div:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT" "@ - sradi %0,%1,%p2\;addze. %0,%0 + rldcl. %0,%1,%2,32 + rldicl. %0,%1,%H2,32 + # #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "exact_log2_cint_operand" "")) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (div:DI (match_dup 1) (match_dup 2)))] + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (div:DI (match_dup 1) (match_dup 2))) + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (div:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "divd %0,%1,%2" - [(set_attr "type" "ldiv")]) - -(define_insn "udivdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "divdu %0,%1,%2" - [(set_attr "type" "ldiv")]) +(define_expand "ashldi3" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")))] + "TARGET_POWERPC64 || TARGET_POWER" + " +{ + if (TARGET_POWERPC64) + ; + else if (TARGET_POWER) + { + emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2])); + DONE; + } + else + FAIL; +}") -(define_insn "rotldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")))] +(define_insn "*ashldi3_internal1" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,0") + "@ + sld %0,%1,%2 + sldi %0,%1,%H2" + [(set_attr "type" "var_shift_rotate,shift")]) -(define_insn "*rotldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) +(define_insn "*ashldi3_internal2" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" "@ - rld%I2cl. %3,%1,%H2,0 + sld. %3,%1,%2 + sldi. %3,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) - (rotate:DI (match_dup 1) (match_dup 2))) + (ashift:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*rotldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) +(define_insn "*ashldi3_internal3" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (ashift:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT" "@ - rld%I2cl. %0,%1,%H2,0 + sld. %0,%1,%2 + sldi. %0,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) + (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (rotate:DI (match_dup 1) (match_dup 2)))] + (ashift:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (rotate:DI (match_dup 1) (match_dup 2))) + (ashift:DI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*rotldi3_internal4" +(define_insn "*ashldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) - (match_operand:DI 3 "mask64_operand" "S")))] - "TARGET_POWERPC64" - "rld%I2c%B3 %0,%1,%H2,%S3") + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:DI 3 "const_int_operand" "n")))] + "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" + "rldic %0,%1,%H2,%W3") -(define_insn "*rotldi3_internal5" +(define_insn "ashldi3_internal5" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "const_int_operand" "n,n")) + (const_int 0))) (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" "@ - rld%I2c%B3. %4,%1,%H2,%S3 + rldic. %4,%1,%H2,%W3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "const_int_operand" "")) + (const_int 0))) (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_POWERPC64 && reload_completed + && includes_rldic_lshift_p (operands[2], operands[3])" [(set (match_dup 4) - (and:DI (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3))) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*rotldi3_internal6" +(define_insn "*ashldi3_internal6" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "const_int_operand" "n,n")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" "@ - rld%I2c%B3. %0,%1,%H2,%S3 + rldic. %0,%1,%H2,%W3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "const_int_operand" "")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed + && includes_rldic_lshift_p (operands[2], operands[3])" [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*rotldi3_internal7" +(define_insn "*ashldi3_internal7" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,56") + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:DI 3 "mask64_operand" "n")))] + "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" + "rldicr %0,%1,%H2,%S3") -(define_insn "*rotldi3_internal8" +(define_insn "ashldi3_internal8" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "n,n")) + (const_int 0))) + (clobber (match_scratch:DI 4 "=r,r"))] + "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" "@ - rld%I2cl. %3,%1,%H2,56 + rldicr. %4,%1,%H2,%S3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:QI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed + && includes_rldicr_lshift_p (operands[2], operands[3])" + [(set (match_dup 4) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) (set (match_dup 0) - (compare:CC (match_dup 3) + (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*rotldi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) +(define_insn "*ashldi3_internal9" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "n,n")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" "@ - rld%I2cl. %0,%1,%H2,56 + rldicr. %0,%1,%H2,%S3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed + && includes_rldicr_lshift_p (operands[2], operands[3])" [(set (match_dup 0) - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*rotldi3_internal10" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,48") - -(define_insn "*rotldi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - rld%I2cl. %3,%1,%H2,48 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:HI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") +(define_expand "lshrdi3" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")))] + "TARGET_POWERPC64 || TARGET_POWER" + " +{ + if (TARGET_POWERPC64) + ; + else if (TARGET_POWER) + { + emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2])); + DONE; + } + else + FAIL; +}") -(define_insn "*rotldi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] +(define_insn "*lshrdi3_internal1" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "TARGET_POWERPC64" "@ - rld%I2cl. %0,%1,%H2,48 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal13" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))] - "TARGET_POWERPC64" - "rld%I2cl %0,%1,%H2,32") + srd %0,%1,%2 + srdi %0,%1,%H2" + [(set_attr "type" "var_shift_rotate,shift")]) -(define_insn "*rotldi3_internal14" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) +(define_insn "*lshrdi3_internal2" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT " "@ - rld%I2cl. %3,%1,%H2,32 + srd. %3,%1,%2 + srdi. %3,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) - (zero_extend:DI (subreg:SI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) + (lshiftrt:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*rotldi3_internal15" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0)) +(define_insn "*lshrdi3_internal3" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (lshiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT" "@ - rld%I2cl. %0,%1,%H2,32 + srd. %0,%1,%2 + srdi. %0,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + (lshiftrt:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (lshiftrt:DI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_expand "ashldi3" +(define_expand "ashrdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" + (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")))] + "WORDS_BIG_ENDIAN" " { if (TARGET_POWERPC64) ; - else if (TARGET_POWER) + else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT) { - emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2])); + emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2])); + DONE; + } + else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT + && WORDS_BIG_ENDIAN) + { + emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2])); DONE; } else FAIL; }") -(define_insn "*ashldi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] +(define_insn "*ashrdi3_internal1" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] "TARGET_POWERPC64" - "sld%I2 %0,%1,%H2" - [(set_attr "length" "8")]) - -(define_insn "*ashldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) + "@ + srad %0,%1,%2 + sradi %0,%1,%H2" + [(set_attr "type" "var_shift_rotate,shift")]) + +(define_insn "*ashrdi3_internal2" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:DI 3 "=r,r,r,r"))] + "TARGET_64BIT" "@ - sld%I2. %3,%1,%H2 + srad. %3,%1,%2 + sradi. %3,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) + (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:DI 3 ""))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) - (ashift:DI (match_dup 1) (match_dup 2))) + (ashiftrt:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*ashldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) +(define_insn "*ashrdi3_internal3" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (ashiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT" "@ - sld%I2. %0,%1,%H2 + srad. %0,%1,%2 + sradi. %0,%1,%H2 + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") + (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_dup 1) (match_dup 2)))] + (ashiftrt:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (ashift:DI (match_dup 1) (match_dup 2))) + (ashiftrt:DI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*ashldi3_internal4" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "const_int_operand" "n")))] - "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" - "rldic %0,%1,%H2,%W3") +(define_expand "anddi3" + [(parallel + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "and64_2_operand" ""))) + (clobber (match_scratch:CC 3 ""))])] + "TARGET_POWERPC64" + "") -(define_insn "ashldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" +(define_insn "anddi3_mc" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t"))) + (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))] + "TARGET_POWERPC64 && rs6000_gen_cell_microcode" "@ - rldic. %4,%1,%H2,%W3 + and %0,%1,%2 + rldic%B2 %0,%1,0,%S2 + rlwinm %0,%1,0,%m2,%M2 + andi. %0,%1,%b2 + andis. %0,%1,%u2 #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") + [(set_attr "type" "*,*,*,compare,compare,*") + (set_attr "length" "4,4,4,4,4,8")]) -(define_insn "*ashldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" +(define_insn "anddi3_nomc" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "?r,S,T,t"))) + (clobber (match_scratch:CC 3 "=X,X,X,X"))] + "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" "@ - rldic. %0,%1,%H2,%W3 + and %0,%1,%2 + rldic%B2 %0,%1,0,%S2 + rlwinm %0,%1,0,%m2,%M2 #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "length" "4,4,4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" ""))) + (clobber (match_scratch:CC 3 ""))] + "TARGET_POWERPC64 + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask_operand (operands[2], DImode) + && !mask64_operand (operands[2], DImode)" [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal7" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "S")))] - "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" - "rldicr %0,%1,%H2,%S3") + (and:DI (rotate:DI (match_dup 1) + (match_dup 4)) + (match_dup 5))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)))] +{ + build_mask64_2_operands (operands[2], &operands[4]); +}) -(define_insn "ashldi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" +(define_insn "*anddi3_internal2_mc" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r")) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))] + "TARGET_64BIT && rs6000_gen_cell_microcode" "@ - rldicr. %4,%1,%H2,%S3 + and. %3,%1,%2 + rldic%B2. %3,%1,0,%S2 + rlwinm. %3,%1,0,%m2,%M2 + andi. %3,%1,%b2 + andis. %3,%1,%u2 + # + # + # + # + # + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare") + (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") + [(set (match_operand:CC 0 "cc_reg_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 "")) + (clobber (match_scratch:CC 4 ""))] + "TARGET_64BIT && reload_completed + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask_operand (operands[2], DImode) + && !mask64_operand (operands[2], DImode)" + [(set (match_dup 3) + (and:DI (rotate:DI (match_dup 1) + (match_dup 5)) + (match_dup 6))) + (parallel [(set (match_dup 0) + (compare:CC (and:DI (rotate:DI (match_dup 3) + (match_dup 7)) + (match_dup 8)) + (const_int 0))) + (clobber (match_dup 3))])] + " +{ + build_mask64_2_operands (operands[2], &operands[5]); +}") -(define_insn "*ashldi3_internal9" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "S,S")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" +(define_insn "*anddi3_internal3_mc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r") + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))] + "TARGET_64BIT && rs6000_gen_cell_microcode" "@ - rldicr. %0,%1,%H2,%S3 + and. %0,%1,%2 + rldic%B2. %0,%1,0,%S2 + rlwinm. %0,%1,0,%m2,%M2 + andi. %0,%1,%b2 + andis. %0,%1,%u2 + # + # + # + # + # + # #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) + [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare") + (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "and64_2_operand" "")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_64BIT && reload_completed" + [(parallel [(set (match_dup 0) + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_expand "lshrdi3" +(define_split + [(set (match_operand:CC 3 "cc_reg_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_64BIT && reload_completed + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask_operand (operands[2], DImode) + && !mask64_operand (operands[2], DImode)" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 5)) + (match_dup 6))) + (parallel [(set (match_dup 3) + (compare:CC (and:DI (rotate:DI (match_dup 0) + (match_dup 7)) + (match_dup 8)) + (const_int 0))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 7)) + (match_dup 8)))])] + " +{ + build_mask64_2_operands (operands[2], &operands[5]); +}") + +(define_expand "iordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" + (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] + "TARGET_POWERPC64" " { - if (TARGET_POWERPC64) - ; - else if (TARGET_POWER) + if (non_logical_cint_operand (operands[2], DImode)) { - emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2])); + HOST_WIDE_INT value; + rtx tmp = ((!can_create_pseudo_p () + || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + if (GET_CODE (operands[2]) == CONST_INT) + { + value = INTVAL (operands[2]); + emit_insn (gen_iordi3 (tmp, operands[1], + GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); + } + else + { + value = CONST_DOUBLE_LOW (operands[2]); + emit_insn (gen_iordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + } + + emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } - else - FAIL; }") -(define_insn "*lshrdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] +(define_expand "xordi3" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] "TARGET_POWERPC64" - "srd%I2 %0,%1,%H2") - -(define_insn "*lshrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - srd%I2. %3,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (lshiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*lshrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - srd%I2. %0,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (lshiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" - " -{ - if (TARGET_POWERPC64) - ; - else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -(define_insn "*ashrdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")))] - "TARGET_POWERPC64" - "srad%I2 %0,%1,%H2") - -(define_insn "*ashrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - srad%I2. %3,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*ashrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - srad%I2. %0,%1,%H2 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "anddi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_operand" "?r,S,K,J"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))] - "TARGET_POWERPC64" - "@ - and %0,%1,%2 - rldic%B2 %0,%1,0,%S2 - andi. %0,%1,%b2 - andis. %0,%1,%u2") - -(define_insn "*anddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,?y,??y,??y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,") - (match_operand:DI 2 "and64_operand" "r,S,K,J,r,S,K,J")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,x,x"))] - "TARGET_POWERPC64" - "@ - and. %3,%1,%2 - rldic%B2. %3,%1,0,%S2 - andi. %3,%1,%b2 - andis. %3,%1,%u2 - # - # - # - #" - [(set_attr "type" "compare,delayed_compare,compare,compare,compare,delayed_compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 3) - (and:DI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*anddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,?y,??y,??y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_operand" "r,S,K,J,r,S,K,J")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,x,x"))] - "TARGET_POWERPC64" - "@ - and. %0,%1,%2 - rldic%B2. %0,%1,0,%S2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - # - # - # - #" - [(set_attr "type" "compare,delayed_compare,compare,compare,compare,delayed_compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 0) - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "iordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - if (GET_CODE (operands[2]) == CONST_INT) - { - value = INTVAL (operands[2]); - emit_insn (gen_iordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - } - else - { - value = CONST_DOUBLE_LOW (operands[2]); - emit_insn (gen_iordi3 (tmp, operands[1], - immed_double_const (value - & (~ (HOST_WIDE_INT) 0xffff), - 0, DImode))); - } - - emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_expand "xordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); + " +{ + if (non_logical_cint_operand (operands[2], DImode)) + { + HOST_WIDE_INT value; + rtx tmp = ((!can_create_pseudo_p () + || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); if (GET_CODE (operands[2]) == CONST_INT) { @@ -7307,7 +7854,7 @@ (match_operand:DI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %3,%1,%2 #" @@ -7315,7 +7862,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(match_operand:DI 1 "gpc_reg_operand" "") (match_operand:DI 2 "gpc_reg_operand" "")]) @@ -7330,13 +7877,13 @@ (define_insn "*booldi3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" + (compare:CC (match_operator:DI 4 "boolean_or_operator" [(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") (match_dup 4))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %0,%1,%2 #" @@ -7344,7 +7891,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(match_operand:DI 1 "gpc_reg_operand" "") (match_operand:DI 2 "gpc_reg_operand" "")]) @@ -7358,7 +7905,7 @@ (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 @@ -7372,7 +7919,7 @@ " { rtx i3,i4; - + if (GET_CODE (operands[2]) == CONST_DOUBLE) { HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); @@ -7386,10 +7933,10 @@ & (~ (HOST_WIDE_INT) 0xffff)); i4 = GEN_INT (INTVAL (operands[2]) & 0xffff); } - operands[4] = gen_rtx (GET_CODE (operands[3]), DImode, - operands[1], i3); - operands[5] = gen_rtx (GET_CODE (operands[3]), DImode, - operands[0], i4); + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, + operands[1], i3); + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, + operands[0], i4); }") (define_insn "*boolcdi3_internal1" @@ -7407,7 +7954,7 @@ (match_operand:DI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %3,%2,%1 #" @@ -7415,7 +7962,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) (match_operand:DI 2 "gpc_reg_operand" "")]) @@ -7436,7 +7983,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %0,%2,%1 #" @@ -7444,7 +7991,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) (match_operand:DI 2 "gpc_reg_operand" "")]) @@ -7473,7 +8020,7 @@ (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %3,%1,%2 #" @@ -7481,7 +8028,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) @@ -7502,7 +8049,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ %q4. %0,%1,%2 #" @@ -7510,7 +8057,7 @@ (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (match_operator:DI 4 "boolean_operator" [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) @@ -7526,47 +8073,12 @@ ;; Now define ways of moving data around. -;; Elf specific ways of loading addresses for non-PIC code. -;; The output of this could be r0, but we make a very strong -;; preference for a base register because it will usually -;; be needed there. -(define_insn "elf_high" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") - (high:SI (match_operand 1 "" "")))] - "TARGET_ELF && ! TARGET_64BIT" - "{liu|lis} %0,%1@ha") - -(define_insn "elf_low" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") - (match_operand 2 "" "")))] - "TARGET_ELF && ! TARGET_64BIT" - "@ - {cal|la} %0,%2@l(%1) - {ai|addic} %0,%1,%K2") - -;; Mach-O PIC trickery. -(define_insn "macho_high" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") - (high:SI (match_operand 1 "" "")))] - "TARGET_MACHO && ! TARGET_64BIT" - "{liu|lis} %0,ha16(%1)") - -(define_insn "macho_low" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") - (match_operand 2 "" "")))] - "TARGET_MACHO && ! TARGET_64BIT" - "@ - {cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)} - {cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}") - ;; Set up a register with a value from the GOT table (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" " { @@ -7579,7 +8091,9 @@ value = INTVAL (offset); if (value != 0) { - rtx tmp = (no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode)); + rtx tmp = (!can_create_pseudo_p () + ? operands[0] + : gen_reg_rtx (Pmode)); emit_insn (gen_movsi_got (tmp, operands[1])); emit_insn (gen_addsi3 (operands[0], tmp, offset)); DONE; @@ -7592,116 +8106,42 @@ (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")]) ;; Used by sched, shorten_branches and final when the GOT pseudo reg ;; didn't get allocated to a hard register. -(define_split +(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 ;; do the load 16-bits at a time. We could do this by loading from memory, ;; and this is even supposed to be faster, but it is simpler not to get ;; integers in the TOC. -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], SImode); DONE; }") - (define_insn "movsi_low" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b") + (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (match_operand 2 "" ""))))] "TARGET_MACHO && ! TARGET_64BIT" "{l|lwz} %0,lo16(%2)(%1)" [(set_attr "type" "load") (set_attr "length" "4")]) -(define_insn "movsi_low_st" - [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b") - (match_operand 2 "" ""))) - (match_operand:SI 0 "gpc_reg_operand" "r"))] - "TARGET_MACHO && ! TARGET_64BIT" - "{st|stw} %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movdf_low" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") - (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" - "* -{ - switch (which_alternative) - { - case 0: - return \"lfd %0,lo16(%2)(%1)\"; - case 1: - { - rtx operands2[4]; - operands2[0] = operands[0]; - operands2[1] = operands[1]; - 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); - /* 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); - return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\"); - } - default: - abort(); - } -}" - [(set_attr "type" "load") - (set_attr "length" "4,12")]) - -(define_insn "movdf_low_st" - [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b") - (match_operand 2 "" ""))) - (match_operand:DF 0 "gpc_reg_operand" "f"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" - "stfd %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movsf_low" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") - (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" - "@ - lfs %0,lo16(%2)(%1) - {l|lwz} %0,lo16(%2)(%1)" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "movsf_low_st" - [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") - (match_operand 2 "" ""))) - (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" - "@ - stfs %0,lo16(%2)(%1) - {st|stw} %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - (define_insn "*movsi_internal1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h") + [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h") (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))] "gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode)" @@ -7718,8 +8158,8 @@ mt%0 %1 mt%0 %1 mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*,*") + {cror 0,0,0|nop}" + [(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 @@ -7736,42 +8176,40 @@ (ior:SI (match_dup 0) (match_dup 3)))] " -{ - operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff); +{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2); + + if (tem == operands[0]) + DONE; + else + FAIL; }") -(define_insn "*movsi_internal2" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r") +(define_insn "*mov_internal2" + [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") + (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] + "" "@ + {cmpi|cmpi} %2,%0,0 mr. %0,%1 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - + [(set_attr "type" "cmp,compare,cmp") + (set_attr "length" "4,4,8")]) + (define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") + [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (match_operand:P 1 "gpc_reg_operand" "") (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 1))] - "! TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))] + "reload_completed" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "") - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], HImode); DONE; }") - -(define_insn "" + +(define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] "gpc_reg_operand (operands[0], HImode) @@ -7784,16 +8222,16 @@ mf%1 %0 mt%0 %1 mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) + {cror 0,0,0|nop}" + [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")]) -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "any_operand" ""))] +(define_expand "mov" + [(set (match_operand:INT 0 "general_operand" "") + (match_operand:INT 1 "any_operand" ""))] "" - "{ rs6000_emit_move (operands[0], operands[1], QImode); DONE; }") + "{ rs6000_emit_move (operands[0], operands[1], mode); DONE; }") -(define_insn "" +(define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] "gpc_reg_operand (operands[0], QImode) @@ -7806,8 +8244,8 @@ mf%1 %0 mt%0 %1 mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) + {cror 0,0,0|nop}" + [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")]) ;; 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. @@ -7818,22 +8256,45 @@ "" "") -(define_insn "" - [(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"))] +(define_insn "*movcc_internal1" + [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,q,cl,r,m") + (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,r,m,r"))] "register_operand (operands[0], CCmode) || register_operand (operands[1], CCmode)" "@ mcrf %0,%1 mtcrf 128,%1 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff - mfcr %0 - mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 + crxor %0,%0,%0 + mfcr %0%Q1 + mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 mr %0,%1 + {lil|li} %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" "*,*,*,compare,*,*,load,store") - (set_attr "length" "*,*,12,*,8,*,*,*")]) + [(set (attr "type") + (cond [(eq_attr "alternative" "0,3") + (const_string "cr_logical") + (eq_attr "alternative" "1,2") + (const_string "mtcr") + (eq_attr "alternative" "6,7,9") + (const_string "integer") + (eq_attr "alternative" "8") + (const_string "mfjmpr") + (eq_attr "alternative" "10") + (const_string "mtjmpr") + (eq_attr "alternative" "11") + (const_string "load") + (eq_attr "alternative" "12") + (const_string "store") + (ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) + (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4,4")]) ;; For floating-point, we normally deal with the floating-point registers ;; unless -msoft-float is used. The sole exception is that parameter passing @@ -7868,14 +8329,15 @@ else operands[2] = gen_lowpart (SImode, operands[0]); - operands[3] = GEN_INT (trunc_int_for_mode (l, SImode)); + operands[3] = gen_int_mode (l, SImode); }") (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,*c*l,*q,!r,*h,!r,!r") + (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT" + || gpc_reg_operand (operands[1], SFmode)) + && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" "@ mr %0,%1 {l%U1%X1|lwz%U1%X1} %0,%1 @@ -7883,27 +8345,36 @@ fmr %0,%1 lfs%U1%X1 %0,%1 stfs%U0%X0 %1,%0 + mt%0 %1 + mt%0 %1 + mf%1 %0 + {cror 0,0,0|nop} # #" - [(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,*,mfjmpr,*,*,*") + (set_attr "length" "4,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" + || 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,*,mfjmpr,load,store,*,*,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")]) (define_expand "movdf" @@ -7933,7 +8404,7 @@ operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); + operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); #endif }") @@ -7958,13 +8429,13 @@ operands[2] = operand_subword (operands[0], endian, 0, DFmode); operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); - operands[4] = GEN_INT (trunc_int_for_mode (l[endian], SImode)); - operands[5] = GEN_INT (trunc_int_for_mode (l[1 - endian], SImode)); + operands[4] = gen_int_mode (l[endian], SImode); + operands[5] = gen_int_mode (l[1 - endian], SImode); }") (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "easy_fp_constant" ""))] + (match_operand:DF 1 "const_double_operand" ""))] "TARGET_POWERPC64 && reload_completed && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) || (GET_CODE (operands[0]) == SUBREG @@ -7976,7 +8447,9 @@ 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); @@ -7984,10 +8457,10 @@ operands[2] = gen_lowpart (DImode, operands[0]); /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ #if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 | - ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); + val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - operands[3] = immed_double_const (val, -(val < 0), DImode); + operands[3] = gen_int_mode (val, DImode); #else operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); #endif @@ -8000,9 +8473,9 @@ ;; 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"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT + [(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 && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8010,7 +8483,7 @@ switch (which_alternative) { default: - abort (); + gcc_unreachable (); case 0: /* We normally copy the low-numbered register first. However, if the first register operand 0 is the same as the second register @@ -8020,11 +8493,12 @@ else return \"mr %0,%1\;mr %L0,%L1\"; case 1: - if (offsettable_memref_p (operands[1]) + if (rs6000_offsettable_memref_p (operands[1]) || (GET_CODE (operands[1]) == MEM && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM || GET_CODE (XEXP (operands[1], 0)) == PRE_INC - || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))) + || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC + || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY))) { /* If the low-address word is used in the address, we must load it last. Otherwise, load it first. Note that we cannot have @@ -8034,7 +8508,7 @@ operands[1], 0)) return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\"; } else { @@ -8046,56 +8520,59 @@ operands[1], 0)) { output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands); output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); - return \"{lx|lwzx} %0,%1\"; + return \"{l%X1|lwz%X1} %0,%1\"; } else { - output_asm_insn (\"{lx|lwzx} %0,%1\", operands); + output_asm_insn (\"{l%X1|lwz%X1} %0,%1\", operands); output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands); output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); return \"\"; } } case 2: - if (offsettable_memref_p (operands[0]) + if (rs6000_offsettable_memref_p (operands[0]) || (GET_CODE (operands[0]) == MEM && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM || GET_CODE (XEXP (operands[0], 0)) == PRE_INC - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))) - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC + || GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY))) + return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\"; else { rtx addreg; addreg = find_addr_reg (XEXP (operands[0], 0)); - output_asm_insn (\"{stx|stwx} %1,%0\", operands); + output_asm_insn (\"{st%X0|stw%X0} %1,%0\", operands); output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); - output_asm_insn (\"{stx|stwx} %L1,%0\", operands); + output_asm_insn (\"{st%X0|stw%X0} %L1,%0\", operands); output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); 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" "two,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") (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT + "! TARGET_POWERPC64 + && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) + || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8103,7 +8580,7 @@ switch (which_alternative) { default: - abort (); + gcc_unreachable (); case 0: /* We normally copy the low-numbered register first. However, if the first register operand 0 is the same as the second register of @@ -8121,192 +8598,350 @@ operands[1], 0)) return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\"; case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\"; case 3: case 4: case 5: return \"#\"; } }" - [(set_attr "type" "*,load,store,*,*,*") + [(set_attr "type" "two,load,store,*,*,*") (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"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT +; ld/std require word-aligned displacements -> 'Y' constraint. +; List Y->r and r->Y before r->r for reload. +(define_insn "*movdf_hardfloat64_mfpgpr" + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f") + (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))] + "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT && (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 + ld%U1%X1 %0,%1 + mr %0,%1 + fmr %0,%1 + lfd%U1%X1 %0,%1 + stfd%U0%X0 %1,%0 + mt%0 %1 + mf%1 %0 + {cror 0,0,0|nop} # # # + mftgpr %0,%1 + mffgpr %0,%1" + [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") + (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) + +; ld/std require word-aligned displacements -> 'Y' constraint. +; List Y->r and r->Y before r->r for reload. +(define_insn "*movdf_hardfloat64" + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))] + "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT + && (gpc_reg_operand (operands[0], DFmode) + || gpc_reg_operand (operands[1], DFmode))" + "@ + std%U0%X0 %1,%0 + ld%U1%X1 %0,%1 + mr %0,%1 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 + {cror 0,0,0|nop} + # + # + #" + [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*") + (set_attr "length" "4,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"))] - "TARGET_POWERPC64 && TARGET_SOFT_FLOAT + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") + (match_operand:DF 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))] + "TARGET_POWERPC64 && (TARGET_SOFT_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 + mr %0,%1 + mt%0 %1 + mf%1 %0 # # - #" - [(set_attr "type" "*,load,store,*,*,*") - (set_attr "length" "*,*,*,8,12,16")]) + # + {cror 0,0,0|nop}" + [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,8,12,16,4")]) (define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") (match_operand:TF 1 "any_operand" ""))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128" "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }") -(define_insn "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r") - (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 +; It's important to list the o->f and f->o moves before f->f because +; otherwise reload, given m->f, will try to pick f->f and reload it, +; which doesn't make progress. Likewise r->Y must be before r->r. +(define_insn_and_split "*movtf_internal" + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r") + (match_operand:TF 1 "input_operand" "f,o,f,YGHF,r,r"))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 && (gpc_reg_operand (operands[0], TFmode) || gpc_reg_operand (operands[1], TFmode))" - "* + "#" + "&& reload_completed" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } + [(set_attr "length" "8,8,8,20,20,16")]) + +(define_insn_and_split "*movtf_softfloat" + [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,Y,r") + (match_operand:TF 1 "input_operand" "YGHF,r,r"))] + "!TARGET_IEEEQUAD + && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128 + && (gpc_reg_operand (operands[0], TFmode) + || gpc_reg_operand (operands[1], TFmode))" + "#" + "&& reload_completed" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } + [(set_attr "length" "20,20,16")]) + +(define_expand "extenddftf2" + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float_extend:TF (match_operand:DF 1 "input_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" { - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"fmr %L0,%L1\;fmr %0,%1\"; - else - return \"fmr %0,%1\;fmr %L0,%L1\"; - case 1: - return \"lfd %0,%1\;lfd %L0,%L1\"; - case 2: - return \"stfd %1,%0\;stfd %L1,%L0\"; - case 3: - case 4: - case 5: - return \"#\"; - } -}" - [(set_attr "type" "fp,fpload,fpstore,*,*,*") - (set_attr "length" "8,8,8,12,16,20")]) - -(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_LONG_DOUBLE_128" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 0) - (float_extend:TF (match_dup 3)))] - " + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); + else + emit_insn (gen_extenddftf2_fprs (operands[0], operands[1])); + DONE; +}) + +(define_expand "extenddftf2_fprs" + [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float_extend:TF (match_operand:DF 1 "input_operand" ""))) + (use (match_dup 2))])] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" +{ + operands[2] = CONST0_RTX (DFmode); + /* Generate GOT reference early for SVR4 PIC. */ + if (DEFAULT_ABI == ABI_V4 && flag_pic) + operands[2] = validize_mem (force_const_mem (DFmode, operands[2])); +}) + +(define_insn_and_split "*extenddftf2_internal" + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r") + (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF"))) + (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" + [(pc)] { - operands[2] = operand_subword (operands[1], 0, 0, DFmode); - operands[3] = gen_reg_rtx (DFmode); -}") + const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word), + operands[1]); + emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word), + operands[2]); + DONE; +}) -(define_insn_and_split "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_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] - " +(define_expand "extendsftf2" + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" { - operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (DFmode); -}") + rtx tmp = gen_reg_rtx (DFmode); + emit_insn (gen_extendsfdf2 (tmp, operands[1])); + emit_insn (gen_extenddftf2 (operands[0], tmp)); + DONE; +}) -(define_insn_and_split "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_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] - " +(define_expand "trunctfdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" + "") + +(define_insn_and_split "trunctfdf2_internal1" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))] + "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "@ + # + fmr %0,%1" + "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" + [(const_int 0)] { - operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (SFmode); -}") + emit_note (NOTE_INSN_DELETED); + DONE; +} + [(set_attr "type" "fp")]) -(define_insn "trunctfdf2" +(define_insn "trunctfdf2_internal2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "!TARGET_IEEEQUAD && TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" "fadd %0,%1,%L1" [(set_attr "type" "fp") - (set_attr "length" "8")]) + (set_attr "fp_type" "fp_addsub_d")]) + +(define_expand "trunctfsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1])); + else + emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); + DONE; +}) -(define_insn_and_split "trunctfsf2" +(define_insn_and_split "trunctfsf2_fprs" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT + && TARGET_LONG_DOUBLE_128" "#" - "" + "&& reload_completed" [(set (match_dup 2) (float_truncate:DF (match_dup 1))) (set (match_dup 0) (float_truncate:SF (match_dup 2)))] - " + "") + +(define_expand "floatsitf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + rtx tmp = gen_reg_rtx (DFmode); + expand_float (tmp, operands[1], false); + emit_insn (gen_extenddftf2 (operands[0], tmp)); + DONE; +}) + +; fadd, but rounding towards zero. +; This is probably not the optimal code sequence. +(define_insn "fix_trunc_helper" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")] + UNSPEC_FIX_TRUNC_TF)) + (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" + [(set_attr "type" "fp") + (set_attr "length" "20")]) + +(define_expand "fix_trunctfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && (TARGET_POWER2 || TARGET_POWERPC) + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1])); + else + emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1])); + DONE; +}) + +(define_expand "fix_trunctfsi2_fprs" + [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:TF 1 "gpc_reg_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3)) + (clobber (match_dup 4)) + (clobber (match_dup 5))])] + "!TARGET_IEEEQUAD + && (TARGET_POWER2 || TARGET_POWERPC) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" { operands[2] = gen_reg_rtx (DFmode); -}") + operands[3] = gen_reg_rtx (DFmode); + operands[4] = gen_reg_rtx (DImode); + operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); +}) -(define_expand "floatditf2" - [(set (match_dup 2) - (float:DF (match_operand:DI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") - (float_extend:TF (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 - && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") +(define_insn_and_split "*fix_trunctfsi2_internal" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_operand:DF 2 "gpc_reg_operand" "=f")) + (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f")) + (clobber (match_operand:DI 4 "gpc_reg_operand" "=f")) + (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "#" + "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))" + [(pc)] +{ + rtx lowword; + emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3])); -(define_expand "floatsitf2" - [(set (match_dup 2) - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") - (float_extend:TF (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + gcc_assert (MEM_P (operands[5])); + lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); -(define_expand "fix_trunctfdi2" - [(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)))] - "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 - && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + emit_insn (gen_fctiwz (operands[4], operands[2])); + emit_move_insn (operands[5], operands[4]); + emit_move_insn (operands[0], lowword); + DONE; +}) -(define_expand "fix_trunctfsi2" - [(set (match_dup 2) - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") +(define_expand "negtf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" + "") -(define_insn "negtf2" +(define_insn "negtf2_internal" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "* { if (REGNO (operands[0]) == REGNO (operands[1]) + 1) @@ -8317,90 +8952,72 @@ [(set_attr "type" "fp") (set_attr "length" "8")]) -(define_insn "abstf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "* +(define_expand "abstf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" + " { - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"fabs %L0,%L1\;fabs %0,%1\"; + rtx label = gen_label_rtx (); + if (TARGET_E500_DOUBLE) + { + if (flag_finite_math_only && !flag_trapping_math) + emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); + else + emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); + } else - return \"fabs %0,%1\;fabs %L0,%L1\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "8")]) + emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); + emit_label (label); + DONE; +}") -(define_insn "" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "* +(define_expand "abstf2_internal" + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (match_operand:TF 1 "gpc_reg_operand" "")) + (set (match_dup 3) (match_dup 5)) + (set (match_dup 5) (abs:DF (match_dup 5))) + (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) + (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 6) (neg:DF (match_dup 6)))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" + " { - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"fnabs %L0,%L1\;fnabs %0,%1\"; - else - return \"fnabs %0,%1\;fnabs %L0,%L1\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "8")]) + const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + operands[3] = gen_reg_rtx (DFmode); + operands[4] = gen_reg_rtx (CCFPmode); + operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); + operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); +}") ;; Next come the multi-word integer load and store and the load and store ;; multiple insns. -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], DImode); DONE; }") +; List r->r after r->"o<>", otherwise reload will try to reload a +; non-offsettable address by using r->r which won't make progress. (define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r") - (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))] + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r") + (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))] "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" - "* -{ - switch (which_alternative) - { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; - case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; - case 3: - return \"fmr %0,%1\"; - case 4: - return \"lfd%U1%X1 %0,%1\"; - case 5: - return \"stfd%U0%X0 %1,%0\"; - case 6: - case 7: - case 8: - case 9: - case 10: - return \"#\"; - } -}" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*") - (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")]) + "@ + # + # + # + fmr %0,%1 + lfd%U1%X1 %0,%1 + stfd%U0%X0 %1,%0 + #" + [(set_attr "type" "load,*,store,fp,fpload,fpstore,*")]) (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -8419,56 +9036,47 @@ operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); + operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); #endif }") (define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed" - [(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, - DImode); - operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, - DImode); - operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); -}") + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "") + (match_operand:DI 1 "input_operand" ""))] + "reload_completed && !TARGET_POWERPC64 + && gpr_or_gpr_p (operands[0], operands[1])" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) -(define_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_mfpgpr" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f") + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))] + "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && (gpc_reg_operand (operands[0], DImode) + || gpc_reg_operand (operands[1], DImode))" + "@ + mr %0,%1 + ld%U1%X1 %0,%1 + std%U0%X0 %1,%0 + li %0,%1 + lis %0,%v1 + # + {cal|la} %0,%a1 + fmr %0,%1 + lfd%U1%X1 %0,%1 + stfd%U0%X0 %1,%0 + mf%1 %0 + mt%0 %1 + {cror 0,0,0|nop} + mftgpr %0,%1 + mffgpr %0,%1" + [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr") + (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")]) (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") + [(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 + "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" "@ @@ -8484,8 +9092,8 @@ stfd%U0%X0 %1,%0 mf%1 %0 mt%0 %1 - cror 0,0,0" - [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*") + {cror 0,0,0|nop}" + [(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 @@ -8548,181 +9156,125 @@ else FAIL; }") - -;; Split a load of a large constant into the appropriate five-instruction -(define_insn "*movdi_internal2" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))] - "TARGET_POWERPC64" - "@ - mr. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") (match_dup 1))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 1)) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") ;; TImode is similar, except that we usually want to compute the address into ;; a register and use lsi/stsi (the exception is during reload). MQ is also ;; clobbered in stsi for POWER, so we need a SCRATCH for it. -(define_expand "movti" - [(parallel [(set (match_operand:TI 0 "general_operand" "") - (match_operand:TI 1 "general_operand" "")) - (clobber (scratch:SI))])] - "TARGET_STRING || TARGET_POWERPC64" - "{ rs6000_emit_move (operands[0], operands[1], TImode); DONE; }") ;; We say that MQ is clobbered in the last alternative because the first ;; alternative would never get used otherwise since it would need a reload ;; while the 2nd alternative would not. We put memory cases first so they ;; are preferred. Otherwise, we'd try to reload the output instead of ;; giving the SCRATCH mq. + (define_insn "*movti_power" - [(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")) - (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] - "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64 + [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r,r") + (match_operand:TI 1 "input_operand" "r,r,r,Q,m,n")) + (clobber (match_scratch:SI 2 "=q,q#X,X,X,X,X"))] + "TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* { switch (which_alternative) { default: - abort (); + gcc_unreachable (); case 0: - return \"{stsi|stswi} %1,%P0,16\"; - + if (TARGET_STRING) + 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. */ - if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 - && REGNO (operands[0]) <= REGNO (operands[1]) + 3) - 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\"; + return \"#\"; 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])) + if (TARGET_STRING + && ! 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. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 1, - REGNO (operands[0]) + 2, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 2, - REGNO (operands[0]) + 3, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; + case 5: + return \"#\"; } }" - [(set_attr "type" "store,store,*,load,load") - (set_attr "length" "*,16,16,*,16")]) + [(set_attr "type" "store,store,*,load,load,*")]) (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"))] - "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64 + [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r") + (match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))] + "! TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* { switch (which_alternative) { default: - abort (); - + gcc_unreachable (); case 0: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; - + if (TARGET_STRING) + return \"{stsi|stswi} %1,%P0,16\"; case 1: - /* 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. */ - if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 - && REGNO (operands[0]) <= REGNO (operands[1]) + 3) - 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: - /* 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. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 1, - REGNO (operands[0]) + 2, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\"; - else if (refers_to_regno_p (REGNO (operands[0]) + 2, - REGNO (operands[0]) + 3, operands[1], 0)) - return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\"; - else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; + return \"#\"; + case 3: + /* If the address is not used in the output, we can use lsi. Otherwise, + fall through to generating four loads. */ + if (TARGET_STRING + && ! reg_overlap_mentioned_p (operands[0], operands[1])) + return \"{lsi|lswi} %0,%P1,16\"; + /* ... fall through ... */ + case 4: + case 5: + return \"#\"; } }" - [(set_attr "type" "store,*,load") - (set_attr "length" "16,16,16")]) + [(set_attr "type" "store_ux,store_ux,*,load_ux,load_ux,*") + (set (attr "cell_micro") (if_then_else (eq (symbol_ref "TARGET_STRING") (const_int 1)) + (const_string "always") + (const_string "conditional")))]) (define_insn "*movti_ppc64" - [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") - (match_operand:TI 1 "input_operand" "r,m,r"))] + [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r") + (match_operand:TI 1 "input_operand" "r,r,m"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" - "* + "#" + [(set_attr "type" "*,load,store")]) + +(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))] + " { - switch (which_alternative) + 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) { - default: - abort (); - case 0: - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mr %L0,%L1\;mr %0,%1\"; - else - return \"mr %0,%1\;mr %L0,%L1\"; - case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"ld %L0,%L1\;ld %0,%1\"; - else - return \"ld%U1 %0,%1\;ld %L0,%L1\"; - case 2: - return \"std%U0 %1,%0\;std %L1,%L0\"; + operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); } -}" - [(set_attr "type" "*,load,store") - (set_attr "length" "8,8,8")]) + else if (GET_CODE (operands[1]) == CONST_INT) + { + operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); + operands[5] = operands[1]; + } + else + FAIL; +}") + +(define_split + [(set (match_operand:TI 0 "nonimmediate_operand" "") + (match_operand:TI 1 "input_operand" ""))] + "reload_completed + && gpr_or_gpr_p (operands[0], operands[1])" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_expand "load_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") @@ -8757,7 +9309,7 @@ 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 "*ldmsi8" @@ -8781,7 +9333,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 8" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_insn "*ldmsi7" @@ -8803,7 +9355,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 7" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_insn "*ldmsi6" @@ -8823,7 +9375,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 6" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_insn "*ldmsi5" @@ -8841,7 +9393,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 5" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_insn "*ldmsi4" @@ -8857,7 +9409,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 4" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_insn "*ldmsi3" @@ -8871,7 +9423,7 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 3" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load") + [(set_attr "type" "load_ux") (set_attr "length" "32")]) (define_expand "store_multiple" @@ -8907,43 +9459,270 @@ 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 "*store_multiple_power" +(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")) + (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_ux") + (set_attr "cell_micro" "always")]) + +(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_ux") + (set_attr "cell_micro" "always")]) + +(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_ux") + (set_attr "cell_micro" "always")]) + +(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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi4" [(match_parallel 0 "store_multiple_operation" - [(set (match_operand:SI 1 "indirect_operand" "=Q") - (match_operand:SI 2 "gpc_reg_operand" "r")) - (clobber (match_scratch:SI 3 "=q"))])] - "TARGET_STRING && TARGET_POWER" - "{stsi|stswi} %2,%P1,%O0" - [(set_attr "type" "store")]) - -(define_insn "*store_multiple_string" + [(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_ux") + (set_attr "cell_micro" "always")]) + +(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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi8_power" + [(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 "=q")) + (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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi7_power" + [(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 "=q")) + (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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi6_power" + [(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 "=q")) + (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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi5_power" + [(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 "=q")) + (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_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*stmsi4_power" [(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 "=q")) + (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")]) + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always")]) +(define_insn "*stmsi3_power" + [(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 "=q")) + (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_ux") + (set_attr "cell_micro" "always")]) +(define_expand "setmemsi" + [(parallel [(set (match_operand:BLK 0 "" "") + (match_operand 2 "const_int_operand" "")) + (use (match_operand:SI 1 "" "")) + (use (match_operand:SI 3 "" ""))])] + "" + " +{ + /* If value to set is not zero, use the library routine. */ + if (operands[2] != const0_rtx) + FAIL; + + if (expand_block_clear (operands)) + DONE; + else + FAIL; +}") + ;; String/block move insn. ;; Argument 0 is the destination ;; Argument 1 is the source ;; Argument 2 is the length ;; Argument 3 is the alignment -(define_expand "movstrsi" +(define_expand "movmemsi" [(parallel [(set (match_operand:BLK 0 "" "") (match_operand:BLK 1 "" "")) (use (match_operand:SI 2 "" "")) @@ -8960,7 +9739,7 @@ ;; Move up to 32 bytes at a time. The fixed registers are needed because the ;; register allocator doesn't have a clue about allocating 8 word registers. ;; rD/rS = r5 is preferred, efficient form. -(define_expand "movstrsi_8reg" +(define_expand "movmemsi_8reg" [(parallel [(set (match_operand 0 "" "") (match_operand 1 "" "")) (use (match_operand 2 "" "")) @@ -8982,7 +9761,7 @@ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) @@ -8998,15 +9777,16 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) (define_insn "" - [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) + [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) + (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) @@ -9014,7 +9794,7 @@ (clobber (reg:SI 10)) (clobber (reg:SI 11)) (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "X"))] + (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && ! TARGET_POWER && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0) @@ -9022,37 +9802,14 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:DI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:DI 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && TARGET_POWERPC64 - && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) - || INTVAL (operands[2]) == 0) - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 5" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) ;; Move up to 24 bytes at a time. The fixed registers are needed because the ;; register allocator doesn't have a clue about allocating 6 word registers. ;; rD/rS = r5 is preferred, efficient form. -(define_expand "movstrsi_6reg" +(define_expand "movmemsi_6reg" [(parallel [(set (match_operand 0 "" "") (match_operand 1 "" "")) (use (match_operand 2 "" "")) @@ -9072,7 +9829,7 @@ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) @@ -9085,55 +9842,36 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) (define_insn "" - [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) + [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) + (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) (clobber (reg:SI 9)) (clobber (reg:SI 10)) - (clobber (match_scratch:SI 5 "X"))] + (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:DI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:DI 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && TARGET_POWERPC64 - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) - && REGNO (operands[4]) == 5" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill ;; problems with TImode. ;; rD/rS = r5 is preferred, efficient form. -(define_expand "movstrsi_4reg" +(define_expand "movmemsi_4reg" [(parallel [(set (match_operand 0 "" "") (match_operand 1 "" "")) (use (match_operand 2 "" "")) @@ -9151,7 +9889,7 @@ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) @@ -9162,49 +9900,32 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) (define_insn "" - [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) + [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) + (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) + (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) (clobber (reg:SI 6)) (clobber (reg:SI 7)) (clobber (reg:SI 8)) - (clobber (match_scratch:SI 5 "X"))] + (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) && REGNO (operands[4]) == 5" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:DI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:DI 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && TARGET_POWERPC64 - && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) - && REGNO (operands[4]) == 5" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) ;; Move up to 8 bytes at a time. -(define_expand "movstrsi_2reg" +(define_expand "movmemsi_2reg" [(parallel [(set (match_operand 0 "" "") (match_operand 1 "" "")) (use (match_operand 2 "" "")) @@ -9224,7 +9945,8 @@ "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) (define_insn "" @@ -9233,15 +9955,16 @@ (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_scratch:DI 4 "=&r")) - (clobber (match_scratch:SI 5 "X"))] + (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) ;; Move up to 4 bytes at a time. -(define_expand "movstrsi_1reg" +(define_expand "movmemsi_1reg" [(parallel [(set (match_operand 0 "" "") (match_operand 1 "" "")) (use (match_operand 2 "" "")) @@ -9261,35 +9984,23 @@ "TARGET_STRING && TARGET_POWER && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) (define_insn "" - [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) + [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) + (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) (use (match_operand:SI 2 "immediate_operand" "i")) (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "X"))] + (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") - (set_attr "length" "8")]) - -(define_insn "" - [(set (mem:BLK (match_operand:DI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:DI 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && TARGET_POWERPC64 - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" - "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" - [(set_attr "type" "load") + [(set_attr "type" "store_ux") + (set_attr "cell_micro" "always") (set_attr "length" "8")]) - ;; Define insns that do load or store with update. Some of these we can ;; get by using pre-decrement or pre-increment, but the hardware can also @@ -9306,34 +10017,43 @@ (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))) (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE" + "TARGET_POWERPC64 && TARGET_UPDATE + && (!avoiding_indexed_address_p (DImode) + || !gpc_reg_operand (operands[2], DImode))" "@ ldux %3,%0,%2 ldu %3,%2(%0)" - [(set_attr "type" "load")]) + [(set_attr "type" "load_ux,load_u")]) -(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")]) +(define_insn "movdi__update" + [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") + (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) + (match_operand:DI 3 "gpc_reg_operand" "r,r")) + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64 && TARGET_UPDATE + && (!avoiding_indexed_address_p (Pmode) + || !gpc_reg_operand (operands[2], Pmode) + || (REG_P (operands[0]) + && REGNO (operands[0]) == STACK_POINTER_REGNUM))" + "@ + stdux %3,%0,%2 + stdu %3,%2(%0)" + [(set_attr "type" "store_ux,store_u")]) -(define_insn "movdi_update" - [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") - (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))) +;; This pattern is only conditional on TARGET_POWERPC64, as it is +;; needed for stack allocation, even if the user passes -mno-update. +(define_insn "movdi__update_stack" + [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") + (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) (match_operand:DI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE" + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64" "@ 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") @@ -9341,11 +10061,25 @@ (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 + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ {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 && rs6000_gen_cell_microcode + && !avoiding_indexed_address_p (DImode)" + "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") @@ -9353,23 +10087,43 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode) + || (REG_P (operands[0]) + && REGNO (operands[0]) == STACK_POINTER_REGNUM))" + "@ + {stux|stwux} %3,%0,%2 + {stu|stwu} %3,%2(%0)" + [(set_attr "type" "store_ux,store_u")]) + +;; This is an unconditional pattern; needed for stack allocation, even +;; if the user passes -mno-update. +(define_insn "movsi_update_stack" + [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") + (match_operand:SI 2 "reg_or_short_operand" "r,I"))) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) + (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") + (plus:SI (match_dup 1) (match_dup 2)))] + "" "@ {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")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9378,11 +10132,13 @@ (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" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9391,11 +10147,13 @@ (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" + "TARGET_UPDATE && rs6000_gen_cell_microcode + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9403,11 +10161,13 @@ (match_operand:HI 3 "gpc_reg_operand" "r,r")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9415,11 +10175,13 @@ (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" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9428,11 +10190,13 @@ (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" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9440,11 +10204,13 @@ (match_operand:QI 3 "gpc_reg_operand" "r,r")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE" + "TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9452,11 +10218,13 @@ (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_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9464,11 +10232,13 @@ (match_operand:SF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9476,11 +10246,13 @@ (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_SOFT_FLOAT && TARGET_UPDATE" + "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ {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") @@ -9488,11 +10260,13 @@ (match_operand:SF 3 "gpc_reg_operand" "r,r")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_SOFT_FLOAT && TARGET_UPDATE" + "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ {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") @@ -9500,11 +10274,13 @@ (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_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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") @@ -9512,37 +10288,235 @@ (match_operand:DF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE + && (!avoiding_indexed_address_p (SImode) + || !gpc_reg_operand (operands[2], SImode))" "@ 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_peephole - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") +(define_insn "*lfq_power2" + [(set (match_operand:V2DF 0 "gpc_reg_operand" "=f") + (match_operand:V2DF 1 "memory_operand" ""))] + "TARGET_POWER2 + && TARGET_HARD_FLOAT && TARGET_FPRS" + "lfq%U1%X1 %0,%1") + +(define_peephole2 + [(set (match_operand:DF 0 "gpc_reg_operand" "") (match_operand:DF 1 "memory_operand" "")) - (set (match_operand:DF 2 "gpc_reg_operand" "=f") + (set (match_operand:DF 2 "gpc_reg_operand" "") (match_operand:DF 3 "memory_operand" ""))] "TARGET_POWER2 - && TARGET_HARD_FLOAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && registers_ok_for_quad_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "lfq%U1%X1 %0,%1") + && mems_ok_for_quad_peep (operands[1], operands[3])" + [(set (match_dup 0) + (match_dup 1))] + "operands[1] = widen_memory_access (operands[1], V2DFmode, 0); + operands[0] = gen_rtx_REG (V2DFmode, REGNO (operands[0]));") -(define_peephole +(define_insn "*stfq_power2" + [(set (match_operand:V2DF 0 "memory_operand" "") + (match_operand:V2DF 1 "gpc_reg_operand" "f"))] + "TARGET_POWER2 + && TARGET_HARD_FLOAT && TARGET_FPRS" + "stfq%U0%X0 %1,%0") + + +(define_peephole2 [(set (match_operand:DF 0 "memory_operand" "") - (match_operand:DF 1 "gpc_reg_operand" "f")) + (match_operand:DF 1 "gpc_reg_operand" "")) (set (match_operand:DF 2 "memory_operand" "") - (match_operand:DF 3 "gpc_reg_operand" "f"))] + (match_operand:DF 3 "gpc_reg_operand" ""))] "TARGET_POWER2 - && TARGET_HARD_FLOAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && registers_ok_for_quad_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "stfq%U0%X0 %1,%0") + && mems_ok_for_quad_peep (operands[0], operands[2])" + [(set (match_dup 0) + (match_dup 1))] + "operands[0] = widen_memory_access (operands[0], V2DFmode, 0); + operands[1] = gen_rtx_REG (V2DFmode, REGNO (operands[1]));") + +;; After inserting conditional returns we can sometimes have +;; unnecessary register moves. Unfortunately we cannot have a +;; modeless peephole here, because some single SImode sets have early +;; clobber outputs. Although those sets expand to multi-ppc-insn +;; sequences, using get_attr_length here will smash the operands +;; array. Neither is there an early_cobbler_p predicate. +;; Disallow subregs for E500 so we don't munge frob_di_df_2. +(define_peephole2 + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (match_operand:DF 1 "any_operand" "")) + (set (match_operand:DF 2 "gpc_reg_operand" "") + (match_dup 0))] + "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG) + && peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 2) (match_dup 1))]) + +(define_peephole2 + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (match_operand:SF 1 "any_operand" "")) + (set (match_operand:SF 2 "gpc_reg_operand" "") + (match_dup 0))] + "peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 2) (match_dup 1))]) + + +;; TLS support. + +;; Mode attributes for different ABIs. +(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) +(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) +(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) +(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) + +(define_insn "tls_gd_aix" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) + (match_operand 4 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" + "addi %0,%1,%2@got@tlsgd\;bl %z3\;%." + [(set_attr "type" "two") + (set_attr "length" "12")]) + +(define_insn "tls_gd_sysv" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) + (match_operand 4 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" +{ + if (flag_pic) + { + if (TARGET_SECURE_PLT && flag_pic == 2) + return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt"; + else + return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt"; + } + else + return "addi %0,%1,%2@got@tlsgd\;bl %z3"; +} + [(set_attr "type" "two") + (set_attr "length" "8")]) + +(define_insn "tls_ld_aix" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) + (match_operand 3 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] + UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" + "addi %0,%1,%&@got@tlsld\;bl %z2\;%." + [(set_attr "length" "12")]) + +(define_insn "tls_ld_sysv" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) + (match_operand 3 "" "g"))) + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] + UNSPEC_TLSLD) + (clobber (reg:SI LR_REGNO))] + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" +{ + if (flag_pic) + { + if (TARGET_SECURE_PLT && flag_pic == 2) + return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt"; + else + return "addi %0,%1,%&@got@tlsld\;bl %z2@plt"; + } + else + return "addi %0,%1,%&@got@tlsld\;bl %z2"; +} + [(set_attr "length" "8")]) + +(define_insn "tls_dtprel_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPREL))] + "HAVE_AS_TLS" + "addi %0,%1,%2@dtprel") + +(define_insn "tls_dtprel_ha_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELHA))] + "HAVE_AS_TLS" + "addis %0,%1,%2@dtprel@ha") + +(define_insn "tls_dtprel_lo_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELLO))] + "HAVE_AS_TLS" + "addi %0,%1,%2@dtprel@l") + +(define_insn "tls_got_dtprel_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL))] + "HAVE_AS_TLS" + "l %0,%2@got@dtprel(%1)") + +(define_insn "tls_tprel_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPREL))] + "HAVE_AS_TLS" + "addi %0,%1,%2@tprel") + +(define_insn "tls_tprel_ha_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELHA))] + "HAVE_AS_TLS" + "addis %0,%1,%2@tprel@ha") + +(define_insn "tls_tprel_lo_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELLO))] + "HAVE_AS_TLS" + "addi %0,%1,%2@tprel@l") + +;; "b" output constraint here and on tls_tls input to support linker tls +;; optimization. The linker may edit the instructions emitted by a +;; tls_got_tprel/tls_tls pair to addis,addi. +(define_insn "tls_got_tprel_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL))] + "HAVE_AS_TLS" + "l %0,%2@got@tprel(%1)") + +(define_insn "tls_tls_" + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTLS))] + "HAVE_AS_TLS" + "add %0,%1,%2@tls") + ;; Next come insns related to the calling sequence. ;; @@ -9550,7 +10524,7 @@ ;; We move the back-chain and decrement the stack pointer. (define_expand "allocate_stack" - [(set (match_operand 0 "gpc_reg_operand" "=r") + [(set (match_operand 0 "gpc_reg_operand" "") (minus (reg 1) (match_operand 1 "reg_or_short_operand" ""))) (set (reg 1) (minus (reg 1) (match_dup 1)))] @@ -9559,14 +10533,15 @@ { rtx chain = gen_reg_rtx (Pmode); rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); rtx neg_op0; + rtx insn, par, set, mem; emit_move_insn (chain, stack_bot); /* Check stack bounds if necessary. */ - if (current_function_limit_stack) + if (crtl->limit_stack) { rtx available; - available = expand_binop (Pmode, sub_optab, + available = expand_binop (Pmode, sub_optab, stack_pointer_rtx, stack_limit_rtx, NULL_RTX, 1, OPTAB_WIDEN); emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); @@ -9585,16 +10560,22 @@ else neg_op0 = GEN_INT (- INTVAL (operands[1])); - if (TARGET_UPDATE) - emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update)) - (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); - - else - { - emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3)) - (stack_pointer_rtx, stack_pointer_rtx, neg_op0)); - emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx), chain); - } + insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack + : gen_movdi_di_update_stack)) + (stack_pointer_rtx, stack_pointer_rtx, neg_op0, + chain)); + /* Since we didn't use gen_frame_mem to generate the MEM, grab + it now and set the alias set/attributes. The above gen_*_update + calls will generate a PARALLEL with the MEM set being the first + operation. */ + par = PATTERN (insn); + gcc_assert (GET_CODE (par) == PARALLEL); + set = XVECEXP (par, 0, 0); + gcc_assert (GET_CODE (set) == SET); + mem = SET_DEST (set); + gcc_assert (MEM_P (mem)); + MEM_NOTRAP_P (mem) = 1; + set_mem_alias_set (mem, get_frame_alias_set ()); emit_move_insn (operands[0], virtual_stack_dynamic_rtx); DONE; @@ -9621,52 +10602,59 @@ "" "DONE;") +;; Adjust stack pointer (op0) to a new value (op1). +;; First copy old stack backchain to new location, and ensure that the +;; scheduler won't reorder the sp assignment before the backchain write. (define_expand "restore_stack_block" - [(use (match_operand 0 "register_operand" "")) - (set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (match_operand 1 "register_operand" "")) - (set (match_dup 3) (match_dup 2))] + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 2)) + (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE)) + (set (match_operand 0 "register_operand" "") + (match_operand 1 "register_operand" ""))] "" " { + operands[1] = force_reg (Pmode, operands[1]); operands[2] = gen_reg_rtx (Pmode); - operands[3] = gen_rtx_MEM (Pmode, operands[0]); + operands[3] = gen_frame_mem (Pmode, operands[0]); + operands[4] = gen_frame_mem (Pmode, operands[1]); + operands[5] = gen_frame_mem (BLKmode, operands[0]); }") (define_expand "save_stack_nonlocal" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "register_operand" "")] + [(set (match_dup 3) (match_dup 4)) + (set (match_operand 0 "memory_operand" "") (match_dup 3)) + (set (match_dup 2) (match_operand 1 "register_operand" ""))] "" " { - rtx temp = gen_reg_rtx (Pmode); + int units_per_word = (TARGET_32BIT) ? 4 : 8; /* Copy the backchain to the first word, sp to the second. */ - emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1])); - emit_move_insn (operand_subword (operands[0], 0, 0, - (TARGET_32BIT ? DImode : TImode)), - temp); - emit_move_insn (operand_subword (operands[0], 1, 0, (TARGET_32BIT ? DImode : TImode)), - operands[1]); - DONE; + operands[0] = adjust_address_nv (operands[0], Pmode, 0); + operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); + operands[3] = gen_reg_rtx (Pmode); + operands[4] = gen_frame_mem (Pmode, operands[1]); }") (define_expand "restore_stack_nonlocal" - [(match_operand 0 "register_operand" "") - (match_operand 1 "memory_operand" "")] + [(set (match_dup 2) (match_operand 1 "memory_operand" "")) + (set (match_dup 3) (match_dup 4)) + (set (match_dup 5) (match_dup 2)) + (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE)) + (set (match_operand 0 "register_operand" "") (match_dup 3))] "" " { - rtx temp = gen_reg_rtx (Pmode); + int units_per_word = (TARGET_32BIT) ? 4 : 8; /* Restore the backchain from the first word, sp from the second. */ - emit_move_insn (temp, - operand_subword (operands[1], 0, 0, (TARGET_32BIT ? DImode : TImode))); - emit_move_insn (operands[0], - operand_subword (operands[1], 1, 0, - (TARGET_32BIT ? DImode : TImode))); - emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp); - DONE; + operands[2] = gen_reg_rtx (Pmode); + operands[3] = gen_reg_rtx (Pmode); + operands[1] = adjust_address_nv (operands[1], Pmode, 0); + operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); + operands[5] = gen_frame_mem (Pmode, operands[3]); + operands[6] = gen_frame_mem (BLKmode, operands[0]); }") ;; TOC register handling. @@ -9675,7 +10663,7 @@ (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" "* @@ -9690,7 +10678,7 @@ (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" "* @@ -9711,68 +10699,111 @@ [(set_attr "type" "load")]) (define_insn "load_toc_v4_pic_si" - [(set (match_operand:SI 0 "register_operand" "=l") - (unspec:SI [(const_int 0)] 7))] + [(set (reg:SI LR_REGNO) + (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") (set_attr "length" "4")]) (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)] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bl %1\\n%1:" + [(set (reg:SI LR_REGNO) + (match_operand:SI 0 "immediate_operand" "s")) + (use (unspec [(match_dup 0)] UNSPEC_TOC))] + "TARGET_ELF && DEFAULT_ABI != ABI_AIX + && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" + "bcl 20,31,%0\\n%0:" [(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)] + [(set (reg:SI LR_REGNO) + (unspec:SI [(match_operand:SI 0 "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,$+8\\n\\t.long %0-$" [(set_attr "type" "branch") (set_attr "length" "8")]) (define_insn "load_toc_v4_PIC_2" - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "b") + [(set (match_operand:SI 0 "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" "{l|lwz} %0,%2-%3(%1)" [(set_attr "type" "load")]) -(define_insn "load_macho_picbase" - [(set (match_operand:SI 0 "register_operand" "=l") - (unspec:SI [(const_int 0)] 15))] - "(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:\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4")]) +(define_insn "load_toc_v4_PIC_3b" + [(set (match_operand:SI 0 "gpc_reg_operand" "=b") + (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (high:SI + (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") + (match_operand:SI 3 "symbol_ref_operand" "s")))))] + "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" + "{cau|addis} %0,%1,%2-%3@ha") + +(define_insn "load_toc_v4_PIC_3c" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") + (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") + (match_operand:SI 3 "symbol_ref_operand" "s"))))] + "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" + "{cal %0,%2-%3@l(%1)|addi %0,%1,%2-%3@l}") ;; 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) + { + rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); + rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); + rtx tmplabrtx; + char tmplab[20]; + + crtl->uses_pic_offset_table = 1; + ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", + CODE_LABEL_NUMBER (operands[0])); + tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); + + emit_insn (gen_load_macho_picbase (tmplabrtx)); + emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); + emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); + } + else +#endif + rs6000_emit_load_toc_table (FALSE); DONE; }") + +;; Elf specific ways of loading addresses for non-PIC code. +;; The output of this could be r0, but we make a very strong +;; preference for a base register because it will usually +;; be needed there. +(define_insn "elf_high" + [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") + (high:SI (match_operand 1 "" "")))] + "TARGET_ELF && ! TARGET_64BIT" + "{liu|lis} %0,%1@ha") + +(define_insn "elf_low" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") + (match_operand 2 "" "")))] + "TARGET_ELF && ! TARGET_64BIT" + "@ + {cal|la} %0,%2@l(%1) + {ai|addic} %0,%1,%K2") ;; A function pointer under AIX is a pointer to a data area whose first word ;; contains the actual address of the function, whose second word contains a @@ -9785,19 +10816,15 @@ (mem:SI (match_operand:SI 0 "gpc_reg_operand" ""))) (set (mem:SI (plus:SI (reg:SI 1) (const_int 20))) (reg:SI 2)) - (set (reg:SI 2) - (mem:SI (plus:SI (match_dup 0) - (const_int 4)))) (set (reg:SI 11) (mem:SI (plus:SI (match_dup 0) (const_int 8)))) (parallel [(call (mem:SI (match_dup 2)) (match_operand 1 "" "")) - (use (reg:SI 2)) + (use (mem:SI (plus:SI (match_dup 0) (const_int 4)))) (use (reg:SI 11)) - (set (reg:SI 2) - (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) - (clobber (scratch:SI))])] + (use (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))])] "TARGET_32BIT" " { operands[2] = gen_reg_rtx (SImode); }") @@ -9807,19 +10834,15 @@ (mem:DI (match_operand:DI 0 "gpc_reg_operand" ""))) (set (mem:DI (plus:DI (reg:DI 1) (const_int 40))) (reg:DI 2)) - (set (reg:DI 2) - (mem:DI (plus:DI (match_dup 0) - (const_int 8)))) (set (reg:DI 11) (mem:DI (plus:DI (match_dup 0) (const_int 16)))) (parallel [(call (mem:SI (match_dup 2)) (match_operand 1 "" "")) - (use (reg:DI 2)) + (use (mem:DI (plus:DI (match_dup 0) (const_int 8)))) (use (reg:DI 11)) - (set (reg:DI 2) - (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) - (clobber (scratch:SI))])] + (use (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))])] "TARGET_64BIT" " { operands[2] = gen_reg_rtx (DImode); }") @@ -9829,20 +10852,16 @@ (mem:SI (match_operand:SI 1 "gpc_reg_operand" ""))) (set (mem:SI (plus:SI (reg:SI 1) (const_int 20))) (reg:SI 2)) - (set (reg:SI 2) - (mem:SI (plus:SI (match_dup 1) - (const_int 4)))) (set (reg:SI 11) (mem:SI (plus:SI (match_dup 1) (const_int 8)))) (parallel [(set (match_operand 0 "" "") (call (mem:SI (match_dup 3)) (match_operand 2 "" ""))) - (use (reg:SI 2)) + (use (mem:SI (plus:SI (match_dup 1) (const_int 4)))) (use (reg:SI 11)) - (set (reg:SI 2) - (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) - (clobber (scratch:SI))])] + (use (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))])] "TARGET_32BIT" " { operands[3] = gen_reg_rtx (SImode); }") @@ -9852,20 +10871,16 @@ (mem:DI (match_operand:DI 1 "gpc_reg_operand" ""))) (set (mem:DI (plus:DI (reg:DI 1) (const_int 40))) (reg:DI 2)) - (set (reg:DI 2) - (mem:DI (plus:DI (match_dup 1) - (const_int 8)))) (set (reg:DI 11) (mem:DI (plus:DI (match_dup 1) (const_int 16)))) (parallel [(set (match_operand 0 "" "") (call (mem:SI (match_dup 3)) (match_operand 2 "" ""))) - (use (reg:DI 2)) + (use (mem:DI (plus:DI (match_dup 1) (const_int 8)))) (use (reg:DI 11)) - (set (reg:DI 2) - (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) - (clobber (scratch:SI))])] + (use (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))])] "TARGET_64BIT" " { operands[3] = gen_reg_rtx (DImode); }") @@ -9875,33 +10890,35 @@ [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) - (clobber (scratch:SI))])] + (clobber (reg:SI LR_REGNO))])] "" " { #if TARGET_MACHO - if (flag_pic) + if (MACHOPIC_INDIRECT) operands[0] = machopic_indirect_call_target (operands[0]); #endif - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); + gcc_assert (GET_CODE (operands[1]) == CONST_INT); operands[0] = XEXP (operands[0], 0); if (GET_CODE (operands[0]) != SYMBOL_REF - || (INTVAL (operands[2]) & CALL_LONG) != 0) + || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0])) + || (DEFAULT_ABI != ABI_DARWIN && (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]); + switch (DEFAULT_ABI) + { + case ABI_V4: + case ABI_DARWIN: + operands[0] = force_reg (Pmode, operands[0]); + break; - else if (DEFAULT_ABI == ABI_AIX) - { + case ABI_AIX: /* AIX function pointers are really pointers to a three word area. */ emit_call_insn (TARGET_32BIT @@ -9912,73 +10929,599 @@ operands[0]), operands[1])); DONE; + + default: + gcc_unreachable (); } - else - abort (); } }") -(define_expand "call_value" - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "address_operand" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (scratch:SI))])] +(define_expand "call_value" + [(parallel [(set (match_operand 0 "" "") + (call (mem:SI (match_operand 1 "address_operand" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNO))])] + "" + " +{ +#if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[1] = machopic_indirect_call_target (operands[1]); +#endif + + gcc_assert (GET_CODE (operands[1]) == MEM); + gcc_assert (GET_CODE (operands[2]) == CONST_INT); + + operands[1] = XEXP (operands[1], 0); + + if (GET_CODE (operands[1]) != SYMBOL_REF + || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1])) + || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) + { + if (INTVAL (operands[3]) & CALL_LONG) + operands[1] = rs6000_longcall_ref (operands[1]); + + switch (DEFAULT_ABI) + { + case ABI_V4: + case ABI_DARWIN: + operands[1] = force_reg (Pmode, operands[1]); + break; + + case ABI_AIX: + /* AIX function pointers are really pointers to a three word + area. */ + emit_call_insn (TARGET_32BIT + ? gen_call_value_indirect_aix32 (operands[0], + force_reg (SImode, + operands[1]), + operands[2]) + : gen_call_value_indirect_aix64 (operands[0], + force_reg (DImode, + operands[1]), + operands[2])); + DONE; + + default: + gcc_unreachable (); + } + } +}") + +;; Call to function in current module. No TOC pointer reload needed. +;; 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. + +(define_insn "*call_local32" + [(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")) + (clobber (reg:SI LR_REGNO))] + "(INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_local64" + [(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")) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_local32" + [(set (match_operand 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")) + (clobber (reg:SI LR_REGNO))] + "(INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + + +(define_insn "*call_value_local64" + [(set (match_operand 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")) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +;; Call to function which may be in another module. Restore the TOC +;; pointer (r2) after the call unless this is System V. +;; 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. + +(define_insn_and_split "*call_indirect_nonlocal_aix32_internal" + [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (use (mem:SI (plus:SI (match_operand:SI 2 "register_operand" "b,b") (const_int 4)))) + (use (reg:SI 11)) + (use (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT && DEFAULT_ABI == ABI_AIX" + "#" + "&& reload_completed" + [(set (reg:SI 2) + (mem:SI (plus:SI (match_dup 2) (const_int 4)))) + (parallel [(call (mem:SI (match_dup 0)) + (match_dup 1)) + (use (reg:SI 2)) + (use (reg:SI 11)) + (set (reg:SI 2) + (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))])] + "" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +(define_insn "*call_indirect_nonlocal_aix32" + [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (use (reg:SI 2)) + (use (reg:SI 11)) + (set (reg:SI 2) + (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed" + "b%T0l\;{l|lwz} 2,20(1)" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + +(define_insn "*call_nonlocal_aix32" + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) + (match_operand 1 "" "g")) + (use (match_operand:SI 2 "immediate_operand" "O")) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "bl %z0\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn_and_split "*call_indirect_nonlocal_aix64_internal" + [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (use (mem:DI (plus:DI (match_operand:DI 2 "register_operand" "b,b") + (const_int 8)))) + (use (reg:DI 11)) + (use (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX" + "#" + "&& reload_completed" + [(set (reg:DI 2) + (mem:DI (plus:DI (match_dup 2) (const_int 8)))) + (parallel [(call (mem:SI (match_dup 0)) + (match_dup 1)) + (use (reg:DI 2)) + (use (reg:DI 11)) + (set (reg:DI 2) + (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))])] + "" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +(define_insn "*call_indirect_nonlocal_aix64" + [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (use (reg:DI 2)) + (use (reg:DI 11)) + (set (reg:DI 2) + (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed" + "b%T0l\;ld 2,40(1)" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + +(define_insn "*call_nonlocal_aix64" + [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) + (match_operand 1 "" "g")) + (use (match_operand:SI 2 "immediate_operand" "O")) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "bl %z0\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn_and_split "*call_value_indirect_nonlocal_aix32_internal" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (use (mem:SI (plus:SI (match_operand:SI 3 "register_operand" "b,b") + (const_int 4)))) + (use (reg:SI 11)) + (use (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT && DEFAULT_ABI == ABI_AIX" + "#" + "&& reload_completed" + [(set (reg:SI 2) + (mem:SI (plus:SI (match_dup 3) (const_int 4)))) + (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1)) + (match_dup 2))) + (use (reg:SI 2)) + (use (reg:SI 11)) + (set (reg:SI 2) + (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))])] + "" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +(define_insn "*call_value_indirect_nonlocal_aix32" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (use (reg:SI 2)) + (use (reg:SI 11)) + (set (reg:SI 2) + (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed" + "b%T1l\;{l|lwz} 2,20(1)" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + +(define_insn "*call_value_nonlocal_aix32" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (clobber (reg:SI LR_REGNO))] + "TARGET_32BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "bl %z1\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn_and_split "*call_value_indirect_nonlocal_aix64_internal" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (use (mem:DI (plus:DI (match_operand:DI 3 "register_operand" "b,b") + (const_int 8)))) + (use (reg:DI 11)) + (use (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX" + "#" + "&& reload_completed" + [(set (reg:DI 2) + (mem:DI (plus:DI (match_dup 3) (const_int 8)))) + (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1)) + (match_dup 2))) + (use (reg:DI 2)) + (use (reg:DI 11)) + (set (reg:DI 2) + (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))])] + "" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +(define_insn "*call_value_indirect_nonlocal_aix64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (use (reg:DI 2)) + (use (reg:DI 11)) + (set (reg:DI 2) + (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed" + "b%T1l\;ld 2,40(1)" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + +(define_insn "*call_value_nonlocal_aix64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (clobber (reg:SI LR_REGNO))] + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "bl %z1\;%." + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +;; A function pointer under System V is just a normal pointer +;; operands[0] is the function pointer +;; operands[1] is the stack size to clean up +;; operands[2] is the value FUNCTION_ARG returns for the VOID argument +;; which indicates how to set cr1 + +(define_insn "*call_indirect_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) + (match_operand 1 "" "g,g,g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) + (clobber (reg:SI LR_REGNO))] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return "b%T0l"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + +(define_insn_and_split "*call_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_DARWIN + || (DEFAULT_ABI == ABI_V4 + && (INTVAL (operands[2]) & CALL_LONG) == 0))" +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + +#if TARGET_MACHO + return output_call(insn, operands, 0, 2); +#else + if (DEFAULT_ABI == ABI_V4 && flag_pic) + { + gcc_assert (!TARGET_SECURE_PLT); + return "bl %z0@plt"; + } + else + return "bl %z0"; +#endif +} + "DEFAULT_ABI == ABI_V4 + && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) + && (INTVAL (operands[2]) & CALL_LONG) == 0" + [(parallel [(call (mem:SI (match_dup 0)) + (match_dup 1)) + (use (match_dup 2)) + (use (match_dup 3)) + (clobber (reg:SI LR_REGNO))])] +{ + operands[3] = pic_offset_table_rtx; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_nonlocal_sysv_secure" + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (use (match_operand:SI 3 "register_operand" "r,r")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_V4 + && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) + && (INTVAL (operands[2]) & CALL_LONG) == 0)" +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + if (flag_pic == 2) + /* The magic 32768 offset here and in the other sysv call insns + corresponds to the offset of r30 in .got2, as given by LCTOC1. + See sysv4.h:toc_section. */ + return "bl %z0+32768@plt"; + else + return "bl %z0@plt"; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_indirect_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) + (match_operand 2 "" "g,g,g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) + (clobber (reg:SI LR_REGNO))] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return "b%T1l"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + +(define_insn_and_split "*call_value_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_DARWIN + || (DEFAULT_ABI == ABI_V4 + && (INTVAL (operands[3]) & CALL_LONG) == 0))" +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + +#if TARGET_MACHO + return output_call(insn, operands, 1, 3); +#else + if (DEFAULT_ABI == ABI_V4 && flag_pic) + { + gcc_assert (!TARGET_SECURE_PLT); + return "bl %z1@plt"; + } + else + return "bl %z1"; +#endif +} + "DEFAULT_ABI == ABI_V4 + && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) + && (INTVAL (operands[3]) & CALL_LONG) == 0" + [(parallel [(set (match_dup 0) + (call (mem:SI (match_dup 1)) + (match_dup 2))) + (use (match_dup 3)) + (use (match_dup 4)) + (clobber (reg:SI LR_REGNO))])] +{ + operands[4] = pic_offset_table_rtx; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_nonlocal_sysv_secure" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (match_operand:SI 4 "register_operand" "r,r")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_V4 + && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) + && (INTVAL (operands[3]) & CALL_LONG) == 0)" +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + if (flag_pic == 2) + return "bl %z1+32768@plt"; + else + return "bl %z1@plt"; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +;; Call subroutine returning any type. +(define_expand "untyped_call" + [(parallel [(call (match_operand 0 "" "") + (const_int 0)) + (match_operand 1 "" "") + (match_operand 2 "" "")])] + "" + " +{ + int i; + + emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx)); + + for (i = 0; i < XVECLEN (operands[2], 0); i++) + { + rtx set = XVECEXP (operands[2], 0, i); + emit_move_insn (SET_DEST (set), SET_SRC (set)); + } + + /* The optimizer does not know that the call sets the function value + registers we stored in the result block. We avoid problems by + claiming that all hard registers are used and clobbered at this + point. */ + emit_insn (gen_blockage ()); + + DONE; +}") + +;; sibling call patterns +(define_expand "sibcall" + [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (use (reg:SI LR_REGNO)) + (return)])] "" " { #if TARGET_MACHO - if (flag_pic) - operands[1] = machopic_indirect_call_target (operands[1]); + if (MACHOPIC_INDIRECT) + operands[0] = machopic_indirect_call_target (operands[0]); #endif - if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT) - abort (); - - operands[1] = XEXP (operands[1], 0); - - if (GET_CODE (operands[1]) != SYMBOL_REF - || (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]); + gcc_assert (GET_CODE (operands[0]) == MEM); + gcc_assert (GET_CODE (operands[1]) == CONST_INT); - else if (DEFAULT_ABI == ABI_AIX) - { - /* AIX function pointers are really pointers to a three word - area. */ - emit_call_insn (TARGET_32BIT - ? gen_call_value_indirect_aix32 (operands[0], - force_reg (SImode, - operands[1]), - operands[2]) - : gen_call_value_indirect_aix64 (operands[0], - force_reg (DImode, - operands[1]), - operands[2])); - DONE; - } - else - abort (); - } + operands[0] = XEXP (operands[0], 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 -;; 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. - -(define_insn "*call_local32" +;; this and similar patterns must be marked as using LR, otherwise +;; dataflow will try to delete the store into it. This is true +;; even when the actual reg to jump to is in CTR, when LR was +;; saved and restored around the PIC-setting BCL. +(define_insn "*sibcall_local32" [(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")) - (clobber (match_scratch:SI 3 "=l,l"))] + (use (reg:SI LR_REGNO)) + (return)] "(INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -9988,16 +11531,17 @@ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; }" [(set_attr "type" "branch") (set_attr "length" "4,8")]) -(define_insn "*call_local64" +(define_insn "*sibcall_local64" [(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")) - (clobber (match_scratch:SI 3 "=l,l"))] + (use (reg:SI LR_REGNO)) + (return)] "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -10007,17 +11551,18 @@ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; }" [(set_attr "type" "branch") (set_attr "length" "4,8")]) -(define_insn "*call_value_local32" +(define_insn "*sibcall_value_local32" [(set (match_operand 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")) - (clobber (match_scratch:SI 4 "=l,l"))] + (use (reg:SI LR_REGNO)) + (return)] "(INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -10027,18 +11572,19 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; }" [(set_attr "type" "branch") (set_attr "length" "4,8")]) -(define_insn "*call_value_local64" +(define_insn "*sibcall_value_local64" [(set (match_operand 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")) - (clobber (match_scratch:SI 4 "=l,l"))] + (use (reg:SI LR_REGNO)) + (return)] "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -10048,136 +11594,74 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; }" [(set_attr "type" "branch") (set_attr "length" "4,8")]) -;; 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 -;; 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. - -(define_insn "*call_indirect_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "register_operand" "cl")) - (match_operand 1 "" "g")) - (use (reg:SI 2)) - (use (reg:SI 11)) - (set (reg:SI 2) - (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) - (clobber (match_scratch:SI 2 "=l"))] - "TARGET_32BIT && DEFAULT_ABI == ABI_AIX" - "b%T0l\;{l|lwz} 2,20(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) - -(define_insn "*call_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "call_operand" "s")) +(define_insn "*sibcall_nonlocal_aix32" + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) (match_operand 1 "" "g")) (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (match_scratch:SI 3 "=l"))] + (use (reg:SI LR_REGNO)) + (return)] "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;%." + "b %z0" [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_indirect_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "register_operand" "cl")) - (match_operand 1 "" "g")) - (use (reg:DI 2)) - (use (reg:DI 11)) - (set (reg:DI 2) - (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) - (clobber (match_scratch:SI 2 "=l"))] - "TARGET_64BIT && DEFAULT_ABI == ABI_AIX" - "b%T0l\;ld 2,40(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) + (set_attr "length" "4")]) -(define_insn "*call_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "call_operand" "s")) +(define_insn "*sibcall_nonlocal_aix64" + [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) (match_operand 1 "" "g")) (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (match_scratch:SI 3 "=l"))] - "TARGET_64BIT + (use (reg:SI LR_REGNO)) + (return)] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;%." + "b %z0" [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_value_indirect_nonlocal_aix32" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "register_operand" "cl")) - (match_operand 2 "" "g"))) - (use (reg:SI 2)) - (use (reg:SI 11)) - (set (reg:SI 2) - (mem:SI (plus:SI (reg:SI 1) (const_int 20)))) - (clobber (match_scratch:SI 3 "=l"))] - "TARGET_32BIT && DEFAULT_ABI == ABI_AIX" - "b%T1l\;{l|lwz} 2,20(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) + (set_attr "length" "4")]) -(define_insn "*call_value_nonlocal_aix32" +(define_insn "*sibcall_value_nonlocal_aix32" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_operand" "s")) + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) (match_operand 2 "" "g"))) (use (match_operand:SI 3 "immediate_operand" "O")) - (clobber (match_scratch:SI 4 "=l"))] + (use (reg:SI LR_REGNO)) + (return)] "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;%." + "b %z1" [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_value_indirect_nonlocal_aix64" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "cl")) - (match_operand 2 "" "g"))) - (use (reg:DI 2)) - (use (reg:DI 11)) - (set (reg:DI 2) - (mem:DI (plus:DI (reg:DI 1) (const_int 40)))) - (clobber (match_scratch:SI 3 "=l"))] - "TARGET_64BIT && DEFAULT_ABI == ABI_AIX" - "b%T1l\;ld 2,40(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) + (set_attr "length" "4")]) -(define_insn "*call_value_nonlocal_aix64" +(define_insn "*sibcall_value_nonlocal_aix64" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "call_operand" "s")) + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) (match_operand 2 "" "g"))) (use (match_operand:SI 3 "immediate_operand" "O")) - (clobber (match_scratch:SI 4 "=l"))] - "TARGET_64BIT + (use (reg:SI LR_REGNO)) + (return)] + "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;%." + "b %z1" [(set_attr "type" "branch") - (set_attr "length" "8")]) - -;; A function pointer under System V is just a normal pointer -;; operands[0] is the function pointer -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument -;; which indicates how to set cr1 + (set_attr "length" "4")]) -(define_insn "*call_nonlocal_sysv" - [(call (mem:SI (match_operand:SI 0 "call_operand" "cl,cl,s,s")) - (match_operand 1 "" "g,g,g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n,O,n")) - (clobber (match_scratch:SI 3 "=l,l,l,l"))] - "DEFAULT_ABI == ABI_AIX_NODESC - || DEFAULT_ABI == ABI_V4 - || DEFAULT_ABI == ABI_DARWIN" +(define_insn "*sibcall_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "")) + (use (match_operand 2 "immediate_operand" "O,n")) + (use (reg:SI LR_REGNO)) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4) + && (INTVAL (operands[2]) & CALL_LONG) == 0" "* { if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) @@ -10186,86 +11670,81 @@ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - switch (which_alternative) + if (DEFAULT_ABI == ABI_V4 && flag_pic) { - default: - abort (); - case 0: - case 1: - return \"b%T0l\"; - case 2: - case 3: - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\"; + gcc_assert (!TARGET_SECURE_PLT); + return \"b %z0@plt\"; } + else + return \"b %z0\"; }" - [(set_attr "type" "jmpreg,jmpreg,branch,branch") - (set_attr "length" "4,8,4,8")]) + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_expand "sibcall_value" + [(parallel [(set (match_operand 0 "register_operand" "") + (call (mem:SI (match_operand 1 "address_operand" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (use (reg:SI LR_REGNO)) + (return)])] + "" + " +{ +#if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[1] = machopic_indirect_call_target (operands[1]); +#endif + + gcc_assert (GET_CODE (operands[1]) == MEM); + gcc_assert (GET_CODE (operands[2]) == CONST_INT); + + operands[1] = XEXP (operands[1], 0); +}") -(define_insn "*call_value_nonlocal_sysv" +(define_insn "*sibcall_value_nonlocal_sysv" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s")) - (match_operand 2 "" "g,g,g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) - (clobber (match_scratch:SI 4 "=l,l,l,l"))] - "DEFAULT_ABI == ABI_AIX_NODESC - || DEFAULT_ABI == ABI_V4 - || DEFAULT_ABI == ABI_DARWIN" + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" ""))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (reg:SI LR_REGNO)) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4) + && (INTVAL (operands[3]) & CALL_LONG) == 0" "* { - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) output_asm_insn (\"crxor 6,6,6\", operands); - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - switch (which_alternative) + if (DEFAULT_ABI == ABI_V4 && flag_pic) { - default: - abort (); - case 0: - case 1: - return \"b%T1l\"; - case 2: - case 3: - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\"; + gcc_assert (!TARGET_SECURE_PLT); + return \"b %z1@plt\"; } + else + return \"b %z1\"; }" - [(set_attr "type" "jmpreg,jmpreg,branch,branch") - (set_attr "length" "4,8,4,8")]) + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) -;; Call subroutine returning any type. -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" +(define_expand "sibcall_epilogue" + [(use (const_int 0))] + "TARGET_SCHED_PROLOG" " { - int i; - - emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; + rs6000_emit_epilogue (TRUE); + DONE; }") ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; 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)] "" "") @@ -10275,10 +11754,10 @@ ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc ;; insns, and branches. We store the operands of compares until we see ;; how it is used. -(define_expand "cmpsi" +(define_expand "cmp" [(set (cc0) - (compare (match_operand:SI 0 "gpc_reg_operand" "") - (match_operand:SI 1 "reg_or_short_operand" "")))] + (compare (match_operand:GPR 0 "gpc_reg_operand" "") + (match_operand:GPR 1 "reg_or_short_operand" "")))] "" " { @@ -10286,26 +11765,7 @@ this might be a logical operation. That insn doesn't exist. */ if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) - operands[1] = force_reg (SImode, operands[1]); - - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 0; - DONE; -}") - -(define_expand "cmpdi" - [(set (cc0) - (compare (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "reg_or_short_operand" "")))] - "TARGET_POWERPC64" - " -{ - /* Take care of the possibility that operands[1] might be negative but - this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 0) - operands[1] = force_reg (DImode, operands[1]); + operands[1] = force_reg (mode, operands[1]); rs6000_compare_op0 = operands[0]; rs6000_compare_op1 = operands[1]; @@ -10313,34 +11773,10 @@ DONE; }") -(define_expand "cmpsf" - [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; - DONE; -}") - -(define_expand "cmpdf" - [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; - DONE; -}") - -(define_expand "cmptf" - [(set (cc0) (compare (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "gpc_reg_operand" "")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" +(define_expand "cmp" + [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "") + (match_operand:FP 1 "gpc_reg_operand" "")))] + "" " { rs6000_compare_op0 = operands[0]; @@ -10401,42 +11837,42 @@ (define_expand "bunordered" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }") (define_expand "bordered" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }") (define_expand "buneq" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }") (define_expand "bunge" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }") (define_expand "bungt" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }") (define_expand "bunle" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }") (define_expand "bunlt" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }") (define_expand "bltgt" [(use (match_operand 0 "" ""))] - "" + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }") ;; For SNE, we would prefer that the xor/abs sequence be used for integers. @@ -10453,11 +11889,24 @@ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" " -{ - if (! rs6000_compare_fp_p) +{ + if (! rs6000_compare_fp_p) + FAIL; + + rs6000_emit_sCOND (NE, operands[0]); + DONE; +}") + +;; A >= 0 is best done the portable way for A an integer. +(define_expand "sge" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "" + " +{ + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; - rs6000_emit_sCOND (NE, operands[0]); + rs6000_emit_sCOND (GE, operands[0]); DONE; }") @@ -10467,120 +11916,231 @@ "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; - rs6000_emit_sCOND (GT, operands[0]); + rs6000_emit_sCOND (GT, operands[0]); DONE; }") -;; A < 0 is best done in the portable way for A an integer. -(define_expand "slt" +;; A <= 0 is best done the portable way for A an integer. +(define_expand "sle" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; - rs6000_emit_sCOND (LT, operands[0]); + rs6000_emit_sCOND (LE, operands[0]); DONE; }") -;; A >= 0 is best done the portable way for A an integer. -(define_expand "sge" +;; A < 0 is best done in the portable way for A an integer. +(define_expand "slt" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; - rs6000_emit_sCOND (GE, operands[0]); + rs6000_emit_sCOND (LT, operands[0]); DONE; }") -;; A <= 0 is best done the portable way for A an integer. -(define_expand "sle" +(define_expand "sgeu" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" - " -{ - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) - FAIL; - - rs6000_emit_sCOND (LE, operands[0]); - DONE; -}") + "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }") (define_expand "sgtu" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }") +(define_expand "sleu" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "" + "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }") + (define_expand "sltu" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] "" "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }") -(define_expand "sgeu" +(define_expand "sunordered" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }") + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }") -(define_expand "sleu" +(define_expand "sordered" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }") + +(define_expand "suneq" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }") + +(define_expand "sunge" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }") + +(define_expand "sungt" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }") + +(define_expand "sunle" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }") + +(define_expand "sunlt" + [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }") + +(define_expand "sltgt" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] + "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" + "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }") + +(define_expand "stack_protect_set" + [(match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "")] "" - "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }") +{ +#ifdef TARGET_THREAD_SSP_OFFSET + rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); + rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); + operands[1] = gen_rtx_MEM (Pmode, addr); +#endif + if (TARGET_64BIT) + emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); + else + emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); + DONE; +}) + +(define_insn "stack_protect_setsi" + [(set (match_operand:SI 0 "memory_operand" "=m") + (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) + (set (match_scratch:SI 2 "=&r") (const_int 0))] + "TARGET_32BIT" + "{l%U1%X1|lwz%U1%X1} %2,%1\;{st%U0%X0|stw%U0%X0} %2,%0\;{lil|li} %2,0" + [(set_attr "type" "three") + (set_attr "length" "12")]) + +(define_insn "stack_protect_setdi" + [(set (match_operand:DI 0 "memory_operand" "=m") + (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) + (set (match_scratch:DI 2 "=&r") (const_int 0))] + "TARGET_64BIT" + "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;{lil|li} %2,0" + [(set_attr "type" "three") + (set_attr "length" "12")]) + +(define_expand "stack_protect_test" + [(match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "") + (match_operand 2 "" "")] + "" +{ +#ifdef TARGET_THREAD_SSP_OFFSET + rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); + rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); + operands[1] = gen_rtx_MEM (Pmode, addr); +#endif + rs6000_compare_op0 = operands[0]; + rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), + UNSPEC_SP_TEST); + rs6000_compare_fp_p = 0; + emit_jump_insn (gen_beq (operands[2])); + DONE; +}) + +(define_insn "stack_protect_testsi" + [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") + (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") + (match_operand:SI 2 "memory_operand" "m,m")] + UNSPEC_SP_TEST)) + (set (match_scratch:SI 4 "=r,r") (const_int 0)) + (clobber (match_scratch:SI 3 "=&r,&r"))] + "TARGET_32BIT" + "@ + {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0 + {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;{cmpl|cmplw} %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0" + [(set_attr "length" "16,20")]) + +(define_insn "stack_protect_testdi" + [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") + (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "m,m") + (match_operand:DI 2 "memory_operand" "m,m")] + UNSPEC_SP_TEST)) + (set (match_scratch:DI 4 "=r,r") (const_int 0)) + (clobber (match_scratch:DI 3 "=&r,&r"))] + "TARGET_64BIT" + "@ + ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0 + ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0" + [(set_attr "length" "16,20")]) + ;; Here are the actual compare insns. -(define_insn "*cmpsi_internal1" +(define_insn "*cmp_internal1" [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] + (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "reg_or_short_operand" "rI")))] "" - "{cmp%I2|cmpw%I2} %0,%1,%2" - [(set_attr "type" "compare")]) - -(define_insn "*cmpdi_internal1" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")))] - "TARGET_POWERPC64" - "cmpd%I2 %0,%1,%2" - [(set_attr "type" "compare")]) + "{cmp%I2|cmp%I2} %0,%1,%2" + [(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 -;; register for the result of the XOR. - -(define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_short_cint_operand" ""))) - (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] - "find_single_use (operands[0], insn, 0) - && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ - || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)" - [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4))) - (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))] - " +;; we can do this with an XOR followed by a compare. But this is profitable +;; only if the large constant is only used for the comparison (and in this +;; case we already have a register to reuse as scratch). +;; +;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: +;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand") + (match_operand:SI 1 "logical_const_operand" "")) + (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" + [(match_dup 0) + (match_operand:SI 2 "logical_const_operand" "")])) + (set (match_operand:CC 4 "cc_reg_operand" "") + (compare:CC (match_operand:SI 5 "gpc_reg_operand" "") + (match_dup 0))) + (set (pc) + (if_then_else (match_operator 6 "equality_operator" + [(match_dup 4) (const_int 0)]) + (match_operand 7 "" "") + (match_operand 8 "" "")))] + "peep2_reg_dead_p (3, operands[0]) + && peep2_reg_dead_p (4, operands[4])" + [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) + (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) + (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] + { - /* Get the constant we are comparing against, C, and see what it looks like - sign-extended to 16 bits. Then see what constant could be XOR'ed - with C to get the sign-extended value. */ - - HOST_WIDE_INT c = INTVAL (operands[2]); - HOST_WIDE_INT sextc = (c & 0x7fff) - (c & 0x8000); + /* Get the constant we are comparing against, and see what it looks like + when sign-extended from 16 to 32 bits. Then see what constant we could + XOR with SEXTC to get the sign-extended value. */ + rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), + SImode, + operands[1], operands[2]); + HOST_WIDE_INT c = INTVAL (cnst); + HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT xorv = c ^ sextc; - operands[4] = GEN_INT (xorv); - operands[5] = GEN_INT (sextc); -}") + operands[9] = GEN_INT (xorv); + operands[10] = GEN_INT (sextc); +}) (define_insn "*cmpsi_internal2" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") @@ -10588,7 +12148,7 @@ (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") @@ -10596,7 +12156,7 @@ (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 @@ -10647,7 +12207,7 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -10655,7 +12215,7 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -10664,10 +12224,70 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") (match_operand:TF 2 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "fcmpu %0,%1,%2\;bne %0,$+4\;fcmpu %0,%L1,%L2" + "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" + "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" [(set_attr "type" "fpcompare") (set_attr "length" "12")]) + +(define_insn_and_split "*cmptf_internal2" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") + (match_operand:TF 2 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 3 "=f")) + (clobber (match_scratch:DF 4 "=f")) + (clobber (match_scratch:DF 5 "=f")) + (clobber (match_scratch:DF 6 "=f")) + (clobber (match_scratch:DF 7 "=f")) + (clobber (match_scratch:DF 8 "=f")) + (clobber (match_scratch:DF 9 "=f")) + (clobber (match_scratch:DF 10 "=f"))] + "!TARGET_IEEEQUAD && TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 13)) + (set (match_dup 4) (match_dup 14)) + (set (match_dup 9) (abs:DF (match_dup 5))) + (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) + (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) + (label_ref (match_dup 11)) + (pc))) + (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) + (set (pc) (label_ref (match_dup 12))) + (match_dup 11) + (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) + (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) + (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) + (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4))) + (match_dup 12)] +{ + REAL_VALUE_TYPE rv; + const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + + operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word); + operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); + operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word); + operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word); + operands[11] = gen_label_rtx (); + operands[12] = gen_label_rtx (); + real_inf (&rv); + operands[13] = force_const_mem (DFmode, + CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); + operands[14] = force_const_mem (DFmode, + CONST_DOUBLE_FROM_REAL_VALUE (dconst0, + DFmode)); + if (TARGET_TOC) + { + operands[13] = gen_const_mem (DFmode, + create_TOC_reference (XEXP (operands[13], 0))); + operands[14] = gen_const_mem (DFmode, + create_TOC_reference (XEXP (operands[14], 0))); + set_mem_alias_set (operands[13], get_TOC_alias_set ()); + set_mem_alias_set (operands[14], get_TOC_alias_set ()); + } +}) ;; Now we have the scc insns. We can do some combinations because of the ;; way the machine works. @@ -10682,8 +12302,31 @@ [(match_operand 2 "cc_reg_operand" "y") (const_int 0)]))] "" - "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "length" "12")]) + "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) + (set_attr "length" "8")]) + +;; Same as above, but get the GT bit. +(define_insn "move_from_CR_gt_bit" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))] + "TARGET_HARD_FLOAT && !TARGET_FPRS" + "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,31,31" + [(set_attr "type" "mfcr") + (set_attr "length" "8")]) + +;; 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")] UNSPEC_MV_CR_OV))] + "TARGET_ISEL" + "mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1" + [(set_attr "type" "mfcr") + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -10691,8 +12334,13 @@ [(match_operand 2 "cc_reg_operand" "y") (const_int 0)]))] "TARGET_POWERPC64" - "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "length" "12")]) + "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -10702,12 +12350,12 @@ (const_int 0))) (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ - %D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1 + mfcr %3%Q2\;{rlinm.|rlwinm.} %3,%3,%J1,1 #" [(set_attr "type" "delayed_compare") - (set_attr "length" "12,16")]) + (set_attr "length" "8,16")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") @@ -10717,7 +12365,7 @@ (const_int 0))) (set (match_operand:SI 3 "gpc_reg_operand" "") (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 3) (match_op_dup 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) @@ -10746,9 +12394,14 @@ operands[4] = GEN_INT (count); operands[5] = GEN_INT (put_bit); - return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; + return \"mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; }" - [(set_attr "length" "12")]) + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -10761,7 +12414,7 @@ (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "* { int is_bit = ccr_bit (operands[1], 1); @@ -10780,13 +12433,13 @@ operands[5] = GEN_INT (count); operands[6] = GEN_INT (put_bit); - return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; + return \"mfcr %4%Q2\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; }" [(set_attr "type" "delayed_compare") - (set_attr "length" "12,16")]) + (set_attr "length" "8,16")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (ashift:SI (match_operator:SI 1 "scc_comparison_operator" [(match_operand 2 "cc_reg_operand" "") @@ -10796,7 +12449,7 @@ (set (match_operand:SI 4 "gpc_reg_operand" "") (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3))) @@ -10817,9 +12470,10 @@ (match_operator:SI 4 "scc_comparison_operator" [(match_operand 5 "cc_reg_operand" "y") (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 "length" "20")]) + "REGNO (operands[2]) != REGNO (operands[5])" + "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" + [(set_attr "type" "mfcr") + (set_attr "length" "12")]) (define_peephole [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -10830,9 +12484,10 @@ (match_operator:DI 4 "scc_comparison_operator" [(match_operand 5 "cc_reg_operand" "y") (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 "length" "20")]) + "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" + "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" + [(set_attr "type" "mfcr") + (set_attr "length" "12")]) ;; There are some scc insns that can be done directly, without a compare. ;; These are faster because they don't involve the communications between @@ -10848,117 +12503,96 @@ ;; otherwise won't accept constants. We do this because it is faster than ;; the cmp/mfcr sequence we would otherwise generate. -(define_insn "" +(define_mode_attr scc_eq_op2 [(SI "rKLI") + (DI "rKJI")]) + +(define_insn_and_split "*eq" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "scc_eq_operand" "")))] + "!TARGET_POWER" + "#" + "!TARGET_POWER" + [(set (match_dup 0) + (clz:GPR (match_dup 3))) + (set (match_dup 0) + (lshiftrt:GPR (match_dup 0) (match_dup 4)))] + { + if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) + { + /* Use output operand as intermediate. */ + operands[3] = operands[0]; + + if (logical_operand (operands[2], mode)) + emit_insn (gen_rtx_SET (VOIDmode, operands[3], + gen_rtx_XOR (mode, + operands[1], operands[2]))); + else + emit_insn (gen_rtx_SET (VOIDmode, operands[3], + gen_rtx_PLUS (mode, operands[1], + negate_rtx (mode, + operands[2])))); + } + else + operands[3] = operands[1]; + + operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (mode))); + }) + +(define_insn_and_split "*eq_compare" + [(set (match_operand:CC 3 "cc_reg_operand" "=y") + (compare:CC + (eq:P (match_operand:P 1 "gpc_reg_operand" "=r") + (match_operand:P 2 "scc_eq_operand" "")) + (const_int 0))) + (set (match_operand:P 0 "gpc_reg_operand" "=r") + (eq:P (match_dup 1) (match_dup 2)))] + "!TARGET_POWER && optimize_size" + "#" + "!TARGET_POWER && optimize_size" + [(set (match_dup 0) + (clz:P (match_dup 4))) + (parallel [(set (match_dup 3) + (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5)) + (const_int 0))) + (set (match_dup 0) + (lshiftrt:P (match_dup 0) (match_dup 5)))])] + { + if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) + { + /* Use output operand as intermediate. */ + operands[4] = operands[0]; + + if (logical_operand (operands[2], mode)) + emit_insn (gen_rtx_SET (VOIDmode, operands[4], + gen_rtx_XOR (mode, + operands[1], operands[2]))); + else + emit_insn (gen_rtx_SET (VOIDmode, operands[4], + gen_rtx_PLUS (mode, operands[1], + negate_rtx (mode, + operands[2])))); + } + else + operands[4] = operands[1]; + + operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (mode))); + }) + +(define_insn "*eqsi_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))) (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))] - "! TARGET_POWERPC64" + "TARGET_POWER" "@ xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0" - [(set_attr "length" "12,8,12,12,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r") - (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I"))) - (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))] - "TARGET_POWERPC64" - "@ - xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0 - subfic %3,%1,0\;adde %0,%3,%1 - xori %0,%1,%b2\;subfic %3,%0,0\;adde %0,%3,%0 - xoris %0,%1,%u2\;subfic %3,%0,0\;adde %0,%3,%0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0" - [(set_attr "length" "12,8,12,12,12")]) - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") - (eq:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] - "! TARGET_POWERPC64" - "@ - xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1 - {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (eq:SI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 0) - (eq:SI (match_dup 1) (match_dup 2))) - (clobber (match_dup 3))]) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") - (eq:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))] - "TARGET_POWERPC64" - "@ - xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %3,%1,0\;adde. %0,%3,%1 - xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0 - xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0 - subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (eq:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (eq:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 0) - (eq:DI (match_dup 1) (match_dup 2))) - (clobber (match_dup 3))]) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") + [(set_attr "type" "three,two,three,three,three") + (set_attr "length" "12,8,12,12,12")]) ;; We have insns of the form shown by the first define_insn below. If ;; there is something inside the comparison operation, we must split it. @@ -10975,30 +12609,31 @@ (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) (match_dup 4)))]) -(define_insn "" +(define_insn "*plus_eqsi" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r") (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")) + (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I")) (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3 {sfi|subfic} %0,%1,0\;{aze|addze} %0,%3 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3" - [(set_attr "length" "12,8,12,12,12")]) + [(set_attr "type" "three,two,three,three,three") + (set_attr "length" "12,8,12,12,12")]) -(define_insn "" +(define_insn "*compare_plus_eqsi" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") (compare:CC (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) + (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT && optimize_size" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 @@ -11018,11 +12653,11 @@ (compare:CC (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 2 "scc_eq_operand" "")) (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && optimize_size && reload_completed" [(set (match_dup 4) (plus:SI (eq:SI (match_dup 1) (match_dup 2)) @@ -11032,17 +12667,17 @@ (const_int 0)))] "") -(define_insn "" +(define_insn "*plus_eqsi_compare" [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") (compare:CC (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I")) + (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r") (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + "TARGET_32BIT && optimize_size" "@ xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3 {sfi|subfic} %0,%1,0\;{aze.|addze.} %0,%3 @@ -11062,12 +12697,12 @@ (compare:CC (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (match_operand:SI 2 "scc_eq_operand" "")) (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && optimize_size && reload_completed" [(set (match_dup 0) (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -11075,63 +12710,91 @@ (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") - (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))))] - "! TARGET_POWERPC64" - "@ - xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0 - {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 - {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "12,8,12,12,12")]) +(define_insn "*neg_eq0" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") + (const_int 0))))] + "" + "{ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0" + [(set_attr "type" "two") + (set_attr "length" "8")]) + +(define_insn_and_split "*neg_eq" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r") + (match_operand:P 2 "scc_eq_operand" ""))))] + "" + "#" + "" + [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))] + { + if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) + { + /* Use output operand as intermediate. */ + operands[3] = operands[0]; + + if (logical_operand (operands[2], mode)) + emit_insn (gen_rtx_SET (VOIDmode, operands[3], + gen_rtx_XOR (mode, + operands[1], operands[2]))); + else + emit_insn (gen_rtx_SET (VOIDmode, operands[3], + gen_rtx_PLUS (mode, operands[1], + negate_rtx (mode, + operands[2])))); + } + else + operands[3] = operands[1]; + }) ;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power, ;; since it nabs/sr is just as fast. -(define_insn "*ne0" +(define_insn "*ne0si" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (const_int 31))) (clobber (match_scratch:SI 2 "=&r"))] - "! TARGET_POWER && ! TARGET_POWERPC64" + "! TARGET_POWER && TARGET_32BIT && !TARGET_ISEL" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) -(define_insn "" +(define_insn "*ne0di" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) (const_int 63))) (clobber (match_scratch:DI 2 "=&r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "addic %2,%1,-1\;subfe %0,%2,%1" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) ;; This is what (plus (ne X (const_int 0)) Y) looks like. -(define_insn "" +(define_insn "*plus_ne0si" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (const_int 31)) (match_operand:SI 2 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 3 "=&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) -(define_insn "" +(define_insn "*plus_ne0di" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) (const_int 63)) (match_operand:DI 2 "gpc_reg_operand" "r"))) (clobber (match_scratch:DI 3 "=&r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "addic %3,%1,-1\;addze %0,%2" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) -(define_insn "" +(define_insn "*compare_plus_ne0si" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (plus:SI (lshiftrt:SI @@ -11141,7 +12804,7 @@ (const_int 0))) (clobber (match_scratch:SI 3 "=&r,&r")) (clobber (match_scratch:SI 4 "=X,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2 #" @@ -11158,18 +12821,18 @@ (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(parallel [(set (match_dup 3) - (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) - (const_int 31)) - (match_dup 2))) + (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) + (const_int 31)) + (match_dup 2))) (clobber (match_dup 4))]) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "" +(define_insn "*compare_plus_ne0di" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (plus:DI (lshiftrt:DI @@ -11178,7 +12841,7 @@ (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ addic %3,%1,-1\;addze. %3,%2 #" @@ -11186,7 +12849,7 @@ (set_attr "length" "8,12")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) @@ -11194,7 +12857,7 @@ (match_operand:DI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_64BIT && reload_completed" [(set (match_dup 3) (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) @@ -11204,7 +12867,7 @@ (const_int 0)))] "") -(define_insn "" +(define_insn "*plus_ne0si_compare" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (plus:SI (lshiftrt:SI @@ -11216,7 +12879,7 @@ (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) (match_dup 2))) (clobber (match_scratch:SI 3 "=&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2 #" @@ -11235,7 +12898,7 @@ (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) (match_dup 2))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(parallel [(set (match_dup 0) (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) (match_dup 2))) @@ -11245,7 +12908,7 @@ (const_int 0)))] "") -(define_insn "" +(define_insn "*plus_ne0di_compare" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (plus:DI (lshiftrt:DI @@ -11257,7 +12920,7 @@ (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) (match_dup 2))) (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ addic %3,%1,-1\;addze. %0,%2 #" @@ -11265,7 +12928,7 @@ (set_attr "length" "8,12")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) @@ -11276,7 +12939,7 @@ (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) (match_dup 2))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_64BIT && reload_completed" [(parallel [(set (match_dup 0) (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63)) (match_dup 2))) @@ -11423,62 +13086,24 @@ {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31" [(set_attr "length" "12")]) -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "! TARGET_POWERPC64" +(define_insn "*leu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (leu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI")))] + "" "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")))] - "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (leu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (leu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (leu:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") + [(set_attr "type" "three") + (set_attr "length" "12")]) -(define_insn "" +(define_insn "*leu_compare" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) + (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (leu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (leu:P (match_dup 1) (match_dup 2)))] + "" "@ {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 #" @@ -11488,42 +13113,28 @@ (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) + (leu:P (match_operand:P 1 "gpc_reg_operand" "") + (match_operand:P 2 "reg_or_short_operand" "")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (leu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") + (leu:P (match_dup 1) (match_dup 2)))] + "reload_completed" [(set (match_dup 0) - (leu:SI (match_dup 1) (match_dup 2))) + (leu:P (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (leu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")) - (match_operand:SI 3 "gpc_reg_operand" "r")))] - "! TARGET_POWERPC64" +(define_insn "*plus_leu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r") + (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI")) + (match_operand:P 3 "gpc_reg_operand" "r")))] + "" "{sf%I2|subf%I2c} %0,%1,%2\;{aze|addze} %0,%3" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -11533,7 +13144,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3 #" @@ -11548,7 +13159,7 @@ (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 4) (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -11566,7 +13177,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf%I2|subf%I2c} %0,%1,%2\;{aze.|addze.} %0,%3 #" @@ -11582,7 +13193,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -11590,23 +13201,25 @@ (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "! TARGET_POWERPC64" +(define_insn "*neg_leu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI"))))] + "" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r")))] - "! TARGET_POWERPC64" +(define_insn "*and_neg_leu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r") + (and:P (neg:P + (leu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI"))) + (match_operand:P 3 "gpc_reg_operand" "r")))] + "" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -11617,7 +13230,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 #" @@ -11633,7 +13246,7 @@ (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 4) (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) @@ -11652,7 +13265,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0 #" @@ -11669,7 +13282,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) @@ -11799,138 +13412,75 @@ "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31" [(set_attr "length" "12")]) -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "! TARGET_POWERPC64" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" - [(set_attr "length" "12")]) +(define_insn_and_split "*ltu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] + "" + "#" + "" + [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) + (set (match_dup 0) (neg:P (match_dup 0)))] + "") -(define_insn "" +(define_insn_and_split "*ltu_compare" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ltu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ltu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ltu:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] + (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") + (ltu:P (match_dup 1) (match_dup 2)))] + "" + "#" + "" + [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) + (parallel [(set (match_dup 3) + (compare:CC (neg:P (match_dup 0)) (const_int 0))) + (set (match_dup 0) (neg:P (match_dup 0)))])] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))] - "! TARGET_POWERPC64" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "! TARGET_POWERPC64" - "@ - {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 4) - (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] +(define_insn_and_split "*plus_ltu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r") + (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) + (match_operand:P 3 "reg_or_short_operand" "rI,rI")))] + "" + "#" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" + [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) + (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] "") -(define_insn "" +(define_insn_and_split "*plus_ltu_compare" [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" - "@ - {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3 - {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) + (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) + (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] + (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") + (plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] + "" + "#" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" + [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) + (parallel [(set (match_dup 4) + (compare:CC (minus:P (match_dup 3) (match_dup 0)) + (const_int 0))) + (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))] - "! TARGET_POWERPC64" +(define_insn "*neg_ltu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))] + "" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -12057,35 +13607,26 @@ "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" [(set_attr "length" "12")]) -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "! TARGET_POWERPC64" +(define_insn "*geu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] + "" "@ {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))] - "TARGET_POWERPC64" - "@ - subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) -(define_insn "" +(define_insn "*geu_compare" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) + (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (geu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" + (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") + (geu:P (match_dup 1) (match_dup 2)))] + "" "@ {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 @@ -12095,64 +13636,32 @@ (set_attr "length" "12,12,16,16")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (geu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (geu:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (geu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC - (geu:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_neg_short_operand" "")) + (geu:P (match_operand:P 1 "gpc_reg_operand" "") + (match_operand:P 2 "reg_or_neg_short_operand" "")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (geu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" + (set (match_operand:P 0 "gpc_reg_operand" "") + (geu:P (match_dup 1) (match_dup 2)))] + "reload_completed" [(set (match_dup 0) - (geu:DI (match_dup 1) (match_dup 2))) + (geu:P (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")))] - "! TARGET_POWERPC64" +(define_insn "*plus_geu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") + (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) + (match_operand:P 3 "gpc_reg_operand" "r,r")))] + "" "@ {sf|subfc} %0,%2,%1\;{aze|addze} %0,%3 {ai|addic} %0,%1,%n2\;{aze|addze} %0,%3" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") @@ -12162,7 +13671,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3 @@ -12179,7 +13688,7 @@ (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 4) (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -12197,7 +13706,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf|subfc} %0,%2,%1\;{aze.|addze.} %0,%3 {ai|addic} %0,%1,%n2\;{aze.|addze.} %0,%3 @@ -12215,7 +13724,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -12223,27 +13732,29 @@ (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))))] - "! TARGET_POWERPC64" +(define_insn "*neg_geu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_short_operand" "r,I"))))] + "" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")))] - "! TARGET_POWERPC64" +(define_insn "*and_neg_geu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") + (and:P (neg:P + (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))) + (match_operand:P 3 "gpc_reg_operand" "r,r")))] + "" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") @@ -12254,7 +13765,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 @@ -12272,7 +13783,7 @@ (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 4) (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) @@ -12291,7 +13802,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0 @@ -12310,7 +13821,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) (set (match_dup 4) @@ -12318,84 +13829,6 @@ (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0)))] - "! TARGET_POWERPC64" - "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (const_int 0)))] - "TARGET_POWERPC64" - "subfic %0,%1,0\;addme %0,%0\;srdi %0,%0,63" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (gt:SI (match_dup 1) (const_int 0)))] - "! TARGET_POWERPC64" - "@ - {sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC - (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gt:SI (match_dup 1) (const_int 0)))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (gt:SI (match_dup 1) (const_int 0))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC - (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (gt:DI (match_dup 1) (const_int 0)))] - "TARGET_POWERPC64" - "@ - subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC - (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (gt:DI (match_dup 1) (const_int 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (gt:DI (match_dup 1) (const_int 0))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -12435,23 +13868,15 @@ (const_int 0)))] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r")))] - "! TARGET_POWERPC64" +(define_insn "*plus_gt0" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r") + (plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r") + (const_int 0)) + (match_operand:P 2 "gpc_reg_operand" "r")))] + "" "{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze|addze} %0,%2" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2" - [(set_attr "length" "12")]) + [(set_attr "type" "three") + (set_attr "length" "12")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -12461,7 +13886,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=&r,&r"))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2 #" @@ -12476,7 +13901,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 3) (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) @@ -12493,7 +13918,7 @@ (match_operand:DI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 #" @@ -12501,14 +13926,14 @@ (set_attr "length" "12,16")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") (const_int 0)) (match_operand:DI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_64BIT && reload_completed" [(set (match_dup 3) (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) @@ -12526,7 +13951,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))] - "! TARGET_POWERPC64" + "TARGET_32BIT" "@ {a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze.|addze.} %0,%2 #" @@ -12542,7 +13967,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + "TARGET_32BIT && reload_completed" [(set (match_dup 0) (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) (set (match_dup 3) @@ -12559,7 +13984,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2 #" @@ -12567,7 +13992,7 @@ (set_attr "length" "12,16")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") (compare:CC (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") (const_int 0)) @@ -12575,7 +14000,7 @@ (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_64BIT && reload_completed" [(set (match_dup 0) (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) (set (match_dup 3) @@ -12615,324 +14040,123 @@ (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "TARGET_POWER && reload_completed" - [(set (match_dup 4) - (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWER" - "@ - doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{aze.|addze.} %0,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWER && reload_completed" - [(set (match_dup 0) - (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int 0))))] - "! TARGET_POWERPC64" - "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (neg:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (const_int 0))))] - "TARGET_POWERPC64" - "subfic %0,%1,0\;addme %0,%0\;sradi %0,%0,63" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "r"))))] - "TARGET_POWER" - "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "! TARGET_POWERPC64" - "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")))] - "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0" - [(set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (gtu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" - "@ - {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gtu:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (gtu:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (gtu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (gtu:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (gtu:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,rI")) - (match_operand:SI 3 "reg_or_short_operand" "r,rI")))] - "! TARGET_POWERPC64" - "@ - {ai|addic} %0,%1,%k2\;{aze|addze} %0,%3 - {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3" - [(set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_short_operand" "I,rI")) - (match_operand:DI 3 "reg_or_short_operand" "r,rI")))] - "TARGET_POWERPC64" - "@ - addic %0,%1,%k2\;addze %0,%3 - subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subf%I3c %0,%0,%3" - [(set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "! TARGET_POWERPC64" - "@ - {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3 - {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 4) - (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))] - "TARGET_POWERPC64" - "@ - addic %4,%1,%k2\;addze. %4,%3 - subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (match_operand:DI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_POWER && reload_completed" [(set (match_dup 4) - (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_short_operand" "r,r")) + (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r") + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWER" "@ - {ai|addic} %0,%1,%k2\;{aze.|addze.} %0,%3 - {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3 - # + doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{aze.|addze.} %0,%3 #" [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) + (set_attr "length" "12,16")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC - (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) + (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_short_operand" "")) (match_operand:SI 3 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWER && reload_completed" [(set (match_dup 0) - (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_short_operand" "r"))))] + "TARGET_POWER" + "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31" + [(set_attr "length" "12")]) + +(define_insn_and_split "*gtu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI")))] + "" + "#" + "" + [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) + (set (match_dup 0) (neg:P (match_dup 0)))] + "") + +(define_insn_and_split "*gtu_compare" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r")) + (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r") + (match_operand:P 2 "reg_or_short_operand" "rI,rI")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64" - "@ - addic %0,%1,%k2\;addze. %0,%3 - subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subfc. %0,%0,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12,12,16")]) + (set (match_operand:P 0 "gpc_reg_operand" "=r,r") + (gtu:P (match_dup 1) (match_dup 2)))] + "" + "#" + "" + [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) + (parallel [(set (match_dup 3) + (compare:CC (neg:P (match_dup 0)) (const_int 0))) + (set (match_dup 0) (neg:P (match_dup 0)))])] + "") -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") +(define_insn_and_split "*plus_gtu" + [(set (match_operand:P 0 "gpc_reg_operand" "=&r") + (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI")) + (match_operand:P 3 "reg_or_short_operand" "rI")))] + "" + "#" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" + [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) + (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] + "") + +(define_insn_and_split "*plus_gtu_compare" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") (compare:CC - (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_short_operand" "")) - (match_operand:DI 3 "gpc_reg_operand" "")) + (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") + (match_operand:P 2 "reg_or_short_operand" "I,r,I,r")) + (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] + (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") + (plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] + "" + "#" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" + [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) + (parallel [(set (match_dup 4) + (compare:CC (minus:P (match_dup 3) (match_dup 0)) + (const_int 0))) + (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] "") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "! TARGET_POWERPC64" +(define_insn "*neg_gtu" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "reg_or_short_operand" "rI"))))] + "" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0" - [(set_attr "length" "8")]) + [(set_attr "type" "two") + (set_attr "length" "8")]) -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (neg:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI"))))] - "TARGET_POWERPC64" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0" - [(set_attr "length" "8")]) ;; Define both directions of branch and return. If we need a reload ;; register, we'd rather use CR0 since it is much easier to copy a @@ -12942,7 +14166,7 @@ [(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)))] @@ -12957,7 +14181,7 @@ [(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)))] @@ -12966,14 +14190,14 @@ { return output_cbranch (operands[0], NULL, 0, insn); }" - [(set_attr "type" "branch") + [(set_attr "type" "jmpreg") (set_attr "length" "4")]) (define_insn "" [(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 "" ""))))] @@ -12988,7 +14212,7 @@ [(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)))] @@ -12997,7 +14221,7 @@ { return output_cbranch (operands[0], NULL, 1, insn); }" - [(set_attr "type" "branch") + [(set_attr "type" "jmpreg") (set_attr "length" "4")]) ;; Logic on condition register values. @@ -13007,56 +14231,57 @@ ; (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") +(define_insn "*cceq_ior_compare" + [(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") +(define_insn "*cceq_rev_compare" + [(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)))] "" "{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. @@ -13078,28 +14303,28 @@ { int positive_1, positive_2; - positive_1 = branch_positive_comparison_operator (operands[1], CCEQmode); - positive_2 = branch_positive_comparison_operator (operands[3], CCEQmode); + positive_1 = branch_positive_comparison_operator (operands[1], + GET_MODE (operands[1])); + positive_2 = branch_positive_comparison_operator (operands[3], + GET_MODE (operands[3])); if (! positive_1) - operands[1] = gen_rtx (rs6000_reverse_condition (GET_MODE (operands[2]), - GET_CODE (operands[1])), - SImode, - operands[2], const0_rtx); + operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), + GET_CODE (operands[1])), + SImode, + operands[2], const0_rtx); else if (GET_MODE (operands[1]) != SImode) - operands[1] = gen_rtx (GET_CODE (operands[1]), - SImode, - operands[2], const0_rtx); + operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, + operands[2], const0_rtx); if (! positive_2) - operands[3] = gen_rtx (rs6000_reverse_condition (GET_MODE (operands[4]), - GET_CODE (operands[3])), - SImode, - operands[4], const0_rtx); + operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), + GET_CODE (operands[3])), + SImode, + operands[4], const0_rtx); else if (GET_MODE (operands[3]) != SImode) - operands[3] = gen_rtx (GET_CODE (operands[3]), - SImode, - operands[4], const0_rtx); + operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, + operands[4], const0_rtx); if (positive_1 == positive_2) { @@ -13128,33 +14353,16 @@ [(set_attr "type" "jmpreg")]) (define_expand "indirect_jump" - [(set (pc) (match_operand 0 "register_operand" ""))] - "" - " -{ - if (TARGET_32BIT) - emit_jump_insn (gen_indirect_jumpsi (operands[0])); - else - emit_jump_insn (gen_indirect_jumpdi (operands[0])); - DONE; -}") + [(set (pc) (match_operand 0 "register_operand" ""))]) -(define_insn "indirect_jumpsi" - [(set (pc) (match_operand:SI 0 "register_operand" "c,*l"))] - "TARGET_32BIT" +(define_insn "*indirect_jump" + [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))] + "" "@ bctr {br|blr}" [(set_attr "type" "jmpreg")]) -(define_insn "indirect_jumpdi" - [(set (pc) (match_operand:DI 0 "register_operand" "c,*l"))] - "TARGET_64BIT" - "@ - bctr - blr" - [(set_attr "type" "jmpreg")]) - ;; Table jump for switch statements: (define_expand "tablejump" [(use (match_operand 0 "" "")) @@ -13183,8 +14391,8 @@ }") (define_expand "tablejumpdi" - [(set (match_dup 4) - (sign_extend:DI (match_operand:SI 0 "lwa_operand" "rm"))) + [(set (match_dup 4) + (sign_extend:DI (match_operand:SI 0 "lwa_operand" ""))) (set (match_dup 3) (plus:DI (match_dup 4) (match_dup 2))) @@ -13193,257 +14401,87 @@ "TARGET_64BIT" " { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); - operands[3] = gen_reg_rtx (DImode); - operands[4] = gen_reg_rtx (DImode); -}") - -(define_insn "" - [(set (pc) - (match_operand:SI 0 "register_operand" "c,*l")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_32BIT" - "@ - bctr - {br|blr}" - [(set_attr "type" "jmpreg")]) - -(define_insn "" - [(set (pc) - (match_operand:DI 0 "register_operand" "c,*l")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_64BIT" - "@ - bctr - blr" - [(set_attr "type" "jmpreg")]) - -(define_insn "nop" - [(const_int 0)] - "" - "{cror 0,0,0|nop}") - -;; Define the subtract-one-and-jump insns, starting with the template -;; so loop.c knows what to generate. - -(define_expand "doloop_end" - [(use (match_operand 0 "" "")) ; loop pseudo - (use (match_operand 1 "" "")) ; iterations; zero if unknown - (use (match_operand 2 "" "")) ; max iterations - (use (match_operand 3 "" "")) ; loop level - (use (match_operand 4 "" ""))] ; label - "" - " -{ - /* Only use this on innermost loops. */ - if (INTVAL (operands[3]) > 1) - FAIL; - if (TARGET_POWERPC64) - { - if (GET_MODE (operands[0]) != DImode) - FAIL; - emit_jump_insn (gen_ctrdi (operands[0], operands[4])); - } - else - { - if (GET_MODE (operands[0]) != SImode) - FAIL; - emit_jump_insn (gen_ctrsi (operands[0], operands[4])); - } - DONE; -}") - -(define_expand "ctrsi" - [(parallel [(set (pc) - (if_then_else (ne (match_operand:SI 0 "register_operand" "") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1))) - (clobber (match_scratch:CC 2 "")) - (clobber (match_scratch:SI 3 ""))])] - "! TARGET_POWERPC64" - "") - -(define_expand "ctrdi" - [(parallel [(set (pc) - (if_then_else (ne (match_operand:DI 0 "register_operand" "") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:DI (match_dup 0) - (const_int -1))) - (clobber (match_scratch:CC 2 "")) - (clobber (match_scratch:DI 3 ""))])] - "TARGET_POWERPC64" - "") - -;; We need to be able to do this for any operand, including MEM, or we -;; will cause reload to blow up since we don't allow output reloads on -;; JUMP_INSNs. -;; For the length attribute to be calculated correctly, the -;; label MUST be operand 0. - -(define_insn "*ctrsi_internal1" - [(set (pc) - (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "*ctrsi_internal2" - [(set (pc) - (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "*ctrdi_internal1" - [(set (pc) - (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "*ctrdi_internal2" - [(set (pc) - (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -;; Similar, but we can use GE since we have a REG_NONNEG. + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (DImode); +}") -(define_insn "*ctrsi_internal3" +(define_insn "*tablejump_internal1" [(set (pc) - (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&X")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (match_operand:P 0 "register_operand" "c,*l")) + (use (label_ref (match_operand 1 "" "")))] + "" + "@ + bctr + {br|blr}" + [(set_attr "type" "jmpreg")]) -(define_insn "*ctrsi_internal4" - [(set (pc) - (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&X")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" - "* +(define_insn "nop" + [(const_int 0)] + "" + "{cror 0,0,0|nop}") + +;; Define the subtract-one-and-jump insns, starting with the template +;; so loop.c knows what to generate. + +(define_expand "doloop_end" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" ""))] ; label + "" + " { - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; + /* Only use this on innermost loops. */ + if (INTVAL (operands[3]) > 1) + FAIL; + if (TARGET_64BIT) + { + if (GET_MODE (operands[0]) != DImode) + FAIL; + emit_jump_insn (gen_ctrdi (operands[0], operands[4])); + } else - return \"{bdn|bdnz} $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + { + if (GET_MODE (operands[0]) != SImode) + FAIL; + emit_jump_insn (gen_ctrsi (operands[0], operands[4])); + } + DONE; +}") + +(define_expand "ctr" + [(parallel [(set (pc) + (if_then_else (ne (match_operand:P 0 "register_operand" "") + (const_int 1)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:P (match_dup 0) + (const_int -1))) + (clobber (match_scratch:CC 2 "")) + (clobber (match_scratch:P 3 ""))])] + "" + "") + +;; We need to be able to do this for any operand, including MEM, or we +;; will cause reload to blow up since we don't allow output reloads on +;; JUMP_INSNs. +;; For the length attribute to be calculated correctly, the +;; label MUST be operand 0. -(define_insn "*ctrdi_internal3" +(define_insn "*ctr_internal1" [(set (pc) - (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r") - (const_int 0)) + (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r") + (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l") + (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" + (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) + (clobber (match_scratch:P 4 "=X,X,&r,r"))] + "" "* { if (which_alternative != 0) @@ -13454,20 +14492,20 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "*,12,16,16")]) -(define_insn "*ctrdi_internal4" +(define_insn "*ctr_internal2" [(set (pc) - (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r") - (const_int 0)) + (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r") + (const_int 1)) (pc) (label_ref (match_operand 0 "" "")))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l") + (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" + (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) + (clobber (match_scratch:P 4 "=X,X,&r,r"))] + "" "* { if (which_alternative != 0) @@ -13478,70 +14516,22 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "*,12,16,16")]) ;; Similar but use EQ -(define_insn "*ctrsi_internal5" - [(set (pc) - (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; - else - return \"{bdn|bdnz} $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "*ctrsi_internal6" - [(set (pc) - (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:SI 4 "=X,X,r"))] - "! TARGET_POWERPC64" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"{bdn|bdnz} %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) - -(define_insn "*ctrdi_internal5" +(define_insn "*ctr_internal5" [(set (pc) - (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r") + (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r") (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l") + (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) + (clobber (match_scratch:P 4 "=X,X,&r,r"))] + "" "* { if (which_alternative != 0) @@ -13552,20 +14542,20 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "*,12,16,16")]) -(define_insn "*ctrdi_internal6" +(define_insn "*ctr_internal6" [(set (pc) - (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r") + (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r") (const_int 1)) (pc) (label_ref (match_operand 0 "" "")))) - (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l") - (plus:DI (match_dup 1) + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l") + (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x")) - (clobber (match_scratch:DI 4 "=X,X,r"))] - "TARGET_POWERPC64" + (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) + (clobber (match_scratch:P 4 "=X,X,&r,r"))] + "" "* { if (which_alternative != 0) @@ -13576,111 +14566,54 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "*,12,16,16")]) ;; Now the splitters if we could not allocate the CTR register (define_split [(set (pc) (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 3) - (compare:CC (plus:SI (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 0) - (plus:SI (match_dup 1) - (const_int -1)))]) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") - -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:SI 0 "nonimmediate_operand" "") - (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed - && ! gpc_reg_operand (operands[0], SImode)" - [(parallel [(set (match_dup 3) - (compare:CC (plus:SI (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 4) - (plus:SI (match_dup 1) - (const_int -1)))]) - (set (match_dup 0) - (match_dup 4)) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") + [(match_operand:P 1 "gpc_reg_operand" "") (const_int 1)]) (match_operand 5 "" "") (match_operand 6 "" ""))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (plus:DI (match_dup 1) - (const_int -1))) + (set (match_operand:P 0 "gpc_reg_operand" "") + (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" + (clobber (match_scratch:P 4 ""))] + "reload_completed" [(parallel [(set (match_dup 3) - (compare:CC (plus:DI (match_dup 1) + (compare:CC (plus:P (match_dup 1) (const_int -1)) (const_int 0))) (set (match_dup 0) - (plus:DI (match_dup 1) + (plus:P (match_dup 1) (const_int -1)))]) (set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))] " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") +{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, + operands[3], const0_rtx); }") (define_split [(set (pc) (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") + [(match_operand:P 1 "gpc_reg_operand" "") (const_int 1)]) (match_operand 5 "" "") (match_operand 6 "" ""))) - (set (match_operand:DI 0 "nonimmediate_operand" "") - (plus:DI (match_dup 1) (const_int -1))) + (set (match_operand:P 0 "nonimmediate_operand" "") + (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && ! gpc_reg_operand (operands[0], DImode)" + (clobber (match_scratch:P 4 ""))] + "reload_completed && ! gpc_reg_operand (operands[0], SImode)" [(parallel [(set (match_dup 3) - (compare:CC (plus:DI (match_dup 1) + (compare:CC (plus:P (match_dup 1) (const_int -1)) (const_int 0))) (set (match_dup 4) - (plus:DI (match_dup 1) + (plus:P (match_dup 1) (const_int -1)))]) (set (match_dup 0) (match_dup 4)) @@ -13688,14 +14621,14 @@ (match_dup 5) (match_dup 6)))] " -{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); }") - +{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, + operands[3], const0_rtx); }") (define_insn "trap" [(trap_if (const_int 1) (const_int 0))] "" - "{t 31,0,0|trap}") + "{t 31,0,0|trap}" + [(set_attr "type" "trap")]) (define_expand "conditional_trap" [(trap_if (match_operator 0 "trap_comparison_operator" @@ -13708,19 +14641,12 @@ (define_insn "" [(trap_if (match_operator 0 "trap_comparison_operator" - [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "reg_or_short_operand" "rI")]) + [(match_operand:GPR 1 "register_operand" "r") + (match_operand:GPR 2 "reg_or_short_operand" "rI")]) (const_int 0))] "" - "{t|tw}%V0%I2 %1,%2") - -(define_insn "" - [(trap_if (match_operator 0 "trap_comparison_operator" - [(match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "reg_or_short_operand" "rI")]) - (const_int 0))] - "TARGET_POWERPC64" - "td%V0%I2 %1,%2") + "{t|t}%V0%I2 %1,%2" + [(set_attr "type" "trap")]) ;; Insns related to generating the function prologue and epilogue. @@ -13733,43 +14659,75 @@ DONE; }") +(define_insn "*movesi_from_cr_one" + [(match_parallel 0 "mfcr_operation" + [(set (match_operand:SI 1 "gpc_reg_operand" "=r") + (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") + (match_operand 3 "immediate_operand" "n")] + UNSPEC_MOVESI_FROM_CR))])] + "TARGET_MFCRF" + "* +{ + int mask = 0; + int i; + for (i = 0; i < XVECLEN (operands[0], 0); i++) + { + mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); + operands[4] = GEN_INT (mask); + output_asm_insn (\"mfcr %1,%4\", operands); + } + return \"\"; +}" + [(set_attr "type" "mfcrf")]) + (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))] + (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO) + (reg:CC CR2_REGNO) (reg:CC CR3_REGNO) + (reg:CC CR4_REGNO) (reg:CC CR5_REGNO) + (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)] + UNSPEC_MOVESI_FROM_CR))] "" - "mfcr %0") + "mfcr %0" + [(set_attr "type" "mfcr")]) (define_insn "*stmw" - [(match_parallel 0 "stmw_operation" - [(set (match_operand:SI 1 "memory_operand" "=m") - (match_operand:SI 2 "gpc_reg_operand" "r"))])] - "TARGET_MULTIPLE" - "{stm|stmw} %2,%1") - -(define_insn "*save_fpregs_si" - [(match_parallel 0 "any_operand" - [(clobber (match_operand:SI 1 "register_operand" "=l")) - (use (match_operand:SI 2 "call_operand" "s")) - (set (match_operand:DF 3 "memory_operand" "=m") - (match_operand:DF 4 "gpc_reg_operand" "f"))])] - "TARGET_32BIT" - "bl %z2") - -(define_insn "*save_fpregs_di" - [(match_parallel 0 "any_operand" - [(clobber (match_operand:DI 1 "register_operand" "=l")) - (use (match_operand:DI 2 "call_operand" "s")) - (set (match_operand:DF 3 "memory_operand" "=m") - (match_operand:DF 4 "gpc_reg_operand" "f"))])] - "TARGET_64BIT" - "bl %z2") + [(match_parallel 0 "stmw_operation" + [(set (match_operand:SI 1 "memory_operand" "=m") + (match_operand:SI 2 "gpc_reg_operand" "r"))])] + "TARGET_MULTIPLE" + "{stm|stmw} %2,%1" + [(set_attr "type" "store_ux")]) + +(define_insn "*save_gpregs_" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:P 3 "memory_operand" "=m") + (match_operand:P 4 "gpc_reg_operand" "r"))])] + "" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_fpregs_" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (match_operand:P 2 "gpc_reg_operand" "r")) + (set (match_operand:DF 3 "memory_operand" "=m") + (match_operand:DF 4 "gpc_reg_operand" "f"))])] + "" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) ; These are to explain that changes to the stack pointer should ; 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")]) @@ -13789,18 +14747,18 @@ ; faster; for instance, on the 601 and 750. (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))] - "" - "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") + [(set (match_operand:CC 0 "cc_reg_operand" "") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "") + (match_dup 2)] UNSPEC_MOVESI_TO_CR))] + "" + "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") (define_insn "*movsi_to_cr" - [(match_parallel 0 "mtcrf_operation" - [(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))])] + [(match_parallel 0 "mtcrf_operation" + [(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")] + UNSPEC_MOVESI_TO_CR))])] "" "* { @@ -13810,133 +14768,116 @@ mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); operands[4] = GEN_INT (mask); return \"mtcrf %4,%2\"; -}") +}" + [(set_attr "type" "mtcr")]) -(define_insn "" - [(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))] - "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") +(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")] + 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" "mtcr")]) ; The load-multiple instructions have similar properties. ; Note that "load_multiple" is a name known to the machine-independent -; code that actually corresponds to the powerpc load-string. +; code that actually corresponds to the PowerPC load-string. (define_insn "*lmw" - [(match_parallel 0 "lmw_operation" - [(set (match_operand:SI 1 "gpc_reg_operand" "=r") - (match_operand:SI 2 "memory_operand" "m"))])] - "TARGET_MULTIPLE" - "{lm|lmw} %1,%2") - -(define_insn "*return_internal_si" - [(return) - (use (match_operand:SI 0 "register_operand" "lc"))] - "TARGET_32BIT" - "b%T0" - [(set_attr "type" "jmpreg")]) - -(define_insn "*return_internal_di" + [(match_parallel 0 "lmw_operation" + [(set (match_operand:SI 1 "gpc_reg_operand" "=r") + (match_operand:SI 2 "memory_operand" "m"))])] + "TARGET_MULTIPLE" + "{lm|lmw} %1,%2" + [(set_attr "type" "load_ux") + (set_attr "cell_micro" "always")]) + +(define_insn "*return_internal_" [(return) - (use (match_operand:DI 0 "register_operand" "lc"))] - "TARGET_64BIT" + (use (match_operand:P 0 "register_operand" "lc"))] + "" "b%T0" [(set_attr "type" "jmpreg")]) ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall -; stuff was in GCC. Oh, and "any_operand" is a bit flexible... +; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... + +(define_insn "*restore_gpregs_" + [(match_parallel 0 "any_parallel_operand" + [(clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:P 4 "gpc_reg_operand" "=r") + (match_operand:P 5 "memory_operand" "m"))])] + "" + "bl %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) -(define_insn "*return_and_restore_fpregs_si" - [(match_parallel 0 "any_operand" +(define_insn "*return_and_restore_gpregs_" + [(match_parallel 0 "any_parallel_operand" [(return) - (use (match_operand:SI 1 "register_operand" "l")) - (use (match_operand:SI 2 "call_operand" "s")) - (set (match_operand:DF 3 "gpc_reg_operand" "=f") - (match_operand:DF 4 "memory_operand" "m"))])] - "TARGET_32BIT" - "b %z2") - -(define_insn "*return_and_restore_fpregs_di" - [(match_parallel 0 "any_operand" + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:P 4 "gpc_reg_operand" "=r") + (match_operand:P 5 "memory_operand" "m"))])] + "" + "b %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_fpregs_" + [(match_parallel 0 "any_parallel_operand" [(return) - (use (match_operand:DI 1 "register_operand" "l")) - (use (match_operand:DI 2 "call_operand" "s")) - (set (match_operand:DF 3 "gpc_reg_operand" "=f") - (match_operand:DF 4 "memory_operand" "m"))])] - "TARGET_64BIT" - "b %z2") + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (match_operand:P 3 "gpc_reg_operand" "r")) + (set (match_operand:DF 4 "gpc_reg_operand" "=f") + (match_operand:DF 5 "memory_operand" "m"))])] + "" + "b %z2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) ; This is used in compiling the unwind routines. (define_expand "eh_return" - [(use (match_operand 0 "general_operand" "")) - (use (match_operand 1 "general_operand" ""))] + [(use (match_operand 0 "general_operand" ""))] "" " { -#if TARGET_AIX - rs6000_emit_eh_toc_restore (operands[0]); -#endif if (TARGET_32BIT) - emit_insn (gen_eh_set_lr_si (operands[1])); + emit_insn (gen_eh_set_lr_si (operands[0])); else - emit_insn (gen_eh_set_lr_di (operands[1])); - emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]); + emit_insn (gen_eh_set_lr_di (operands[0])); DONE; }") ; 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) - (clobber (match_scratch:SI 1 "=&b"))] - "TARGET_32BIT" - "#") - -(define_insn "eh_set_lr_di" - [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 9) - (clobber (match_scratch:DI 1 "=&b"))] - "TARGET_64BIT" +(define_insn "eh_set_lr_" + [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] + UNSPECV_EH_RR) + (clobber (match_scratch:P 1 "=&b"))] + "" "#") (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)] " { - rs6000_stack_t *info = rs6000_stack_info (); - - if (info->lr_save_p) - { - rtx frame_rtx = stack_pointer_rtx; - int sp_offset = 0; - rtx tmp; - - if (frame_pointer_needed - || current_function_calls_alloca - || info->total_size > 32767) - { - emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx)); - frame_rtx = operands[1]; - } - else if (info->push_p) - sp_offset = info->total_size; - - tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset); - tmp = gen_rtx_MEM (Pmode, tmp); - emit_move_insn (tmp, operands[0]); - } - else - emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]); + rs6000_emit_eh_reg_restore (operands[0], operands[1]); DONE; }") (define_insn "prefetch" - [(prefetch (match_operand:V4SI 0 "address_operand" "p") + [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n"))] "TARGET_POWERPC" @@ -13948,1849 +14889,9 @@ }" [(set_attr "type" "load")]) -;; AltiVec patterns - -;; Generic LVX load instruction. -(define_insn "altivec_lvx_4si" - [(set (match_operand:V4SI 0 "altivec_register_operand" "=v") - (match_operand:V4SI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_8hi" - [(set (match_operand:V8HI 0 "altivec_register_operand" "=v") - (match_operand:V8HI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_16qi" - [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") - (match_operand:V16QI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_4sf" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (match_operand:V4SF 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -;; Generic STVX store instruction. -(define_insn "altivec_stvx_4si" - [(set (match_operand:V4SI 0 "memory_operand" "=m") - (match_operand:V4SI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_8hi" - [(set (match_operand:V8HI 0 "memory_operand" "=m") - (match_operand:V8HI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_16qi" - [(set (match_operand:V16QI 0 "memory_operand" "=m") - (match_operand:V16QI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_4sf" - [(set (match_operand:V4SF 0 "memory_operand" "=m") - (match_operand:V4SF 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -;; Vector move instructions. -(define_expand "movv4si" - [(set (match_operand:V4SI 0 "nonimmediate_operand" "") - (match_operand:V4SI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }") - -(define_insn "*movv4si_internal" - [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv8hi" - [(set (match_operand:V8HI 0 "nonimmediate_operand" "") - (match_operand:V8HI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }") - -(define_insn "*movv8hi_internal1" - [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv16qi" - [(set (match_operand:V16QI 0 "nonimmediate_operand" "") - (match_operand:V16QI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }") - -(define_insn "*movv16qi_internal1" - [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv4sf" - [(set (match_operand:V4SF 0 "nonimmediate_operand" "") - (match_operand:V4SF 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }") - -(define_insn "*movv4sf_internal1" - [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_insn "get_vrsave_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(reg:SI 109)] 214))] - "TARGET_ALTIVEC" - "* -{ - if (TARGET_MACHO) - return \"mtspr 256,%0\"; - else - return \"mtvrsave %0\"; -}" - [(set_attr "type" "altivec")]) - -(define_insn "*set_vrsave_internal" - [(match_parallel 0 "vrsave_operation" - [(set (reg:SI 109) - (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") - (reg:SI 109)] 30))])] - "TARGET_ALTIVEC" - "* -{ - if (TARGET_MACHO) - return \"mfspr %1,256\"; - else - return \"mtvrsave %1\"; -}" - [(set_attr "type" "altivec")]) - -;; Vector clears -(define_insn "*movv4si_const0" - [(set (match_operand:V4SI 0 "altivec_register_operand" "=v") - (match_operand:V4SI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv4sf_const0" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (match_operand:V4SF 1 "zero_constant" ""))] - - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv8hi_const0" - [(set (match_operand:V8HI 0 "altivec_register_operand" "=v") - (match_operand:V8HI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv16qi_const0" - [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") - (match_operand:V16QI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -;; Simple binary operations. - -(define_insn "addv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (plus:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vaddubm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (plus:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vadduhm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vadduwm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vaddfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vaddcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 35))] - "TARGET_ALTIVEC" - "vaddcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddubs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 36))] - "TARGET_ALTIVEC" - "vaddubs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddsbs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 37))] - "TARGET_ALTIVEC" - "vaddsbs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vadduhs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 38))] - "TARGET_ALTIVEC" - "vadduhs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 39))] - "TARGET_ALTIVEC" - "vaddshs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vadduws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 40))] - "TARGET_ALTIVEC" - "vadduws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 41))] - "TARGET_ALTIVEC" - "vaddsws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "andv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (and:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vand %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vandc" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (and:V4SI (match_operand:V4SI 1 "register_operand" "v") - (not:V4SI (match_operand:V4SI 2 "register_operand" "v"))))] - "TARGET_ALTIVEC" - "vandc %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgub" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 44))] - "TARGET_ALTIVEC" - "vavgub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 45))] - "TARGET_ALTIVEC" - "vavgsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavguh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 46))] - "TARGET_ALTIVEC" - "vavguh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 47))] - "TARGET_ALTIVEC" - "vavgsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavguw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 48))] - "TARGET_ALTIVEC" - "vavguw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 49))] - "TARGET_ALTIVEC" - "vavgsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpbfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 50))] - "TARGET_ALTIVEC" - "vcmpbfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpequb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 51))] - "TARGET_ALTIVEC" - "vcmpequb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpequh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 52))] - "TARGET_ALTIVEC" - "vcmpequh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpequw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 53))] - "TARGET_ALTIVEC" - "vcmpequw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpeqfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 54))] - "TARGET_ALTIVEC" - "vcmpeqfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpgefp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 55))] - "TARGET_ALTIVEC" - "vcmpgefp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpgtub" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 56))] - "TARGET_ALTIVEC" - "vcmpgtub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 57))] - "TARGET_ALTIVEC" - "vcmpgtsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtuh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 58))] - "TARGET_ALTIVEC" - "vcmpgtuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 59))] - "TARGET_ALTIVEC" - "vcmpgtsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 60))] - "TARGET_ALTIVEC" - "vcmpgtuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 61))] - "TARGET_ALTIVEC" - "vcmpgtsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 62))] - "TARGET_ALTIVEC" - "vcmpgtfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -;; Fused multiply add -(define_insn "altivec_vmaddfp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_operand:V4SF 3 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaddfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -;; The unspec here is a vec splat of 0. We do multiply as a fused -;; multiply-add with an add of a 0 vector. - -(define_expand "mulv4sf3" - [(set (match_dup 3) (unspec:V4SF [(const_int 0)] 142)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_dup 3)))] - "TARGET_ALTIVEC && TARGET_FUSED_MADD" - " -{ operands[3] = gen_reg_rtx (V4SFmode); }") - -;; Fused multiply subtract -(define_insn "altivec_vnmsubfp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_operand:V4SF 3 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vnmsubfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - - -(define_insn "altivec_vmsumubm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 65))] - "TARGET_ALTIVEC" - "vmsumubm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsummbm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 66))] - "TARGET_ALTIVEC" - "vmsumubm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumuhm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 67))] - "TARGET_ALTIVEC" - "vmsumuhm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 68))] - "TARGET_ALTIVEC" - "vmsumshm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumuhs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 69))] - "TARGET_ALTIVEC" - "vmsumuhs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 70))] - "TARGET_ALTIVEC" - "vmsumshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "umaxv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (umax:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (smax:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "umaxv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (umax:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (smax:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "umaxv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (umax:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (smax:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vmhaddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 71))] - "TARGET_ALTIVEC" - "vmhaddshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) -(define_insn "altivec_vmhraddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 72))] - "TARGET_ALTIVEC" - "vmhraddshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) -(define_insn "altivec_vmladduhm" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 73))] - "TARGET_ALTIVEC" - "vmladduhm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmrghb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v") - (parallel [(const_int 8) - (const_int 9) - (const_int 10) - (const_int 11) - (const_int 12) - (const_int 13) - (const_int 14) - (const_int 15) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3) - (const_int 4) - (const_int 5) - (const_int 6) - (const_int 7)])) - (match_operand:V16QI 2 "register_operand" "v") - (const_int 255)))] - "TARGET_ALTIVEC" - "vmrghb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v") - (parallel [(const_int 4) - (const_int 5) - (const_int 6) - (const_int 7) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3)])) - (match_operand:V8HI 2 "register_operand" "v") - (const_int 15)))] - "TARGET_ALTIVEC" - "vmrghh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v") - (parallel [(const_int 2) - (const_int 3) - (const_int 0) - (const_int 1)])) - (match_operand:V4SI 2 "register_operand" "v") - (const_int 12)))] - "TARGET_ALTIVEC" - "vmrghw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v") - (parallel [(const_int 8) - (const_int 9) - (const_int 10) - (const_int 11) - (const_int 12) - (const_int 13) - (const_int 14) - (const_int 15) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3) - (const_int 4) - (const_int 5) - (const_int 6) - (const_int 7)])) - (match_operand:V16QI 1 "register_operand" "v") - (const_int 255)))] - "TARGET_ALTIVEC" - "vmrglb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v") - (parallel [(const_int 4) - (const_int 5) - (const_int 6) - (const_int 7) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3)])) - (match_operand:V8HI 1 "register_operand" "v") - (const_int 15)))] - "TARGET_ALTIVEC" - "vmrglh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v") - (parallel [(const_int 2) - (const_int 3) - (const_int 0) - (const_int 1)])) - (match_operand:V4SI 1 "register_operand" "v") - (const_int 12)))] - "TARGET_ALTIVEC" - "vmrglw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "uminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (umin:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (smin:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "uminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (umin:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (smin:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "uminv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (umin:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (smin:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vmuleub" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 83))] - "TARGET_ALTIVEC" - "vmuleub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulesb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 84))] - "TARGET_ALTIVEC" - "vmulesb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmuleuh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 85))] - "TARGET_ALTIVEC" - "vmuleuh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulesh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 86))] - "TARGET_ALTIVEC" - "vmulesh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmuloub" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 87))] - "TARGET_ALTIVEC" - "vmuloub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulosb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 88))] - "TARGET_ALTIVEC" - "vmulosb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulouh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 89))] - "TARGET_ALTIVEC" - "vmulouh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulosh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 90))] - "TARGET_ALTIVEC" - "vmulosh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vnor" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (not:V4SI (ior:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v"))))] - "TARGET_ALTIVEC" - "vnor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "iorv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (ior:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vpkuhum" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 93))] - "TARGET_ALTIVEC" - "vpkuhum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwum" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 94))] - "TARGET_ALTIVEC" - "vpkuwum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkpx" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 95))] - "TARGET_ALTIVEC" - "vpkpx %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuhss" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 96))] - "TARGET_ALTIVEC" - "vpkuhss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshss" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 97))] - "TARGET_ALTIVEC" - "vpkshss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwss" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 98))] - "TARGET_ALTIVEC" - "vpkuwss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswss" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 99))] - "TARGET_ALTIVEC" - "vpkswss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuhus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 100))] - "TARGET_ALTIVEC" - "vpkuhus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 101))] - "TARGET_ALTIVEC" - "vpkshus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 102))] - "TARGET_ALTIVEC" - "vpkuwus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 103))] - "TARGET_ALTIVEC" - "vpkswus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vrlb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 104))] - "TARGET_ALTIVEC" - "vrlb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vrlh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 105))] - "TARGET_ALTIVEC" - "vrlh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vrlw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 106))] - "TARGET_ALTIVEC" - "vrlw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 107))] - "TARGET_ALTIVEC" - "vslb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 108))] - "TARGET_ALTIVEC" - "vslh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 109))] - "TARGET_ALTIVEC" - "vslw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsl" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 110))] - "TARGET_ALTIVEC" - "vsl %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vslo" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 111))] - "TARGET_ALTIVEC" - "vslo %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsrb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 112))] - "TARGET_ALTIVEC" - "vsrb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 113))] - "TARGET_ALTIVEC" - "vsrh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 114))] - "TARGET_ALTIVEC" - "vsrw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrab" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 115))] - "TARGET_ALTIVEC" - "vsrab %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrah" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 116))] - "TARGET_ALTIVEC" - "vsrah %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsraw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 117))] - "TARGET_ALTIVEC" - "vsraw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsr" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 118))] - "TARGET_ALTIVEC" - "vsr %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsro" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 119))] - "TARGET_ALTIVEC" - "vsro %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "subv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (minus:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsububm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (minus:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubuhm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (minus:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubuwm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vsubcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 124))] - "TARGET_ALTIVEC" - "vsubcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsububs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 125))] - "TARGET_ALTIVEC" - "vsububs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubsbs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 126))] - "TARGET_ALTIVEC" - "vsubsbs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubuhs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 127))] - "TARGET_ALTIVEC" - "vsubuhs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 128))] - "TARGET_ALTIVEC" - "vsubshs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubuws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 129))] - "TARGET_ALTIVEC" - "vsubuws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 130))] - "TARGET_ALTIVEC" - "vsubsws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsum4ubs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 131))] - "TARGET_ALTIVEC" - "vsum4ubs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum4sbs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 132))] - "TARGET_ALTIVEC" - "vsum4sbs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum4shs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 133))] - "TARGET_ALTIVEC" - "vsum4shs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum2sws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 134))] - "TARGET_ALTIVEC" - "vsum2sws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsumsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 135))] - "TARGET_ALTIVEC" - "vsumsws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "xorv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (xor:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vxor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vspltb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 136))] - "TARGET_ALTIVEC" - "vspltb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsplth" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 137))] - "TARGET_ALTIVEC" - "vsplth %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 138))] - "TARGET_ALTIVEC" - "vspltw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltisb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")] 139))] - "TARGET_ALTIVEC" - "vspltisb %0, %1" - [(set_attr "type" "vecsimple")]) - - -(define_insn "altivec_vspltish" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")] 140))] - "TARGET_ALTIVEC" - "vspltish %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vspltisw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")] 141))] - "TARGET_ALTIVEC" - "vspltisw %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:QI 1 "immediate_operand" "i")] 142))] - "TARGET_ALTIVEC" - "vspltisw %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "ftruncv4sf2" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vrfiz %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vperm_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 144))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 145))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 146))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 147))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vrfip" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 148))] - "TARGET_ALTIVEC" - "vrfip %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrfin" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 149))] - "TARGET_ALTIVEC" - "vrfin %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrfim" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 150))] - "TARGET_ALTIVEC" - "vrfim %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfux" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 151))] - "TARGET_ALTIVEC" - "vcfux %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfsx" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 152))] - "TARGET_ALTIVEC" - "vcfsx %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctuxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 153))] - "TARGET_ALTIVEC" - "vctuxs %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctsxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 154))] - "TARGET_ALTIVEC" - "vctsxs %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vlogefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 155))] - "TARGET_ALTIVEC" - "vlogefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vexptefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 156))] - "TARGET_ALTIVEC" - "vexptefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrsqrtefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 157))] - "TARGET_ALTIVEC" - "vrsqrtefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 158))] - "TARGET_ALTIVEC" - "vrefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vsel_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 159))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 160))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 161))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 162))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 163))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 164))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 165))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 166))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhsb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 167))] - "TARGET_ALTIVEC" - "vupkhsb %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhpx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 168))] - "TARGET_ALTIVEC" - "vupkhpx %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhsh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 169))] - "TARGET_ALTIVEC" - "vupkhsh %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklsb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 170))] - "TARGET_ALTIVEC" - "vupklsb %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklpx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 171))] - "TARGET_ALTIVEC" - "vupklpx %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklsh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 172))] - "TARGET_ALTIVEC" - "vupklsh %0, %1" - [(set_attr "type" "vecperm")]) - -;; AltiVec predicates. - -(define_expand "cr6_test_for_zero" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC" - "") - -(define_expand "cr6_test_for_zero_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" - "") - -(define_expand "cr6_test_for_lt" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC" - "") - -(define_expand "cr6_test_for_lt_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" - "") - -;; We can get away with generating the opcode on the fly (%3 below) -;; because all the predicates have the same scheduling parameters. - -(define_insn "altivec_predicate_v4si" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 173)) - (clobber (match_scratch:V4SI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v4sf" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 174)) - (clobber (match_scratch:V4SF 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v8hi" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 175)) - (clobber (match_scratch:V8HI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v16qi" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 175)) - (clobber (match_scratch:V16QI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_mtvscr" - [(unspec [(match_operand:V4SI 0 "register_operand" "v")] 186)] - "TARGET_ALTIVEC" - "mtvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_mfvscr" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(const_int 0)] 187))] - "TARGET_ALTIVEC" - "mfvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dssall" - [(unspec [(const_int 0)] 188)] - "TARGET_ALTIVEC" - "dssall" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dss" - [(unspec [(match_operand:QI 0 "immediate_operand" "i")] 189)] - "TARGET_ALTIVEC" - "dss %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dst" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 190)] - "TARGET_ALTIVEC" - "dst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstt" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 191)] - "TARGET_ALTIVEC" - "dstt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstst" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 192)] - "TARGET_ALTIVEC" - "dstst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dststt" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 193)] - "TARGET_ALTIVEC" - "dststt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_lvsl" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")] 194))] - "TARGET_ALTIVEC" - "lvsl %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvsr" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")] 195))] - "TARGET_ALTIVEC" - "lvsr %0,%1,%2" - [(set_attr "type" "vecload")]) - -;; Parallel some of the LVE* and STV*'s with unspecs because some have -;; identical rtl but different instructions-- and gcc gets confused. - -(define_insn "altivec_lvebx" - [(parallel - [(set (match_operand:V16QI 0 "register_operand" "=v") - (mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")))) - (unspec [(const_int 0)] 196)])] - "TARGET_ALTIVEC" - "lvebx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvehx" - [(parallel - [(set (match_operand:V8HI 0 "register_operand" "=v") - (mem:V8HI - (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -2)))) - (unspec [(const_int 0)] 197)])] - "TARGET_ALTIVEC" - "lvehx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvewx" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI - (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -4)))) - (unspec [(const_int 0)] 198)])] - "TARGET_ALTIVEC" - "lvewx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvxl" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")))) - (unspec [(const_int 0)] 213)])] - "TARGET_ALTIVEC" - "lvxl %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_ALTIVEC" - "lvx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_stvx" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -16))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 201)])] - "TARGET_ALTIVEC" - "stvx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvxl" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -16))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 202)])] - "TARGET_ALTIVEC" - "stvxl %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvebx" - [(parallel - [(set (mem:V16QI - (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r"))) - (match_operand:V16QI 2 "register_operand" "v")) - (unspec [(const_int 0)] 203)])] - "TARGET_ALTIVEC" - "stvebx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvehx" - [(parallel - [(set (mem:V8HI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -2))) - (match_operand:V8HI 2 "register_operand" "v")) - (unspec [(const_int 0)] 204)])] - "TARGET_ALTIVEC" - "stvehx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvewx" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -4))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 205)])] - "TARGET_ALTIVEC" - "stvewx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "absv16qi2" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (abs:V16QI (match_operand:V16QI 1 "register_operand" "v"))) - (clobber (match_scratch:V16QI 2 "=v")) - (clobber (match_scratch:V16QI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsububm %3,%2,%1\;vmaxsb %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv8hi2" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (abs:V8HI (match_operand:V8HI 1 "register_operand" "v"))) - (clobber (match_scratch:V8HI 2 "=v")) - (clobber (match_scratch:V8HI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubuhm %3,%2,%1\;vmaxsh %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv4si2" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (abs:V4SI (match_operand:V4SI 1 "register_operand" "v"))) - (clobber (match_scratch:V4SI 2 "=v")) - (clobber (match_scratch:V4SI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubuwm %3,%2,%1\;vmaxsw %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv4sf2" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (abs:V4SF (match_operand:V4SF 1 "register_operand" "v"))) - (clobber (match_scratch:V4SF 2 "=v")) - (clobber (match_scratch:V4SF 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisw %2, -1\;vslw %3,%2,%2\;vandc %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "altivec_abss_v16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 210)) - (clobber (match_scratch:V16QI 2 "=v")) - (clobber (match_scratch:V16QI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubsbs %3,%2,%1\;vmaxsb %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "altivec_abss_v8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")] 211)) - (clobber (match_scratch:V8HI 2 "=v")) - (clobber (match_scratch:V8HI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubshs %3,%2,%1\;vmaxsh %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) -(define_insn "altivec_abss_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")] 212)) - (clobber (match_scratch:V4SI 2 "=v")) - (clobber (match_scratch:V4SI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) +(include "sync.md") +(include "altivec.md") +(include "spe.md") +(include "dfp.md") +(include "paired.md")