1169689Skan;; Predicate definitions for POWER and PowerPC. 2169689Skan;; Copyright (C) 2005, 2006 Free Software Foundation, Inc. 3169689Skan;; 4169689Skan;; This file is part of GCC. 5169689Skan;; 6169689Skan;; GCC is free software; you can redistribute it and/or modify 7169689Skan;; it under the terms of the GNU General Public License as published by 8169689Skan;; the Free Software Foundation; either version 2, or (at your option) 9169689Skan;; any later version. 10169689Skan;; 11169689Skan;; GCC is distributed in the hope that it will be useful, 12169689Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13169689Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169689Skan;; GNU General Public License for more details. 15169689Skan;; 16169689Skan;; You should have received a copy of the GNU General Public License 17169689Skan;; along with GCC; see the file COPYING. If not, write to 18169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19169689Skan;; Boston, MA 02110-1301, USA. 20169689Skan 21169689Skan;; Return 1 for anything except PARALLEL. 22169689Skan(define_predicate "any_operand" 23169689Skan (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")) 24169689Skan 25169689Skan;; Return 1 for any PARALLEL. 26169689Skan(define_predicate "any_parallel_operand" 27169689Skan (match_code "parallel")) 28169689Skan 29169689Skan;; Return 1 if op is COUNT register. 30169689Skan(define_predicate "count_register_operand" 31169689Skan (and (match_code "reg") 32169689Skan (match_test "REGNO (op) == COUNT_REGISTER_REGNUM 33169689Skan || REGNO (op) > LAST_VIRTUAL_REGISTER"))) 34169689Skan 35169689Skan;; Return 1 if op is an Altivec register. 36169689Skan(define_predicate "altivec_register_operand" 37169689Skan (and (match_operand 0 "register_operand") 38169689Skan (match_test "GET_CODE (op) != REG 39169689Skan || ALTIVEC_REGNO_P (REGNO (op)) 40169689Skan || REGNO (op) > LAST_VIRTUAL_REGISTER"))) 41169689Skan 42169689Skan;; Return 1 if op is XER register. 43169689Skan(define_predicate "xer_operand" 44169689Skan (and (match_code "reg") 45169689Skan (match_test "XER_REGNO_P (REGNO (op))"))) 46169689Skan 47169689Skan;; Return 1 if op is a signed 5-bit constant integer. 48169689Skan(define_predicate "s5bit_cint_operand" 49169689Skan (and (match_code "const_int") 50169689Skan (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15"))) 51169689Skan 52169689Skan;; Return 1 if op is a unsigned 5-bit constant integer. 53169689Skan(define_predicate "u5bit_cint_operand" 54169689Skan (and (match_code "const_int") 55169689Skan (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31"))) 56169689Skan 57169689Skan;; Return 1 if op is a signed 8-bit constant integer. 58169689Skan;; Integer multiplication complete more quickly 59169689Skan(define_predicate "s8bit_cint_operand" 60169689Skan (and (match_code "const_int") 61169689Skan (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127"))) 62169689Skan 63169689Skan;; Return 1 if op is a constant integer that can fit in a D field. 64169689Skan(define_predicate "short_cint_operand" 65169689Skan (and (match_code "const_int") 66169689Skan (match_test "satisfies_constraint_I (op)"))) 67169689Skan 68169689Skan;; Return 1 if op is a constant integer that can fit in an unsigned D field. 69169689Skan(define_predicate "u_short_cint_operand" 70169689Skan (and (match_code "const_int") 71169689Skan (match_test "satisfies_constraint_K (op)"))) 72169689Skan 73169689Skan;; Return 1 if op is a constant integer that cannot fit in a signed D field. 74169689Skan(define_predicate "non_short_cint_operand" 75169689Skan (and (match_code "const_int") 76169689Skan (match_test "(unsigned HOST_WIDE_INT) 77169689Skan (INTVAL (op) + 0x8000) >= 0x10000"))) 78169689Skan 79169689Skan;; Return 1 if op is a positive constant integer that is an exact power of 2. 80169689Skan(define_predicate "exact_log2_cint_operand" 81169689Skan (and (match_code "const_int") 82169689Skan (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0"))) 83169689Skan 84169689Skan;; Return 1 if op is a register that is not special. 85169689Skan(define_predicate "gpc_reg_operand" 86169689Skan (and (match_operand 0 "register_operand") 87169689Skan (match_test "(GET_CODE (op) != REG 88169689Skan || (REGNO (op) >= ARG_POINTER_REGNUM 89169689Skan && !XER_REGNO_P (REGNO (op))) 90169689Skan || REGNO (op) < MQ_REGNO) 91169689Skan && !((TARGET_E500_DOUBLE || TARGET_SPE) 92169689Skan && invalid_e500_subreg (op, mode))"))) 93169689Skan 94169689Skan;; Return 1 if op is a register that is a condition register field. 95169689Skan(define_predicate "cc_reg_operand" 96169689Skan (and (match_operand 0 "register_operand") 97169689Skan (match_test "GET_CODE (op) != REG 98169689Skan || REGNO (op) > LAST_VIRTUAL_REGISTER 99169689Skan || CR_REGNO_P (REGNO (op))"))) 100169689Skan 101169689Skan;; Return 1 if op is a register that is a condition register field not cr0. 102169689Skan(define_predicate "cc_reg_not_cr0_operand" 103169689Skan (and (match_operand 0 "register_operand") 104169689Skan (match_test "GET_CODE (op) != REG 105169689Skan || REGNO (op) > LAST_VIRTUAL_REGISTER 106169689Skan || CR_REGNO_NOT_CR0_P (REGNO (op))"))) 107169689Skan 108169689Skan;; Return 1 if op is a constant integer valid for D field 109169689Skan;; or non-special register register. 110169689Skan(define_predicate "reg_or_short_operand" 111169689Skan (if_then_else (match_code "const_int") 112169689Skan (match_operand 0 "short_cint_operand") 113169689Skan (match_operand 0 "gpc_reg_operand"))) 114169689Skan 115169689Skan;; Return 1 if op is a constant integer valid whose negation is valid for 116169689Skan;; D field or non-special register register. 117169689Skan;; Do not allow a constant zero because all patterns that call this 118169689Skan;; predicate use "addic r1,r2,-const" to set carry when r2 is greater than 119169689Skan;; or equal to const, which does not work for zero. 120169689Skan(define_predicate "reg_or_neg_short_operand" 121169689Skan (if_then_else (match_code "const_int") 122169689Skan (match_test "satisfies_constraint_P (op) 123169689Skan && INTVAL (op) != 0") 124169689Skan (match_operand 0 "gpc_reg_operand"))) 125169689Skan 126169689Skan;; Return 1 if op is a constant integer valid for DS field 127169689Skan;; or non-special register. 128169689Skan(define_predicate "reg_or_aligned_short_operand" 129169689Skan (if_then_else (match_code "const_int") 130169689Skan (and (match_operand 0 "short_cint_operand") 131169689Skan (match_test "!(INTVAL (op) & 3)")) 132169689Skan (match_operand 0 "gpc_reg_operand"))) 133169689Skan 134169689Skan;; Return 1 if op is a constant integer whose high-order 16 bits are zero 135169689Skan;; or non-special register. 136169689Skan(define_predicate "reg_or_u_short_operand" 137169689Skan (if_then_else (match_code "const_int") 138169689Skan (match_operand 0 "u_short_cint_operand") 139169689Skan (match_operand 0 "gpc_reg_operand"))) 140169689Skan 141169689Skan;; Return 1 if op is any constant integer 142169689Skan;; or non-special register. 143169689Skan(define_predicate "reg_or_cint_operand" 144169689Skan (ior (match_code "const_int") 145169689Skan (match_operand 0 "gpc_reg_operand"))) 146169689Skan 147169689Skan;; Return 1 if op is a constant integer valid for addition 148169689Skan;; or non-special register. 149169689Skan(define_predicate "reg_or_add_cint_operand" 150169689Skan (if_then_else (match_code "const_int") 151169689Skan (match_test "(HOST_BITS_PER_WIDE_INT == 32 152169689Skan && (mode == SImode || INTVAL (op) < 0x7fff8000)) 153169689Skan || ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000) 154169689Skan < (unsigned HOST_WIDE_INT) 0x100000000ll)") 155169689Skan (match_operand 0 "gpc_reg_operand"))) 156169689Skan 157169689Skan;; Return 1 if op is a constant integer valid for subtraction 158169689Skan;; or non-special register. 159169689Skan(define_predicate "reg_or_sub_cint_operand" 160169689Skan (if_then_else (match_code "const_int") 161169689Skan (match_test "(HOST_BITS_PER_WIDE_INT == 32 162169689Skan && (mode == SImode || - INTVAL (op) < 0x7fff8000)) 163169689Skan || ((unsigned HOST_WIDE_INT) (- INTVAL (op) 164169689Skan + (mode == SImode 165169689Skan ? 0x80000000 : 0x80008000)) 166169689Skan < (unsigned HOST_WIDE_INT) 0x100000000ll)") 167169689Skan (match_operand 0 "gpc_reg_operand"))) 168169689Skan 169169689Skan;; Return 1 if op is any 32-bit unsigned constant integer 170169689Skan;; or non-special register. 171169689Skan(define_predicate "reg_or_logical_cint_operand" 172169689Skan (if_then_else (match_code "const_int") 173169689Skan (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT 174169689Skan && INTVAL (op) >= 0) 175169689Skan || ((INTVAL (op) & GET_MODE_MASK (mode) 176169689Skan & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)") 177169689Skan (if_then_else (match_code "const_double") 178169689Skan (match_test "GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT 179169689Skan && mode == DImode 180169689Skan && CONST_DOUBLE_HIGH (op) == 0") 181169689Skan (match_operand 0 "gpc_reg_operand")))) 182169689Skan 183169689Skan;; Return 1 if operand is a CONST_DOUBLE that can be set in a register 184169689Skan;; with no more than one instruction per word. 185169689Skan(define_predicate "easy_fp_constant" 186169689Skan (match_code "const_double") 187169689Skan{ 188169689Skan long k[4]; 189169689Skan REAL_VALUE_TYPE rv; 190169689Skan 191169689Skan if (GET_MODE (op) != mode 192169689Skan || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode)) 193169689Skan return 0; 194169689Skan 195169689Skan /* Consider all constants with -msoft-float to be easy. */ 196169689Skan if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) 197169689Skan && mode != DImode) 198169689Skan return 1; 199169689Skan 200169689Skan if (DECIMAL_FLOAT_MODE_P (mode)) 201169689Skan return 0; 202169689Skan 203169689Skan /* If we are using V.4 style PIC, consider all constants to be hard. */ 204169689Skan if (flag_pic && DEFAULT_ABI == ABI_V4) 205169689Skan return 0; 206169689Skan 207169689Skan#ifdef TARGET_RELOCATABLE 208169689Skan /* Similarly if we are using -mrelocatable, consider all constants 209169689Skan to be hard. */ 210169689Skan if (TARGET_RELOCATABLE) 211169689Skan return 0; 212169689Skan#endif 213169689Skan 214169689Skan switch (mode) 215169689Skan { 216169689Skan case TFmode: 217169689Skan REAL_VALUE_FROM_CONST_DOUBLE (rv, op); 218169689Skan REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); 219169689Skan 220169689Skan return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 221169689Skan && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1 222169689Skan && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1 223169689Skan && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1); 224169689Skan 225169689Skan case DFmode: 226169689Skan /* Force constants to memory before reload to utilize 227169689Skan compress_float_constant. 228169689Skan Avoid this when flag_unsafe_math_optimizations is enabled 229169689Skan because RDIV division to reciprocal optimization is not able 230169689Skan to regenerate the division. */ 231169689Skan if (TARGET_E500_DOUBLE 232169689Skan || (!reload_in_progress && !reload_completed 233169689Skan && !flag_unsafe_math_optimizations)) 234169689Skan return 0; 235169689Skan 236169689Skan REAL_VALUE_FROM_CONST_DOUBLE (rv, op); 237169689Skan REAL_VALUE_TO_TARGET_DOUBLE (rv, k); 238169689Skan 239169689Skan return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 240169689Skan && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1); 241169689Skan 242169689Skan case SFmode: 243169689Skan /* The constant 0.f is easy. */ 244169689Skan if (op == CONST0_RTX (SFmode)) 245169689Skan return 1; 246169689Skan 247169689Skan /* Force constants to memory before reload to utilize 248169689Skan compress_float_constant. 249169689Skan Avoid this when flag_unsafe_math_optimizations is enabled 250169689Skan because RDIV division to reciprocal optimization is not able 251169689Skan to regenerate the division. */ 252169689Skan if (!reload_in_progress && !reload_completed 253169689Skan && !flag_unsafe_math_optimizations) 254169689Skan return 0; 255169689Skan 256169689Skan REAL_VALUE_FROM_CONST_DOUBLE (rv, op); 257169689Skan REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]); 258169689Skan 259169689Skan return num_insns_constant_wide (k[0]) == 1; 260169689Skan 261169689Skan case DImode: 262169689Skan return ((TARGET_POWERPC64 263169689Skan && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0) 264169689Skan || (num_insns_constant (op, DImode) <= 2)); 265169689Skan 266169689Skan case SImode: 267169689Skan return 1; 268169689Skan 269169689Skan default: 270169689Skan gcc_unreachable (); 271169689Skan } 272169689Skan}) 273169689Skan 274169689Skan;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a 275169689Skan;; vector register without using memory. 276169689Skan(define_predicate "easy_vector_constant" 277169689Skan (match_code "const_vector") 278169689Skan{ 279169689Skan if (ALTIVEC_VECTOR_MODE (mode)) 280169689Skan { 281169689Skan if (zero_constant (op, mode)) 282169689Skan return true; 283169689Skan return easy_altivec_constant (op, mode); 284169689Skan } 285169689Skan 286169689Skan if (SPE_VECTOR_MODE (mode)) 287169689Skan { 288169689Skan int cst, cst2; 289169689Skan if (zero_constant (op, mode)) 290169689Skan return true; 291169689Skan if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) 292169689Skan return false; 293169689Skan 294169689Skan /* Limit SPE vectors to 15 bits signed. These we can generate with: 295169689Skan li r0, CONSTANT1 296169689Skan evmergelo r0, r0, r0 297169689Skan li r0, CONSTANT2 298169689Skan 299169689Skan I don't know how efficient it would be to allow bigger constants, 300169689Skan considering we'll have an extra 'ori' for every 'li'. I doubt 5 301169689Skan instructions is better than a 64-bit memory load, but I don't 302169689Skan have the e500 timing specs. */ 303169689Skan if (mode == V2SImode) 304169689Skan { 305169689Skan cst = INTVAL (CONST_VECTOR_ELT (op, 0)); 306169689Skan cst2 = INTVAL (CONST_VECTOR_ELT (op, 1)); 307169689Skan return cst >= -0x7fff && cst <= 0x7fff 308169689Skan && cst2 >= -0x7fff && cst2 <= 0x7fff; 309169689Skan } 310169689Skan } 311169689Skan 312169689Skan return false; 313169689Skan}) 314169689Skan 315169689Skan;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. 316169689Skan(define_predicate "easy_vector_constant_add_self" 317169689Skan (and (match_code "const_vector") 318169689Skan (and (match_test "TARGET_ALTIVEC") 319169689Skan (match_test "easy_altivec_constant (op, mode)"))) 320169689Skan{ 321169689Skan rtx last = CONST_VECTOR_ELT (op, GET_MODE_NUNITS (mode) - 1); 322169689Skan HOST_WIDE_INT val = ((INTVAL (last) & 0xff) ^ 0x80) - 0x80; 323169689Skan return EASY_VECTOR_15_ADD_SELF (val); 324169689Skan}) 325169689Skan 326169689Skan;; Return 1 if operand is constant zero (scalars and vectors). 327169689Skan(define_predicate "zero_constant" 328169689Skan (and (match_code "const_int,const_double,const_vector") 329169689Skan (match_test "op == CONST0_RTX (mode)"))) 330169689Skan 331169689Skan;; Return 1 if operand is 0.0. 332169689Skan;; or non-special register register field no cr0 333169689Skan(define_predicate "zero_fp_constant" 334169689Skan (and (match_code "const_double") 335169689Skan (match_test "SCALAR_FLOAT_MODE_P (mode) 336169689Skan && op == CONST0_RTX (mode)"))) 337169689Skan 338169689Skan;; Return 1 if the operand is in volatile memory. Note that during the 339169689Skan;; RTL generation phase, memory_operand does not return TRUE for volatile 340169689Skan;; memory references. So this function allows us to recognize volatile 341169689Skan;; references where it's safe. 342169689Skan(define_predicate "volatile_mem_operand" 343169689Skan (and (and (match_code "mem") 344169689Skan (match_test "MEM_VOLATILE_P (op)")) 345169689Skan (if_then_else (match_test "reload_completed") 346169689Skan (match_operand 0 "memory_operand") 347169689Skan (if_then_else (match_test "reload_in_progress") 348169689Skan (match_test "strict_memory_address_p (mode, XEXP (op, 0))") 349169689Skan (match_test "memory_address_p (mode, XEXP (op, 0))"))))) 350169689Skan 351169689Skan;; Return 1 if the operand is an offsettable memory operand. 352169689Skan(define_predicate "offsettable_mem_operand" 353169689Skan (and (match_code "mem") 354169689Skan (match_test "offsettable_address_p (reload_completed 355169689Skan || reload_in_progress, 356169689Skan mode, XEXP (op, 0))"))) 357169689Skan 358169689Skan;; Return 1 if the operand is a memory operand with an address divisible by 4 359169689Skan(define_predicate "word_offset_memref_operand" 360169689Skan (and (match_operand 0 "memory_operand") 361169689Skan (match_test "GET_CODE (XEXP (op, 0)) != PLUS 362169689Skan || ! REG_P (XEXP (XEXP (op, 0), 0)) 363169689Skan || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT 364169689Skan || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0"))) 365169689Skan 366169689Skan;; Return 1 if the operand is an indexed or indirect memory operand. 367169689Skan(define_predicate "indexed_or_indirect_operand" 368169689Skan (match_code "mem") 369169689Skan{ 370169689Skan op = XEXP (op, 0); 371169689Skan if (TARGET_ALTIVEC 372169689Skan && ALTIVEC_VECTOR_MODE (mode) 373169689Skan && GET_CODE (op) == AND 374169689Skan && GET_CODE (XEXP (op, 1)) == CONST_INT 375169689Skan && INTVAL (XEXP (op, 1)) == -16) 376169689Skan op = XEXP (op, 0); 377169689Skan 378169689Skan return indexed_or_indirect_address (op, mode); 379169689Skan}) 380169689Skan 381169689Skan;; Return 1 if the operand is an indexed or indirect address. 382169689Skan(define_special_predicate "indexed_or_indirect_address" 383169689Skan (and (match_test "REG_P (op) 384169689Skan || (GET_CODE (op) == PLUS 385169689Skan /* Omit testing REG_P (XEXP (op, 0)). */ 386169689Skan && REG_P (XEXP (op, 1)))") 387169689Skan (match_operand 0 "address_operand"))) 388169689Skan 389169689Skan;; Used for the destination of the fix_truncdfsi2 expander. 390169689Skan;; If stfiwx will be used, the result goes to memory; otherwise, 391169689Skan;; we're going to emit a store and a load of a subreg, so the dest is a 392169689Skan;; register. 393169689Skan(define_predicate "fix_trunc_dest_operand" 394169689Skan (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT") 395169689Skan (match_operand 0 "memory_operand") 396169689Skan (match_operand 0 "gpc_reg_operand"))) 397169689Skan 398169689Skan;; Return 1 if the operand is either a non-special register or can be used 399169689Skan;; as the operand of a `mode' add insn. 400169689Skan(define_predicate "add_operand" 401169689Skan (if_then_else (match_code "const_int") 402169689Skan (match_test "satisfies_constraint_I (op) 403169689Skan || satisfies_constraint_L (op)") 404169689Skan (match_operand 0 "gpc_reg_operand"))) 405169689Skan 406169689Skan;; Return 1 if OP is a constant but not a valid add_operand. 407169689Skan(define_predicate "non_add_cint_operand" 408169689Skan (and (match_code "const_int") 409169689Skan (match_test "!satisfies_constraint_I (op) 410169689Skan && !satisfies_constraint_L (op)"))) 411169689Skan 412169689Skan;; Return 1 if the operand is a constant that can be used as the operand 413169689Skan;; of an OR or XOR. 414169689Skan(define_predicate "logical_const_operand" 415169689Skan (match_code "const_int,const_double") 416169689Skan{ 417169689Skan HOST_WIDE_INT opl, oph; 418169689Skan 419169689Skan if (GET_CODE (op) == CONST_INT) 420169689Skan { 421169689Skan opl = INTVAL (op) & GET_MODE_MASK (mode); 422169689Skan 423169689Skan if (HOST_BITS_PER_WIDE_INT <= 32 424169689Skan && GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0) 425169689Skan return 0; 426169689Skan } 427169689Skan else if (GET_CODE (op) == CONST_DOUBLE) 428169689Skan { 429169689Skan gcc_assert (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT); 430169689Skan 431169689Skan opl = CONST_DOUBLE_LOW (op); 432169689Skan oph = CONST_DOUBLE_HIGH (op); 433169689Skan if (oph != 0) 434169689Skan return 0; 435169689Skan } 436169689Skan else 437169689Skan return 0; 438169689Skan 439169689Skan return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0 440169689Skan || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0); 441169689Skan}) 442169689Skan 443169689Skan;; Return 1 if the operand is a non-special register or a constant that 444169689Skan;; can be used as the operand of an OR or XOR. 445169689Skan(define_predicate "logical_operand" 446169689Skan (ior (match_operand 0 "gpc_reg_operand") 447169689Skan (match_operand 0 "logical_const_operand"))) 448169689Skan 449169689Skan;; Return 1 if op is a constant that is not a logical operand, but could 450169689Skan;; be split into one. 451169689Skan(define_predicate "non_logical_cint_operand" 452169689Skan (and (match_code "const_int,const_double") 453169689Skan (and (not (match_operand 0 "logical_operand")) 454169689Skan (match_operand 0 "reg_or_logical_cint_operand")))) 455169689Skan 456169689Skan;; Return 1 if op is a constant that can be encoded in a 32-bit mask, 457169689Skan;; suitable for use with rlwinm (no more than two 1->0 or 0->1 458169689Skan;; transitions). Reject all ones and all zeros, since these should have 459169689Skan;; been optimized away and confuse the making of MB and ME. 460169689Skan(define_predicate "mask_operand" 461169689Skan (match_code "const_int") 462169689Skan{ 463169689Skan HOST_WIDE_INT c, lsb; 464169689Skan 465169689Skan c = INTVAL (op); 466169689Skan 467169689Skan if (TARGET_POWERPC64) 468169689Skan { 469169689Skan /* Fail if the mask is not 32-bit. */ 470169689Skan if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0) 471169689Skan return 0; 472169689Skan 473169689Skan /* Fail if the mask wraps around because the upper 32-bits of the 474169689Skan mask will all be 1s, contrary to GCC's internal view. */ 475169689Skan if ((c & 0x80000001) == 0x80000001) 476169689Skan return 0; 477169689Skan } 478169689Skan 479169689Skan /* We don't change the number of transitions by inverting, 480169689Skan so make sure we start with the LS bit zero. */ 481169689Skan if (c & 1) 482169689Skan c = ~c; 483169689Skan 484169689Skan /* Reject all zeros or all ones. */ 485169689Skan if (c == 0) 486169689Skan return 0; 487169689Skan 488169689Skan /* Find the first transition. */ 489169689Skan lsb = c & -c; 490169689Skan 491169689Skan /* Invert to look for a second transition. */ 492169689Skan c = ~c; 493169689Skan 494169689Skan /* Erase first transition. */ 495169689Skan c &= -lsb; 496169689Skan 497169689Skan /* Find the second transition (if any). */ 498169689Skan lsb = c & -c; 499169689Skan 500169689Skan /* Match if all the bits above are 1's (or c is zero). */ 501169689Skan return c == -lsb; 502169689Skan}) 503169689Skan 504169689Skan;; Return 1 for the PowerPC64 rlwinm corner case. 505169689Skan(define_predicate "mask_operand_wrap" 506169689Skan (match_code "const_int") 507169689Skan{ 508169689Skan HOST_WIDE_INT c, lsb; 509169689Skan 510169689Skan c = INTVAL (op); 511169689Skan 512169689Skan if ((c & 0x80000001) != 0x80000001) 513169689Skan return 0; 514169689Skan 515169689Skan c = ~c; 516169689Skan if (c == 0) 517169689Skan return 0; 518169689Skan 519169689Skan lsb = c & -c; 520169689Skan c = ~c; 521169689Skan c &= -lsb; 522169689Skan lsb = c & -c; 523169689Skan return c == -lsb; 524169689Skan}) 525169689Skan 526169689Skan;; Return 1 if the operand is a constant that is a PowerPC64 mask 527169689Skan;; suitable for use with rldicl or rldicr (no more than one 1->0 or 0->1 528169689Skan;; transition). Reject all zeros, since zero should have been 529169689Skan;; optimized away and confuses the making of MB and ME. 530169689Skan(define_predicate "mask64_operand" 531169689Skan (match_code "const_int") 532169689Skan{ 533169689Skan HOST_WIDE_INT c, lsb; 534169689Skan 535169689Skan c = INTVAL (op); 536169689Skan 537169689Skan /* Reject all zeros. */ 538169689Skan if (c == 0) 539169689Skan return 0; 540169689Skan 541169689Skan /* We don't change the number of transitions by inverting, 542169689Skan so make sure we start with the LS bit zero. */ 543169689Skan if (c & 1) 544169689Skan c = ~c; 545169689Skan 546169689Skan /* Find the first transition. */ 547169689Skan lsb = c & -c; 548169689Skan 549169689Skan /* Match if all the bits above are 1's (or c is zero). */ 550169689Skan return c == -lsb; 551169689Skan}) 552169689Skan 553169689Skan;; Like mask64_operand, but allow up to three transitions. This 554169689Skan;; predicate is used by insn patterns that generate two rldicl or 555169689Skan;; rldicr machine insns. 556169689Skan(define_predicate "mask64_2_operand" 557169689Skan (match_code "const_int") 558169689Skan{ 559169689Skan HOST_WIDE_INT c, lsb; 560169689Skan 561169689Skan c = INTVAL (op); 562169689Skan 563169689Skan /* Disallow all zeros. */ 564169689Skan if (c == 0) 565169689Skan return 0; 566169689Skan 567169689Skan /* We don't change the number of transitions by inverting, 568169689Skan so make sure we start with the LS bit zero. */ 569169689Skan if (c & 1) 570169689Skan c = ~c; 571169689Skan 572169689Skan /* Find the first transition. */ 573169689Skan lsb = c & -c; 574169689Skan 575169689Skan /* Invert to look for a second transition. */ 576169689Skan c = ~c; 577169689Skan 578169689Skan /* Erase first transition. */ 579169689Skan c &= -lsb; 580169689Skan 581169689Skan /* Find the second transition. */ 582169689Skan lsb = c & -c; 583169689Skan 584169689Skan /* Invert to look for a third transition. */ 585169689Skan c = ~c; 586169689Skan 587169689Skan /* Erase second transition. */ 588169689Skan c &= -lsb; 589169689Skan 590169689Skan /* Find the third transition (if any). */ 591169689Skan lsb = c & -c; 592169689Skan 593169689Skan /* Match if all the bits above are 1's (or c is zero). */ 594169689Skan return c == -lsb; 595169689Skan}) 596169689Skan 597169689Skan;; Like and_operand, but also match constants that can be implemented 598169689Skan;; with two rldicl or rldicr insns. 599169689Skan(define_predicate "and64_2_operand" 600169689Skan (ior (match_operand 0 "mask64_2_operand") 601169689Skan (if_then_else (match_test "fixed_regs[CR0_REGNO]") 602169689Skan (match_operand 0 "gpc_reg_operand") 603169689Skan (match_operand 0 "logical_operand")))) 604169689Skan 605169689Skan;; Return 1 if the operand is either a non-special register or a 606169689Skan;; constant that can be used as the operand of a logical AND. 607169689Skan(define_predicate "and_operand" 608169689Skan (ior (match_operand 0 "mask_operand") 609169689Skan (ior (and (match_test "TARGET_POWERPC64 && mode == DImode") 610169689Skan (match_operand 0 "mask64_operand")) 611169689Skan (if_then_else (match_test "fixed_regs[CR0_REGNO]") 612169689Skan (match_operand 0 "gpc_reg_operand") 613169689Skan (match_operand 0 "logical_operand"))))) 614169689Skan 615169689Skan;; Return 1 if the operand is either a logical operand or a short cint operand. 616169689Skan(define_predicate "scc_eq_operand" 617169689Skan (ior (match_operand 0 "logical_operand") 618169689Skan (match_operand 0 "short_cint_operand"))) 619169689Skan 620169689Skan;; Return 1 if the operand is a general non-special register or memory operand. 621169689Skan(define_predicate "reg_or_mem_operand" 622169689Skan (ior (match_operand 0 "memory_operand") 623169689Skan (ior (and (match_code "mem") 624169689Skan (match_test "macho_lo_sum_memory_operand (op, mode)")) 625169689Skan (ior (match_operand 0 "volatile_mem_operand") 626169689Skan (match_operand 0 "gpc_reg_operand"))))) 627169689Skan 628169689Skan;; Return 1 if the operand is either an easy FP constant or memory or reg. 629169689Skan(define_predicate "reg_or_none500mem_operand" 630169689Skan (if_then_else (match_code "mem") 631169689Skan (and (match_test "!TARGET_E500_DOUBLE") 632169689Skan (ior (match_operand 0 "memory_operand") 633169689Skan (ior (match_test "macho_lo_sum_memory_operand (op, mode)") 634169689Skan (match_operand 0 "volatile_mem_operand")))) 635169689Skan (match_operand 0 "gpc_reg_operand"))) 636169689Skan 637169689Skan;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand. 638169689Skan(define_predicate "zero_reg_mem_operand" 639169689Skan (ior (match_operand 0 "zero_fp_constant") 640169689Skan (match_operand 0 "reg_or_mem_operand"))) 641169689Skan 642169689Skan;; Return 1 if the operand is a general register or memory operand without 643169689Skan;; pre_inc or pre_dec, which produces invalid form of PowerPC lwa 644169689Skan;; instruction. 645169689Skan(define_predicate "lwa_operand" 646169689Skan (match_code "reg,subreg,mem") 647169689Skan{ 648169689Skan rtx inner = op; 649169689Skan 650169689Skan if (reload_completed && GET_CODE (inner) == SUBREG) 651169689Skan inner = SUBREG_REG (inner); 652169689Skan 653169689Skan return gpc_reg_operand (inner, mode) 654169689Skan || (memory_operand (inner, mode) 655169689Skan && GET_CODE (XEXP (inner, 0)) != PRE_INC 656169689Skan && GET_CODE (XEXP (inner, 0)) != PRE_DEC 657169689Skan && (GET_CODE (XEXP (inner, 0)) != PLUS 658169689Skan || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT 659169689Skan || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0)); 660169689Skan}) 661169689Skan 662169689Skan;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. 663169689Skan(define_predicate "symbol_ref_operand" 664169689Skan (and (match_code "symbol_ref") 665169689Skan (match_test "(mode == VOIDmode || GET_MODE (op) == mode) 666169689Skan && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))"))) 667169689Skan 668169689Skan;; Return 1 if op is an operand that can be loaded via the GOT. 669169689Skan;; or non-special register register field no cr0 670169689Skan(define_predicate "got_operand" 671169689Skan (match_code "symbol_ref,const,label_ref")) 672169689Skan 673169689Skan;; Return 1 if op is a simple reference that can be loaded via the GOT, 674169689Skan;; excluding labels involving addition. 675169689Skan(define_predicate "got_no_const_operand" 676169689Skan (match_code "symbol_ref,label_ref")) 677169689Skan 678169689Skan;; Return 1 if op is a SYMBOL_REF for a TLS symbol. 679169689Skan(define_predicate "rs6000_tls_symbol_ref" 680169689Skan (and (match_code "symbol_ref") 681169689Skan (match_test "RS6000_SYMBOL_REF_TLS_P (op)"))) 682169689Skan 683169689Skan;; Return 1 if the operand, used inside a MEM, is a valid first argument 684169689Skan;; to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. 685169689Skan(define_predicate "call_operand" 686169689Skan (if_then_else (match_code "reg") 687169689Skan (match_test "REGNO (op) == LINK_REGISTER_REGNUM 688169689Skan || REGNO (op) == COUNT_REGISTER_REGNUM 689169689Skan || REGNO (op) >= FIRST_PSEUDO_REGISTER") 690169689Skan (match_code "symbol_ref"))) 691169689Skan 692169689Skan;; Return 1 if the operand is a SYMBOL_REF for a function known to be in 693169689Skan;; this file. 694169689Skan(define_predicate "current_file_function_operand" 695169689Skan (and (match_code "symbol_ref") 696169689Skan (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)) 697171825Skan && ((SYMBOL_REF_LOCAL_P (op) 698171825Skan && (DEFAULT_ABI != ABI_AIX 699171825Skan || !SYMBOL_REF_EXTERNAL_P (op))) 700169689Skan || (op == XEXP (DECL_RTL (current_function_decl), 701169689Skan 0)))"))) 702169689Skan 703169689Skan;; Return 1 if this operand is a valid input for a move insn. 704169689Skan(define_predicate "input_operand" 705169689Skan (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem, 706169689Skan const_double,const_vector,const_int,plus") 707169689Skan{ 708169689Skan /* Memory is always valid. */ 709169689Skan if (memory_operand (op, mode)) 710169689Skan return 1; 711169689Skan 712169689Skan /* For floating-point, easy constants are valid. */ 713169689Skan if (SCALAR_FLOAT_MODE_P (mode) 714169689Skan && CONSTANT_P (op) 715169689Skan && easy_fp_constant (op, mode)) 716169689Skan return 1; 717169689Skan 718169689Skan /* Allow any integer constant. */ 719169689Skan if (GET_MODE_CLASS (mode) == MODE_INT 720169689Skan && (GET_CODE (op) == CONST_INT 721169689Skan || GET_CODE (op) == CONST_DOUBLE)) 722169689Skan return 1; 723169689Skan 724169689Skan /* Allow easy vector constants. */ 725169689Skan if (GET_CODE (op) == CONST_VECTOR 726169689Skan && easy_vector_constant (op, mode)) 727169689Skan return 1; 728169689Skan 729169689Skan /* Do not allow invalid E500 subregs. */ 730169689Skan if ((TARGET_E500_DOUBLE || TARGET_SPE) 731169689Skan && GET_CODE (op) == SUBREG 732169689Skan && invalid_e500_subreg (op, mode)) 733169689Skan return 0; 734169689Skan 735169689Skan /* For floating-point or multi-word mode, the only remaining valid type 736169689Skan is a register. */ 737169689Skan if (SCALAR_FLOAT_MODE_P (mode) 738169689Skan || GET_MODE_SIZE (mode) > UNITS_PER_WORD) 739169689Skan return register_operand (op, mode); 740169689Skan 741169689Skan /* The only cases left are integral modes one word or smaller (we 742169689Skan do not get called for MODE_CC values). These can be in any 743169689Skan register. */ 744169689Skan if (register_operand (op, mode)) 745169689Skan return 1; 746169689Skan 747169689Skan /* A SYMBOL_REF referring to the TOC is valid. */ 748169689Skan if (legitimate_constant_pool_address_p (op)) 749169689Skan return 1; 750169689Skan 751169689Skan /* A constant pool expression (relative to the TOC) is valid */ 752169689Skan if (toc_relative_expr_p (op)) 753169689Skan return 1; 754169689Skan 755169689Skan /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region 756169689Skan to be valid. */ 757169689Skan if (DEFAULT_ABI == ABI_V4 758169689Skan && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) 759169689Skan && small_data_operand (op, Pmode)) 760169689Skan return 1; 761169689Skan 762169689Skan return 0; 763169689Skan}) 764169689Skan 765169689Skan;; Return true if OP is an invalid SUBREG operation on the e500. 766169689Skan(define_predicate "rs6000_nonimmediate_operand" 767169689Skan (match_code "reg,subreg,mem") 768169689Skan{ 769169689Skan if ((TARGET_E500_DOUBLE || TARGET_SPE) 770169689Skan && GET_CODE (op) == SUBREG 771169689Skan && invalid_e500_subreg (op, mode)) 772169689Skan return 0; 773169689Skan 774169689Skan return nonimmediate_operand (op, mode); 775169689Skan}) 776169689Skan 777169689Skan;; Return true if operand is boolean operator. 778169689Skan(define_predicate "boolean_operator" 779169689Skan (match_code "and,ior,xor")) 780169689Skan 781169689Skan;; Return true if operand is OR-form of boolean operator. 782169689Skan(define_predicate "boolean_or_operator" 783169689Skan (match_code "ior,xor")) 784169689Skan 785169689Skan;; Return true if operand is an equality operator. 786169689Skan(define_special_predicate "equality_operator" 787169689Skan (match_code "eq,ne")) 788169689Skan 789169689Skan;; Return true if operand is MIN or MAX operator. 790169689Skan(define_predicate "min_max_operator" 791169689Skan (match_code "smin,smax,umin,umax")) 792169689Skan 793169689Skan;; Return 1 if OP is a comparison operation that is valid for a branch 794169689Skan;; instruction. We check the opcode against the mode of the CC value. 795169689Skan;; validate_condition_mode is an assertion. 796169689Skan(define_predicate "branch_comparison_operator" 797169689Skan (and (match_operand 0 "comparison_operator") 798169689Skan (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC") 799169689Skan (match_test "validate_condition_mode (GET_CODE (op), 800169689Skan GET_MODE (XEXP (op, 0))), 801169689Skan 1")))) 802169689Skan 803169689Skan;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- 804169689Skan;; it must be a positive comparison. 805169689Skan(define_predicate "scc_comparison_operator" 806169689Skan (and (match_operand 0 "branch_comparison_operator") 807169689Skan (match_code "eq,lt,gt,ltu,gtu,unordered"))) 808169689Skan 809169689Skan;; Return 1 if OP is a comparison operation that is valid for a branch 810169689Skan;; insn, which is true if the corresponding bit in the CC register is set. 811169689Skan(define_predicate "branch_positive_comparison_operator" 812169689Skan (and (match_operand 0 "branch_comparison_operator") 813169689Skan (match_code "eq,lt,gt,ltu,gtu,unordered"))) 814169689Skan 815169689Skan;; Return 1 is OP is a comparison operation that is valid for a trap insn. 816169689Skan(define_predicate "trap_comparison_operator" 817169689Skan (and (match_operand 0 "comparison_operator") 818169689Skan (match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu"))) 819169689Skan 820169689Skan;; Return 1 if OP is a load multiple operation, known to be a PARALLEL. 821169689Skan(define_predicate "load_multiple_operation" 822169689Skan (match_code "parallel") 823169689Skan{ 824169689Skan int count = XVECLEN (op, 0); 825169689Skan unsigned int dest_regno; 826169689Skan rtx src_addr; 827169689Skan int i; 828169689Skan 829169689Skan /* Perform a quick check so we don't blow up below. */ 830169689Skan if (count <= 1 831169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 832169689Skan || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 833169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 834169689Skan return 0; 835169689Skan 836169689Skan dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 837169689Skan src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 838169689Skan 839169689Skan for (i = 1; i < count; i++) 840169689Skan { 841169689Skan rtx elt = XVECEXP (op, 0, i); 842169689Skan 843169689Skan if (GET_CODE (elt) != SET 844169689Skan || GET_CODE (SET_DEST (elt)) != REG 845169689Skan || GET_MODE (SET_DEST (elt)) != SImode 846169689Skan || REGNO (SET_DEST (elt)) != dest_regno + i 847169689Skan || GET_CODE (SET_SRC (elt)) != MEM 848169689Skan || GET_MODE (SET_SRC (elt)) != SImode 849169689Skan || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS 850169689Skan || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) 851169689Skan || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT 852169689Skan || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) 853169689Skan return 0; 854169689Skan } 855169689Skan 856169689Skan return 1; 857169689Skan}) 858169689Skan 859169689Skan;; Return 1 if OP is a store multiple operation, known to be a PARALLEL. 860169689Skan;; The second vector element is a CLOBBER. 861169689Skan(define_predicate "store_multiple_operation" 862169689Skan (match_code "parallel") 863169689Skan{ 864169689Skan int count = XVECLEN (op, 0) - 1; 865169689Skan unsigned int src_regno; 866169689Skan rtx dest_addr; 867169689Skan int i; 868169689Skan 869169689Skan /* Perform a quick check so we don't blow up below. */ 870169689Skan if (count <= 1 871169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 872169689Skan || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 873169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 874169689Skan return 0; 875169689Skan 876169689Skan src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 877169689Skan dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 878169689Skan 879169689Skan for (i = 1; i < count; i++) 880169689Skan { 881169689Skan rtx elt = XVECEXP (op, 0, i + 1); 882169689Skan 883169689Skan if (GET_CODE (elt) != SET 884169689Skan || GET_CODE (SET_SRC (elt)) != REG 885169689Skan || GET_MODE (SET_SRC (elt)) != SImode 886169689Skan || REGNO (SET_SRC (elt)) != src_regno + i 887169689Skan || GET_CODE (SET_DEST (elt)) != MEM 888169689Skan || GET_MODE (SET_DEST (elt)) != SImode 889169689Skan || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS 890169689Skan || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) 891169689Skan || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT 892169689Skan || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) 893169689Skan return 0; 894169689Skan } 895169689Skan 896169689Skan return 1; 897169689Skan}) 898169689Skan 899169689Skan;; Return 1 if OP is valid for a save_world call in prologue, known to be 900169689Skan;; a PARLLEL. 901169689Skan(define_predicate "save_world_operation" 902169689Skan (match_code "parallel") 903169689Skan{ 904169689Skan int index; 905169689Skan int i; 906169689Skan rtx elt; 907169689Skan int count = XVECLEN (op, 0); 908169689Skan 909169689Skan if (count != 55) 910169689Skan return 0; 911169689Skan 912169689Skan index = 0; 913169689Skan if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER 914169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != USE) 915169689Skan return 0; 916169689Skan 917169689Skan for (i=1; i <= 18; i++) 918169689Skan { 919169689Skan elt = XVECEXP (op, 0, index++); 920169689Skan if (GET_CODE (elt) != SET 921169689Skan || GET_CODE (SET_DEST (elt)) != MEM 922169689Skan || ! memory_operand (SET_DEST (elt), DFmode) 923169689Skan || GET_CODE (SET_SRC (elt)) != REG 924169689Skan || GET_MODE (SET_SRC (elt)) != DFmode) 925169689Skan return 0; 926169689Skan } 927169689Skan 928169689Skan for (i=1; i <= 12; i++) 929169689Skan { 930169689Skan elt = XVECEXP (op, 0, index++); 931169689Skan if (GET_CODE (elt) != SET 932169689Skan || GET_CODE (SET_DEST (elt)) != MEM 933169689Skan || GET_CODE (SET_SRC (elt)) != REG 934169689Skan || GET_MODE (SET_SRC (elt)) != V4SImode) 935169689Skan return 0; 936169689Skan } 937169689Skan 938169689Skan for (i=1; i <= 19; i++) 939169689Skan { 940169689Skan elt = XVECEXP (op, 0, index++); 941169689Skan if (GET_CODE (elt) != SET 942169689Skan || GET_CODE (SET_DEST (elt)) != MEM 943169689Skan || ! memory_operand (SET_DEST (elt), Pmode) 944169689Skan || GET_CODE (SET_SRC (elt)) != REG 945169689Skan || GET_MODE (SET_SRC (elt)) != Pmode) 946169689Skan return 0; 947169689Skan } 948169689Skan 949169689Skan elt = XVECEXP (op, 0, index++); 950169689Skan if (GET_CODE (elt) != SET 951169689Skan || GET_CODE (SET_DEST (elt)) != MEM 952169689Skan || ! memory_operand (SET_DEST (elt), Pmode) 953169689Skan || GET_CODE (SET_SRC (elt)) != REG 954169689Skan || REGNO (SET_SRC (elt)) != CR2_REGNO 955169689Skan || GET_MODE (SET_SRC (elt)) != Pmode) 956169689Skan return 0; 957169689Skan 958169689Skan if (GET_CODE (XVECEXP (op, 0, index++)) != USE 959169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != USE 960169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) 961169689Skan return 0; 962169689Skan return 1; 963169689Skan}) 964169689Skan 965169689Skan;; Return 1 if OP is valid for a restore_world call in epilogue, known to be 966169689Skan;; a PARLLEL. 967169689Skan(define_predicate "restore_world_operation" 968169689Skan (match_code "parallel") 969169689Skan{ 970169689Skan int index; 971169689Skan int i; 972169689Skan rtx elt; 973169689Skan int count = XVECLEN (op, 0); 974169689Skan 975169689Skan if (count != 59) 976169689Skan return 0; 977169689Skan 978169689Skan index = 0; 979169689Skan if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN 980169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != USE 981169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != USE 982169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) 983169689Skan return 0; 984169689Skan 985169689Skan elt = XVECEXP (op, 0, index++); 986169689Skan if (GET_CODE (elt) != SET 987169689Skan || GET_CODE (SET_SRC (elt)) != MEM 988169689Skan || ! memory_operand (SET_SRC (elt), Pmode) 989169689Skan || GET_CODE (SET_DEST (elt)) != REG 990169689Skan || REGNO (SET_DEST (elt)) != CR2_REGNO 991169689Skan || GET_MODE (SET_DEST (elt)) != Pmode) 992169689Skan return 0; 993169689Skan 994169689Skan for (i=1; i <= 19; i++) 995169689Skan { 996169689Skan elt = XVECEXP (op, 0, index++); 997169689Skan if (GET_CODE (elt) != SET 998169689Skan || GET_CODE (SET_SRC (elt)) != MEM 999169689Skan || ! memory_operand (SET_SRC (elt), Pmode) 1000169689Skan || GET_CODE (SET_DEST (elt)) != REG 1001169689Skan || GET_MODE (SET_DEST (elt)) != Pmode) 1002169689Skan return 0; 1003169689Skan } 1004169689Skan 1005169689Skan for (i=1; i <= 12; i++) 1006169689Skan { 1007169689Skan elt = XVECEXP (op, 0, index++); 1008169689Skan if (GET_CODE (elt) != SET 1009169689Skan || GET_CODE (SET_SRC (elt)) != MEM 1010169689Skan || GET_CODE (SET_DEST (elt)) != REG 1011169689Skan || GET_MODE (SET_DEST (elt)) != V4SImode) 1012169689Skan return 0; 1013169689Skan } 1014169689Skan 1015169689Skan for (i=1; i <= 18; i++) 1016169689Skan { 1017169689Skan elt = XVECEXP (op, 0, index++); 1018169689Skan if (GET_CODE (elt) != SET 1019169689Skan || GET_CODE (SET_SRC (elt)) != MEM 1020169689Skan || ! memory_operand (SET_SRC (elt), DFmode) 1021169689Skan || GET_CODE (SET_DEST (elt)) != REG 1022169689Skan || GET_MODE (SET_DEST (elt)) != DFmode) 1023169689Skan return 0; 1024169689Skan } 1025169689Skan 1026169689Skan if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER 1027169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER 1028169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER 1029169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER 1030169689Skan || GET_CODE (XVECEXP (op, 0, index++)) != USE) 1031169689Skan return 0; 1032169689Skan return 1; 1033169689Skan}) 1034169689Skan 1035169689Skan;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL. 1036169689Skan(define_predicate "vrsave_operation" 1037169689Skan (match_code "parallel") 1038169689Skan{ 1039169689Skan int count = XVECLEN (op, 0); 1040169689Skan unsigned int dest_regno, src_regno; 1041169689Skan int i; 1042169689Skan 1043169689Skan if (count <= 1 1044169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 1045169689Skan || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 1046169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE 1047169689Skan || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE) 1048169689Skan return 0; 1049169689Skan 1050169689Skan dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 1051169689Skan src_regno = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1)); 1052169689Skan 1053169689Skan if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO) 1054169689Skan return 0; 1055169689Skan 1056169689Skan for (i = 1; i < count; i++) 1057169689Skan { 1058169689Skan rtx elt = XVECEXP (op, 0, i); 1059169689Skan 1060169689Skan if (GET_CODE (elt) != CLOBBER 1061169689Skan && GET_CODE (elt) != SET) 1062169689Skan return 0; 1063169689Skan } 1064169689Skan 1065169689Skan return 1; 1066169689Skan}) 1067169689Skan 1068169689Skan;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL. 1069169689Skan(define_predicate "mfcr_operation" 1070169689Skan (match_code "parallel") 1071169689Skan{ 1072169689Skan int count = XVECLEN (op, 0); 1073169689Skan int i; 1074169689Skan 1075169689Skan /* Perform a quick check so we don't blow up below. */ 1076169689Skan if (count < 1 1077169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 1078169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC 1079169689Skan || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) 1080169689Skan return 0; 1081169689Skan 1082169689Skan for (i = 0; i < count; i++) 1083169689Skan { 1084169689Skan rtx exp = XVECEXP (op, 0, i); 1085169689Skan rtx unspec; 1086169689Skan int maskval; 1087169689Skan rtx src_reg; 1088169689Skan 1089169689Skan src_reg = XVECEXP (SET_SRC (exp), 0, 0); 1090169689Skan 1091169689Skan if (GET_CODE (src_reg) != REG 1092169689Skan || GET_MODE (src_reg) != CCmode 1093169689Skan || ! CR_REGNO_P (REGNO (src_reg))) 1094169689Skan return 0; 1095169689Skan 1096169689Skan if (GET_CODE (exp) != SET 1097169689Skan || GET_CODE (SET_DEST (exp)) != REG 1098169689Skan || GET_MODE (SET_DEST (exp)) != SImode 1099169689Skan || ! INT_REGNO_P (REGNO (SET_DEST (exp)))) 1100169689Skan return 0; 1101169689Skan unspec = SET_SRC (exp); 1102169689Skan maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg)); 1103169689Skan 1104169689Skan if (GET_CODE (unspec) != UNSPEC 1105169689Skan || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR 1106169689Skan || XVECLEN (unspec, 0) != 2 1107169689Skan || XVECEXP (unspec, 0, 0) != src_reg 1108169689Skan || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT 1109169689Skan || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) 1110169689Skan return 0; 1111169689Skan } 1112169689Skan return 1; 1113169689Skan}) 1114169689Skan 1115169689Skan;; Return 1 if OP is valid for mtcrf insn, known to be a PARALLEL. 1116169689Skan(define_predicate "mtcrf_operation" 1117169689Skan (match_code "parallel") 1118169689Skan{ 1119169689Skan int count = XVECLEN (op, 0); 1120169689Skan int i; 1121169689Skan rtx src_reg; 1122169689Skan 1123169689Skan /* Perform a quick check so we don't blow up below. */ 1124169689Skan if (count < 1 1125169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 1126169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC 1127169689Skan || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) 1128169689Skan return 0; 1129169689Skan src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0); 1130169689Skan 1131169689Skan if (GET_CODE (src_reg) != REG 1132169689Skan || GET_MODE (src_reg) != SImode 1133169689Skan || ! INT_REGNO_P (REGNO (src_reg))) 1134169689Skan return 0; 1135169689Skan 1136169689Skan for (i = 0; i < count; i++) 1137169689Skan { 1138169689Skan rtx exp = XVECEXP (op, 0, i); 1139169689Skan rtx unspec; 1140169689Skan int maskval; 1141169689Skan 1142169689Skan if (GET_CODE (exp) != SET 1143169689Skan || GET_CODE (SET_DEST (exp)) != REG 1144169689Skan || GET_MODE (SET_DEST (exp)) != CCmode 1145169689Skan || ! CR_REGNO_P (REGNO (SET_DEST (exp)))) 1146169689Skan return 0; 1147169689Skan unspec = SET_SRC (exp); 1148169689Skan maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp))); 1149169689Skan 1150169689Skan if (GET_CODE (unspec) != UNSPEC 1151169689Skan || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR 1152169689Skan || XVECLEN (unspec, 0) != 2 1153169689Skan || XVECEXP (unspec, 0, 0) != src_reg 1154169689Skan || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT 1155169689Skan || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) 1156169689Skan return 0; 1157169689Skan } 1158169689Skan return 1; 1159169689Skan}) 1160169689Skan 1161169689Skan;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL. 1162169689Skan(define_predicate "lmw_operation" 1163169689Skan (match_code "parallel") 1164169689Skan{ 1165169689Skan int count = XVECLEN (op, 0); 1166169689Skan unsigned int dest_regno; 1167169689Skan rtx src_addr; 1168169689Skan unsigned int base_regno; 1169169689Skan HOST_WIDE_INT offset; 1170169689Skan int i; 1171169689Skan 1172169689Skan /* Perform a quick check so we don't blow up below. */ 1173169689Skan if (count <= 1 1174169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 1175169689Skan || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 1176169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 1177169689Skan return 0; 1178169689Skan 1179169689Skan dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 1180169689Skan src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 1181169689Skan 1182169689Skan if (dest_regno > 31 1183169689Skan || count != 32 - (int) dest_regno) 1184169689Skan return 0; 1185169689Skan 1186169689Skan if (legitimate_indirect_address_p (src_addr, 0)) 1187169689Skan { 1188169689Skan offset = 0; 1189169689Skan base_regno = REGNO (src_addr); 1190169689Skan if (base_regno == 0) 1191169689Skan return 0; 1192169689Skan } 1193169689Skan else if (rs6000_legitimate_offset_address_p (SImode, src_addr, 0)) 1194169689Skan { 1195169689Skan offset = INTVAL (XEXP (src_addr, 1)); 1196169689Skan base_regno = REGNO (XEXP (src_addr, 0)); 1197169689Skan } 1198169689Skan else 1199169689Skan return 0; 1200169689Skan 1201169689Skan for (i = 0; i < count; i++) 1202169689Skan { 1203169689Skan rtx elt = XVECEXP (op, 0, i); 1204169689Skan rtx newaddr; 1205169689Skan rtx addr_reg; 1206169689Skan HOST_WIDE_INT newoffset; 1207169689Skan 1208169689Skan if (GET_CODE (elt) != SET 1209169689Skan || GET_CODE (SET_DEST (elt)) != REG 1210169689Skan || GET_MODE (SET_DEST (elt)) != SImode 1211169689Skan || REGNO (SET_DEST (elt)) != dest_regno + i 1212169689Skan || GET_CODE (SET_SRC (elt)) != MEM 1213169689Skan || GET_MODE (SET_SRC (elt)) != SImode) 1214169689Skan return 0; 1215169689Skan newaddr = XEXP (SET_SRC (elt), 0); 1216169689Skan if (legitimate_indirect_address_p (newaddr, 0)) 1217169689Skan { 1218169689Skan newoffset = 0; 1219169689Skan addr_reg = newaddr; 1220169689Skan } 1221169689Skan else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0)) 1222169689Skan { 1223169689Skan addr_reg = XEXP (newaddr, 0); 1224169689Skan newoffset = INTVAL (XEXP (newaddr, 1)); 1225169689Skan } 1226169689Skan else 1227169689Skan return 0; 1228169689Skan if (REGNO (addr_reg) != base_regno 1229169689Skan || newoffset != offset + 4 * i) 1230169689Skan return 0; 1231169689Skan } 1232169689Skan 1233169689Skan return 1; 1234169689Skan}) 1235169689Skan 1236169689Skan;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL. 1237169689Skan(define_predicate "stmw_operation" 1238169689Skan (match_code "parallel") 1239169689Skan{ 1240169689Skan int count = XVECLEN (op, 0); 1241169689Skan unsigned int src_regno; 1242169689Skan rtx dest_addr; 1243169689Skan unsigned int base_regno; 1244169689Skan HOST_WIDE_INT offset; 1245169689Skan int i; 1246169689Skan 1247169689Skan /* Perform a quick check so we don't blow up below. */ 1248169689Skan if (count <= 1 1249169689Skan || GET_CODE (XVECEXP (op, 0, 0)) != SET 1250169689Skan || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 1251169689Skan || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 1252169689Skan return 0; 1253169689Skan 1254169689Skan src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 1255169689Skan dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 1256169689Skan 1257169689Skan if (src_regno > 31 1258169689Skan || count != 32 - (int) src_regno) 1259169689Skan return 0; 1260169689Skan 1261169689Skan if (legitimate_indirect_address_p (dest_addr, 0)) 1262169689Skan { 1263169689Skan offset = 0; 1264169689Skan base_regno = REGNO (dest_addr); 1265169689Skan if (base_regno == 0) 1266169689Skan return 0; 1267169689Skan } 1268169689Skan else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, 0)) 1269169689Skan { 1270169689Skan offset = INTVAL (XEXP (dest_addr, 1)); 1271169689Skan base_regno = REGNO (XEXP (dest_addr, 0)); 1272169689Skan } 1273169689Skan else 1274169689Skan return 0; 1275169689Skan 1276169689Skan for (i = 0; i < count; i++) 1277169689Skan { 1278169689Skan rtx elt = XVECEXP (op, 0, i); 1279169689Skan rtx newaddr; 1280169689Skan rtx addr_reg; 1281169689Skan HOST_WIDE_INT newoffset; 1282169689Skan 1283169689Skan if (GET_CODE (elt) != SET 1284169689Skan || GET_CODE (SET_SRC (elt)) != REG 1285169689Skan || GET_MODE (SET_SRC (elt)) != SImode 1286169689Skan || REGNO (SET_SRC (elt)) != src_regno + i 1287169689Skan || GET_CODE (SET_DEST (elt)) != MEM 1288169689Skan || GET_MODE (SET_DEST (elt)) != SImode) 1289169689Skan return 0; 1290169689Skan newaddr = XEXP (SET_DEST (elt), 0); 1291169689Skan if (legitimate_indirect_address_p (newaddr, 0)) 1292169689Skan { 1293169689Skan newoffset = 0; 1294169689Skan addr_reg = newaddr; 1295169689Skan } 1296169689Skan else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0)) 1297169689Skan { 1298169689Skan addr_reg = XEXP (newaddr, 0); 1299169689Skan newoffset = INTVAL (XEXP (newaddr, 1)); 1300169689Skan } 1301169689Skan else 1302169689Skan return 0; 1303169689Skan if (REGNO (addr_reg) != base_regno 1304169689Skan || newoffset != offset + 4 * i) 1305169689Skan return 0; 1306169689Skan } 1307169689Skan 1308169689Skan return 1; 1309169689Skan}) 1310