X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gcc%2Fconfig%2Frs6000%2Frs6000.md;h=b5aeaed16aa0f0c69d4d3e949936cc3647cce127;hb=4abf82644ee3d501ab3b2c0e18f28ba888a6f2c3;hp=20204682069ec6d1366c5b50a5eb414995c2564c;hpb=dc2faee140907409050417fc38004d94dd40ed22;p=platform%2Fupstream%2Fgcc.git diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2020468..b5aeaed 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,5 +1,5 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990-2013 Free Software Foundation, Inc. +;; Copyright (C) 1990-2014 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GCC. @@ -56,18 +56,8 @@ (TFHAR_REGNO 114) (TFIAR_REGNO 115) (TEXASR_REGNO 116) - - ; ABI defined stack offsets for storing the TOC pointer with AIX calls. - (TOC_SAVE_OFFSET_32BIT 20) - (TOC_SAVE_OFFSET_64BIT 40) - - ; Function TOC offset in the AIX function descriptor. - (AIX_FUNC_DESC_TOC_32BIT 4) - (AIX_FUNC_DESC_TOC_64BIT 8) - - ; Static chain offset in the AIX function descriptor. - (AIX_FUNC_DESC_SC_32BIT 8) - (AIX_FUNC_DESC_SC_64BIT 16) + (FIRST_SPE_HIGH_REGNO 117) + (LAST_SPE_HIGH_REGNO 148) ]) ;; @@ -137,6 +127,16 @@ UNSPEC_P8V_MTVSRD UNSPEC_P8V_XXPERMDI UNSPEC_P8V_RELOAD_FROM_VSX + UNSPEC_ADDG6S + UNSPEC_CDTBCD + UNSPEC_CBCDTD + UNSPEC_DIVE + UNSPEC_DIVEO + UNSPEC_DIVEU + UNSPEC_DIVEUO + UNSPEC_UNPACK_128BIT + UNSPEC_PACK_128BIT + UNSPEC_LSQ ]) ;; @@ -152,14 +152,76 @@ UNSPECV_ISYNC ; isync instruction UNSPECV_MFTB ; move from time base UNSPECV_NLGR ; non-local goto receiver + UNSPECV_MFFS ; Move from FPSCR + UNSPECV_MTFSF ; Move to FPSCR Fields ]) ;; Define an insn type attribute. This is used in function unit delay ;; computations. -(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto,htm" +(define_attr "type" + "integer,two,three, + add,logical,shift,insert, + mul,halfmul,div, + exts,cntlz,popcnt,isel, + load,store,fpload,fpstore,vecload,vecstore, + cmp, + branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, + compare, + cr_logical,delayed_cr,mfcr,mfcrf,mtcr, + fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt, + brinc, + vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, + vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, + htm" (const_string "integer")) +;; What data size does this instruction work on? +;; This is used for insert, mul. +(define_attr "size" "8,16,32,64" (const_string "32")) + +;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? +;; This is used for add, logical, shift, exts, mul. +(define_attr "dot" "no,yes" (const_string "no")) + +;; Does this instruction sign-extend its result? +;; This is used for load insns. +(define_attr "sign_extend" "no,yes" (const_string "no")) + +;; Does this instruction use indexed (that is, reg+reg) addressing? +;; This is used for load and store insns. If operand 0 or 1 is a MEM +;; it is automatically set based on that. If a load or store instruction +;; has fewer than two operands it needs to set this attribute manually +;; or the compiler will crash. +(define_attr "indexed" "no,yes" + (if_then_else (ior (match_operand 0 "indexed_address_mem") + (match_operand 1 "indexed_address_mem")) + (const_string "yes") + (const_string "no"))) + +;; Does this instruction use update addressing? +;; This is used for load and store insns. See the comments for "indexed". +(define_attr "update" "no,yes" + (if_then_else (ior (match_operand 0 "update_address_mem") + (match_operand 1 "update_address_mem")) + (const_string "yes") + (const_string "no"))) + +;; Is this instruction using operands[2] as shift amount, and can that be a +;; register? +;; This is used for shift insns. +(define_attr "maybe_var_shift" "no,yes" (const_string "no")) + +;; Is this instruction using a shift amount from a register? +;; This is used for shift insns. +(define_attr "var_shift" "no,yes" + (if_then_else (and (eq_attr "type" "shift") + (eq_attr "maybe_var_shift" "yes")) + (if_then_else (match_operand 2 "gpc_reg_operand") + (const_string "yes") + (const_string "no")) + (const_string "no"))) + ;; Define floating point instruction sub-types for use with Xfpu.md (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) @@ -191,7 +253,13 @@ ;; If this instruction is microcoded on the CELL processor ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded (define_attr "cell_micro" "not,conditional,always" - (if_then_else (eq_attr "type" "compare,delayed_compare,imul_compare,lmul_compare,load_ext,load_ext_ux,var_shift_rotate,var_delayed_compare") + (if_then_else (ior (eq_attr "type" "compare") + (and (eq_attr "type" "shift,exts,mul") + (eq_attr "dot" "yes")) + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes")) + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes"))) (const_string "always") (const_string "not"))) @@ -241,8 +309,14 @@ ; Any supported integer mode that fits in one register. (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) -; extend modes for DImode -(define_mode_iterator QHSI [QI HI SI]) +; Everything we can extend QImode to. +(define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")]) + +; Everything we can extend HImode to. +(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) + +; Everything we can extend SImode to. +(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) ; QImode or HImode for small atomic ops (define_mode_iterator QHI [QI HI]) @@ -298,7 +372,8 @@ (V4SI "") (V4SF "") (V2DI "") - (V2DF "")]) + (V2DF "") + (V1TI "")]) ; Whether a floating point move is ok, don't allow SD without hardware FP (define_mode_attr fmove_ok [(SF "") @@ -325,7 +400,7 @@ (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")]) ; Definitions for 32-bit fpr direct move -(define_mode_attr f32_dm [(SF "wn") (SD "wm")]) +(define_mode_attr f32_dm [(SF "wn") (SD "wh")]) ; These modes do not fit in integer registers in 32-bit mode. ; but on e500v2, the gpr are 64 bit registers @@ -362,6 +437,11 @@ (simple_return "1")]) (define_code_attr return_str [(return "") (simple_return "simple_")]) +; Signed/unsigned variants of ops. +(define_code_iterator any_extend [sign_extend zero_extend]) +(define_code_attr u [(sign_extend "") (zero_extend "u")]) +(define_code_attr su [(sign_extend "s") (zero_extend "u")]) + ; Various instructions that come in SI and DI forms. ; A generic w/d attribute, for things like cmpw/cmpd. (define_mode_attr wd [(QI "b") @@ -373,12 +453,22 @@ (V4SI "w") (V2DI "d")]) +;; How many bits in this mode? +(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")]) + ; DImode bits (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) ;; ISEL/ISEL64 target selection (define_mode_attr sel [(SI "") (DI "64")]) +;; Bitmask for shift instructions +(define_mode_attr hH [(SI "h") (DI "H")]) + +;; A mode twice the size of the given mode +(define_mode_attr dmode [(SI "di") (DI "ti")]) +(define_mode_attr DMODE [(SI "DI") (DI "TI")]) + ;; Suffix for reload patterns (define_mode_attr ptrsize [(SI "32bit") (DI "64bit")]) @@ -397,6 +487,8 @@ (define_mode_attr rreg [(SF "f") (DF "ws") + (TF "f") + (TD "f") (V4SF "wf") (V2DF "wd")]) @@ -420,7 +512,8 @@ (V4SI "TARGET_ALTIVEC") (V4SF "TARGET_ALTIVEC") (V2DI "TARGET_ALTIVEC") - (V2DF "TARGET_ALTIVEC")]) + (V2DF "TARGET_ALTIVEC") + (V1TI "TARGET_ALTIVEC")]) ;; For the GPRs we use 3 constraints for register outputs, two that are the ;; same as the output register, and a third where the output register is an @@ -436,7 +529,8 @@ (V4SI "wa,v,&?r,?r,?r") (V4SF "wa,v,&?r,?r,?r") (V2DI "wa,v,&?r,?r,?r") - (V2DF "wa,v,&?r,?r,?r")]) + (V2DF "wa,v,&?r,?r,?r") + (V1TI "wa,v,&?r,?r,?r")]) ;; Mode attribute for boolean operation register constraints for operand1 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v") @@ -446,7 +540,8 @@ (V4SI "wa,v,r,0,r") (V4SF "wa,v,r,0,r") (V2DI "wa,v,r,0,r") - (V2DF "wa,v,r,0,r")]) + (V2DF "wa,v,r,0,r") + (V1TI "wa,v,r,0,r")]) ;; Mode attribute for boolean operation register constraints for operand2 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v") @@ -456,7 +551,8 @@ (V4SI "wa,v,r,r,0") (V4SF "wa,v,r,r,0") (V2DI "wa,v,r,r,0") - (V2DF "wa,v,r,r,0")]) + (V2DF "wa,v,r,r,0") + (V1TI "wa,v,r,r,0")]) ;; Mode attribute for boolean operation register constraints for operand1 ;; for one_cmpl. To simplify things, we repeat the constraint where 0 @@ -468,1049 +564,598 @@ (V4SI "wa,v,r,0,0") (V4SF "wa,v,r,0,0") (V2DI "wa,v,r,0,0") - (V2DF "wa,v,r,0,0")]) - -;; Mode attribute for the clobber of CC0 for AND expansion. -;; For the 128-bit types, we never do AND immediate, but we need to -;; get the correct number of X's for the number of operands. -(define_mode_attr BOOL_REGS_AND_CR0 [(TI "X,X,X,X,X") - (PTI "X,X,X") - (V16QI "X,X,X,X,X") - (V8HI "X,X,X,X,X") - (V4SI "X,X,X,X,X") - (V4SF "X,X,X,X,X") - (V2DI "X,X,X,X,X") - (V2DF "X,X,X,X,X")]) - + (V2DF "wa,v,r,0,0") + (V1TI "wa,v,r,0,0")]) ;; 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_extenddi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") +(define_insn "zero_extendqi2" + [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") + (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] + "" + "@ + lbz%U1%X1 %0,%1 + rlwinm %0,%1,0,0xff" + [(set_attr "type" "load,shift")]) -(define_insn "*zero_extenddi2_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64 && (mode != SImode || !TARGET_LFIWZX)" - "@ - lz%U1%X1 %0,%1 - rldicl %0,%1,0," - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*")])]) - -(define_insn "*zero_extenddi2_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) +(define_insn_and_split "*zero_extendqi2_dot" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:EXTQI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ - rldicl. %2,%1,0, + andi. %0,%1,0xff #" - [(set_attr "type" "compare") + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (zero_extend:EXTQI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) +(define_insn_and_split "*zero_extendqi2_dot2" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (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) + (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") + (zero_extend:EXTQI (match_dup 1)))] + "rs6000_gen_cell_microcode" + "@ + andi. %0,%1,0xff + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (zero_extend:EXTQI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*zero_extenddi2_internal3" + +(define_insn "zero_extendhi2" + [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") + (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] + "" + "@ + lhz%U1%X1 %0,%1 + rlwinm %0,%1,0,0xffff" + [(set_attr "type" "load,shift")]) + +(define_insn_and_split "*zero_extendhi2_dot" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) + (compare:CC (zero_extend:EXTHI (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" + (clobber (match_scratch:EXTHI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ - rldicl. %0,%1,0, + andi. %0,%1,0xffff #" - [(set_attr "type" "compare") + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (zero_extend:EXTHI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) +(define_insn_and_split "*zero_extendhi2_dot2" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" + (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") + (zero_extend:EXTHI (match_dup 1)))] + "rs6000_gen_cell_microcode" + "@ + andi. %0,%1,0xffff + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) + (zero_extend:EXTHI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + -(define_insn "*zero_extendsidi2_lfiwzx" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wz,!wu") - (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))] - "TARGET_POWERPC64 && TARGET_LFIWZX" +(define_insn "zero_extendsi2" + [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu") + (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))] + "" "@ lwz%U1%X1 %0,%1 rldicl %0,%1,0,32 mtvsrwz %x0,%1 lfiwzx %0,%y1 lxsiwzx %x0,%y1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*") - (const_string "mffgpr") - (const_string "fpload") - (const_string "fpload")])]) - -(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" - [(set_attr "type" "exts")]) + [(set_attr "type" "load,shift,mffgpr,fpload,fpload")]) -(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")) +(define_insn_and_split "*zero_extendsi2_dot" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:EXTSI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ - extsb. %2,%1 + rldicl. %0,%1,0,32 #" - [(set_attr "type" "compare") + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (zero_extend:DI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) +(define_insn_and_split "*zero_extendsi2_dot2" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (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) + (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") + (zero_extend:EXTSI (match_dup 1)))] + "rs6000_gen_cell_microcode" + "@ + rldicl. %0,%1,0,32 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (zero_extend:EXTSI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "" + +(define_insn "extendqi2" + [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r") + (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))] + "" + "extsb %0,%1" + [(set_attr "type" "exts")]) + +(define_insn_and_split "*extendqi2_dot" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) + (compare:CC (sign_extend:EXTQI (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" + (clobber (match_scratch:EXTQI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ extsb. %0,%1 #" - [(set_attr "type" "compare") + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (sign_extend:EXTQI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "exts") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) +(define_insn_and_split "*extendqi2_dot2" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" + (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") + (sign_extend:EXTQI (match_dup 1)))] + "rs6000_gen_cell_microcode" + "@ + extsb. %0,%1 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) + (sign_extend:EXTQI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "exts") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_expand "extendhidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" + +(define_expand "extendhi2" + [(set (match_operand:EXTHI 0 "gpc_reg_operand" "") + (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))] + "" "") -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode" +(define_insn "*extendhi2" + [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") + (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] + "rs6000_gen_cell_microcode" "@ lha%U1%X1 %0,%1 extsh %0,%1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_u") - (const_string "load_ext"))) - (const_string "exts")])]) + [(set_attr "type" "load,exts") + (set_attr "sign_extend" "yes")]) -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" +(define_insn "*extendhi2_noload" + [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r") + (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))] + "!rs6000_gen_cell_microcode" "extsh %0,%1" [(set_attr "type" "exts")]) -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) +(define_insn_and_split "*extendhi2_dot" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:EXTHI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ - extsh. %2,%1 + extsh. %0,%1 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (sign_extend:EXTHI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "exts") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "" +(define_insn_and_split "*extendhi2_dot2" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) + (compare:CC (sign_extend:EXTHI (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" + (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") + (sign_extend:EXTHI (match_dup 1)))] + "rs6000_gen_cell_microcode" "@ extsh. %0,%1 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) + (sign_extend:EXTHI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "exts") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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 "*extendsidi2_lfiwax" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wm,!wl,!wu") - (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r,r,Z,Z")))] - "TARGET_POWERPC64 && TARGET_LFIWAX" +(define_insn "extendsi2" + [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu") + (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))] + "" "@ lwa%U1%X1 %0,%1 extsw %0,%1 mtvsrwa %x0,%1 lfiwax %0,%y1 lxsiwax %x0,%y1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_u") - (const_string "load_ext"))) - (const_string "exts") - (const_string "mffgpr") - (const_string "fpload") - (const_string "fpload")])]) - -(define_insn "*extendsidi2_nocell" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode && !TARGET_LFIWAX" - "@ - lwa%U1%X1 %0,%1 - extsw %0,%1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_u") - (const_string "load_ext"))) - (const_string "exts")])]) - -(define_insn "*extendsidi2_nocell" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" - "extsw %0,%1" - [(set_attr "type" "exts")]) + [(set_attr "type" "load,exts,mffgpr,fpload,fpload") + (set_attr "sign_extend" "yes")]) -(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")) +(define_insn_and_split "*extendsi2_dot" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:EXTSI 0 "=r,r"))] + "rs6000_gen_cell_microcode" "@ - extsw. %2,%1 + extsw. %0,%1 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" + [(set (match_dup 0) + (sign_extend:EXTSI (match_dup 1))) + (set (match_dup 2) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "exts") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "" +(define_insn_and_split "*extendsi2_dot2" [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (compare:CC (sign_extend:EXTSI (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" + (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") + (sign_extend:EXTSI (match_dup 1)))] + "rs6000_gen_cell_microcode" "@ extsw. %0,%1 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) + (sign_extend:EXTSI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (const_int 0)))] - "") - -(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 - rlwinm %0,%1,0,0xff" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*")])]) - -(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"))] "" - "@ - andi. %2,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "exts") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) + +;; IBM 405, 440, 464 and 476 half-word multiplication operations. -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") +(define_insn "*macchwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_dup 2) + (const_int 16)) + (sign_extend:SI + (match_dup 1))) + (match_dup 4)))] + "TARGET_MULHW" + "macchw. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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)))] - "" - "@ - andi. %0,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) +(define_insn "*macchw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "macchw %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (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)))] - "") +(define_insn "*macchwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_dup 2) + (const_int 16)) + (zero_extend:SI + (match_dup 1))) + (match_dup 4)))] + "TARGET_MULHW" + "macchwu. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_insn "extendqisi2" +(define_insn "*macchwu" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "" - "extsb %0,%1" - [(set_attr "type" "exts")]) + (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "macchwu %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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"))] - "" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) +(define_insn "*machhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_dup 1) + (const_int 16)) + (ashiftrt:SI + (match_dup 2) + (const_int 16))) + (match_dup 4)))] + "TARGET_MULHW" + "machhw. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") +(define_insn "*machhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "machhw %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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)))] - "" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) +(define_insn "*machhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_dup 1) + (const_int 16)) + (lshiftrt:SI + (match_dup 2) + (const_int 16))) + (match_dup 4)))] + "TARGET_MULHW" + "machhwu. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (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)))] - "") +(define_insn "*machhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (lshiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (lshiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "machhwu %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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 - rlwinm %0,%1,0,0xff" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*")])]) +(define_insn "*maclhwc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (sign_extend:SI + (match_dup 1)) + (sign_extend:SI + (match_dup 2))) + (match_dup 4)))] + "TARGET_MULHW" + "maclhw. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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"))] - "" - "@ - andi. %2,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) +(define_insn "*maclhw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (sign_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "maclhw %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:HI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:HI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") +(define_insn "*maclhwuc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (plus:SI (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 4 "gpc_reg_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (zero_extend:SI + (match_dup 1)) + (zero_extend:SI + (match_dup 2))) + (match_dup 4)))] + "TARGET_MULHW" + "maclhwu. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(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)))] - "" - "@ - andi. %0,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) +(define_insn "*maclhwu" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (mult:SI (zero_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "%r")) + (zero_extend:SI + (match_operand:HI 2 "gpc_reg_operand" "r"))) + (match_operand:SI 3 "gpc_reg_operand" "0")))] + "TARGET_MULHW" + "maclhwu %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (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)))] - "") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "gpc_reg_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "" - "extsb %0,%1" - [(set_attr "type" "exts")]) - -(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"))] - "" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:HI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend:HI (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 (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)))] - "" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (sign_extend:HI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (sign_extend:HI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(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 - rlwinm %0,%1,0,0xffff" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*")])]) - -(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"))] - "" - "@ - andi. %2,%1,0xffff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend: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 (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)))] - "" - "@ - andi. %0,%1,0xffff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (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)))] - "") - -(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,r") - (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "rs6000_gen_cell_microcode" - "@ - lha%U1%X1 %0,%1 - extsh %0,%1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_ext_u") - (const_string "load_ext"))) - (const_string "exts")])]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))] - "!rs6000_gen_cell_microcode" - "extsh %0,%1" - [(set_attr "type" "exts")]) - -(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"))] - "" - "@ - extsh. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend: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 (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)))] - "" - "@ - extsh. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (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)))] - "") - -;; IBM 405, 440, 464 and 476 half-word multiplication operations. - -(define_insn "*macchwc" +(define_insn "*nmacchwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) + (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r")))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_dup 2) - (const_int 16)) - (sign_extend:SI - (match_dup 1))) - (match_dup 4)))] + (minus:SI (match_dup 4) + (mult:SI (ashiftrt:SI + (match_dup 2) + (const_int 16)) + (sign_extend:SI + (match_dup 1)))))] "TARGET_MULHW" - "macchw. %0,%1,%2" - [(set_attr "type" "imul3")]) + "nmacchw. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_insn "*macchw" +(define_insn "*nmacchw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] + (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)) + (sign_extend:SI + (match_operand:HI 1 "gpc_reg_operand" "r")))))] "TARGET_MULHW" - "macchw %0,%1,%2" - [(set_attr "type" "imul3")]) + "nmacchw %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_insn "*macchwuc" +(define_insn "*nmachhwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) + (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)))) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_dup 2) - (const_int 16)) - (zero_extend:SI - (match_dup 1))) - (match_dup 4)))] + (minus:SI (match_dup 4) + (mult:SI (ashiftrt:SI + (match_dup 1) + (const_int 16)) + (ashiftrt:SI + (match_dup 2) + (const_int 16)))))] "TARGET_MULHW" - "macchwu. %0,%1,%2" - [(set_attr "type" "imul3")]) + "nmachhw. %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_insn "*macchwu" +(define_insn "*nmachhw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] + (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") + (mult:SI (ashiftrt:SI + (match_operand:SI 1 "gpc_reg_operand" "%r") + (const_int 16)) + (ashiftrt:SI + (match_operand:SI 2 "gpc_reg_operand" "r") + (const_int 16)))))] "TARGET_MULHW" - "macchwu %0,%1,%2" - [(set_attr "type" "imul3")]) + "nmachhw %0,%1,%2" + [(set_attr "type" "halfmul")]) -(define_insn "*machhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_dup 1) - (const_int 16)) - (ashiftrt:SI - (match_dup 2) - (const_int 16))) - (match_dup 4)))] - "TARGET_MULHW" - "machhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "machhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_dup 1) - (const_int 16)) - (lshiftrt:SI - (match_dup 2) - (const_int 16))) - (match_dup 4)))] - "TARGET_MULHW" - "machhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "machhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (sign_extend:SI - (match_dup 1)) - (sign_extend:SI - (match_dup 2))) - (match_dup 4)))] - "TARGET_MULHW" - "maclhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "maclhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (zero_extend:SI - (match_dup 1)) - (zero_extend:SI - (match_dup 2))) - (match_dup 4)))] - "TARGET_MULHW" - "maclhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "maclhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmacchwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r")))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_dup 4) - (mult:SI (ashiftrt:SI - (match_dup 2) - (const_int 16)) - (sign_extend:SI - (match_dup 1)))))] - "TARGET_MULHW" - "nmacchw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmacchw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r")))))] - "TARGET_MULHW" - "nmacchw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmachhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_dup 4) - (mult:SI (ashiftrt:SI - (match_dup 1) - (const_int 16)) - (ashiftrt:SI - (match_dup 2) - (const_int 16)))))] - "TARGET_MULHW" - "nmachhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmachhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)))))] - "TARGET_MULHW" - "nmachhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmaclhwc" +(define_insn "*nmaclhwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") (mult:SI (sign_extend:SI @@ -1526,7 +1171,7 @@ (match_dup 2)))))] "TARGET_MULHW" "nmaclhw. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*nmaclhw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1537,7 +1182,7 @@ (match_operand:HI 2 "gpc_reg_operand" "r")))))] "TARGET_MULHW" "nmaclhw %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulchwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1555,7 +1200,7 @@ (match_dup 1))))] "TARGET_MULHW" "mulchw. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulchw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1566,7 +1211,7 @@ (match_operand:HI 1 "gpc_reg_operand" "r"))))] "TARGET_MULHW" "mulchw %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulchwuc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1584,7 +1229,7 @@ (match_dup 1))))] "TARGET_MULHW" "mulchwu. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulchwu" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1595,7 +1240,7 @@ (match_operand:HI 1 "gpc_reg_operand" "r"))))] "TARGET_MULHW" "mulchwu %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulhhwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1615,7 +1260,7 @@ (const_int 16))))] "TARGET_MULHW" "mulhhw. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulhhw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1627,7 +1272,7 @@ (const_int 16))))] "TARGET_MULHW" "mulhhw %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulhhwuc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1647,7 +1292,7 @@ (const_int 16))))] "TARGET_MULHW" "mulhhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mulhhwu" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1659,7 +1304,7 @@ (const_int 16))))] "TARGET_MULHW" "mulhhwu %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mullhwc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1675,7 +1320,7 @@ (match_dup 2))))] "TARGET_MULHW" "mullhw. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mullhw" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1685,7 +1330,7 @@ (match_operand:HI 2 "gpc_reg_operand" "r"))))] "TARGET_MULHW" "mullhw %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mullhwuc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") @@ -1701,7 +1346,7 @@ (match_dup 2))))] "TARGET_MULHW" "mullhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) (define_insn "*mullhwu" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1711,7 +1356,7 @@ (match_operand:HI 2 "gpc_reg_operand" "r"))))] "TARGET_MULHW" "mullhwu %0,%1,%2" - [(set_attr "type" "imul3")]) + [(set_attr "type" "halfmul")]) ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. (define_insn "dlmzb" @@ -1828,7 +1473,7 @@ addi %0,%1,%2 addic %0,%1,%2 addis %0,%1,%v2" - [(set_attr "length" "4,4,4,4")]) + [(set_attr "type" "add")]) (define_insn "addsi3_high" [(set (match_operand:SI 0 "gpc_reg_operand" "=b") @@ -1836,7 +1481,7 @@ (high:SI (match_operand 2 "" ""))))] "TARGET_MACHO && !TARGET_64BIT" "addis %0,%1,ha16(%2)" - [(set_attr "length" "4")]) + [(set_attr "type" "add")]) (define_insn "*add3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") @@ -1850,7 +1495,8 @@ addic. %3,%1,%2 # #" - [(set_attr "type" "fast_compare,compare,compare,compare") + [(set_attr "type" "add,compare,compare,compare") + (set_attr "dot" "yes") (set_attr "length" "4,4,8,8")]) (define_split @@ -1882,7 +1528,8 @@ addic. %0,%1,%2 # #" - [(set_attr "type" "fast_compare,compare,compare,compare") + [(set_attr "type" "add,compare,compare,compare") + (set_attr "dot" "yes") (set_attr "length" "4,4,8,8")]) (define_split @@ -1938,7 +1585,7 @@ { if (mode == DImode && !TARGET_POWERPC64) { - rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX); + rs6000_split_logical (operands, NOT, false, false, false); DONE; } }) @@ -1958,7 +1605,8 @@ "@ nor. %2,%1,%1 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "logical,compare") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -1984,7 +1632,8 @@ "@ nor. %0,%1,%1 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "logical,compare") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -2008,7 +1657,8 @@ "" "@ subf %0,%2,%1 - subfic %0,%2,%1") + subfic %0,%2,%1" + [(set_attr "type" "add")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -2020,7 +1670,8 @@ "@ subf. %3,%2,%1 #" - [(set_attr "type" "fast_compare") + [(set_attr "type" "add") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -2050,7 +1701,8 @@ "@ subf. %0,%2,%1 #" - [(set_attr "type" "fast_compare") + [(set_attr "type" "add") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -2095,7 +1747,8 @@ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] "" - "neg %0,%1") + "neg %0,%1" + [(set_attr "type" "add")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -2106,7 +1759,8 @@ "@ neg. %2,%1 #" - [(set_attr "type" "fast_compare") + [(set_attr "type" "add") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -2132,7 +1786,8 @@ "@ neg. %0,%1 #" - [(set_attr "type" "fast_compare") + [(set_attr "type" "add") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -2159,12 +1814,14 @@ (define_expand "ctz2" [(set (match_dup 2) (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) - (parallel [(set (match_dup 3) (and:GPR (match_dup 1) - (match_dup 2))) - (clobber (scratch:CC))]) - (set (match_dup 4) (clz:GPR (match_dup 3))) + (set (match_dup 3) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (clz:GPR (match_dup 3))) (set (match_operand:GPR 0 "gpc_reg_operand" "") - (minus:GPR (match_dup 5) (match_dup 4)))] + (minus:GPR (match_dup 5) + (match_dup 4)))] "" { operands[2] = gen_reg_rtx (mode); @@ -2176,12 +1833,14 @@ (define_expand "ffs2" [(set (match_dup 2) (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) - (parallel [(set (match_dup 3) (and:GPR (match_dup 1) - (match_dup 2))) - (clobber (scratch:CC))]) - (set (match_dup 4) (clz:GPR (match_dup 3))) + (set (match_dup 3) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (clz:GPR (match_dup 3))) (set (match_operand:GPR 0 "gpc_reg_operand" "") - (minus:GPR (match_dup 5) (match_dup 4)))] + (minus:GPR (match_dup 5) + (match_dup 4)))] "" { operands[2] = gen_reg_rtx (mode); @@ -2391,7 +2050,7 @@ ;; Non-power7/cell, fall back to use lwbrx/stwbrx (define_insn "*bswapdi2_64bit" - [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r") + [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r") (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) (clobber (match_scratch:DI 2 "=&b,&b,&r")) (clobber (match_scratch:DI 3 "=&r,&r,&r")) @@ -2465,6 +2124,7 @@ emit_insn (gen_bswapsi2 (op4_32, word_high)); emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32))); emit_insn (gen_iordi3 (dest, dest, op4)); + DONE; }") (define_split @@ -2526,6 +2186,7 @@ } emit_insn (gen_bswapsi2 (word_high, src_si)); emit_insn (gen_bswapsi2 (word_low, op3_si)); + DONE; }") (define_split @@ -2553,10 +2214,11 @@ emit_insn (gen_bswapsi2 (op3_si, op2_si)); emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); emit_insn (gen_iordi3 (dest, dest, op3)); + DONE; }") (define_insn "bswapdi2_32bit" - [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r") + [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r") (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) (clobber (match_scratch:SI 2 "=&b,&b,X"))] "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" @@ -2609,6 +2271,7 @@ emit_insn (gen_bswapsi2 (dest2, word1)); emit_insn (gen_bswapsi2 (dest1, word2)); + DONE; }") (define_split @@ -2657,6 +2320,7 @@ emit_insn (gen_bswapsi2 (word2, src1)); emit_insn (gen_bswapsi2 (word1, src2)); + DONE; }") (define_split @@ -2676,106 +2340,193 @@ emit_insn (gen_bswapsi2 (dest1, src2)); emit_insn (gen_bswapsi2 (dest2, src1)); + DONE; }") -(define_insn "mulsi3" - [(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")))] + +(define_insn "mul3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] "" "@ - mullw %0,%1,%2 + mull %0,%1,%2 mulli %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 2 "s8bit_cint_operand" "") - (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") - (const_string "imul2")] - (const_string "imul")))]) - -(define_insn "*mulsi3_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")) + [(set_attr "type" "mul") + (set (attr "size") + (cond [(match_operand:GPR 2 "s8bit_cint_operand" "") + (const_string "8") + (match_operand:GPR 2 "short_cint_operand" "") + (const_string "16")] + (const_string "")))]) + +(define_insn_and_split "*mul3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - mullw. %3,%1,%2 + mull. %0,%1,%2 #" - [(set_attr "type" "imul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (mult:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (mult:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "mul") + (set_attr "size" "") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*mulsi3_internal2" +(define_insn_and_split "*mul3_dot2" [(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")) + (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 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_32BIT" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (mult:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - mullw. %0,%1,%2 + mull. %0,%1,%2 #" - [(set_attr "type" "imul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (mult:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT && reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" [(set (match_dup 0) - (mult:SI (match_dup 1) (match_dup 2))) + (mult:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") - - -(define_insn "udiv3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r")))] "" - "divu %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 0 "" "") - (const_string "idiv")] - (const_string "ldiv")))]) + [(set_attr "type" "mul") + (set_attr "size" "") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -;; For powers of two we can do srai/aze for divide and then adjust for -;; modulus. If it isn't a power of two, force operands into register and do -;; a normal divide. -(define_expand "div3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "reg_or_cint_operand" "")))] +(define_expand "mul3_highpart" + [(set (match_operand:GPR 0 "gpc_reg_operand") + (subreg:GPR + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand"))) + 0))] "" { - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 0 - || exact_log2 (INTVAL (operands[2])) < 0) - operands[2] = force_reg (mode, operands[2]); -}) + if (mode == SImode && TARGET_POWERPC64) + { + emit_insn (gen_mulsi3_highpart_64 (operands[0], operands[1], + operands[2])); + DONE; + } + + if (!WORDS_BIG_ENDIAN) + { + emit_insn (gen_mul3_highpart_le (operands[0], operands[1], + operands[2])); + DONE; + } +}) + +(define_insn "*mul3_highpart" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (subreg:GPR + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand" "r")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand" "r"))) + 0))] + "WORDS_BIG_ENDIAN && !(mode == SImode && TARGET_POWERPC64)" + "mulh %0,%1,%2" + [(set_attr "type" "mul") + (set_attr "size" "")]) + +(define_insn "mulsi3_highpart_le" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (subreg:SI + (mult:DI (any_extend:DI + (match_operand:SI 1 "gpc_reg_operand" "r")) + (any_extend:DI + (match_operand:SI 2 "gpc_reg_operand" "r"))) + 4))] + "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" + "mulhw %0,%1,%2" + [(set_attr "type" "mul")]) + +(define_insn "muldi3_highpart_le" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (subreg:DI + (mult:TI (any_extend:TI + (match_operand:DI 1 "gpc_reg_operand" "r")) + (any_extend:TI + (match_operand:DI 2 "gpc_reg_operand" "r"))) + 8))] + "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" + "mulhd %0,%1,%2" + [(set_attr "type" "mul") + (set_attr "size" "64")]) + +(define_insn "mulsi3_highpart_64" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (truncate:SI + (lshiftrt:DI + (mult:DI (any_extend:DI + (match_operand:SI 1 "gpc_reg_operand" "r")) + (any_extend:DI + (match_operand:SI 2 "gpc_reg_operand" "r"))) + (const_int 32))))] + "TARGET_POWERPC64" + "mulhw %0,%1,%2" + [(set_attr "type" "mul")]) + +(define_expand "mul3" + [(set (match_operand: 0 "gpc_reg_operand") + (mult: (any_extend: + (match_operand:GPR 1 "gpc_reg_operand")) + (any_extend: + (match_operand:GPR 2 "gpc_reg_operand"))))] + "!(mode == SImode && TARGET_POWERPC64)" +{ + rtx l = gen_reg_rtx (mode); + rtx h = gen_reg_rtx (mode); + emit_insn (gen_mul3 (l, operands[1], operands[2])); + emit_insn (gen_mul3_highpart (h, operands[1], operands[2])); + emit_move_insn (gen_lowpart (mode, operands[0]), l); + emit_move_insn (gen_highpart (mode, operands[0]), h); + DONE; +}) + + +(define_insn "udiv3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")))] + "" + "divu %0,%1,%2" + [(set_attr "type" "div") + (set_attr "size" "")]) + + +;; For powers of two we can do srai/aze for divide and then adjust for +;; modulus. If it isn't a power of two, force operands into register and do +;; a normal divide. +(define_expand "div3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "reg_or_cint_operand" "")))] + "" +{ + if (GET_CODE (operands[2]) != CONST_INT + || INTVAL (operands[2]) <= 0 + || exact_log2 (INTVAL (operands[2])) < 0) + operands[2] = force_reg (mode, operands[2]); +}) (define_insn "*div3" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") @@ -2783,10 +2534,8 @@ (match_operand:GPR 2 "gpc_reg_operand" "r")))] "" "div %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 0 "" "") - (const_string "idiv")] - (const_string "ldiv")))]) + [(set_attr "type" "div") + (set_attr "size" "")]) (define_expand "mod3" [(use (match_operand:GPR 0 "gpc_reg_operand" "")) @@ -2888,214 +2637,278 @@ ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all ;; those rotate-and-mask operations. Thus, the AND insns come first. -(define_expand "andsi3" - [(parallel - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] +(define_expand "and3" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "") + (match_operand:SDI 2 "reg_or_cint_operand" "")))] "" - "") - -(define_insn "andsi3_mc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "and_operand" "?r,T,K,L"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))] - "rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2" - [(set_attr "type" "*,*,fast_compare,fast_compare")]) +{ + if (mode == DImode && !TARGET_POWERPC64) + { + rs6000_split_logical (operands, AND, false, false, false); + DONE; + } -(define_insn "andsi3_nomc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "and_operand" "?r,T"))) - (clobber (match_scratch:CC 3 "=X,X"))] - "!rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2") + if (logical_const_operand (operands[2], mode) + && !any_mask_operand (operands[2], mode)) + { + emit_insn (gen_and3_imm (operands[0], operands[1], operands[2])); + DONE; + } -(define_insn "andsi3_internal0_nomc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "and_operand" "?r,T")))] - "!rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2") + if ((mode == DImode && !and64_2_operand (operands[2], mode)) + || (mode != DImode && !and_operand (operands[2], mode))) + operands[2] = force_reg (mode, operands[2]); +}) -;; 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 "*and3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")))] + "" + "and %0,%1,%2" + [(set_attr "type" "logical")]) -(define_insn "*andsi3_internal2_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) +(define_insn_and_split "*and3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")) (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 && rs6000_gen_cell_microcode" - "@ - and. %3,%1,%2 - andi. %3,%1,%b2 - andis. %3,%1,%u2 - rlwinm. %3,%1,0,%m2,%M2 - # - # - # + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" + "@ + and. %0,%1,%2 #" - [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\ - compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_insn "*andsi3_internal3_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + +(define_insn_and_split "*and3_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (and:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - # - andi. %3,%1,%b2 - andis. %3,%1,%u2 - rlwinm. %3,%1,0,%m2,%M2 - # - # - # + and. %0,%1,%2 #" - [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\ - compare,compare,compare") - (set_attr "length" "8,4,4,4,8,8,8,8")]) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "and_operand" "")) - (const_int 0))) - (clobber (match_scratch:GPR 3 "")) - (clobber (match_scratch:CC 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (and: (match_dup 1) - (match_dup 2))) + +(define_insn "and3_imm" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") + (match_operand:GPR 2 "logical_const_operand" "n"))) + (clobber (match_scratch:CC 3 "=x"))] + "rs6000_gen_cell_microcode + && !any_mask_operand (operands[2], mode)" + "andi%e2. %0,%1,%u2" + [(set_attr "type" "logical") + (set_attr "dot" "yes")]) + +(define_insn_and_split "*and3_imm_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=r,r")) + (clobber (match_scratch:CC 4 "=X,x"))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && !any_mask_operand (operands[2], mode)" + "@ + andi%e2. %0,%1,%u2 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(parallel [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") - -;; 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. + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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" "")) +(define_insn_and_split "*and3_imm_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) (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))) + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (and:GPR (match_dup 1) + (match_dup 2))) + (clobber (match_scratch:CC 4 "=X,x"))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && !any_mask_operand (operands[2], mode)" + "@ + andi%e2. %0,%1,%u2 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(parallel [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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")) +(define_insn_and_split "*and3_imm_mask_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) (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 && rs6000_gen_cell_microcode" + (clobber (match_scratch:GPR 0 "=r,r"))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && any_mask_operand (operands[2], mode)" "@ - and. %0,%1,%2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - rlwinm. %0,%1,0,%m2,%M2 - # - # - # + andi%e2. %0,%1,%u2 #" - [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\ - compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_insn "*andsi3_internal5_mc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + +(define_insn_and_split "*and3_imm_mask_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (and:GPR (match_dup 1) + (match_dup 2)))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && any_mask_operand (operands[2], mode)" "@ - # - andi. %0,%1,%b2 - andis. %0,%1,%u2 - rlwinm. %0,%1,0,%m2,%M2 - # - # - # + andi%e2. %0,%1,%u2 #" - [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\ - compare,compare,compare") - (set_attr "length" "8,4,4,4,8,8,8,8")]) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" "")) + +(define_insn "*and3_mask" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "any_mask_operand" "S,T")))] + "" + "@ + rldic%B2 %0,%1,0,%S2 + rlwinm %0,%1,0,%m2,%M2" + [(set_attr "type" "shift")]) + +(define_insn_and_split "*and3_mask_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:GPR 2 "any_mask_operand" "S,T,S,T")) (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))]) + (clobber (match_scratch:GPR 0 "=r,r,r,r"))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && !logical_const_operand (operands[2], mode)" + "@ + rldic%B2. %0,%1,0,%S2 + rlwinm. %0,%1,0,%m2,%M2 + # + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "dot" "yes") + (set_attr "length" "4,4,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" "")) +(define_insn_and_split "*and3_mask_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r") + (match_operand:GPR 2 "any_mask_operand" "S,T,S,T")) (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_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r") + (and:GPR (match_dup 1) + (match_dup 2)))] + "(mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && !logical_const_operand (operands[2], mode)" + "@ + rldic%B2. %0,%1,0,%S2 + rlwinm. %0,%1,0,%m2,%M2 + # + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "dot" "yes") + (set_attr "length" "4,4,8,8")]) + + + +(define_insn "andsi3_internal0_nomc" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "and_operand" "?r,T")))] + "!rs6000_gen_cell_microcode" + "@ + and %0,%1,%2 + rlwinm %0,%1,0,%m2,%M2" + [(set_attr "type" "logical,shift")]) + ;; Handle the PowerPC64 rlwinm corner case @@ -3121,272 +2934,270 @@ }" [(set_attr "length" "8")]) -(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" "")))] + +(define_expand "ior3" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (ior:SDI (match_operand:SDI 1 "gpc_reg_operand" "") + (match_operand:SDI 2 "reg_or_cint_operand" "")))] "" - " { - if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], SImode)) + if (mode == DImode && !TARGET_POWERPC64) + { + rs6000_split_logical (operands, IOR, false, false, false); + DONE; + } + + if (non_logical_cint_operand (operands[2], mode)) { - HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((!can_create_pseudo_p () || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); + ? operands[0] : gen_reg_rtx (mode)); + HOST_WIDE_INT value = INTVAL (operands[2]); - emit_insn (gen_iorsi3 (tmp, operands[1], + emit_insn (gen_ior3 (tmp, operands[1], GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + + emit_insn (gen_ior3 (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 (!reg_or_logical_cint_operand (operands[2], mode)) + operands[2] = force_reg (mode, operands[2]); +}) + +(define_expand "xor3" + [(set (match_operand:SDI 0 "gpc_reg_operand" "") + (xor:SDI (match_operand:SDI 1 "gpc_reg_operand" "") + (match_operand:SDI 2 "reg_or_cint_operand" "")))] "" - " { - if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], SImode)) + if (mode == DImode && !TARGET_POWERPC64) + { + rs6000_split_logical (operands, XOR, false, false, false); + DONE; + } + + if (non_logical_cint_operand (operands[2], mode)) { - HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((!can_create_pseudo_p () || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); + ? operands[0] : gen_reg_rtx (mode)); + HOST_WIDE_INT value = INTVAL (operands[2]); - emit_insn (gen_xorsi3 (tmp, operands[1], + emit_insn (gen_xor3 (tmp, operands[1], GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + + emit_insn (gen_xor3 (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 - %q3i %0,%1,%b2 - %q3is %0,%1,%u2") + if (!reg_or_logical_cint_operand (operands[2], mode)) + operands[2] = force_reg (mode, operands[2]); +}) -(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" "fast_compare,compare") - (set_attr "length" "4,8")]) +(define_insn "*bool3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 3 "boolean_or_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")]))] + "" + "%q3 %0,%1,%2" + [(set_attr "type" "logical")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") +(define_insn "*bool3_imm" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 3 "boolean_or_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "%r") + (match_operand:GPR 2 "logical_const_operand" "n")]))] + "" + "%q3i%e2 %0,%1,%u2" + [(set_attr "type" "logical")]) -(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")]) +(define_insn_and_split "*bool3_dot" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_or_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - %q4. %0,%1,%2 + %q3. %0,%1,%2 #" - [(set_attr "type" "fast_compare,compare") + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")]) +(define_insn_and_split "*bool3_dot2" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_or_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) (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) + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (match_dup 3))] + "mode == Pmode && rs6000_gen_cell_microcode" + "@ + %q3. %0,%1,%2 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) ;; 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_operand:GPR 0 "gpc_reg_operand" "") + (match_operator:GPR 3 "boolean_or_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 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_fmt_ee (GET_CODE (operands[3]), SImode, + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), mode, operands[1], i); i = GEN_INT (INTVAL (operands[2]) & 0xffff); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), mode, 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")]))] + +(define_insn "*boolc3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) + (match_operand:GPR 1 "gpc_reg_operand" "r")]))] "" - "%q3 %0,%2,%1") + "%q3 %0,%1,%2" + [(set_attr "type" "logical")]) -(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")]) +(define_insn_and_split "*boolc3_dot" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) + (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - %q4. %3,%2,%1 + %q3. %0,%1,%2 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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")]) +(define_insn_and_split "*boolc3_dot2" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) + (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (match_dup 3))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - %q4. %0,%2,%1 + %q3. %0,%1,%2 #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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"))]))] + +(define_insn "*boolcc3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) + (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] "" - "%q3 %0,%1,%2") + "%q3 %0,%1,%2" + [(set_attr "type" "logical")]) -(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"))]) +(define_insn_and_split "*boolcc3_dot" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) + (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - %q4. %3,%1,%2 + %q3. %0,%1,%2 #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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"))]) +(define_insn_and_split "*boolcc3_dot2" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC (match_operator:GPR 3 "boolean_operator" + [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) + (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (match_dup 3))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - %q4. %0,%1,%2 + %q3. %0,%1,%2 #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + + +;; TODO: Should have dots of this as well. +(define_insn "*eqv3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r"))))] + "" + "eqv %0,%1,%2" + [(set_attr "type" "logical")]) ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. @@ -3432,7 +3243,7 @@ operands[1] = GEN_INT (start + size - 1); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "*insvsi_internal1" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3451,7 +3262,7 @@ operands[1] = GEN_INT (start + size - 1); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "*insvsi_internal2" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3470,7 +3281,7 @@ operands[1] = GEN_INT (start + size - 1); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "*insvsi_internal3" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3489,7 +3300,7 @@ operands[1] = GEN_INT (start + size - 1); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "*insvsi_internal4" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") @@ -3511,7 +3322,7 @@ operands[1] = GEN_INT (insert_start + insert_size - 1); return \"rlwimi %0,%3,%h5,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) ;; combine patterns for rlwimi (define_insn "*insvsi_internal5" @@ -3531,7 +3342,7 @@ operands[1] = GEN_INT(me); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "*insvsi_internal6" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -3550,7 +3361,7 @@ operands[1] = GEN_INT(me); return \"rlwimi %0,%3,%h4,%h2,%h1\"; }" - [(set_attr "type" "insert_word")]) + [(set_attr "type" "insert")]) (define_insn "insvdi_internal" [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") @@ -3566,7 +3377,8 @@ operands[1] = GEN_INT (64 - start - size); return \"rldimi %0,%3,%H1,%H2\"; }" - [(set_attr "type" "insert_dword")]) + [(set_attr "type" "insert") + (set_attr "size" "64")]) (define_insn "*insvdi_internal2" [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") @@ -3648,7 +3460,8 @@ else operands[3] = GEN_INT (start + size); return \"rlwinm %0,%1,%3,%s2,31\"; -}") +}" + [(set_attr "type" "shift")]) (define_insn "*extzvsi_internal1" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -3689,7 +3502,8 @@ operands[3] = GEN_INT (start + size); return \"rlwinm. %4,%1,%3,%s2,31\"; }" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -3740,7 +3554,8 @@ operands[3] = GEN_INT (start + size); return \"rlwinm. %0,%1,%3,%s2,31\"; }" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -3776,7 +3591,8 @@ operands[3] = GEN_INT (start + size); operands[2] = GEN_INT (64 - size); return \"rldicl %0,%1,%3,%2\"; -}") +}" + [(set_attr "type" "shift")]) (define_insn "*extzvdi_internal1" [(set (match_operand:CC 0 "gpc_reg_operand" "=x") @@ -3798,7 +3614,8 @@ operands[2] = GEN_INT (64 - size); return \"rldicl. %4,%1,%3,%2\"; }" - [(set_attr "type" "compare")]) + [(set_attr "type" "shift") + (set_attr "dot" "yes")]) (define_insn "*extzvdi_internal2" [(set (match_operand:CC 4 "gpc_reg_operand" "=x") @@ -3821,116 +3638,104 @@ operands[2] = GEN_INT (64 - size); return \"rldicl. %0,%1,%3,%2\"; }" - [(set_attr "type" "compare")]) + [(set_attr "type" "shift") + (set_attr "dot" "yes")]) -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] + +(define_insn "rotl3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")))] "" - "@ - rlwnm %0,%1,%2,0xffffffff - rlwinm %0,%1,%h2,0xffffffff" - [(set_attr "type" "var_shift_rotate,integer")]) + "rotl%I2 %0,%1,%2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*rotlsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] - "TARGET_64BIT" - "@ - rlwnm %0,%1,%2,0xffffffff - rlwinm %0,%1,%h2,0xffffffff" - [(set_attr "type" "var_shift_rotate,integer")]) + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] + "TARGET_POWERPC64" + "rotlw%I2 %0,%1,%h2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(define_insn "*rotlsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn_and_split "*rotl3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - rlwnm. %3,%1,%2,0xffffffff - rlwinm. %3,%1,%h2,0xffffffff - # + rotl%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (rotate:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (rotate:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*rotlsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn_and_split "*rotl3_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (rotate:SI (match_dup 1) (match_dup 2)))] - "" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (rotate:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - rlwnm. %0,%1,%2,0xffffffff - rlwinm. %0,%1,%h2,0xffffffff - # + rotl%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (rotate:SI (match_dup 1) (match_dup 2)))] - "reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" [(set (match_dup 0) - (rotate:SI (match_dup 1) (match_dup 2))) + (rotate:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + (define_insn "*rotlsi3_internal4" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) - (match_operand:SI 3 "mask_operand" "n,n")))] + [(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" "rn")) + (match_operand:SI 3 "mask_operand" "n")))] "" - "@ - rlwnm %0,%1,%2,%m3,%M3 - rlwinm %0,%1,%h2,%m3,%M3" - [(set_attr "type" "var_shift_rotate,integer")]) + "rlw%I2nm %0,%1,%h2,%m3,%M3" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*rotlsi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:SI 3 "mask_operand" "n,n,n,n")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r,r,r"))] + (clobber (match_scratch:SI 4 "=r,r"))] "" "@ - rlwnm. %4,%1,%2,%m3,%M3 - rlwinm. %4,%1,%h2,%m3,%M3 - # + rlw%I2nm. %4,%1,%h2,%m3,%M3 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") @@ -3951,22 +3756,22 @@ "") (define_insn "*rotlsi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:SI 3 "mask_operand" "n,n,n,n")) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "" "@ - rlwnm. %0,%1,%2,%m3,%M3 - rlwinm. %0,%1,%h2,%m3,%M3 - # + rlw%I2nm. %0,%1,%h2,%m3,%M3 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") @@ -3996,7 +3801,8 @@ [(set (attr "cell_micro") (if_then_else (match_operand:SI 2 "const_int_operand" "") (const_string "not") - (const_string "always")))]) + (const_string "always"))) + (set_attr "type" "shift")]) (define_insn "*rotlsi3_internal7be" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -4009,41 +3815,42 @@ [(set (attr "cell_micro") (if_then_else (match_operand:SI 2 "const_int_operand" "") (const_string "not") - (const_string "always")))]) + (const_string "always"))) + (set_attr "type" "shift")]) (define_insn "*rotlsi3_internal8le" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "!BYTES_BIG_ENDIAN" "@ - rlwnm. %3,%1,%2,0xff - rlwinm. %3,%1,%h2,0xff - # + rlw%I2nm. %3,%1,%h2,0xff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_insn "*rotlsi3_internal8be" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "BYTES_BIG_ENDIAN" "@ - rlwnm. %3,%1,%2,0xff - rlwinm. %3,%1,%h2,0xff - # + rlw%I2nm. %3,%1,%h2,0xff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") @@ -4082,40 +3889,40 @@ "") (define_insn "*rotlsi3_internal9le" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "!BYTES_BIG_ENDIAN" "@ - rlwnm. %0,%1,%2,0xff - rlwinm. %0,%1,%h2,0xff - # + rlw%I2nm. %0,%1,%h2,0xff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_insn "*rotlsi3_internal9be" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))] "BYTES_BIG_ENDIAN" "@ - rlwnm. %0,%1,%2,0xff - rlwinm. %0,%1,%h2,0xff - # + rlw%I2nm. %0,%1,%h2,0xff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") @@ -4152,62 +3959,60 @@ "") (define_insn "*rotlsi3_internal10le" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))] + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")) 0)))] "!BYTES_BIG_ENDIAN" - "@ - rlwnm %0,%1,%2,0xffff - rlwinm %0,%1,%h2,0xffff" - [(set_attr "type" "var_shift_rotate,integer")]) + "rlw%I2nm %0,%1,%h2,0xffff" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*rotlsi3_internal10be" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extend:SI (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 2)))] + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")) 2)))] "BYTES_BIG_ENDIAN" - "@ - rlwnm %0,%1,%2,0xffff - rlwinm %0,%1,%h2,0xffff" - [(set_attr "type" "var_shift_rotate,integer")]) + "rlw%I2nm %0,%1,%h2,0xffff" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*rotlsi3_internal11le" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "!BYTES_BIG_ENDIAN" "@ - rlwnm. %3,%1,%2,0xffff - rlwinm. %3,%1,%h2,0xffff - # + rlw%I2nm. %3,%1,%h2,0xffff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_insn "*rotlsi3_internal11be" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2)) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] + (clobber (match_scratch:SI 3 "=r,r"))] "BYTES_BIG_ENDIAN" "@ - rlwnm. %3,%1,%2,0xffff - rlwinm. %3,%1,%h2,0xffff - # + rlw%I2nm. %3,%1,%h2,0xffff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") @@ -4246,40 +4051,40 @@ "") (define_insn "*rotlsi3_internal12le" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 0)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "!BYTES_BIG_ENDIAN" "@ - rlwnm. %0,%1,%2,0xffff - rlwinm. %0,%1,%h2,0xffff - # + rlw%I2nm. %0,%1,%h2,0xffff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_insn "*rotlsi3_internal12be" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") + [(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,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2)) + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 2)) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))] "BYTES_BIG_ENDIAN" "@ - rlwnm. %0,%1,%2,0xffff - rlwinm. %0,%1,%h2,0xffff - # + rlw%I2nm. %0,%1,%h2,0xffff #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") @@ -4315,86 +4120,74 @@ (const_int 0)))] "") -(define_insn "ashlsi3" - [(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")))] + +(define_insn "ashl3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")))] "" - "@ - slw %0,%1,%2 - slwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) + "sl%I2 %0,%1,%2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*ashlsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] "TARGET_POWERPC64" - "@ - slw %0,%1,%2 - slwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) + "slw%I2 %0,%1,%h2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(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")) +(define_insn_and_split "*ashl3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - slw. %3,%1,%2 - slwi. %3,%1,%h2 - # + sl%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift: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_32BIT && reload_completed" - [(set (match_dup 3) - (ashift:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (ashift:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(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")) +(define_insn_and_split "*ashl3_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashift:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (ashift:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - slw. %0,%1,%2 - slwi. %0,%1,%h2 - # + sl%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift: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_32BIT && reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" [(set (match_dup 0) - (ashift:SI (match_dup 1) (match_dup 2))) + (ashift:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + (define_insn "rlwinm" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -4402,7 +4195,8 @@ (match_operand:SI 2 "const_int_operand" "i")) (match_operand:SI 3 "mask_operand" "n")))] "includes_lshift_p (operands[2], operands[3])" - "rlwinm %0,%1,%h2,%m3,%M3") + "rlwinm %0,%1,%h2,%m3,%M3" + [(set_attr "type" "shift")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -4416,7 +4210,8 @@ "@ rlwinm. %4,%1,%h2,%m3,%M3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4449,7 +4244,8 @@ "@ rlwinm. %0,%1,%h2,%m3,%M3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4469,91 +4265,74 @@ (const_int 0)))] "") -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))] + +(define_insn "lshr3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")))] "" - "@ - mr %0,%1 - srw %0,%1,%2 - srwi %0,%1,%h2" - [(set_attr "type" "integer,var_shift_rotate,shift")]) + "sr%I2 %0,%1,%2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*lshrsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] "TARGET_POWERPC64" - "@ - srw %0,%1,%2 - srwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) + "srw%I2 %0,%1,%h2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(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" "O,r,i,O,r,i")) +(define_insn_and_split "*lshr3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))] - "TARGET_32BIT" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - mr. %1,%1 - srw. %3,%1,%2 - srwi. %3,%1,%h2 - # - # + sr%I2. %0,%1,%2 #" - [(set_attr "type" "fast_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,4,8,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (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_32BIT && reload_completed" - [(set (match_dup 3) - (lshiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (lshiftrt:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i")) +(define_insn_and_split "*lshr3_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r") - (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (lshiftrt:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - mr. %0,%1 - srw. %0,%1,%2 - srwi. %0,%1,%h2 - # - # + sr%I2. %0,%1,%2 #" - [(set_attr "type" "fast_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,4,8,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt: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" "") - (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT && reload_completed" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" [(set (match_dup 0) - (lshiftrt:SI (match_dup 1) (match_dup 2))) + (lshiftrt:GPR (match_dup 1) + (match_dup 2))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -4561,7 +4340,8 @@ (match_operand:SI 2 "const_int_operand" "i")) (match_operand:SI 3 "mask_operand" "n")))] "includes_rshift_p (operands[2], operands[3])" - "rlwinm %0,%1,%s2,%m3,%M3") + "rlwinm %0,%1,%s2,%m3,%M3" + [(set_attr "type" "shift")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -4575,7 +4355,8 @@ "@ rlwinm. %4,%1,%s2,%m3,%M3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4608,7 +4389,8 @@ "@ rlwinm. %0,%1,%s2,%m3,%M3 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4635,7 +4417,8 @@ (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) 0)))] "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))" - "rlwinm %0,%1,%s2,0xff") + "rlwinm %0,%1,%s2,0xff" + [(set_attr "type" "shift")]) (define_insn "*lshiftrt_internal1be" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -4644,7 +4427,8 @@ (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) 3)))] "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))" - "rlwinm %0,%1,%s2,0xff") + "rlwinm %0,%1,%s2,0xff" + [(set_attr "type" "shift")]) (define_insn "*lshiftrt_internal2le" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -4659,7 +4443,8 @@ "@ rlwinm. %3,%1,%s2,0xff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_insn "*lshiftrt_internal2be" @@ -4675,7 +4460,8 @@ "@ rlwinm. %3,%1,%s2,0xff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4730,7 +4516,8 @@ "@ rlwinm. %0,%1,%s2,0xff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_insn "*lshiftrt_internal3be" @@ -4747,7 +4534,8 @@ "@ rlwinm. %0,%1,%s2,0xff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4793,7 +4581,8 @@ (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) 0)))] "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))" - "rlwinm %0,%1,%s2,0xffff") + "rlwinm %0,%1,%s2,0xffff" + [(set_attr "type" "shift")]) (define_insn "*lshiftrt_internal4be" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -4802,7 +4591,8 @@ (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) 2)))] "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))" - "rlwinm %0,%1,%s2,0xffff") + "rlwinm %0,%1,%s2,0xffff" + [(set_attr "type" "shift")]) (define_insn "*lshiftrt_internal5le" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -4817,7 +4607,8 @@ "@ rlwinm. %3,%1,%s2,0xffff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_insn "*lshiftrt_internal5be" @@ -4833,7 +4624,8 @@ "@ rlwinm. %3,%1,%s2,0xffff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4888,7 +4680,8 @@ "@ rlwinm. %0,%1,%s2,0xffff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_insn "*lshiftrt_internal5be" @@ -4905,7 +4698,8 @@ "@ rlwinm. %0,%1,%s2,0xffff #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split @@ -4944,71 +4738,95 @@ (const_int 0)))] "") -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] + +(define_expand "ashr3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") + (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:SI 2 "reg_or_cint_operand" "")))] "" - "@ - sraw %0,%1,%2 - srawi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) +{ + /* The generic code does not generate optimal code for the low word + (it should be a rlwimi and a rot). Until we have target code to + solve this generically, keep this expander. */ + + if (mode == DImode && !TARGET_POWERPC64) + { + if (CONST_INT_P (operands[2])) + { + emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2])); + DONE; + } + else + FAIL; + } +}) + +(define_insn "*ashr3" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn")))] + "" + "sra%I2 %0,%1,%2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) (define_insn "*ashrsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (sign_extend:DI + (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] "TARGET_POWERPC64" - "@ - sraw %0,%1,%2 - srawi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) + "sraw%I2 %0,%1,%h2" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn_and_split "*ashr3_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" + (clobber (match_scratch:GPR 0 "=r,r"))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - sraw. %3,%1,%2 - srawi. %3,%1,%h2 - # + sra%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ashiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (ashiftrt:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) (const_int 0)))] - "") + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn_and_split "*ashr3_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "" + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (ashiftrt:GPR (match_dup 1) + (match_dup 2)))] + "mode == Pmode && rs6000_gen_cell_microcode" "@ - sraw. %0,%1,%2 - srawi. %0,%1,%h2 - # + sra%I2. %0,%1,%2 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (ashiftrt:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) ;; Builtins to replace a division to generate FRE reciprocal estimate ;; instructions and the necessary fixup instructions @@ -5049,22 +4867,6 @@ DONE; }) -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ashiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - ;; Floating-point insns, excluding normal data motion. We combine the SF/DF ;; modes here, and also add in conditional vsx/power8-vector support to access ;; values in the traditional Altivec registers if the appropriate @@ -5253,25 +5055,7 @@ emit_note (NOTE_INSN_DELETED); DONE; } - [(set_attr_alternative "type" - [(const_string "fp") - (const_string "fp") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (const_string "fp") - (const_string "vecsimple") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload")))])]) + [(set_attr "type" "fp,fp,fpload,fp,vecsimple,fpload")]) (define_expand "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -5616,7 +5400,7 @@ ; We don't define lfiwax/lfiwzx with the normal definition, because we ; don't want to support putting SImode in FPR registers. (define_insn "lfiwax" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm") + [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] UNSPEC_LFIWAX))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" @@ -5676,7 +5460,7 @@ [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,") (float:SFDF (sign_extend:DI - (match_operand:SI 1 "memory_operand" "Z,Z")))) + (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) (clobber (match_scratch:DI 2 "=0,d"))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && " @@ -5696,7 +5480,7 @@ (set_attr "type" "fpload")]) (define_insn "lfiwzx" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wm,!wm") + [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] UNSPEC_LFIWZX))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" @@ -5751,7 +5535,7 @@ [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,") (unsigned_float:SFDF (zero_extend:DI - (match_operand:SI 1 "memory_operand" "Z,Z")))) + (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) (clobber (match_scratch:DI 2 "=0,d"))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && " @@ -6477,9 +6261,8 @@ (define_expand "floatdisf2_internal2" [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") (const_int 53))) - (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1) - (const_int 2047))) - (clobber (scratch:CC))]) + (set (match_operand:DI 0 "" "") (and:DI (match_dup 1) + (const_int 2047))) (set (match_dup 3) (plus:DI (match_dup 3) (const_int 1))) (set (match_dup 0) (plus:DI (match_dup 0) @@ -6488,9 +6271,8 @@ (const_int 2))) (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 1))) - (parallel [(set (match_dup 0) (and:DI (match_dup 0) - (const_int -2048))) - (clobber (scratch:CC))]) + (set (match_dup 0) (and:DI (match_dup 0) + (const_int -2048))) (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) (label_ref (match_operand:DI 2 "" "")) (pc))) @@ -6535,6 +6317,49 @@ [(set_attr "length" "8") (set_attr "type" "fpload")]) +;; Define the TImode operations that can be done in a small number +;; of instructions. The & constraints are to prevent the register +;; allocator from allocating registers that overlap with the inputs +;; (for example, having an input in 7,8 and an output in 6,7). We +;; also allow for the output being the same as one of the inputs. + +(define_insn "addti3" + [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r") + (plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0") + (match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))] + "TARGET_64BIT" +{ + if (WORDS_BIG_ENDIAN) + return (GET_CODE (operands[2])) != CONST_INT + ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\" + : \"addic %L0,%L1,%2\;add%G2e %0,%1\"; + else + return (GET_CODE (operands[2])) != CONST_INT + ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\" + : \"addic %0,%1,%2\;add%G2e %L0,%L1\"; +} + [(set_attr "type" "two") + (set_attr "length" "8")]) + +(define_insn "subti3" + [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r") + (minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I") + (match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))] + "TARGET_64BIT" +{ + if (WORDS_BIG_ENDIAN) + return (GET_CODE (operands[1]) != CONST_INT) + ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\" + : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\"; + else + return (GET_CODE (operands[1]) != CONST_INT) + ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\" + : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\"; +} + [(set_attr "type" "two") + (set_attr "length" "8")]) + + ;; Define the DImode operations that can be done in a small number ;; of instructions. The & constraints are to prevent the register ;; allocator from allocating registers that overlap with the inputs @@ -6577,1813 +6402,879 @@ : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\"; }" [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*negdi2_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"subfic %L0,%L1,0\;subfze %0,%1\" - : \"subfic %0,%1,0\;subfze %L0,%L1\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\"; -} - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "smulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhw %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "umulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhwu %0,%1,%2" - [(set_attr "type" "imul")]) - -;; Shift by a variable amount is too complex to be worth open-coding. We -;; just handle shifts by constants. -(define_insn "ashrdi3_no_power" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "M,i")))] - "!TARGET_POWERPC64" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - if (WORDS_BIG_ENDIAN) - return \"srawi %0,%1,31\;srawi %L0,%1,%h2\"; - else - return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\"; - case 1: - if (WORDS_BIG_ENDIAN) - return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\"; - else - return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\"; - } -}" - [(set_attr "type" "two,three") - (set_attr "length" "8,12")]) - -(define_insn "*ashrdisi3_noppc64be" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (const_int 32)) 4))] - "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"\"; - else - return \"mr %0,%1\"; -}" - [(set_attr "length" "4")]) - - -;; PowerPC64 DImode operations. - -(define_insn "muldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I")))] - "TARGET_POWERPC64" - "@ - mulld %0,%1,%2 - mulli %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 2 "s8bit_cint_operand" "") - (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") - (const_string "imul2")] - (const_string "lmul")))]) - -(define_insn "*muldi3_internal1" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_POWERPC64" - "@ - mulld. %3,%1,%2 - #" - [(set_attr "type" "lmul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (mult:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*muldi3_internal2" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (mult:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - mulld. %0,%1,%2 - #" - [(set_attr "type" "lmul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (mult:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "smuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (sign_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (sign_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhd %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (zero_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhdu %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_expand "mulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - -(define_expand "umulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - -(define_insn "rotldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - rldcl %0,%1,%2,0 - rldicl %0,%1,%H2,0" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldcl. %3,%1,%2,0 - rldicl. %3,%1,%H2,0 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (rotate:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - rldcl. %0,%1,%2,0 - rldicl. %0,%1,%H2,0 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (rotate:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal4" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) - (match_operand:DI 3 "mask64_operand" "n,n")))] - "TARGET_POWERPC64" - "@ - rldc%B3 %0,%1,%2,%S3 - rldic%B3 %0,%1,%H2,%S3" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:DI 3 "mask64_operand" "n,n,n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldc%B3. %4,%1,%2,%S3 - rldic%B3. %4,%1,%H2,%S3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 4) - (and:DI (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:DI 3 "mask64_operand" "n,n,n,n")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_64BIT" - "@ - rldc%B3. %0,%1,%2,%S3 - rldic%B3. %0,%1,%H2,%S3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal7le" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,56 - rldicl %0,%1,%H2,56" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal7be" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 7)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,56 - rldicl %0,%1,%H2,56" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal8le" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,56 - rldicl. %3,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal8be" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,56 - rldicl. %3,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:QI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 7)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:QI - (rotate:DI (match_dup 1) - (match_dup 2)) 7))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal9le" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,56 - rldicl. %0,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal9be" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,56 - rldicl. %0,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 7)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal10le" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,48 - rldicl %0,%1,%H2,48" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal10be" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 6)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,48 - rldicl %0,%1,%H2,48" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal11le" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,48 - rldicl. %3,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal11be" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,48 - rldicl. %3,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:HI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 6)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:HI - (rotate:DI (match_dup 1) - (match_dup 2)) 6))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal12le" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,48 - rldicl. %0,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal12be" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,48 - rldicl. %0,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 6)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal13le" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,32 - rldicl %0,%1,%H2,32" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal13be" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 4)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" - "@ - rldcl %0,%1,%2,32 - rldicl %0,%1,%H2,32" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal14le" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,32 - rldicl. %3,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal14be" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %3,%1,%2,32 - rldicl. %3,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:SI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 4)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:SI - (rotate:DI (match_dup 1) - (match_dup 2)) 4))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal15le" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT && !BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,32 - rldicl. %0,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*rotldi3_internal15be" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))] - "TARGET_64BIT && BYTES_BIG_ENDIAN" - "@ - rldcl. %0,%1,%2,32 - rldicl. %0,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 4)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))] - "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "*ashldi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - sld %0,%1,%2 - sldi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) + (set_attr "length" "8")]) -(define_insn "*ashldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - sld. %3,%1,%2 - sldi. %3,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) +(define_insn "*negdi2_noppc64" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") + (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))] + "! TARGET_POWERPC64" + "* +{ + return (WORDS_BIG_ENDIAN) + ? \"subfic %L0,%L1,0\;subfze %0,%1\" + : \"subfic %0,%1,0\;subfze %L0,%L1\"; +}" + [(set_attr "type" "two") + (set_attr "length" "8")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") -(define_insn "*ashldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - sld. %0,%1,%2 - sldi. %0,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) +;; Shift by a variable amount is too complex to be worth open-coding. We +;; just handle shifts by constants. +(define_insn "ashrdi3_no_power" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") + (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "M,i")))] + "!TARGET_POWERPC64" + "* +{ + switch (which_alternative) + { + default: + gcc_unreachable (); + case 0: + if (WORDS_BIG_ENDIAN) + return \"srawi %0,%1,31\;srawi %L0,%1,%h2\"; + else + return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\"; + case 1: + if (WORDS_BIG_ENDIAN) + return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\"; + else + return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\"; + } +}" + [(set_attr "type" "two,three") + (set_attr "length" "8,12")]) -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") +(define_insn "*ashrdisi3_noppc64be" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 32)) 4))] + "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN" + "* +{ + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"\"; + else + return \"mr %0,%1\"; +}" + [(set_attr "length" "4")]) -(define_insn "*ashldi3_internal4" + +;; PowerPC64 DImode operations. + +(define_insn "*rotldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "const_int_operand" "n")))] - "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" - "rldic %0,%1,%H2,%W3") + (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) + (match_operand:DI 3 "mask64_operand" "n")))] + "TARGET_POWERPC64" + "rld%I2c%B3 %0,%1,%H2,%S3" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(define_insn "ashldi3_internal5" +(define_insn "*rotldi3_internal5" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (const_int 0))) + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) + (match_operand:DI 3 "mask64_operand" "n,n")) + (const_int 0))) (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" + "TARGET_64BIT" "@ - rldic. %4,%1,%H2,%W3 + rld%I2c%B3. %4,%1,%H2,%S3 #" - [(set_attr "type" "compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" + "TARGET_POWERPC64 && reload_completed" [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) + (and:DI (rotate:DI (match_dup 1) + (match_dup 2)) + (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*ashldi3_internal6" +(define_insn "*rotldi3_internal6" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (const_int 0))) + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) + (match_operand:DI 3 "mask64_operand" "n,n")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT" "@ - rldic. %0,%1,%H2,%W3 + rld%I2c%B3. %0,%1,%H2,%S3 #" - [(set_attr "type" "compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) + (compare:CC (and:DI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) + (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*ashldi3_internal7" +(define_insn "*rotldi3_internal7le" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "n")))] - "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" - "rldicr %0,%1,%H2,%S3") + (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,56" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(define_insn "ashldi3_internal8" +(define_insn "*rotldi3_internal7be" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 7)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,56" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) + +(define_insn "*rotldi3_internal8le" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r"))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" "@ - rldicr. %4,%1,%H2,%S3 + rld%I2cl. %3,%1,%H2,56 #" - [(set_attr "type" "compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal9" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "n,n")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" +(define_insn "*rotldi3_internal8be" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r"))] + "TARGET_64BIT && BYTES_BIG_ENDIAN" "@ - rldicr. %0,%1,%H2,%S3 + rld%I2cl. %3,%1,%H2,56 #" - [(set_attr "type" "compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:QI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) (const_int 0)))] "") -(define_expand "lshrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "*lshrdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - srd %0,%1,%2 - srdi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*lshrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT " - "@ - srd. %3,%1,%2 - srdi. %3,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 7)) (const_int 0))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" [(set (match_dup 3) - (lshiftrt:DI (match_dup 1) (match_dup 2))) + (zero_extend:DI (subreg:QI + (rotate:DI (match_dup 1) + (match_dup 2)) 7))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*lshrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn "*rotldi3_internal9le" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" "@ - srd. %0,%1,%2 - srdi. %0,%1,%H2 - # + rld%I2cl. %0,%1,%H2,56 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + +(define_insn "*rotldi3_internal9be" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 7)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))] + "TARGET_64BIT && BYTES_BIG_ENDIAN" + "@ + rld%I2cl. %0,%1,%H2,56 + #" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" [(set (match_dup 0) - (lshiftrt:DI (match_dup 1) (match_dup 2))) + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_expand "ashrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "" - " -{ - if (TARGET_POWERPC64) - ; - else if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2])); - DONE; - } - else - FAIL; -}") +(define_split + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:QI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 7)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") -(define_insn "*ashrdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" +(define_insn "*rotldi3_internal10le" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,48" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) + +(define_insn "*rotldi3_internal10be" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 6)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,48" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) + +(define_insn "*rotldi3_internal11le" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r"))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" "@ - srad %0,%1,%2 - sradi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) + rld%I2cl. %3,%1,%H2,48 + #" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*ashrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) +(define_insn "*rotldi3_internal11be" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6)) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:DI 3 "=r,r"))] + "TARGET_64BIT && BYTES_BIG_ENDIAN" "@ - srad. %3,%1,%2 - sradi. %3,%1,%H2 - # + rld%I2cl. %3,%1,%H2,48 #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" [(set (match_dup 3) - (ashiftrt:DI (match_dup 1) (match_dup 2))) + (zero_extend:DI (subreg:HI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*ashrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - srad. %0,%1,%2 - sradi. %0,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - (define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 6)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:HI + (rotate:DI (match_dup 1) + (match_dup 2)) 6))) + (set (match_dup 0) + (compare:CC (match_dup 3) (const_int 0)))] "") -(define_expand "anddi3" - [(parallel - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] - "" -{ - if (!TARGET_POWERPC64) - { - rtx cc = gen_rtx_SCRATCH (CCmode); - rs6000_split_logical (operands, AND, false, false, false, cc); - DONE; - } - else if (!and64_2_operand (operands[2], DImode)) - operands[2] = force_reg (DImode, operands[2]); -}) - -(define_insn "anddi3_mc" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t"))) - (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rldic%B2 %0,%1,0,%S2 - rlwinm %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - #" - [(set_attr "type" "*,*,*,fast_compare,fast_compare,*") - (set_attr "length" "4,4,4,4,4,8")]) - -(define_insn "anddi3_nomc" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "?r,S,T,t"))) - (clobber (match_scratch:CC 3 "=X,X,X,X"))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" +(define_insn "*rotldi3_internal12le" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" "@ - and %0,%1,%2 - rldic%B2 %0,%1,0,%S2 - rlwinm %0,%1,0,%m2,%M2 + rld%I2cl. %0,%1,%H2,48 #" - [(set_attr "length" "4,4,4,8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" ""))) - (clobber (match_scratch:CC 3 ""))] - "TARGET_POWERPC64 - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) - (match_dup 4)) - (match_dup 5))) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (match_dup 6)) - (match_dup 7)))] -{ - build_mask64_2_operands (operands[2], &operands[4]); -}) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*anddi3_internal2_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) +(define_insn "*rotldi3_internal12be" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 6)) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))] + "TARGET_64BIT && BYTES_BIG_ENDIAN" "@ - and. %3,%1,%2 - rldic%B2. %3,%1,0,%S2 - rlwinm. %3,%1,0,%m2,%M2 - andi. %3,%1,%b2 - andis. %3,%1,%u2 - # - # - # - # - # - # + rld%I2cl. %0,%1,%H2,48 #" - [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\ - fast_compare,compare,compare,compare,compare,compare,\ - compare,compare") - (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 3) - (and:DI (rotate:DI (match_dup 1) - (match_dup 5)) - (match_dup 6))) - (parallel [(set (match_dup 0) - (compare:CC (and:DI (rotate:DI (match_dup 3) - (match_dup 7)) - (match_dup 8)) - (const_int 0))) - (clobber (match_dup 3))])] - " -{ - build_mask64_2_operands (operands[2], &operands[5]); -}") - -(define_insn "*anddi3_internal3_mc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" - "@ - and. %0,%1,%2 - rldic%B2. %0,%1,0,%S2 - rlwinm. %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - # - # - # - # - # - # - #" - [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\ - fast_compare,compare,compare,compare,compare,compare,\ - compare,compare") - (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") (define_split [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and64_2_operand" "")) + (compare:CC (zero_extend:DI + (subreg:HI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 6)) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed" - [(parallel [(set (match_dup 0) - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_dup 4))]) + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6))) (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:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) - (match_dup 5)) - (match_dup 6))) - (parallel [(set (match_dup 3) - (compare:CC (and:DI (rotate:DI (match_dup 0) - (match_dup 7)) - (match_dup 8)) - (const_int 0))) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (match_dup 7)) - (match_dup 8)))])] - " -{ - build_mask64_2_operands (operands[2], &operands[5]); -}") - -(define_expand "iordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "" -{ - if (!TARGET_POWERPC64) - { - rs6000_split_logical (operands, IOR, false, false, false, NULL_RTX); - DONE; - } - else if (!reg_or_logical_cint_operand (operands[2], DImode)) - operands[2] = force_reg (DImode, operands[2]); - else if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - value = INTVAL (operands[2]); - emit_insn (gen_iordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - - emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}) - -(define_expand "xordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] - "" -{ - if (!TARGET_POWERPC64) - { - rs6000_split_logical (operands, XOR, false, false, false, NULL_RTX); - DONE; - } - else if (!reg_or_logical_cint_operand (operands[2], DImode)) - operands[2] = force_reg (DImode, operands[2]); - if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - value = INTVAL (operands[2]); - emit_insn (gen_xordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); +(define_insn "*rotldi3_internal13le" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,32" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) - emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}) +(define_insn "*rotldi3_internal13be" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_cint_operand" "rn")) 4)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN" + "rld%I2cl %0,%1,%H2,32" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes")]) -(define_insn "*booldi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") - (match_operator:DI 3 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,JF")]))] - "TARGET_POWERPC64" +(define_insn "*rotldi3_internal14le" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) + (const_int 0))) + (clobber (match_scratch:DI 3 "=r,r"))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" "@ - %q3 %0,%1,%2 - %q3i %0,%1,%b2 - %q3is %0,%1,%u2") + rld%I2cl. %3,%1,%H2,32 + #" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) -(define_insn "*booldi3_internal2" +(define_insn "*rotldi3_internal14be" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4)) + (const_int 0))) (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_64BIT" + "TARGET_64BIT && BYTES_BIG_ENDIAN" "@ - %q4. %3,%1,%2 + rld%I2cl. %3,%1,%H2,32 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")]) - (const_int 0))) + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) (match_dup 4)) + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:SI + (rotate:DI (match_dup 1) + (match_dup 2)) 0))) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") + +(define_split + [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 4)) + (const_int 0))) + (clobber (match_scratch:DI 3 ""))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 3) + (zero_extend:DI (subreg:SI + (rotate:DI (match_dup 1) + (match_dup 2)) 4))) (set (match_dup 0) (compare:CC (match_dup 3) (const_int 0)))] "") -(define_insn "*booldi3_internal3" +(define_insn "*rotldi3_internal15le" [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 0)) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_64BIT" + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_64BIT && !BYTES_BIG_ENDIAN" + "@ + rld%I2cl. %0,%1,%H2,32 + #" + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + +(define_insn "*rotldi3_internal15be" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_cint_operand" "rn,rn")) 4)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))] + "TARGET_64BIT && BYTES_BIG_ENDIAN" "@ - %q4. %0,%1,%2 + rld%I2cl. %0,%1,%H2,32 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "maybe_var_shift" "yes") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "gpc_reg_operand" "")]) - (const_int 0))) + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) + (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] + "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) (set (match_dup 3) (compare:CC (match_dup 0) (const_int 0)))] "") -;; 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:DI 0 "gpc_reg_operand" "") - (match_operator:DI 3 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")]))] - "TARGET_POWERPC64" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 0) (match_dup 5))] -" -{ - rtx i3,i4; - - i3 = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - i4 = GEN_INT (INTVAL (operands[2]) & 0xffff); - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, - operands[1], i3); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, - operands[0], i4); -}") + [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") + (compare:CC (zero_extend:DI + (subreg:SI + (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "reg_or_cint_operand" "")) 4)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))] + "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed" + [(set (match_dup 0) + (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") -(define_insn "*boolcdi3_internal1" +(define_insn "*ashldi3_internal4" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 3 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")]))] - "TARGET_POWERPC64" - "%q3 %0,%2,%1") + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:DI 3 "const_int_operand" "n")))] + "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" + "rldic %0,%1,%H2,%W3" + [(set_attr "type" "shift")]) -(define_insn "*boolcdi3_internal2" +(define_insn "ashldi3_internal5" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")]) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "const_int_operand" "n,n")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:DI 4 "=r,r"))] + "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" "@ - %q4. %3,%2,%1 + rldic. %4,%1,%H2,%W3 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")]) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "const_int_operand" "")) (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) (match_dup 4)) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed + && includes_rldic_lshift_p (operands[2], operands[3])" + [(set (match_dup 4) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) (set (match_dup 0) - (compare:CC (match_dup 3) + (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*boolcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) - (match_operand:DI 2 "gpc_reg_operand" "r,r")]) +(define_insn "*ashldi3_internal6" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "const_int_operand" "n,n")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_64BIT" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" "@ - %q4. %0,%2,%1 + rldic. %0,%1,%H2,%W3 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (match_operand:DI 2 "gpc_reg_operand" "")]) + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "const_int_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed + && includes_rldic_lshift_p (operands[2], operands[3])" + [(set (match_dup 0) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -(define_insn "*boolccdi3_internal1" +(define_insn "*ashldi3_internal7" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 3 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))]))] - "TARGET_POWERPC64" - "%q3 %0,%1,%2") + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:DI 3 "mask64_operand" "n")))] + "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" + "rldicr %0,%1,%H2,%S3" + [(set_attr "type" "shift")]) -(define_insn "*boolccdi3_internal2" +(define_insn "ashldi3_internal8" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))]) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_64BIT" + (clobber (match_scratch:DI 4 "=r,r"))] + "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" "@ - %q4. %3,%1,%2 + rldicr. %4,%1,%H2,%S3 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) (match_dup 4)) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed + && includes_rldicr_lshift_p (operands[2], operands[3])" + [(set (match_dup 4) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) (set (match_dup 0) - (compare:CC (match_dup 3) + (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*boolccdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))]) +(define_insn "*ashldi3_internal9" + [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_64BIT" + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" "@ - %q4. %0,%1,%2 + rldicr. %0,%1,%H2,%S3 #" - [(set_attr "type" "fast_compare,compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "4,8")]) (define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) + [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") + (compare:CC + (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:DI 3 "mask64_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + "TARGET_POWERPC64 && reload_completed + && includes_rldicr_lshift_p (operands[2], operands[3])" + [(set (match_dup 0) + (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (match_dup 3))) + (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") -;; Eqv operation. -(define_insn "*eqv3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (not:GPR - (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r"))))] + +(define_insn_and_split "*anddi3_2rld" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r") + (match_operand:DI 2 "and_2rld_operand" "n")))] + "TARGET_POWERPC64" + "#" "" - "eqv %0,%1,%2" - [(set_attr "type" "integer") - (set_attr "length" "4")]) + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 4)) + (match_dup 5))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)))] +{ + build_mask64_2_operands (operands[2], &operands[4]); +} + [(set_attr "length" "8")]) + +(define_insn_and_split "*anddi3_2rld_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "and_2rld_operand" "n,n")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=r,r"))] + "TARGET_64BIT && rs6000_gen_cell_microcode" + "@ + # + #" + "&& reload_completed" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 4)) + (match_dup 5))) + (parallel [(set (match_dup 3) + (compare:CC (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)) + (const_int 0))) + (clobber (match_dup 0))])] +{ + build_mask64_2_operands (operands[2], &operands[4]); +} + [(set_attr "type" "compare") + (set_attr "dot" "yes") + (set_attr "length" "8,12")]) +(define_insn_and_split "*anddi3_2rld_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") + (match_operand:DI 2 "and_2rld_operand" "n,n")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (and:DI (match_dup 1) + (match_dup 2)))] + "TARGET_64BIT && rs6000_gen_cell_microcode" + "@ + # + #" + "&& reload_completed" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 4)) + (match_dup 5))) + (parallel [(set (match_dup 3) + (compare:CC (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)) + (const_int 0))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)))])] +{ + build_mask64_2_operands (operands[2], &operands[4]); +} + [(set_attr "type" "compare") + (set_attr "dot" "yes") + (set_attr "length" "8,12")]) ;; 128-bit logical operations expanders (define_expand "and3" - [(parallel [(set (match_operand:BOOL_128 0 "vlogical_operand" "") - (and:BOOL_128 - (match_operand:BOOL_128 1 "vlogical_operand" "") - (match_operand:BOOL_128 2 "vlogical_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] + [(set (match_operand:BOOL_128 0 "vlogical_operand" "") + (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") + (match_operand:BOOL_128 2 "vlogical_operand" "")))] "" "") @@ -8456,8 +7347,7 @@ [(set (match_operand:BOOL_128 0 "vlogical_operand" "=") (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "%") - (match_operand:BOOL_128 2 "vlogical_operand" ""))) - (clobber (match_scratch:CC 3 ""))] + (match_operand:BOOL_128 2 "vlogical_operand" "")))] "" { if (TARGET_VSX && vsx_register_operand (operands[0], mode)) @@ -8471,7 +7361,7 @@ "reload_completed && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, AND, false, false, false, operands[3]); + rs6000_split_logical (operands, AND, false, false, false); DONE; } [(set (attr "type") @@ -8507,8 +7397,7 @@ "reload_completed && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false, - NULL_RTX); + rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); DONE; } [(set (attr "type") @@ -8546,8 +7435,7 @@ && reload_completed && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false, - NULL_RTX); + rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false); DONE; } [(set (attr "type") @@ -8575,8 +7463,7 @@ "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false, - NULL_RTX); + rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false); DONE; } [(set_attr "type" "integer") @@ -8608,8 +7495,7 @@ && reload_completed && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true, - NULL_RTX); + rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); DONE; } [(set (attr "type") @@ -8638,8 +7524,7 @@ "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true, - NULL_RTX); + rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); DONE; } [(set_attr "type" "integer") @@ -8668,7 +7553,7 @@ && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX); + rs6000_split_logical (operands, XOR, true, false, false); DONE; } [(set (attr "type") @@ -8696,7 +7581,7 @@ "reload_completed && !TARGET_P8_VECTOR" [(const_int 0)] { - rs6000_split_logical (operands, XOR, true, false, false, NULL_RTX); + rs6000_split_logical (operands, XOR, true, false, false); DONE; } [(set_attr "type" "integer") @@ -8724,7 +7609,7 @@ "reload_completed && int_reg_operand (operands[0], mode)" [(const_int 0)] { - rs6000_split_logical (operands, NOT, false, false, false, NULL_RTX); + rs6000_split_logical (operands, NOT, false, false, false); DONE; } [(set (attr "type") @@ -8828,31 +7713,7 @@ mt%0 %1 mt%0 %1 nop" - [(set_attr_alternative "type" - [(const_string "*") - (const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "mfjmpr") - (const_string "mtjmpr") - (const_string "*") - (const_string "*")]) - + [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*") (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")]) (define_insn "*movsi_internal1_single" @@ -8874,44 +7735,7 @@ nop stfs%U0%X0 %1,%0 lfs%U1%X1 %0,%1" - [(set_attr_alternative "type" - [(const_string "*") - (const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "mfjmpr") - (const_string "mtjmpr") - (const_string "*") - (const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload")))]) + [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload") (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) ;; Split a load of a large constant into the appropriate two-insn @@ -8928,9 +7752,8 @@ (ior:SI (match_dup 0) (match_dup 3)))] " -{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2); - - if (tem == operands[0]) +{ + if (rs6000_emit_set_const (operands[0], operands[1])) DONE; else FAIL; @@ -8946,7 +7769,8 @@ cmpi %2,%0,0 mr. %0,%1 #" - [(set_attr "type" "cmp,fast_compare,cmp") + [(set_attr "type" "cmp,logical,cmp") + (set_attr "dot" "yes") (set_attr "length" "4,4,8")]) (define_split @@ -8974,26 +7798,7 @@ mf%1 %0 mt%0 %1 nop" - [(set_attr_alternative "type" - [(const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "*") - (const_string "mfjmpr") - (const_string "mtjmpr") - (const_string "*")])]) + [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")]) (define_expand "mov" [(set (match_operand:INT 0 "general_operand" "") @@ -9014,26 +7819,7 @@ mf%1 %0 mt%0 %1 nop" - [(set_attr_alternative "type" - [(const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "*") - (const_string "mfjmpr") - (const_string "mtjmpr") - (const_string "*")])]) + [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")]) ;; Here is how to move condition codes around. When we store CC data in ;; an integer register or memory, we store just the high-order 4 bits. @@ -9074,23 +7860,9 @@ (eq_attr "alternative" "9") (const_string "mtjmpr") (eq_attr "alternative" "10") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], - VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) + (const_string "load") (eq_attr "alternative" "11") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], - VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) + (const_string "store") (match_test "TARGET_MFCRF") (const_string "mfcrf") ] @@ -9159,48 +7931,7 @@ nop # #" - [(set_attr_alternative "type" - [(const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "fp") - (const_string "vecsimple") - (const_string "vecsimple") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (const_string "fpload") - (const_string "fpstore") - (const_string "mftgpr") - (const_string "mffgpr") - (const_string "mtjmpr") - (const_string "mfjmpr") - (const_string "*") - (const_string "*") - (const_string "*")]) + [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*") (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")]) (define_insn "*mov_softfloat" @@ -9220,29 +7951,7 @@ # # nop" - [(set_attr_alternative "type" - [(const_string "*") - (const_string "mtjmpr") - (const_string "mfjmpr") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "*")]) + [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) @@ -9357,38 +8066,7 @@ # # #" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (const_string "fp") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (const_string "fpload")) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (const_string "fpstore")) - (const_string "vecsimple") - (const_string "vecsimple") - (const_string "store") - (const_string "load") - (const_string "two") - (const_string "fp") - (const_string "fp") - (const_string "*")]) + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*") (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")]) (define_insn "*mov_softfloat32" @@ -9396,7 +8074,8 @@ (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] "! TARGET_POWERPC64 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) - || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) + || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE + || (mode == DDmode && TARGET_E500_DOUBLE)) && (gpc_reg_operand (operands[0], mode) || gpc_reg_operand (operands[1], mode))" "#" @@ -9406,8 +8085,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*mov_hardfloat64" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wm") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wm,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wk") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wk,r"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], mode) || gpc_reg_operand (operands[1], mode))" @@ -9432,57 +8111,7 @@ mffgpr %0,%1 mfvsrd %0,%x1 mtvsrd %x0,%1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (const_string "fp") - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (const_string "fpload")) - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (const_string "fpstore")) - (const_string "vecsimple") - (const_string "vecsimple") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*") - (const_string "mtjmpr") - (const_string "mfjmpr") - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "mftgpr") - (const_string "mffgpr") - (const_string "mftgpr") - (const_string "mffgpr")]) + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr") (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")]) (define_insn "*mov_softfloat64" @@ -9501,28 +8130,7 @@ # # nop" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*") - (const_string "mtjmpr") - (const_string "mfjmpr") - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "*")]) + [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") (set_attr "length" "4,4,4,4,4,8,12,16,4")]) (define_expand "mov" @@ -9534,10 +8142,40 @@ ;; It's important to list Y->r and r->Y before r->r because otherwise ;; reload, given m->r, will try to pick r->r and reload it, which ;; doesn't make progress. -(define_insn_and_split "*mov_internal" + +;; We can't split little endian direct moves of TDmode, because the words are +;; not swapped like they are for TImode or TFmode. Subregs therefore are +;; problematical. Don't allow direct move for this case. + +(define_insn_and_split "*mov_64bit_dm" + [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r,r,wm") + (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r,wm,r"))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 + && (mode != TDmode || WORDS_BIG_ENDIAN) + && (gpc_reg_operand (operands[0], mode) + || gpc_reg_operand (operands[1], mode))" + "#" + "&& reload_completed" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } + [(set_attr "length" "8,8,8,12,12,8,8,8")]) + +(define_insn_and_split "*movtd_64bit_nodm" + [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") + (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN + && (gpc_reg_operand (operands[0], TDmode) + || gpc_reg_operand (operands[1], TDmode))" + "#" + "&& reload_completed" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } + [(set_attr "length" "8,8,8,12,12,8")]) + +(define_insn_and_split "*mov_32bit" [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r") (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r"))] - "TARGET_HARD_FLOAT && TARGET_FPRS + "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64 && (gpc_reg_operand (operands[0], mode) || gpc_reg_operand (operands[1], mode))" "#" @@ -9973,6 +8611,15 @@ [(set_attr "length" "12") (set_attr "type" "three")]) +(define_split + [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "") + (match_operand:FMOVE128_GPR 1 "input_operand" ""))] + "reload_completed + && (int_reg_operand (operands[0], mode) + || int_reg_operand (operands[1], mode))" + [(pc)] +{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) + ;; Move SFmode to a VSX from a GPR register. Because scalar floating point ;; type is stored internally as double precision in the VSX registers, we have ;; to convert it from the vector format. @@ -9982,7 +8629,7 @@ (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_P8V_RELOAD_FROM_GPR)) (clobber (match_operand:DI 2 "register_operand" "=r"))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && WORDS_BIG_ENDIAN" + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" "#" "&& reload_completed" [(const_int 0)] @@ -9990,13 +8637,16 @@ rtx op0 = operands[0]; rtx op1 = operands[1]; rtx op2 = operands[2]; - rtx op0_di = simplify_gen_subreg (DImode, op0, SFmode, 0); + /* Also use the destination register to hold the unconverted DImode value. + This is conceptually a separate value from OP0, so we use gen_rtx_REG + rather than simplify_gen_subreg. */ + rtx op0_di = gen_rtx_REG (DImode, REGNO (op0)); rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); /* Move SF value to upper 32-bits for xscvspdpn. */ emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); emit_move_insn (op0_di, op2); - emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); + emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di)); DONE; } [(set_attr "length" "8") @@ -10009,7 +8659,7 @@ [(set (match_operand:DF 0 "register_operand" "=r") (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] UNSPEC_P8V_RELOAD_FROM_VSX))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && WORDS_BIG_ENDIAN" + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" "mfvsrd %0,%x1" [(set_attr "type" "mftgpr")]) @@ -10019,7 +8669,7 @@ [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] UNSPEC_P8V_RELOAD_FROM_VSX)) (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && WORDS_BIG_ENDIAN" + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" "#" "&& reload_completed" [(const_int 0)] @@ -10046,7 +8696,7 @@ (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] UNSPEC_P8V_RELOAD_FROM_VSX)) (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && WORDS_BIG_ENDIAN" + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" "#" "&& reload_completed" [(const_int 0)] @@ -10068,7 +8718,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")] UNSPEC_P8V_RELOAD_FROM_VSX))] - "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && WORDS_BIG_ENDIAN" + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" "mfvsrd %0,%x1" [(set_attr "type" "mftgpr")]) @@ -10094,26 +8744,7 @@ lfd%U1%X1 %0,%1 fmr %0,%1 #" - [(set_attr_alternative "type" - [(const_string "store") - (const_string "load") - (const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (const_string "fp") - (const_string "*")])]) + [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")]) (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -10144,8 +8775,8 @@ { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wm") - (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wm,r"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi") + (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -10165,49 +8796,10 @@ mftgpr %0,%1 mffgpr %0,%1 mfvsrd %0,%x1 - mtvsrd %x0,%1" - [(set_attr_alternative "type" - [(if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "load_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "load_u") - (const_string "load"))) - (const_string "*") - (const_string "*") - (const_string "*") - (const_string "*") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_u") - (const_string "fpstore"))) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (if_then_else - (match_test "update_address_mem (operands[1], VOIDmode)") - (const_string "fpload_u") - (const_string "fpload"))) - (const_string "fp") - (const_string "mfjmpr") - (const_string "mtjmpr") - (const_string "*") - (const_string "mftgpr") - (const_string "mffgpr") - (const_string "mftgpr") - (const_string "mffgpr")]) - (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4")]) + mtvsrd %x0,%1 + xxlxor %x0,%x0,%x0" + [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple") + (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")]) ;; Generate all one-bits and clear left or right. ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber. @@ -10233,9 +8825,8 @@ [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] " -{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5); - - if (tem == operands[0]) +{ + if (rs6000_emit_set_const (operands[0], operands[1])) DONE; else FAIL; @@ -10243,14 +8834,13 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] + (match_operand:DI 1 "const_scalar_int_operand" ""))] "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] " -{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5); - - if (tem == operands[0]) +{ + if (rs6000_emit_set_const (operands[0], operands[1])) DONE; else FAIL; @@ -10290,7 +8880,9 @@ return \"#\"; } }" - [(set_attr "type" "store_ux,store_ux,load_ux,load_ux,*,*") + [(set_attr "type" "store,store,load,load,*,*") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING") (const_string "always") (const_string "conditional")))]) @@ -10309,7 +8901,7 @@ (define_split [(set (match_operand:TI2 0 "int_reg_operand" "") - (match_operand:TI2 1 "const_double_operand" ""))] + (match_operand:TI2 1 "const_scalar_int_operand" ""))] "TARGET_POWERPC64 && (VECTOR_MEM_NONE_P (mode) || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" @@ -10321,12 +8913,12 @@ mode); operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, mode); - if (GET_CODE (operands[1]) == CONST_DOUBLE) + if (CONST_WIDE_INT_P (operands[1])) { - operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); + operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); + operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); } - else if (GET_CODE (operands[1]) == CONST_INT) + else if (CONST_INT_P (operands[1])) { operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); operands[5] = operands[1]; @@ -10402,7 +8994,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 8" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_insn "*ldmsi7" @@ -10424,7 +9018,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 7" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_insn "*ldmsi6" @@ -10444,7 +9040,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 6" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_insn "*ldmsi5" @@ -10462,7 +9060,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 5" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_insn "*ldmsi4" @@ -10478,7 +9078,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 4" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_insn "*ldmsi3" @@ -10492,7 +9094,9 @@ "TARGET_STRING && XVECLEN (operands[0], 0) == 3" "* { return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "length" "32")]) (define_expand "store_multiple" @@ -10560,7 +9164,9 @@ (match_operand:SI 10 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 9" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*stmsi7" @@ -10582,7 +9188,9 @@ (match_operand:SI 9 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 8" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*stmsi6" @@ -10602,7 +9210,9 @@ (match_operand:SI 8 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 7" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*stmsi5" @@ -10620,7 +9230,9 @@ (match_operand:SI 7 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 6" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*stmsi4" @@ -10636,7 +9248,9 @@ (match_operand:SI 6 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 5" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*stmsi3" @@ -10650,7 +9264,9 @@ (match_operand:SI 5 "gpc_reg_operand" "r"))])] "TARGET_STRING && XVECLEN (operands[0], 0) == 4" "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_expand "setmemsi" @@ -10732,7 +9348,9 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) && REGNO (operands[4]) == 5" "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always") (set_attr "length" "8")]) @@ -10772,7 +9390,9 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) && REGNO (operands[4]) == 5" "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always") (set_attr "length" "8")]) @@ -10808,7 +9428,9 @@ && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) && REGNO (operands[4]) == 5" "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always") (set_attr "length" "8")]) @@ -10833,7 +9455,9 @@ "TARGET_STRING && ! TARGET_POWERPC64 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always") (set_attr "length" "8")]) @@ -10857,7 +9481,9 @@ (clobber (match_scratch:SI 5 "=X"))] "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always") (set_attr "length" "8")]) @@ -10882,7 +9508,9 @@ "@ ldux %3,%0,%2 ldu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "movdi__update" [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") @@ -10898,7 +9526,9 @@ "@ stdux %3,%0,%2 stdu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) ;; This pattern is only conditional on TARGET_POWERPC64, as it is ;; needed for stack allocation, even if the user passes -mno-update. @@ -10912,7 +9542,9 @@ "@ stdux %3,%0,%2 stdu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsi_update1" [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") @@ -10926,7 +9558,9 @@ "@ lwzux %3,%0,%2 lwzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsi_update2" [(set (match_operand:DI 3 "gpc_reg_operand" "=r") @@ -10938,7 +9572,10 @@ "TARGET_POWERPC64 && rs6000_gen_cell_microcode && !avoiding_indexed_address_p (DImode)" "lwaux %3,%0,%2" - [(set_attr "type" "load_ext_ux")]) + [(set_attr "type" "load") + (set_attr "sign_extend" "yes") + (set_attr "update" "yes") + (set_attr "indexed" "yes")]) (define_insn "movsi_update" [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -10954,7 +9591,9 @@ "@ stwux %3,%0,%2 stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) ;; This is an unconditional pattern; needed for stack allocation, even ;; if the user passes -mno-update. @@ -10968,7 +9607,9 @@ "@ stwux %3,%0,%2 stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movhi_update1" [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") @@ -10982,7 +9623,9 @@ "@ lhzux %3,%0,%2 lhzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movhi_update2" [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") @@ -10997,7 +9640,9 @@ "@ lhzux %3,%0,%2 lhzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movhi_update3" [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") @@ -11012,7 +9657,10 @@ "@ lhaux %3,%0,%2 lhau %3,%2(%0)" - [(set_attr "type" "load_ext_ux,load_ext_u")]) + [(set_attr "type" "load") + (set_attr "sign_extend" "yes") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movhi_update4" [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -11026,7 +9674,9 @@ "@ sthux %3,%0,%2 sthu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movqi_update1" [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") @@ -11040,7 +9690,9 @@ "@ lbzux %3,%0,%2 lbzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movqi_update2" [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") @@ -11055,7 +9707,9 @@ "@ lbzux %3,%0,%2 lbzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movqi_update3" [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -11069,7 +9723,9 @@ "@ stbux %3,%0,%2 stbu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsf_update1" [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") @@ -11083,7 +9739,9 @@ "@ lfsux %3,%0,%2 lfsu %3,%2(%0)" - [(set_attr "type" "fpload_ux,fpload_u")]) + [(set_attr "type" "fpload") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsf_update2" [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -11097,7 +9755,9 @@ "@ stfsux %3,%0,%2 stfsu %3,%2(%0)" - [(set_attr "type" "fpstore_ux,fpstore_u")]) + [(set_attr "type" "fpstore") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsf_update3" [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") @@ -11111,7 +9771,9 @@ "@ lwzux %3,%0,%2 lwzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movsf_update4" [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -11125,7 +9787,9 @@ "@ stwux %3,%0,%2 stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movdf_update1" [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") @@ -11139,7 +9803,9 @@ "@ lfdux %3,%0,%2 lfdu %3,%2(%0)" - [(set_attr "type" "fpload_ux,fpload_u")]) + [(set_attr "type" "fpload") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) (define_insn "*movdf_update2" [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") @@ -11153,7 +9819,9 @@ "@ stfdux %3,%0,%2 stfdu %3,%2(%0)" - [(set_attr "type" "fpstore_ux,fpstore_u")]) + [(set_attr "type" "fpstore") + (set_attr "update" "yes") + (set_attr "indexed" "yes,no")]) ;; After inserting conditional returns we can sometimes have @@ -11197,7 +9865,7 @@ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" + "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" { if (TARGET_CMODEL != CMODEL_SMALL) return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" @@ -11306,7 +9974,8 @@ (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" + "HAVE_AS_TLS && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" "bl %z1(%3@tlsgd)\;nop" [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -11338,7 +10007,7 @@ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" + "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" { if (TARGET_CMODEL != CMODEL_SMALL) return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" @@ -11441,7 +10110,8 @@ (match_operand 2 "" "g"))) (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" + "HAVE_AS_TLS && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" "bl %z1(%&@tlsld)\;nop" [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -11812,7 +10482,7 @@ [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (unspec:SI [(const_int 0)] UNSPEC_TOC)) (use (reg:SI 2))])] - "DEFAULT_ABI == ABI_AIX && TARGET_32BIT" + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" "* { char buf[30]; @@ -11821,13 +10491,15 @@ operands[2] = gen_rtx_REG (Pmode, 2); return \"lwz %0,%1(%2)\"; }" - [(set_attr "type" "load")]) + [(set_attr "type" "load") + (set_attr "update" "no") + (set_attr "indexed" "no")]) (define_insn "load_toc_aix_di" [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (unspec:DI [(const_int 0)] UNSPEC_TOC)) (use (reg:DI 2))])] - "DEFAULT_ABI == ABI_AIX && TARGET_64BIT" + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" "* { char buf[30]; @@ -11843,7 +10515,9 @@ operands[2] = gen_rtx_REG (Pmode, 2); return \"ld %0,%1(%2)\"; }" - [(set_attr "type" "load")]) + [(set_attr "type" "load") + (set_attr "update" "no") + (set_attr "indexed" "no")]) (define_insn "load_toc_v4_pic_si" [(set (reg:SI LR_REGNO) @@ -11857,7 +10531,7 @@ [(parallel [(set (reg:SI LR_REGNO) (match_operand:SI 0 "immediate_operand" "s")) (use (unspec [(match_dup 0)] UNSPEC_TOC))])] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX + "TARGET_ELF && DEFAULT_ABI == ABI_V4 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" "") @@ -11865,7 +10539,7 @@ [(set (reg:SI LR_REGNO) (match_operand:SI 0 "immediate_operand" "s")) (use (unspec [(match_dup 0)] UNSPEC_TOC))] - "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX + "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" "bcl 20,31,%0\\n%0:" [(set_attr "type" "branch") @@ -11875,7 +10549,7 @@ [(set (reg:SI LR_REGNO) (match_operand:SI 0 "immediate_operand" "s")) (use (unspec [(match_dup 0)] UNSPEC_TOC))] - "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX + "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" "* { @@ -11895,7 +10569,7 @@ (label_ref (match_operand 1 "" ""))] UNSPEC_TOCPTR)) (match_dup 1)])] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" "") (define_insn "load_toc_v4_PIC_1b_normal" @@ -11904,7 +10578,7 @@ (label_ref (match_operand 1 "" ""))] UNSPEC_TOCPTR)) (match_dup 1)] - "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" "bcl 20,31,$+8\;.long %0-$" [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -11915,7 +10589,7 @@ (label_ref (match_operand 1 "" ""))] UNSPEC_TOCPTR)) (match_dup 1)] - "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" "* { char name[32]; @@ -11933,7 +10607,7 @@ (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") (minus:SI (match_operand:SI 2 "immediate_operand" "s") (match_operand:SI 3 "immediate_operand" "s")))))] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" "lwz %0,%2-%3(%1)" [(set_attr "type" "load")]) @@ -11943,7 +10617,7 @@ (high:SI (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") (match_operand:SI 3 "symbol_ref_operand" "s")))))] - "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" + "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" "addis %0,%1,%2-%3@ha") (define_insn "load_toc_v4_PIC_3c" @@ -11951,7 +10625,7 @@ (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") (match_operand:SI 3 "symbol_ref_operand" "s"))))] - "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" + "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" "addi %0,%1,%2-%3@l") ;; If the TOC is shared over a translation unit, as happens with all @@ -12093,8 +10767,13 @@ operands[0] = XEXP (operands[0], 0); + if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) + { + rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); + DONE; + } + if (GET_CODE (operands[0]) != SYMBOL_REF - || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0])) || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0)) { if (INTVAL (operands[2]) & CALL_LONG) @@ -12107,12 +10786,6 @@ operands[0] = force_reg (Pmode, operands[0]); break; - case ABI_AIX: - /* AIX function pointers are really pointers to a three word - area. */ - rs6000_call_indirect_aix (NULL_RTX, operands[0], operands[1]); - DONE; - default: gcc_unreachable (); } @@ -12138,8 +10811,13 @@ operands[1] = XEXP (operands[1], 0); + if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) + { + rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); + DONE; + } + if (GET_CODE (operands[1]) != SYMBOL_REF - || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1])) || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) { if (INTVAL (operands[3]) & CALL_LONG) @@ -12152,12 +10830,6 @@ operands[1] = force_reg (Pmode, operands[1]); break; - case ABI_AIX: - /* AIX function pointers are really pointers to a three word - area. */ - rs6000_call_indirect_aix (operands[0], operands[1], operands[2]); - DONE; - default: gcc_unreachable (); } @@ -12223,161 +10895,32 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn (\"creqv 6,6,6\", operands); - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - - -(define_insn "*call_value_local64" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -;; Call to indirect functions with the AIX abi using a 3 word descriptor. -;; Operand0 is the addresss of the function to call -;; Operand1 is the flag for System V.4 for unprototyped or FP registers -;; Operand2 is the location in the function descriptor to load r2 from -;; Operand3 is the stack location to hold the current TOC pointer - -(define_insn "call_indirect_aix" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (use (match_operand:P 2 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" ",")) - (use (reg:P STATIC_CHAIN_REGNUM)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS" - " 2,%2\;b%T0l\; 2,%3" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Like call_indirect_aix, but no use of the static chain -;; Operand0 is the addresss of the function to call -;; Operand1 is the flag for System V.4 for unprototyped or FP registers -;; Operand2 is the location in the function descriptor to load r2 from -;; Operand3 is the stack location to hold the current TOC pointer - -(define_insn "call_indirect_aix_nor11" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (use (match_operand:P 2 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" ",")) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS" - " 2,%2\;b%T0l\; 2,%3" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Operand0 is the return result of the function -;; Operand1 is the addresss of the function to call -;; Operand2 is the flag for System V.4 for unprototyped or FP registers -;; Operand3 is the location in the function descriptor to load r2 from -;; Operand4 is the stack location to hold the current TOC pointer - -(define_insn "call_value_indirect_aix" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (use (match_operand:P 3 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" ",")) - (use (reg:P STATIC_CHAIN_REGNUM)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS" - " 2,%3\;b%T1l\; 2,%4" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Like call_value_indirect_aix, but no use of the static chain -;; Operand0 is the return result of the function -;; Operand1 is the addresss of the function to call -;; Operand2 is the flag for System V.4 for unprototyped or FP registers -;; Operand3 is the location in the function descriptor to load r2 from -;; Operand4 is the stack location to hold the current TOC pointer - -(define_insn "call_value_indirect_aix_nor11" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (use (match_operand:P 3 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" ",")) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS" - " 2,%3\;b%T1l\; 2,%4" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Call to function which may be in another module. Restore the TOC -;; pointer (r2) after the call unless this is System V. -;; Operand2 is nonzero if we are using the V.4 calling sequence and -;; either the function was not prototyped, or it was prototyped as a -;; variable argument function. It is > 0 if FP registers were passed -;; and < 0 if they were not. - -(define_insn "*call_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) - (match_operand 1 "" "g")) - (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_32BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) - (match_operand 1 "" "g")) - (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_value_nonlocal_aix32" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (use (match_operand:SI 3 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_32BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;nop" + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; +}" [(set_attr "type" "branch") - (set_attr "length" "8")]) + (set_attr "length" "4,8")]) -(define_insn "*call_value_nonlocal_aix64" + +(define_insn "*call_value_local64" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (use (match_operand:SI 3 "immediate_operand" "O")) + (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;nop" + "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; +}" [(set_attr "type" "branch") - (set_attr "length" "8")]) + (set_attr "length" "4,8")]) + ;; A function pointer under System V is just a normal pointer ;; operands[0] is the function pointer @@ -12560,6 +11103,104 @@ [(set_attr "type" "branch,branch") (set_attr "length" "4,8")]) + +;; Call to AIX abi function in the same module. + +(define_insn "*call_local_aix" + [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) + (match_operand 1 "" "g")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "bl %z0" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*call_value_local_aix" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) + (match_operand 2 "" "g"))) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +;; Call to AIX abi function which may be in another module. +;; Restore the TOC pointer (r2) after the call. + +(define_insn "*call_nonlocal_aix" + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) + (match_operand 1 "" "g")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "bl %z0\;nop" + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +(define_insn "*call_value_nonlocal_aix" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "bl %z1\;nop" + [(set_attr "type" "branch") + (set_attr "length" "8")]) + +;; Call to indirect functions with the AIX abi using a 3 word descriptor. +;; Operand0 is the addresss of the function to call +;; Operand2 is the location in the function descriptor to load r2 from +;; Operand3 is the stack location to hold the current TOC pointer + +(define_insn "*call_indirect_aix" + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (use (match_operand:P 2 "memory_operand" ",")) + (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" ",")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX" + " 2,%2\;b%T0l\; 2,%3" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +(define_insn "*call_value_indirect_aix" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (use (match_operand:P 3 "memory_operand" ",")) + (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" ",")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_AIX" + " 2,%3\;b%T1l\; 2,%4" + [(set_attr "type" "jmpreg") + (set_attr "length" "12")]) + +;; Call to indirect functions with the ELFv2 ABI. +;; Operand0 is the addresss of the function to call +;; Operand2 is the stack location to hold the current TOC pointer + +(define_insn "*call_indirect_elfv2" + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) + (match_operand 1 "" "g,g")) + (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" ",")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_ELFv2" + "b%T0l\; 2,%2" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + +(define_insn "*call_value_indirect_elfv2" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) + (match_operand 2 "" "g,g"))) + (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" ",")) + (clobber (reg:P LR_REGNO))] + "DEFAULT_ABI == ABI_ELFv2" + "b%T1l\; 2,%3" + [(set_attr "type" "jmpreg") + (set_attr "length" "8")]) + + ;; Call subroutine returning any type. (define_expand "untyped_call" [(parallel [(call (match_operand 0 "" "") @@ -12607,6 +11248,39 @@ gcc_assert (GET_CODE (operands[1]) == CONST_INT); operands[0] = XEXP (operands[0], 0); + + if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) + { + rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); + DONE; + } +}") + +(define_expand "sibcall_value" + [(parallel [(set (match_operand 0 "register_operand" "") + (call (mem:SI (match_operand 1 "address_operand" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (use (reg:SI LR_REGNO)) + (simple_return)])] + "" + " +{ +#if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[1] = machopic_indirect_call_target (operands[1]); +#endif + + gcc_assert (GET_CODE (operands[1]) == MEM); + gcc_assert (GET_CODE (operands[2]) == CONST_INT); + + operands[1] = XEXP (operands[1], 0); + + if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) + { + rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); + DONE; + } }") ;; this and similar patterns must be marked as using LR, otherwise @@ -12674,7 +11348,6 @@ [(set_attr "type" "branch") (set_attr "length" "4,8")]) - (define_insn "*sibcall_value_local64" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) @@ -12696,35 +11369,6 @@ [(set_attr "type" "branch") (set_attr "length" "4,8")]) -(define_insn "*sibcall_nonlocal_aix" - [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,O")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "@ - b %z0 - b%T0" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*sibcall_value_nonlocal_aix" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,O")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "@ - b %z1 - b%T1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - (define_insn "*sibcall_nonlocal_sysv" [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) (match_operand 1 "" "")) @@ -12755,27 +11399,6 @@ [(set_attr "type" "branch") (set_attr "length" "4,8,4,8")]) -(define_expand "sibcall_value" - [(parallel [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "address_operand" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (use (reg:SI LR_REGNO)) - (simple_return)])] - "" - " -{ -#if TARGET_MACHO - if (MACHOPIC_INDIRECT) - operands[1] = machopic_indirect_call_target (operands[1]); -#endif - - gcc_assert (GET_CODE (operands[1]) == MEM); - gcc_assert (GET_CODE (operands[2]) == CONST_INT); - - operands[1] = XEXP (operands[1], 0); -}") - (define_insn "*sibcall_value_nonlocal_sysv" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) @@ -12807,6 +11430,31 @@ [(set_attr "type" "branch") (set_attr "length" "4,8,4,8")]) +;; AIX ABI sibling call patterns. + +(define_insn "*sibcall_aix" + [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) + (match_operand 1 "" "g,g")) + (simple_return)] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "@ + b %z0 + b%T0" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_value_aix" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) + (match_operand 2 "" "g,g"))) + (simple_return)] + "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" + "@ + b %z1 + b%T1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + (define_expand "sibcall_epilogue" [(use (const_int 0))] "" @@ -12845,14 +11493,15 @@ operands[1] = gen_rtx_REG (Pmode, 0); return "st%U0%X0 %1,%0"; } - [(set (attr "type") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "store_ux") - (if_then_else - (match_test "update_address_mem (operands[0], VOIDmode)") - (const_string "store_u") - (const_string "store")))) + [(set_attr "type" "store") + (set (attr "update") + (if_then_else (match_operand 0 "update_address_mem") + (const_string "yes") + (const_string "no"))) + (set (attr "indexed") + (if_then_else (match_operand 0 "indexed_address_mem") + (const_string "yes") + (const_string "no"))) (set_attr "length" "4")]) (define_insn "probe_stack_range" @@ -13285,7 +11934,8 @@ "@ mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 #" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "8,16")]) (define_split @@ -13366,7 +12016,8 @@ return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\"; }" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "shift") + (set_attr "dot" "yes") (set_attr "length" "8,16")]) (define_split @@ -15049,7 +13700,9 @@ (match_operand:SI 2 "gpc_reg_operand" "r"))])] "TARGET_MULTIPLE" "stmw %2,%1" - [(set_attr "type" "store_ux")]) + [(set_attr "type" "store") + (set_attr "update" "yes") + (set_attr "indexed" "yes")]) ; The following comment applies to: ; save_gpregs_* @@ -15208,7 +13861,9 @@ (match_operand:SI 2 "memory_operand" "m"))])] "TARGET_MULTIPLE" "lmw %1,%2" - [(set_attr "type" "load_ux") + [(set_attr "type" "load") + (set_attr "update" "yes") + (set_attr "indexed" "yes") (set_attr "cell_micro" "always")]) (define_insn "*return_internal_" @@ -15623,6 +14278,20 @@ }) +(define_insn "rs6000_mffs" + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "mffs %0") + +(define_insn "rs6000_mtfsf" + [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") + (match_operand:DF 1 "gpc_reg_operand" "d")] + UNSPECV_MTFSF)] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "mtfsf %0,%1") + + ;; Power8 fusion support for fusing an addis instruction with a D-form load of ;; a GPR. The addis instruction must be adjacent to the load, and use the same ;; register that is being loaded. The fused ops must be physically adjacent. @@ -15660,6 +14329,172 @@ }) +;; Miscellaneous ISA 2.06 (power7) instructions +(define_insn "addg6s" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] + UNSPEC_ADDG6S))] + "TARGET_POPCNTD" + "addg6s %0,%1,%2" + [(set_attr "type" "integer") + (set_attr "length" "4")]) + +(define_insn "cdtbcd" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r")] + UNSPEC_CDTBCD))] + "TARGET_POPCNTD" + "cdtbcd %0,%1" + [(set_attr "type" "integer") + (set_attr "length" "4")]) + +(define_insn "cbcdtd" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r")] + UNSPEC_CBCDTD))] + "TARGET_POPCNTD" + "cbcdtd %0,%1" + [(set_attr "type" "integer") + (set_attr "length" "4")]) + +(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE + UNSPEC_DIVEO + UNSPEC_DIVEU + UNSPEC_DIVEUO]) + +(define_int_attr div_extend [(UNSPEC_DIVE "e") + (UNSPEC_DIVEO "eo") + (UNSPEC_DIVEU "eu") + (UNSPEC_DIVEUO "euo")]) + +(define_insn "div_" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") + (match_operand:GPR 2 "register_operand" "r")] + UNSPEC_DIV_EXTEND))] + "TARGET_POPCNTD" + "div %0,%1,%2" + [(set_attr "type" "div") + (set_attr "size" "")]) + + +;; Pack/unpack 128-bit floating point types that take 2 scalar registers + +; Type of the 64-bit part when packing/unpacking 128-bit floating point types +(define_mode_attr FP128_64 [(TF "DF") (TD "DI")]) + +(define_expand "unpack" + [(set (match_operand: 0 "nonimmediate_operand" "") + (unspec: + [(match_operand:FMOVE128 1 "register_operand" "") + (match_operand:QI 2 "const_0_to_1_operand" "")] + UNSPEC_UNPACK_128BIT))] + "" + "") + +(define_insn_and_split "unpack_dm" + [(set (match_operand: 0 "nonimmediate_operand" "=d,m,d,r,m") + (unspec: + [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") + (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] + UNSPEC_UNPACK_128BIT))] + "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 3))] +{ + unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); + + if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) + { + emit_note (NOTE_INSN_DELETED); + DONE; + } + + operands[3] = gen_rtx_REG (mode, fp_regno); +} + [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") + (set_attr "length" "4")]) + +(define_insn_and_split "unpack_nodm" + [(set (match_operand: 0 "nonimmediate_operand" "=d,m") + (unspec: + [(match_operand:FMOVE128 1 "register_operand" "d,d") + (match_operand:QI 2 "const_0_to_1_operand" "i,i")] + UNSPEC_UNPACK_128BIT))] + "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 3))] +{ + unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); + + if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) + { + emit_note (NOTE_INSN_DELETED); + DONE; + } + + operands[3] = gen_rtx_REG (mode, fp_regno); +} + [(set_attr "type" "fp,fpstore") + (set_attr "length" "4")]) + +(define_insn_and_split "pack" + [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") + (unspec:FMOVE128 + [(match_operand: 1 "register_operand" "0,d") + (match_operand: 2 "register_operand" "d,d")] + UNSPEC_PACK_128BIT))] + "" + "@ + fmr %L0,%2 + #" + "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (match_dup 2))] +{ + unsigned dest_hi = REGNO (operands[0]); + unsigned dest_lo = dest_hi + 1; + + gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); + gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); + + operands[3] = gen_rtx_REG (mode, dest_hi); + operands[4] = gen_rtx_REG (mode, dest_lo); +} + [(set_attr "type" "fp,fp") + (set_attr "length" "4,8")]) + +(define_insn "unpackv1ti" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa") + (match_operand:QI 2 "const_0_to_1_operand" "O,i")] + UNSPEC_UNPACK_128BIT))] + "TARGET_VSX" +{ + if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) + return ASM_COMMENT_START " xxpermdi to same register"; + + operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); + return "xxpermdi %x0,%x1,%x1,%3"; +} + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_insn "packv1ti" + [(set (match_operand:V1TI 0 "register_operand" "=wa") + (unspec:V1TI + [(match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")] + UNSPEC_PACK_128BIT))] + "TARGET_VSX" + "xxpermdi %x0,%x1,%x2,0" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + + (include "sync.md") (include "vector.md")