;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GCC. ;; GCC is free software; you can redistribute it and/or modify it ;; under the terms of the GNU General Public License as published ;; by the Free Software Foundation; either version 2, or (at your ;; option) any later version. ;; GCC is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ;; License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING. If not, write to the ;; Free Software Foundation, 59 Temple Place - Suite 330, Boston, ;; MA 02111-1307, USA. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ;; ;; UNSPEC usage ;; (define_constants [(UNSPEC_FRSP 0) ; frsp for POWER machines (UNSPEC_TIE 5) ; tie stack contents and stack pointer (UNSPEC_TOCPTR 6) ; address of a word pointing to the TOC (UNSPEC_TOC 7) ; address of the TOC (more-or-less) (UNSPEC_MOVSI_GOT 8) (UNSPEC_MV_CR_OV 9) ; move_from_CR_ov_bit (UNSPEC_FCTIWZ 10) (UNSPEC_LD_MPIC 15) ; load_macho_picbase (UNSPEC_MPIC_CORRECT 16) ; macho_correct_pic (UNSPEC_TLSGD 17) (UNSPEC_TLSLD 18) (UNSPEC_MOVESI_FROM_CR 19) (UNSPEC_MOVESI_TO_CR 20) (UNSPEC_TLSDTPREL 21) (UNSPEC_TLSDTPRELHA 22) (UNSPEC_TLSDTPRELLO 23) (UNSPEC_TLSGOTDTPREL 24) (UNSPEC_TLSTPREL 25) (UNSPEC_TLSTPRELHA 26) (UNSPEC_TLSTPRELLO 27) (UNSPEC_TLSGOTTPREL 28) (UNSPEC_TLSTLS 29) (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero (UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit ]) ;; ;; UNSPEC_VOLATILE usage ;; (define_constants [(UNSPECV_BLOCK 0) (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,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,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" (const_string "integer")) ;; Length (in bytes). ; '(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") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -32768)) (lt (minus (match_dup 0) (pc)) (const_int 32764))) (const_int 4) (const_int 8)) (const_int 4))) ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,cellppu,power4,power5" (const (symbol_ref "rs6000_cpu_attr"))) ;; not microcode, conditional microcode, microcode (define_attr "microcode" "nmc, cmc, mc" (const_string "nmc")) (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 "dd2.md") ;;(include "cellppu.md") (include "power4.md") (include "power5.md") ;; 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" [(set (match_operand:DI 0 "gpc_reg_operand" "") (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))] "TARGET_POWERPC64" "") (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] "TARGET_POWERPC64" "@ lbz%U1%X1 %0,%1 rldicl %0,%1,0,56" [(set_attr "type" "load,*")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:DI 2 "=r,r"))] "TARGET_64BIT" "@ rldicl. %2,%1,0,56 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:DI (match_operand:QI 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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:DI (match_operand:QI 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_64BIT" "@ rldicl. %0,%1,0,56 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (zero_extend:DI (match_operand:QI 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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_insn "extendqidi2" [(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") (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_64BIT" "@ extsb. %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:DI 2 ""))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 2) (sign_extend:DI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_64BIT" "@ extsb. %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (sign_extend:DI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (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_64BIT" "@ rldicl. %2,%1,0,48 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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_64BIT" "@ rldicl. %0,%1,0,48 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendhidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] "TARGET_POWERPC64" "") (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))] "TARGET_POWERPC64" "extsh %0,%1" [(set_attr "type" "integer")]) (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_POWERPC64 && rs6000_gen_microcode" "lha%U1%X1 %0,%1" [(set_attr "type" "load_ext") (set_attr "microcode" "mc")]) (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_64BIT" "@ extsh. %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_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) (sign_extend:DI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_64BIT" "@ extsh. %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (sign_extend:DI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (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_64BIT" "@ rldicl. %2,%1,0,32 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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_64BIT" "@ rldicl. %0,%1,0,32 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendsidi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] "TARGET_POWERPC64" "") (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (sign_extend:DI (match_operand:SI 1 "lwa_mem_operand" "m")))] "TARGET_POWERPC64 && rs6000_gen_microcode" "lwa%U1%X1 %0,%1" [(set_attr "type" "load_ext") (set_attr "microcode" "mc")]) (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))] "TARGET_POWERPC64" "extsw %0,%1") (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_64BIT" "@ extsw. %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_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) (sign_extend:DI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (sign_extend:DI (match_dup 1)))] "TARGET_64BIT" "@ extsw. %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") (sign_extend:DI (match_dup 1)))] "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (sign_extend:DI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))] "" "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] "" "@ lbz%U1%X1 %0,%1 {rlinm|rlwinm} %0,%1,0,0xff" [(set_attr "type" "load,*")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "" "@ {andil.|andi.} %2,%1,0xff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "reload_completed" [(set (match_dup 2) (zero_extend:SI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_dup 1)))] "" "@ {andil.|andi.} %0,%1,0xff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (match_dup 1)))] "reload_completed" [(set (match_dup 0) (zero_extend:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendqisi2" [(use (match_operand:SI 0 "gpc_reg_operand" "")) (use (match_operand:QI 1 "gpc_reg_operand" ""))] "" " { if (TARGET_POWERPC) emit_insn (gen_extendqisi2_ppc (operands[0], operands[1])); else if (TARGET_POWER) emit_insn (gen_extendqisi2_power (operands[0], operands[1])); else emit_insn (gen_extendqisi2_no_power (operands[0], operands[1])); DONE; }") (define_insn "extendqisi2_ppc" [(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") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "TARGET_POWERPC" "@ extsb. %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "TARGET_POWERPC && reload_completed" [(set (match_dup 2) (sign_extend:SI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (sign_extend:SI (match_dup 1)))] "TARGET_POWERPC" "@ extsb. %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (sign_extend:SI (match_dup 1)))] "TARGET_POWERPC && reload_completed" [(set (match_dup 0) (sign_extend:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendqisi2_power" [(parallel [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") (const_int 24))) (clobber (scratch:SI))]) (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24))) (clobber (scratch:SI))])] "TARGET_POWER" " { operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }") (define_expand "extendqisi2_no_power" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") (const_int 24))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] "! TARGET_POWER && ! TARGET_POWERPC" " { operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }") (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "gpc_reg_operand" "") (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))] "" "") (define_insn "" [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r") (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] "" "@ lbz%U1%X1 %0,%1 {rlinm|rlwinm} %0,%1,0,0xff" [(set_attr "type" "load,*")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:HI 2 "=r,r"))] "" "@ {andil.|andi.} %2,%1,0xff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:HI 2 ""))] "reload_completed" [(set (match_dup 2) (zero_extend:HI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") (zero_extend:HI (match_dup 1)))] "" "@ {andil.|andi.} %0,%1,0xff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "") (zero_extend:HI (match_dup 1)))] "reload_completed" [(set (match_dup 0) (zero_extend:HI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendqihi2" [(use (match_operand:HI 0 "gpc_reg_operand" "")) (use (match_operand:QI 1 "gpc_reg_operand" ""))] "" " { if (TARGET_POWERPC) emit_insn (gen_extendqihi2_ppc (operands[0], operands[1])); else if (TARGET_POWER) emit_insn (gen_extendqihi2_power (operands[0], operands[1])); else emit_insn (gen_extendqihi2_no_power (operands[0], operands[1])); DONE; }") (define_insn "extendqihi2_ppc" [(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") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:HI 2 "=r,r"))] "TARGET_POWERPC" "@ extsb. %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:HI 2 ""))] "TARGET_POWERPC && reload_completed" [(set (match_dup 2) (sign_extend:HI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") (sign_extend:HI (match_dup 1)))] "TARGET_POWERPC" "@ extsb. %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:HI 0 "gpc_reg_operand" "") (sign_extend:HI (match_dup 1)))] "TARGET_POWERPC && reload_completed" [(set (match_dup 0) (sign_extend:HI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendqihi2_power" [(parallel [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") (const_int 24))) (clobber (scratch:SI))]) (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24))) (clobber (scratch:SI))])] "TARGET_POWER" " { operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }") (define_expand "extendqihi2_no_power" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") (const_int 24))) (set (match_operand:HI 0 "gpc_reg_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] "! TARGET_POWER && ! TARGET_POWERPC" " { operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }") (define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] "" "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] "" "@ lhz%U1%X1 %0,%1 {rlinm|rlwinm} %0,%1,0,0xffff" [(set_attr "type" "load,*")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "" "@ {andil.|andi.} %2,%1,0xffff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "reload_completed" [(set (match_dup 2) (zero_extend:SI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (match_dup 1)))] "" "@ {andil.|andi.} %0,%1,0xffff #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (match_dup 1)))] "reload_completed" [(set (match_dup 0) (zero_extend:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") (define_expand "extendhisi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] "" "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))] "" "{exts|extsh} %0,%1" [(set_attr "type" "integer")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "rs6000_gen_microcode" "lha%U1%X1 %0,%1" [(set_attr "type" "load_ext") (set_attr "microcode" "mc")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "" "@ {exts.|extsh.} %2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "reload_completed" [(set (match_dup 2) (sign_extend:SI (match_dup 1))) (set (match_dup 0) (compare:CC (match_dup 2) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (sign_extend:SI (match_dup 1)))] "" "@ {exts.|extsh.} %0,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 2 "cc_reg_operand" "") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (sign_extend:SI (match_dup 1)))] "reload_completed" [(set (match_dup 0) (sign_extend:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[2], CCmode)) FAIL;") ;; 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" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT && ! add_operand (operands[2], SImode)) { rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (SImode)); HOST_WIDE_INT val = INTVAL (operands[2]); HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); /* 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))); 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")))] "" "@ {cax|add} %0,%1,%2 {cal %0,%2(%1)|addi %0,%1,%2} {ai|addic} %0,%1,%2 {cau|addis} %0,%1,%v2" [(set_attr "length" "4,4,4,4")]) (define_insn "addsi3_high" [(set (match_operand:SI 0 "gpc_reg_operand" "=b") (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") (high:SI (match_operand 2 "" ""))))] "TARGET_MACHO && !TARGET_64BIT" "{cau|addis} %0,%1,ha16(%2)" [(set_attr "length" "4")]) (define_insn "*addsi3_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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r,r,r"))] "TARGET_32BIT" "@ {cax.|add.} %3,%1,%2 {ai.|addic.} %3,%1,%2 # #" [(set_attr "type" "fast_compare,compare,compare,compare") (set_attr "microcode" "mc,mc,*,*") (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" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "TARGET_32BIT && reload_completed" [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "*addsi3_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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "@ {cax.|add.} %0,%1,%2 {ai.|addic.} %0,%1,%2 # #" [(set_attr "type" "fast_compare,compare,compare,compare") (set_attr "microcode" "mc,mc,*,*") (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" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT && reload_completed" [(set (match_dup 0) (plus:SI (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:SI 0 "gpc_reg_operand" "") (plus:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 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)))] " { HOST_WIDE_INT val = INTVAL (operands[2]); HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); operands[3] = GEN_INT (rest); operands[4] = GEN_INT (low); }") (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (match_operand:SI 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")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "TARGET_32BIT" "@ nor. %2,%1,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "TARGET_32BIT && reload_completed" [(set (match_dup 2) (not:SI (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 (not:SI (match_operand:SI 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_32BIT" "@ nor. %0,%1,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (not:SI (match_dup 1)))] "TARGET_32BIT && reload_completed" [(set (match_dup 0) (not:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI") (match_operand:SI 2 "gpc_reg_operand" "r")))] "! TARGET_POWERPC" "{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")))] "TARGET_POWERPC" "@ subf %0,%2,%1 subfic %0,%2,%1") (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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWERPC" "@ {sf.|subfc.} %3,%2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_POWERPC && TARGET_32BIT" "@ subf. %3,%2,%1 #" [(set_attr "type" "fast_compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "TARGET_32BIT && reload_completed" [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) (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 (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (minus:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWERPC" "@ {sf.|subfc.} %0,%2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (minus:SI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC && TARGET_32BIT" "@ subf. %0,%2,%1 #" [(set_attr "type" "fast_compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT && reload_completed" [(set (match_dup 0) (minus:SI (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" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT) { emit_insn (gen_addsi3 (operands[0], operands[1], negate_rtx (SImode, operands[2]))); DONE; } }") ;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i] ;; instruction and some auxiliary computations. Then we just have a single ;; DEFINE_INSN for doz[i] and the define_splits to make them if made by ;; combine. (define_expand "sminsi3" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" "")) (const_int 0) (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_ISEL" " { 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" "") (smin:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] "TARGET_POWER" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1)))) (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))] "") (define_expand "smaxsi3" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" "")) (const_int 0) (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_ISEL" " { 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" "") (smax:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] "TARGET_POWER" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1)))) (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))] "") (define_expand "uminsi3" [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_dup 5))) (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "") (match_dup 5))) (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4)) (const_int 0) (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_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); }") (define_expand "umaxsi3" [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_dup 5))) (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "") (match_dup 5))) (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4)) (const_int 0) (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_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); }") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] "TARGET_POWER" "doz%I2 %0,%1,%2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_POWER" "@ doz%I2. %3,%1,%2 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" "")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "TARGET_POWER && reload_completed" [(set (match_dup 3) (if_then_else:SI (gt (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1)))) (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 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (if_then_else:SI (gt (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] "TARGET_POWER" "@ doz%I2. %0,%1,%2 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_short_operand" "")) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (if_then_else:SI (gt (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] "TARGET_POWER && reload_completed" [(set (match_dup 0) (if_then_else:SI (gt (match_dup 1) (match_dup 2)) (const_int 0) (minus:SI (match_dup 2) (match_dup 1)))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") ;; We don't need abs with condition code because such comparisons should ;; never be done. (define_expand "abssi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))] "" " { 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" [(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_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"))) (clobber (match_scratch:SI 2 "=&r,&r"))] "! 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)))] "") (define_insn "*nabs_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))] "TARGET_POWER" "nabs %0,%1") (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")))) (clobber (match_scratch:SI 2 "=&r,&r"))] "! TARGET_POWER" "#" "&& 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")))] "" "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")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] "TARGET_32BIT" "@ neg. %2,%1 #" [(set_attr "type" "fast_compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] "TARGET_32BIT && reload_completed" [(set (match_dup 2) (neg:SI (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 (neg:SI (match_operand:SI 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_32BIT" "@ neg. %0,%1 #" [(set_attr "type" "fast_compare") (set_attr "microcode" "mc,*") (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" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (neg:SI (match_dup 1)))] "TARGET_32BIT && reload_completed" [(set (match_dup 0) (neg:SI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "clzsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (clz:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] "" "{cntlz|cntlzw} %0,%1") (define_expand "ctzsi2" [(set (match_dup 2) (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (parallel [(set (match_dup 3) (and:SI (match_dup 1) (match_dup 2))) (clobber (scratch:CC))]) (set (match_dup 4) (clz:SI (match_dup 3))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (minus:SI (const_int 31) (match_dup 4)))] "" { operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }) (define_expand "ffssi2" [(set (match_dup 2) (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (parallel [(set (match_dup 3) (and:SI (match_dup 1) (match_dup 2))) (clobber (scratch:CC))]) (set (match_dup 4) (clz:SI (match_dup 3))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (minus:SI (const_int 32) (match_dup 4)))] "" { operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }) (define_expand "mulsi3" [(use (match_operand:SI 0 "gpc_reg_operand" "")) (use (match_operand:SI 1 "gpc_reg_operand" "")) (use (match_operand:SI 2 "reg_or_short_operand" ""))] "" " { if (TARGET_POWER) emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2])); else emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2])); DONE; }") (define_insn "mulsi3_mq" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") (match_operand:SI 2 "reg_or_short_operand" "r,I"))) (clobber (match_scratch:SI 3 "=q,q"))] "TARGET_POWER" "@ {muls|mullw} %0,%1,%2 {muli|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 "imul")))]) (define_insn "mulsi3_no_mq" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") (match_operand:SI 2 "reg_or_short_operand" "r,I")))] "! TARGET_POWER" "@ {muls|mullw} %0,%1,%2 {muli|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 "imul")))]) (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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,q"))] "TARGET_POWER" "@ {muls.|mullw.} %3,%1,%2 #" [(set_attr "type" "imul_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (mult: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:SI 4 ""))] "TARGET_POWER && reload_completed" [(parallel [(set (match_dup 3) (mult: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 "*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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWER" "@ {muls.|mullw.} %3,%1,%2 #" [(set_attr "type" "imul_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "! TARGET_POWER && reload_completed" [(set (match_dup 3) (mult:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,q"))] "TARGET_POWER" "@ {muls.|mullw.} %0,%1,%2 #" [(set_attr "type" "imul_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC (mult: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" "") (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 ""))] "TARGET_POWER && reload_completed" [(parallel [(set (match_dup 0) (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_dup 4))]) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") (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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER" "@ {muls.|mullw.} %0,%1,%2 #" [(set_attr "type" "imul_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_operand" "") (compare:CC (mult: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" "") (mult:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER && reload_completed" [(set (match_dup 0) (mult:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") ;; Operand 1 is divided by operand 2; quotient goes to operand ;; 0 and remainder to operand 3. ;; ??? At some point, see what, if anything, we can do about if (x % y == 0). (define_expand "divmodsi4" [(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 "register_operand" "") (mod:SI (match_dup 1) (match_dup 2)))])] "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)" " { if (! TARGET_POWER && ! TARGET_POWERPC) { emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); emit_insn (gen_divss_call ()); emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); emit_move_insn (operands[3], gen_rtx_REG (SImode, 4)); DONE; } }") (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 "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" "")))] "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)" " { if (! TARGET_POWER && ! TARGET_POWERPC) { emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); emit_insn (gen_quous_call ()); emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); DONE; } else if (TARGET_POWER) { emit_insn (gen_udivsi3_mq (operands[0], operands[1], operands[2])); DONE; } }") (define_insn "udivsi3_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"))) (clobber (match_scratch:SI 3 "=q"))] "TARGET_POWERPC && TARGET_POWER" "divwu %0,%1,%2" [(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")))] "TARGET_POWERPC && ! TARGET_POWER" "divwu %0,%1,%2" [(set_attr "type" "idiv")]) ;; 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" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0 && exact_log2 (INTVAL (operands[2])) >= 0) ; else if (TARGET_POWERPC) { operands[2] = force_reg (SImode, operands[2]); if (TARGET_POWER) { emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2])); DONE; } } else if (TARGET_POWER) FAIL; else { emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); emit_insn (gen_quoss_call ()); emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); DONE; } }") (define_insn "divsi3_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"))) (clobber (match_scratch:SI 3 "=q"))] "TARGET_POWERPC && TARGET_POWER" "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")))] "TARGET_POWERPC && ! TARGET_POWER" "divw %0,%1,%2" [(set_attr "type" "idiv")]) (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" ""))] "" " { 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 (SImode); temp2 = gen_reg_rtx (SImode); 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)); 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")))] "" "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0" [(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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "" "@ {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3 #" [(set_attr "type" "compare") (set_attr "length" "8,12")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "exact_log2_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "reload_completed" [(set (match_dup 3) (div:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (div:SI (match_dup 1) (match_dup 2)))] "" "@ {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "8,12")]) (define_split [(set (match_operand:CC 3 "cc_reg_operand" "") (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "exact_log2_cint_operand" "")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (div:SI (match_dup 1) (match_dup 2)))] "reload_completed" [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) (const_int 32)) (zero_extend:DI (match_operand:SI 4 "register_operand" "2"))) (match_operand:SI 3 "gpc_reg_operand" "r"))) (set (match_operand:SI 2 "register_operand" "=*q") (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)) (zero_extend:DI (match_dup 4))) (match_dup 3)))] "TARGET_POWER" "div %0,%1,%3" [(set_attr "type" "idiv")]) ;; To do unsigned divide we handle the cases of the divisor looking like a ;; negative number. If it is a constant that is less than 2**31, we don't ;; have to worry about the branches. So make a few subroutines here. ;; ;; First comes the normal case. (define_expand "udivmodsi4_normal" [(set (match_dup 4) (const_int 0)) (parallel [(set (match_operand:SI 0 "" "") (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4)) (const_int 32)) (zero_extend:DI (match_operand:SI 1 "" ""))) (match_operand:SI 2 "" ""))) (set (match_operand:SI 3 "" "") (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4)) (const_int 32)) (zero_extend:DI (match_dup 1))) (match_dup 2)))])] "TARGET_POWER" " { operands[4] = gen_reg_rtx (SImode); }") ;; This handles the branches. (define_expand "udivmodsi4_tests" [(set (match_operand:SI 0 "" "") (const_int 0)) (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" "")) (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" ""))) (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0)) (label_ref (match_operand:SI 4 "" "")) (pc))) (set (match_dup 0) (const_int 1)) (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0))) (set (pc) (if_then_else (lt (match_dup 6) (const_int 0)) (label_ref (match_dup 4)) (pc)))] "TARGET_POWER" " { operands[5] = gen_reg_rtx (CCUNSmode); operands[6] = gen_reg_rtx (CCmode); }") (define_expand "udivmodsi4" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" ""))) (set (match_operand:SI 3 "gpc_reg_operand" "") (umod:SI (match_dup 1) (match_dup 2)))])] "" " { rtx label = 0; if (! TARGET_POWER) { if (! TARGET_POWERPC) { emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]); emit_insn (gen_divus_call ()); emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); emit_move_insn (operands[3], gen_rtx_REG (SImode, 4)); DONE; } else FAIL; } if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0) { operands[2] = force_reg (SImode, operands[2]); label = gen_label_rtx (); emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2], operands[3], label)); } else operands[2] = force_reg (SImode, operands[2]); emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2], operands[3])); if (label) emit_label (label); DONE; }") ;; AIX architecture-independent common-mode multiply (DImode), ;; divide/modulus, and quotient subroutine calls. Input operands in R3 and ;; R4; results in R3 and sometimes R4; link register always clobbered by bla ;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but ;; assumed unused if generating common-mode, so ignore. (define_insn "mulh_call" [(set (reg:SI 3) (truncate:SI (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"))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __mulh" [(set_attr "type" "imul")]) (define_insn "mull_call" [(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 0))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __mull" [(set_attr "type" "imul")]) (define_insn "divss_call" [(set (reg:SI 3) (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 0))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __divss" [(set_attr "type" "idiv")]) (define_insn "divus_call" [(set (reg:SI 3) (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 0)) (clobber (match_scratch:CC 1 "=x")) (clobber (reg:CC 69))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __divus" [(set_attr "type" "idiv")]) (define_insn "quoss_call" [(set (reg:SI 3) (div:SI (reg:SI 3) (reg:SI 4))) (clobber (match_scratch:SI 0 "=l"))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __quoss" [(set_attr "type" "idiv")]) (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 0)) (clobber (match_scratch:CC 1 "=x")) (clobber (reg:CC 69))] "! TARGET_POWER && ! TARGET_POWERPC" "bla __quous" [(set_attr "type" "idiv")]) ;; Logical instructions ;; The logical instructions are mostly combined by using match_operator, ;; but the plain AND insns are somewhat different because there is no ;; 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" [(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"))] "" "@ and %0,%1,%2 {rlinm|rlwinm} %0,%1,0,%m2,%M2 {andil.|andi.} %0,%1,%b2 {andiu.|andis.} %0,%1,%u2" [(set_attr "microcode" "*,*,mc,mc")]) ;; Note to set cr's other than cr0 we do the and immediate and then ;; the test again -- this avoids a mfcr which on the higher end ;; machines causes an execution serialization (define_insn "*andsi3_internal2" [(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_32BIT" "@ and. %3,%1,%2 {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 "microcode" "mc,mc,mc,mc,*,*,*,*") (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_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 "microcode" "*,mc,mc,mc,*,*,*,*") (set_attr "length" "8,4,4,4,8,8,8,8")]) (define_insn "*andsi3_internal3_nomc" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y,??y,??y,?y") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (match_operand:SI 2 "and_operand" "r,r,K,L,T")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r,r,r,r")) (clobber (match_scratch:CC 4 "=X,X,x,x,X"))] "TARGET_64BIT && !rs6000_gen_microcode" "#" [(set_attr "type" "compare") (set_attr "length" "8,8,8,8,8")]) ;; 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_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "and_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:CC 4 ""))] "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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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_32BIT" "@ and. %0,%1,%2 {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 "microcode" "mc,mc,mc,mc,*,*,*,*") (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_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 "microcode" "*,mc,mc,mc,*,*,*,*") (set_attr "length" "8,4,4,4,8,8,8,8")]) (define_insn "*andsi3_internal5_nomc" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,??y,??y,?y") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (match_operand:SI 2 "and_operand" "r,r,K,L,T")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 "=X,X,x,x,X"))] "TARGET_64BIT && !rs6000_gen_microcode" "#" [(set_attr "type" "compare") (set_attr "length" "8,8,8,8,8")]) (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))) (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 "and_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 ""))] "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)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") ;; 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_insn_and_split "*andsi3_internal7" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") (compare:CC (and:SI (match_operand:SI 0 "gpc_reg_operand" "r,r") (match_operand:SI 1 "mask_operand_wrap" "i,i")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_POWERPC64" "#" "TARGET_POWERPC64" [(parallel [(set (match_dup 2) (compare:CC (and:SI (rotate:SI (match_dup 0) (match_dup 4)) (match_dup 5)) (const_int 0))) (clobber (match_dup 3))])] " { int mb = extract_MB (operands[1]); int me = extract_ME (operands[1]); operands[4] = GEN_INT (me + 1); operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); }" [(set_attr "type" "delayed_compare,compare") (set_attr "length" "4,8")]) (define_insn_and_split "*andsi3_internal8" [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "mask_operand_wrap" "i,i")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" "#" "TARGET_POWERPC64" [(parallel [(set (match_dup 3) (compare:CC (and:SI (rotate:SI (match_dup 1) (match_dup 4)) (match_dup 5)) (const_int 0))) (set (match_dup 0) (and:SI (rotate:SI (match_dup 1) (match_dup 4)) (match_dup 5)))]) (set (match_dup 0) (rotate:SI (match_dup 0) (match_dup 6)))] " { int mb = extract_MB (operands[2]); int me = extract_ME (operands[2]); operands[4] = GEN_INT (me + 1); operands[6] = GEN_INT (32 - (me + 1)); operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); }" [(set_attr "type" "delayed_compare,compare") (set_attr "length" "8,12")]) (define_expand "iorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_logical_cint_operand" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT && ! logical_operand (operands[2], SImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (SImode)); emit_insn (gen_iorsi3 (tmp, operands[1], GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } }") (define_expand "xorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_logical_cint_operand" "")))] "" " { if (GET_CODE (operands[2]) == CONST_INT && ! logical_operand (operands[2], SImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (SImode)); emit_insn (gen_xorsi3 (tmp, operands[1], GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } }") (define_insn "*boolsi3_internal1" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (match_operator:SI 3 "boolean_or_operator" [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r") (match_operand:SI 2 "logical_operand" "r,K,L")]))] "" "@ %q3 %0,%1,%2 {%q3il|%q3i} %0,%1,%b2 {%q3iu|%q3is} %0,%1,%u2") (define_insn "*boolsi3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_or_operator" [(match_operand:SI 1 "gpc_reg_operand" "%r,r") (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_32BIT" "@ %q4. %3,%1,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "*boolsi3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_operator" [(match_operand:SI 1 "gpc_reg_operand" "%r,r") (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] "TARGET_32BIT" "@ %q4. %0,%1,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") ;; Split a logical operation that we can't do in one insn into two insns, ;; each of which does one 16-bit part. This is used by combine. (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (match_operator:SI 3 "boolean_or_operator" [(match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "non_logical_cint_operand" "")]))] "" [(set (match_dup 0) (match_dup 4)) (set (match_dup 0) (match_dup 5))] " { rtx i; i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); operands[4] = gen_rtx (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); }") (define_insn "*boolcsi3_internal1" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_operator:SI 3 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (match_operand:SI 2 "gpc_reg_operand" "r")]))] "" "%q3 %0,%2,%1") (define_insn "*boolcsi3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_32BIT" "@ %q4. %3,%2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "*boolcsi3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")) (match_operand:SI 2 "gpc_reg_operand" "r,r")]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] "TARGET_32BIT" "@ %q4. %0,%2,%1 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "*boolccsi3_internal1" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_operator:SI 3 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))]))] "" "%q3 %0,%1,%2") (define_insn "*boolccsi3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "TARGET_32BIT" "@ %q4. %3,%1,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "*boolccsi3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") (compare:CC (match_operator:SI 4 "boolean_operator" [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")) (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 4))] "TARGET_32BIT" "@ %q4. %0,%1,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_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_32BIT && reload_completed" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") ;; maskir insn. We need four forms because things might be in arbitrary ;; orders. Don't define forms that only set CR fields because these ;; would modify an input register. (define_insn "*maskir_internal1" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 1 "gpc_reg_operand" "0")) (and:SI (match_dup 2) (match_operand:SI 3 "gpc_reg_operand" "r"))))] "TARGET_POWER" "maskir %0,%3,%2") (define_insn "*maskir_internal2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")) (match_operand:SI 1 "gpc_reg_operand" "0")) (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_dup 2))))] "TARGET_POWER" "maskir %0,%3,%2") (define_insn "*maskir_internal3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r") (match_operand:SI 3 "gpc_reg_operand" "r")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] "TARGET_POWER" "maskir %0,%3,%2") (define_insn "*maskir_internal4" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] "TARGET_POWER" "maskir %0,%3,%2") (define_insn "*maskir_internal5" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) (match_operand:SI 1 "gpc_reg_operand" "0,0")) (and:SI (match_dup 2) (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3))))] "TARGET_POWER" "@ maskir. %0,%3,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) (match_operand:SI 1 "gpc_reg_operand" "")) (and:SI (match_dup 2) (match_operand:SI 3 "gpc_reg_operand" ""))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3))))] "TARGET_POWER && reload_completed" [(set (match_dup 0) (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3)))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "*maskir_internal6" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")) (match_operand:SI 1 "gpc_reg_operand" "0,0")) (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") (match_dup 2))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2))))] "TARGET_POWER" "@ maskir. %0,%3,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "")) (match_operand:SI 1 "gpc_reg_operand" "")) (and:SI (match_operand:SI 3 "gpc_reg_operand" "") (match_dup 2))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2))))] "TARGET_POWER && reload_completed" [(set (match_dup 0) (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2)))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "*maskir_internal7" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r,r") (match_operand:SI 3 "gpc_reg_operand" "r,r")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0,0"))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER" "@ maskir. %0,%3,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "") (match_operand:SI 3 "gpc_reg_operand" "")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" ""))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER && reload_completed" [(set (match_dup 0) (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1)))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") (define_insn "*maskir_internal8" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r") (match_operand:SI 2 "gpc_reg_operand" "r,r")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0,0"))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER" "@ maskir. %0,%3,%2 #" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "") (match_operand:SI 2 "gpc_reg_operand" "")) (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" ""))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] "TARGET_POWER && reload_completed" [(set (match_dup 0) (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1)))) (set (match_dup 4) (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" [(set (zero_extract (match_operand 0 "gpc_reg_operand" "") (match_operand:SI 1 "const_int_operand" "") (match_operand:SI 2 "const_int_operand" "")) (match_operand 3 "gpc_reg_operand" ""))] "" " { /* 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. */ if (GET_CODE (operands[0]) == SUBREG && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) FAIL; if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode) emit_insn (gen_insvdi (operands[0], operands[1], operands[2], operands[3])); else emit_insn (gen_insvsi (operands[0], operands[1], operands[2], operands[3])); DONE; }") (define_insn "insvsi" [(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")) (match_operand:SI 3 "gpc_reg_operand" "r"))] "" "* { int start = INTVAL (operands[2]) & 31; int size = INTVAL (operands[1]) & 31; 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") (match_operand:SI 4 "const_int_operand" "i")))] "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" "* { int shift = INTVAL (operands[4]) & 31; int start = INTVAL (operands[2]) & 31; int size = INTVAL (operands[1]) & 31; 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") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) (ashiftrt: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])" "* { int shift = INTVAL (operands[4]) & 31; int start = INTVAL (operands[2]) & 31; int size = INTVAL (operands[1]) & 31; 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") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) (lshiftrt: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])" "* { int shift = INTVAL (operands[4]) & 31; int start = INTVAL (operands[2]) & 31; int size = INTVAL (operands[1]) & 31; 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") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_operand:SI 4 "const_int_operand" "i") (match_operand:SI 5 "const_int_operand" "i")))] "INTVAL (operands[4]) >= INTVAL (operands[1])" "* { int extract_start = INTVAL (operands[5]) & 31; int extract_size = INTVAL (operands[4]) & 31; int insert_start = INTVAL (operands[2]) & 31; int insert_size = INTVAL (operands[1]) & 31; /* Align extract field with insert field */ 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")]) (define_insn "insvdi" [(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")) (match_operand:DI 3 "gpc_reg_operand" "r"))] "TARGET_POWERPC64" "* { int start = INTVAL (operands[2]) & 63; int size = INTVAL (operands[1]) & 63; operands[1] = GEN_INT (64 - start - size); return \"rldimi %0,%3,%H1,%H2\"; }") (define_insn_and_split "insvdi_internal" [(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")) (match_operand:DI 3 "const_int_operand" "i")) (clobber (match_operand:DI 4 "gpc_reg_operand" "=&r"))] "TARGET_POWERPC64" "#" "" [(set (match_dup:DI 4) (match_dup:DI 3)) (set (zero_extract:DI (match_dup:DI 0) (match_dup:SI 1) (match_dup:SI 2)) (match_dup:DI 4))] "") (define_insn_and_split "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")) (lshiftrt:DI (match_operand:DI 3 "register_operand" "r") (match_operand:DI 4 "const_int_operand" "i"))) (clobber (match_operand:DI 5 "gpc_reg_operand" "=&r"))] "TARGET_POWERPC64" "#" "" [(set (match_dup:DI 5) (lshiftrt:DI (match_dup:DI 3) (match_dup:DI 4))) (set (zero_extract:DI (match_dup:DI 0) (match_dup:SI 1) (match_dup:SI 2)) (match_dup:DI 5))] "") (define_insn_and_split "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")) (zero_extract:DI (match_operand:DI 3 "gpc_reg_operand" "+r") (match_operand:SI 4 "const_int_operand" "i") (match_operand:SI 5 "const_int_operand" "i"))) (clobber (match_operand:DI 6 "gpc_reg_operand" "=&r"))] "TARGET_POWERPC64" "#" "" [(set (match_dup:DI 6) (zero_extract:DI (match_dup:DI 3) (match_dup:SI 4) (match_dup:SI 5))) (set (zero_extract:DI (match_dup:DI 0) (match_dup:SI 1) (match_dup:SI 2)) (match_dup:DI 6))] "") (define_insn_and_split "insvdi_internal4" [(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")) (and:DI (match_operand:DI 3 "register_operand" "r") (match_operand:DI 4 "const_int_operand" "i")))] "TARGET_POWERPC64 && (1 << INTVAL(operands[1])) - 1 == INTVAL(operands[4])" "#" "" [(set (zero_extract:DI (match_dup:DI 0) (match_dup:SI 1) (match_dup:SI 2)) (match_dup:DI 3))] "") (define_expand "extzv" [(set (match_operand 0 "gpc_reg_operand" "") (zero_extract (match_operand 1 "gpc_reg_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" "")))] "" " { /* 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. */ if (GET_CODE (operands[0]) == SUBREG && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) FAIL; if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode) emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], operands[3])); else emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], operands[3])); DONE; }") (define_insn "extzvsi" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "const_int_operand" "i")))] "" "* { int start = INTVAL (operands[3]) & 31; int size = INTVAL (operands[2]) & 31; if (start + size >= 32) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\"; }") (define_insn "*extzvsi_internal1" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i") (match_operand:SI 3 "const_int_operand" "i,i")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] "" "* { int start = INTVAL (operands[3]) & 31; int size = INTVAL (operands[2]) & 31; /* Force split for non-cc0 compare. */ if (which_alternative == 1) return \"#\"; /* 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 position is 0 because the LT and GT bits may be set wrong. */ if ((start > 0 && start + size <= 16) || start >= 16) { operands[3] = GEN_INT (((1 << (16 - (start & 15))) - (1 << (16 - (start & 15) - size)))); if (start < 16) return \"{andiu.|andis.} %4,%1,%3\"; else return \"{andil.|andi.} %4,%1,%3\"; } if (start + size >= 32) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\"; }" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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 ""))] "reload_completed" [(set (match_dup 4) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "*extzvsi_internal2" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i") (match_operand:SI 3 "const_int_operand" "i,i")) (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)))] "" "* { int start = INTVAL (operands[3]) & 31; int size = INTVAL (operands[2]) & 31; /* Force split for non-cc0 compare. */ 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 << size) - 1); return \"{andil.|andi.} %0,%1,%3\"; } if (start + size >= 32) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\"; }" [(set_attr "type" "compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_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)))] "reload_completed" [(set (match_dup 0) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[4], CCmode)) FAIL;") (define_insn "extzvdi" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "const_int_operand" "i")))] "TARGET_POWERPC64" "* { int start = INTVAL (operands[3]) & 63; int size = INTVAL (operands[2]) & 63; if (start + size >= 64) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl %0,%1,%3,%2\"; }") (define_insn "*extzvdi_internal1" [(set (match_operand:CC 0 "gpc_reg_operand" "=x") (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "const_int_operand" "i")) (const_int 0))) (clobber (match_scratch:DI 4 "=r"))] "TARGET_64BIT && rs6000_gen_microcode" "* { int start = INTVAL (operands[3]) & 63; int size = INTVAL (operands[2]) & 63; if (start + size >= 64) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl. %4,%1,%3,%2\"; }" [(set_attr "microcode" "mc")]) (define_insn "*extzvdi_internal2" [(set (match_operand:CC 4 "gpc_reg_operand" "=x") (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "const_int_operand" "i")) (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_64BIT && rs6000_gen_microcode" "* { int start = INTVAL (operands[3]) & 63; int size = INTVAL (operands[2]) & 63; if (start + size >= 64) operands[3] = const0_rtx; else operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl. %0,%1,%3,%2\"; }" [(set_attr "microcode" "mc")]) (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")))] "" "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") (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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "" "@ {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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 ""))] "reload_completed" [(set (match_dup 3) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (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")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (rotate:SI (match_dup 1) (match_dup 2)))] "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_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)))] "reload_completed" [(set (match_dup 0) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") (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" "n")))] "" "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") (define_insn "*rotlsi3_internal5" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?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" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] "" "@ {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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 ""))] "reload_completed" [(set (match_dup 4) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "*rotlsi3_internal6" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?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" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_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))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "reload_completed" [(set (match_dup 0) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[4], CCmode)) FAIL;") (define_insn "*rotlsi3_internal7" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extend:SI (subreg:QI (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") (define_insn "*rotlsi3_internal8" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?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)) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "" "@ {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:SI (subreg:QI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "reload_completed" [(set (match_dup 3) (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "*rotlsi3_internal9" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?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)) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_operand" "") (compare:CC (zero_extend:SI (subreg:QI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "reload_completed" [(set (match_dup 0) (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") (define_insn "*rotlsi3_internal10" [(set (match_operand:SI 0 "gpc_reg_operand" "=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)))] "" "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") (define_insn "*rotlsi3_internal11" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?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)) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "" "@ {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_operand" "") (compare:CC (zero_extend:SI (subreg:HI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (clobber (match_scratch:SI 3 ""))] "reload_completed" [(set (match_dup 3) (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "*rotlsi3_internal12" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?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)) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_operand" "") (compare:CC (zero_extend:SI (subreg:HI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "reload_completed" [(set (match_dup 0) (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[3], CCmode)) FAIL;") ;; Note that we use "sle." instead of "sl." so that we can set ;; SHIFT_COUNT_TRUNCATED. (define_expand "ashlsi3" [(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" ""))] "" " { if (TARGET_POWER) emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2])); else emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2])); DONE; }") (define_insn "ashlsi3_power" [(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"))) (clobber (match_scratch:SI 3 "=q,X"))] "TARGET_POWER" "@ sle %0,%1,%2 {sli|slwi} %0,%1,%h2") (define_insn "ashlsi3_no_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "! TARGET_POWER" "{sl|slw}%I2 %0,%1,%h2" [(set_attr "microcode" "mc")]) (define_insn "" [(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,r,r")) (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ sle. %3,%1,%2 {sli.|slwi.} %3,%1,%h2 # #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,mc,*,*") (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 4 ""))] "TARGET_POWER && reload_completed" [(parallel [(set (match_dup 3) (ashift: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 "" [(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")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] "! TARGET_POWER && TARGET_32BIT" "@ {sl|slw}%I2. %3,%1,%h2 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (ashift: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_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 3) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "" [(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,r,r") (ashift:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X,q,X"))] "TARGET_POWER" "@ sle. %0,%1,%2 {sli.|slwi.} %0,%1,%h2 # #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,mc,*,*") (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC (ashift: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" "") (ashift:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 ""))] "TARGET_POWER && reload_completed" [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) (clobber (match_dup 4))]) (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 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashift:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER && TARGET_32BIT" "@ {sl|slw}%I2. %0,%1,%h2 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC (ashift: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" "") (ashift:SI (match_dup 1) (match_dup 2)))] "! TARGET_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 0) (ashift:SI (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") (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" "n")))] "includes_lshift_p (operands[2], operands[3])" "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (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" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_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 ""))] "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))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[0], CCmode)) FAIL;") (define_insn "" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (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" "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)))] "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,*") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_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))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "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) (compare:CC (match_dup 0) (const_int 0)))] "if (rs6000_gen_microcode && cr0_reg_operand(operands[4], CCmode)) FAIL;") ;; The AIX assembler mis-handles "sri x,x,0", so write that case as ;; "sli x,x,0". (define_expand "lshrsi3" [(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" ""))] "" " { if (TARGET_POWER) emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2])); else emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2])); DONE; }") (define_insn "lshrsi3_power" [(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" "r,O,i"))) (clobber (match_scratch:SI 3 "=q,X,X"))] "TARGET_POWER" "@ sre %0,%1,%2 mr %0,%1 {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")))] "! TARGET_POWER" "@ mr %0,%1 {sr|srw}%I2 %0,%1,%h2" [(set_attr "microcode" "*,mc")]) (define_insn "" [(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" "r,O,i,r,O,i")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,X,r,r,X,r")) (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))] "TARGET_POWER" "@ sre. %3,%1,%2 mr. %1,%1 {s%A2i.|s%A2wi.} %3,%1,%h2 # # #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,mc,mc,*,*,*") (set_attr "length" "4,4,4,8,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 4 ""))] "TARGET_POWER && reload_completed" [(parallel [(set (match_dup 3) (lshiftrt: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 "" [(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")) (const_int 0))) (clobber (match_scratch:SI 3 "=X,r,X,r"))] "! TARGET_POWER && TARGET_32BIT" "@ mr. %1,%1 {sr|srw}%I2. %3,%1,%h2 # #" [(set_attr "type" "delayed_compare") (set_attr "microcode" "mc,mc,*,*") (set_attr "length" "4,4,8,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (lshiftrt: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_POWER && TARGET_32BIT && reload_completed" [(set (match_dup 3) (lshiftrt:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") (define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y") (c