138fd1498Szrj;; Predicate definitions for IA-32 and x86-64. 238fd1498Szrj;; Copyright (C) 2004-2018 Free Software Foundation, Inc. 338fd1498Szrj;; 438fd1498Szrj;; This file is part of GCC. 538fd1498Szrj;; 638fd1498Szrj;; GCC is free software; you can redistribute it and/or modify 738fd1498Szrj;; it under the terms of the GNU General Public License as published by 838fd1498Szrj;; the Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj;; any later version. 1038fd1498Szrj;; 1138fd1498Szrj;; GCC is distributed in the hope that it will be useful, 1238fd1498Szrj;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj;; GNU General Public License for more details. 1538fd1498Szrj;; 1638fd1498Szrj;; You should have received a copy of the GNU General Public License 1738fd1498Szrj;; along with GCC; see the file COPYING3. If not see 1838fd1498Szrj;; <http://www.gnu.org/licenses/>. 1938fd1498Szrj 2038fd1498Szrj;; Return true if OP is either a i387 or SSE fp register. 2138fd1498Szrj(define_predicate "any_fp_register_operand" 2238fd1498Szrj (and (match_code "reg") 2338fd1498Szrj (match_test "ANY_FP_REGNO_P (REGNO (op))"))) 2438fd1498Szrj 2538fd1498Szrj;; Return true if OP is an i387 fp register. 2638fd1498Szrj(define_predicate "fp_register_operand" 2738fd1498Szrj (and (match_code "reg") 2838fd1498Szrj (match_test "STACK_REGNO_P (REGNO (op))"))) 2938fd1498Szrj 3038fd1498Szrj;; True if the operand is a GENERAL class register. 3138fd1498Szrj(define_predicate "general_reg_operand" 3238fd1498Szrj (and (match_code "reg") 3338fd1498Szrj (match_test "GENERAL_REGNO_P (REGNO (op))"))) 3438fd1498Szrj 3538fd1498Szrj;; True if the operand is a nonimmediate operand with GENERAL class register. 3638fd1498Szrj(define_predicate "nonimmediate_gr_operand" 3738fd1498Szrj (if_then_else (match_code "reg") 3838fd1498Szrj (match_test "GENERAL_REGNO_P (REGNO (op))") 3938fd1498Szrj (match_operand 0 "nonimmediate_operand"))) 4038fd1498Szrj 4138fd1498Szrj;; True if the operand is a general operand with GENERAL class register. 4238fd1498Szrj(define_predicate "general_gr_operand" 4338fd1498Szrj (if_then_else (match_code "reg") 4438fd1498Szrj (match_test "GENERAL_REGNO_P (REGNO (op))") 4538fd1498Szrj (match_operand 0 "general_operand"))) 4638fd1498Szrj 4738fd1498Szrj;; True if the operand is an MMX register. 4838fd1498Szrj(define_predicate "mmx_reg_operand" 4938fd1498Szrj (and (match_code "reg") 5038fd1498Szrj (match_test "MMX_REGNO_P (REGNO (op))"))) 5138fd1498Szrj 5238fd1498Szrj;; True if the operand is an SSE register. 5338fd1498Szrj(define_predicate "sse_reg_operand" 5438fd1498Szrj (and (match_code "reg") 5538fd1498Szrj (match_test "SSE_REGNO_P (REGNO (op))"))) 5638fd1498Szrj 5738fd1498Szrj;; True if the operand is an AVX-512 new register. 5838fd1498Szrj(define_predicate "ext_sse_reg_operand" 5938fd1498Szrj (and (match_code "reg") 6038fd1498Szrj (match_test "EXT_REX_SSE_REGNO_P (REGNO (op))"))) 6138fd1498Szrj 6238fd1498Szrj;; Return true if op is a QImode register. 6338fd1498Szrj(define_predicate "any_QIreg_operand" 6438fd1498Szrj (and (match_code "reg") 6538fd1498Szrj (match_test "ANY_QI_REGNO_P (REGNO (op))"))) 6638fd1498Szrj 6738fd1498Szrj;; Return true if op is one of QImode registers: %[abcd][hl]. 6838fd1498Szrj(define_predicate "QIreg_operand" 6938fd1498Szrj (and (match_code "reg") 7038fd1498Szrj (match_test "QI_REGNO_P (REGNO (op))"))) 7138fd1498Szrj 7238fd1498Szrj;; Return true if op is a QImode register operand other than %[abcd][hl]. 7338fd1498Szrj(define_predicate "ext_QIreg_operand" 7438fd1498Szrj (and (match_test "TARGET_64BIT") 7538fd1498Szrj (match_code "reg") 7638fd1498Szrj (not (match_test "QI_REGNO_P (REGNO (op))")))) 7738fd1498Szrj 7838fd1498Szrj;; Return true if op is the AX register. 7938fd1498Szrj(define_predicate "ax_reg_operand" 8038fd1498Szrj (and (match_code "reg") 8138fd1498Szrj (match_test "REGNO (op) == AX_REG"))) 8238fd1498Szrj 8338fd1498Szrj;; Return true if op is the flags register. 8438fd1498Szrj(define_predicate "flags_reg_operand" 8538fd1498Szrj (and (match_code "reg") 8638fd1498Szrj (match_test "REGNO (op) == FLAGS_REG"))) 8738fd1498Szrj 8838fd1498Szrj;; Match a DI, SI or HImode register for a zero_extract. 8938fd1498Szrj(define_special_predicate "ext_register_operand" 9038fd1498Szrj (and (match_operand 0 "register_operand") 9138fd1498Szrj (ior (and (match_test "TARGET_64BIT") 9238fd1498Szrj (match_test "GET_MODE (op) == DImode")) 9338fd1498Szrj (match_test "GET_MODE (op) == SImode") 9438fd1498Szrj (match_test "GET_MODE (op) == HImode")))) 9538fd1498Szrj 9638fd1498Szrj;; Match register operands, but include memory operands for TARGET_SSE_MATH. 9738fd1498Szrj(define_predicate "register_ssemem_operand" 9838fd1498Szrj (if_then_else 9938fd1498Szrj (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH") 10038fd1498Szrj (match_operand 0 "nonimmediate_operand") 10138fd1498Szrj (match_operand 0 "register_operand"))) 10238fd1498Szrj 10338fd1498Szrj;; Match nonimmediate operands, but exclude memory operands 10438fd1498Szrj;; for TARGET_SSE_MATH if TARGET_MIX_SSE_I387 is not enabled. 10538fd1498Szrj(define_predicate "nonimm_ssenomem_operand" 10638fd1498Szrj (if_then_else 10738fd1498Szrj (and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH") 10838fd1498Szrj (not (match_test "TARGET_MIX_SSE_I387"))) 10938fd1498Szrj (match_operand 0 "register_operand") 11038fd1498Szrj (match_operand 0 "nonimmediate_operand"))) 11138fd1498Szrj 11238fd1498Szrj;; The above predicate, suitable for x87 arithmetic operators. 11338fd1498Szrj(define_predicate "x87nonimm_ssenomem_operand" 11438fd1498Szrj (if_then_else 11538fd1498Szrj (and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH") 11638fd1498Szrj (not (match_test "TARGET_MIX_SSE_I387 && X87_ENABLE_ARITH (mode)"))) 11738fd1498Szrj (match_operand 0 "register_operand") 11838fd1498Szrj (match_operand 0 "nonimmediate_operand"))) 11938fd1498Szrj 12038fd1498Szrj;; Match register operands, include memory operand for TARGET_SSE4_1. 12138fd1498Szrj(define_predicate "register_sse4nonimm_operand" 12238fd1498Szrj (if_then_else (match_test "TARGET_SSE4_1") 12338fd1498Szrj (match_operand 0 "nonimmediate_operand") 12438fd1498Szrj (match_operand 0 "register_operand"))) 12538fd1498Szrj 12638fd1498Szrj;; Return true if VALUE is symbol reference 12738fd1498Szrj(define_predicate "symbol_operand" 12838fd1498Szrj (match_code "symbol_ref")) 12938fd1498Szrj 13038fd1498Szrj;; Return true if VALUE can be stored in a sign extended immediate field. 13138fd1498Szrj(define_predicate "x86_64_immediate_operand" 13238fd1498Szrj (match_code "const_int,symbol_ref,label_ref,const") 13338fd1498Szrj{ 13438fd1498Szrj if (!TARGET_64BIT) 13538fd1498Szrj return immediate_operand (op, mode); 13638fd1498Szrj 13738fd1498Szrj switch (GET_CODE (op)) 13838fd1498Szrj { 13938fd1498Szrj case CONST_INT: 14038fd1498Szrj { 14138fd1498Szrj HOST_WIDE_INT val = INTVAL (op); 14238fd1498Szrj return trunc_int_for_mode (val, SImode) == val; 14338fd1498Szrj } 14438fd1498Szrj case SYMBOL_REF: 14538fd1498Szrj /* TLS symbols are not constant. */ 14638fd1498Szrj if (SYMBOL_REF_TLS_MODEL (op)) 14738fd1498Szrj return false; 14838fd1498Szrj 14938fd1498Szrj /* Load the external function address via the GOT slot. */ 15038fd1498Szrj if (ix86_force_load_from_GOT_p (op)) 15138fd1498Szrj return false; 15238fd1498Szrj 15338fd1498Szrj /* For certain code models, the symbolic references are known to fit. 15438fd1498Szrj in CM_SMALL_PIC model we know it fits if it is local to the shared 15538fd1498Szrj library. Don't count TLS SYMBOL_REFs here, since they should fit 15638fd1498Szrj only if inside of UNSPEC handled below. */ 15738fd1498Szrj return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL 15838fd1498Szrj || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op))); 15938fd1498Szrj 16038fd1498Szrj case LABEL_REF: 16138fd1498Szrj /* For certain code models, the code is near as well. */ 16238fd1498Szrj return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM 16338fd1498Szrj || ix86_cmodel == CM_KERNEL); 16438fd1498Szrj 16538fd1498Szrj case CONST: 16638fd1498Szrj /* We also may accept the offsetted memory references in certain 16738fd1498Szrj special cases. */ 16838fd1498Szrj if (GET_CODE (XEXP (op, 0)) == UNSPEC) 16938fd1498Szrj switch (XINT (XEXP (op, 0), 1)) 17038fd1498Szrj { 17138fd1498Szrj case UNSPEC_GOTPCREL: 17238fd1498Szrj case UNSPEC_DTPOFF: 17338fd1498Szrj case UNSPEC_GOTNTPOFF: 17438fd1498Szrj case UNSPEC_NTPOFF: 17538fd1498Szrj return true; 17638fd1498Szrj default: 17738fd1498Szrj break; 17838fd1498Szrj } 17938fd1498Szrj 18038fd1498Szrj if (GET_CODE (XEXP (op, 0)) == PLUS) 18138fd1498Szrj { 18238fd1498Szrj rtx op1 = XEXP (XEXP (op, 0), 0); 18338fd1498Szrj rtx op2 = XEXP (XEXP (op, 0), 1); 18438fd1498Szrj 185*58e805e6Szrj if (ix86_cmodel == CM_LARGE && GET_CODE (op1) != UNSPEC) 18638fd1498Szrj return false; 18738fd1498Szrj if (!CONST_INT_P (op2)) 18838fd1498Szrj return false; 18938fd1498Szrj 19038fd1498Szrj HOST_WIDE_INT offset = INTVAL (op2); 19138fd1498Szrj if (trunc_int_for_mode (offset, SImode) != offset) 19238fd1498Szrj return false; 19338fd1498Szrj 19438fd1498Szrj switch (GET_CODE (op1)) 19538fd1498Szrj { 19638fd1498Szrj case SYMBOL_REF: 19738fd1498Szrj /* TLS symbols are not constant. */ 19838fd1498Szrj if (SYMBOL_REF_TLS_MODEL (op1)) 19938fd1498Szrj return false; 20038fd1498Szrj 20138fd1498Szrj /* Load the external function address via the GOT slot. */ 20238fd1498Szrj if (ix86_force_load_from_GOT_p (op1)) 20338fd1498Szrj return false; 20438fd1498Szrj 20538fd1498Szrj /* For CM_SMALL assume that latest object is 16MB before 20638fd1498Szrj end of 31bits boundary. We may also accept pretty 20738fd1498Szrj large negative constants knowing that all objects are 20838fd1498Szrj in the positive half of address space. */ 20938fd1498Szrj if ((ix86_cmodel == CM_SMALL 21038fd1498Szrj || (ix86_cmodel == CM_MEDIUM 21138fd1498Szrj && !SYMBOL_REF_FAR_ADDR_P (op1))) 21238fd1498Szrj && offset < 16*1024*1024) 21338fd1498Szrj return true; 21438fd1498Szrj /* For CM_KERNEL we know that all object resist in the 21538fd1498Szrj negative half of 32bits address space. We may not 21638fd1498Szrj accept negative offsets, since they may be just off 21738fd1498Szrj and we may accept pretty large positive ones. */ 21838fd1498Szrj if (ix86_cmodel == CM_KERNEL 21938fd1498Szrj && offset > 0) 22038fd1498Szrj return true; 22138fd1498Szrj break; 22238fd1498Szrj 22338fd1498Szrj case LABEL_REF: 22438fd1498Szrj /* These conditions are similar to SYMBOL_REF ones, just the 22538fd1498Szrj constraints for code models differ. */ 22638fd1498Szrj if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM) 22738fd1498Szrj && offset < 16*1024*1024) 22838fd1498Szrj return true; 22938fd1498Szrj if (ix86_cmodel == CM_KERNEL 23038fd1498Szrj && offset > 0) 23138fd1498Szrj return true; 23238fd1498Szrj break; 23338fd1498Szrj 23438fd1498Szrj case UNSPEC: 23538fd1498Szrj switch (XINT (op1, 1)) 23638fd1498Szrj { 23738fd1498Szrj case UNSPEC_DTPOFF: 23838fd1498Szrj case UNSPEC_NTPOFF: 23938fd1498Szrj return true; 24038fd1498Szrj } 24138fd1498Szrj break; 24238fd1498Szrj 24338fd1498Szrj default: 24438fd1498Szrj break; 24538fd1498Szrj } 24638fd1498Szrj } 24738fd1498Szrj break; 24838fd1498Szrj 24938fd1498Szrj default: 25038fd1498Szrj gcc_unreachable (); 25138fd1498Szrj } 25238fd1498Szrj 25338fd1498Szrj return false; 25438fd1498Szrj}) 25538fd1498Szrj 25638fd1498Szrj;; Return true if VALUE can be stored in the zero extended immediate field. 25738fd1498Szrj(define_predicate "x86_64_zext_immediate_operand" 25838fd1498Szrj (match_code "const_int,symbol_ref,label_ref,const") 25938fd1498Szrj{ 26038fd1498Szrj switch (GET_CODE (op)) 26138fd1498Szrj { 26238fd1498Szrj case CONST_INT: 26338fd1498Szrj return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff); 26438fd1498Szrj 26538fd1498Szrj case SYMBOL_REF: 26638fd1498Szrj /* TLS symbols are not constant. */ 26738fd1498Szrj if (SYMBOL_REF_TLS_MODEL (op)) 26838fd1498Szrj return false; 26938fd1498Szrj 27038fd1498Szrj /* Load the external function address via the GOT slot. */ 27138fd1498Szrj if (ix86_force_load_from_GOT_p (op)) 27238fd1498Szrj return false; 27338fd1498Szrj 27438fd1498Szrj /* For certain code models, the symbolic references are known to fit. */ 27538fd1498Szrj return (ix86_cmodel == CM_SMALL 27638fd1498Szrj || (ix86_cmodel == CM_MEDIUM 27738fd1498Szrj && !SYMBOL_REF_FAR_ADDR_P (op))); 27838fd1498Szrj 27938fd1498Szrj case LABEL_REF: 28038fd1498Szrj /* For certain code models, the code is near as well. */ 28138fd1498Szrj return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM; 28238fd1498Szrj 28338fd1498Szrj case CONST: 28438fd1498Szrj /* We also may accept the offsetted memory references in certain 28538fd1498Szrj special cases. */ 28638fd1498Szrj if (GET_CODE (XEXP (op, 0)) == PLUS) 28738fd1498Szrj { 28838fd1498Szrj rtx op1 = XEXP (XEXP (op, 0), 0); 28938fd1498Szrj rtx op2 = XEXP (XEXP (op, 0), 1); 29038fd1498Szrj 29138fd1498Szrj if (ix86_cmodel == CM_LARGE) 29238fd1498Szrj return false; 29338fd1498Szrj if (!CONST_INT_P (op2)) 29438fd1498Szrj return false; 29538fd1498Szrj 29638fd1498Szrj HOST_WIDE_INT offset = INTVAL (op2); 29738fd1498Szrj if (trunc_int_for_mode (offset, SImode) != offset) 29838fd1498Szrj return false; 29938fd1498Szrj 30038fd1498Szrj switch (GET_CODE (op1)) 30138fd1498Szrj { 30238fd1498Szrj case SYMBOL_REF: 30338fd1498Szrj /* TLS symbols are not constant. */ 30438fd1498Szrj if (SYMBOL_REF_TLS_MODEL (op1)) 30538fd1498Szrj return false; 30638fd1498Szrj 30738fd1498Szrj /* Load the external function address via the GOT slot. */ 30838fd1498Szrj if (ix86_force_load_from_GOT_p (op1)) 30938fd1498Szrj return false; 31038fd1498Szrj 31138fd1498Szrj /* For small code model we may accept pretty large positive 31238fd1498Szrj offsets, since one bit is available for free. Negative 31338fd1498Szrj offsets are limited by the size of NULL pointer area 31438fd1498Szrj specified by the ABI. */ 31538fd1498Szrj if ((ix86_cmodel == CM_SMALL 31638fd1498Szrj || (ix86_cmodel == CM_MEDIUM 31738fd1498Szrj && !SYMBOL_REF_FAR_ADDR_P (op1))) 31838fd1498Szrj && offset > -0x10000) 31938fd1498Szrj return true; 32038fd1498Szrj /* ??? For the kernel, we may accept adjustment of 32138fd1498Szrj -0x10000000, since we know that it will just convert 32238fd1498Szrj negative address space to positive, but perhaps this 32338fd1498Szrj is not worthwhile. */ 32438fd1498Szrj break; 32538fd1498Szrj 32638fd1498Szrj case LABEL_REF: 32738fd1498Szrj /* These conditions are similar to SYMBOL_REF ones, just the 32838fd1498Szrj constraints for code models differ. */ 32938fd1498Szrj if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM) 33038fd1498Szrj && offset > -0x10000) 33138fd1498Szrj return true; 33238fd1498Szrj break; 33338fd1498Szrj 33438fd1498Szrj default: 33538fd1498Szrj return false; 33638fd1498Szrj } 33738fd1498Szrj } 33838fd1498Szrj break; 33938fd1498Szrj 34038fd1498Szrj default: 34138fd1498Szrj gcc_unreachable (); 34238fd1498Szrj } 34338fd1498Szrj return false; 34438fd1498Szrj}) 34538fd1498Szrj 34638fd1498Szrj;; Return true if VALUE is a constant integer whose low and high words satisfy 34738fd1498Szrj;; x86_64_immediate_operand. 34838fd1498Szrj(define_predicate "x86_64_hilo_int_operand" 34938fd1498Szrj (match_code "const_int,const_wide_int") 35038fd1498Szrj{ 35138fd1498Szrj switch (GET_CODE (op)) 35238fd1498Szrj { 35338fd1498Szrj case CONST_INT: 35438fd1498Szrj return x86_64_immediate_operand (op, mode); 35538fd1498Szrj 35638fd1498Szrj case CONST_WIDE_INT: 35738fd1498Szrj gcc_assert (CONST_WIDE_INT_NUNITS (op) == 2); 35838fd1498Szrj return (x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op, 0)), 35938fd1498Szrj DImode) 36038fd1498Szrj && x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op, 36138fd1498Szrj 1)), 36238fd1498Szrj DImode)); 36338fd1498Szrj 36438fd1498Szrj default: 36538fd1498Szrj gcc_unreachable (); 36638fd1498Szrj } 36738fd1498Szrj}) 36838fd1498Szrj 36938fd1498Szrj;; Return true if VALUE is a constant integer whose value is 37038fd1498Szrj;; x86_64_immediate_operand value zero extended from word mode to mode. 37138fd1498Szrj(define_predicate "x86_64_dwzext_immediate_operand" 37238fd1498Szrj (match_code "const_int,const_wide_int") 37338fd1498Szrj{ 37438fd1498Szrj switch (GET_CODE (op)) 37538fd1498Szrj { 37638fd1498Szrj case CONST_INT: 37738fd1498Szrj if (!TARGET_64BIT) 37838fd1498Szrj return UINTVAL (op) <= HOST_WIDE_INT_UC (0xffffffff); 37938fd1498Szrj return UINTVAL (op) <= HOST_WIDE_INT_UC (0x7fffffff); 38038fd1498Szrj 38138fd1498Szrj case CONST_WIDE_INT: 38238fd1498Szrj if (!TARGET_64BIT) 38338fd1498Szrj return false; 38438fd1498Szrj return (CONST_WIDE_INT_NUNITS (op) == 2 38538fd1498Szrj && CONST_WIDE_INT_ELT (op, 1) == 0 38638fd1498Szrj && (trunc_int_for_mode (CONST_WIDE_INT_ELT (op, 0), SImode) 38738fd1498Szrj == (HOST_WIDE_INT) CONST_WIDE_INT_ELT (op, 0))); 38838fd1498Szrj 38938fd1498Szrj default: 39038fd1498Szrj gcc_unreachable (); 39138fd1498Szrj } 39238fd1498Szrj}) 39338fd1498Szrj 39438fd1498Szrj;; Return true if size of VALUE can be stored in a sign 39538fd1498Szrj;; extended immediate field. 39638fd1498Szrj(define_predicate "x86_64_immediate_size_operand" 39738fd1498Szrj (and (match_code "symbol_ref") 39838fd1498Szrj (ior (not (match_test "TARGET_64BIT")) 39938fd1498Szrj (match_test "ix86_cmodel == CM_SMALL") 40038fd1498Szrj (match_test "ix86_cmodel == CM_KERNEL")))) 40138fd1498Szrj 40238fd1498Szrj;; Return true if OP is general operand representable on x86_64. 40338fd1498Szrj(define_predicate "x86_64_general_operand" 40438fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 40538fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 40638fd1498Szrj (match_operand 0 "x86_64_immediate_operand")) 40738fd1498Szrj (match_operand 0 "general_operand"))) 40838fd1498Szrj 40938fd1498Szrj;; Return true if OP's both words are general operands representable 41038fd1498Szrj;; on x86_64. 41138fd1498Szrj(define_predicate "x86_64_hilo_general_operand" 41238fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 41338fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 41438fd1498Szrj (match_operand 0 "x86_64_hilo_int_operand")) 41538fd1498Szrj (match_operand 0 "general_operand"))) 41638fd1498Szrj 41738fd1498Szrj;; Return true if OP is non-VOIDmode general operand representable 41838fd1498Szrj;; on x86_64. This predicate is used in sign-extending conversion 41938fd1498Szrj;; operations that require non-VOIDmode immediate operands. 42038fd1498Szrj(define_predicate "x86_64_sext_operand" 42138fd1498Szrj (and (match_test "GET_MODE (op) != VOIDmode") 42238fd1498Szrj (match_operand 0 "x86_64_general_operand"))) 42338fd1498Szrj 42438fd1498Szrj;; Return true if OP is non-VOIDmode general operand. This predicate 42538fd1498Szrj;; is used in sign-extending conversion operations that require 42638fd1498Szrj;; non-VOIDmode immediate operands. 42738fd1498Szrj(define_predicate "sext_operand" 42838fd1498Szrj (and (match_test "GET_MODE (op) != VOIDmode") 42938fd1498Szrj (match_operand 0 "general_operand"))) 43038fd1498Szrj 43138fd1498Szrj;; Return true if OP is representable on x86_64 as zero-extended operand. 43238fd1498Szrj;; This predicate is used in zero-extending conversion operations that 43338fd1498Szrj;; require non-VOIDmode immediate operands. 43438fd1498Szrj(define_predicate "x86_64_zext_operand" 43538fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 43638fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 43738fd1498Szrj (and (match_operand 0 "x86_64_zext_immediate_operand") 43838fd1498Szrj (match_test "GET_MODE (op) != VOIDmode"))) 43938fd1498Szrj (match_operand 0 "nonimmediate_operand"))) 44038fd1498Szrj 44138fd1498Szrj;; Return true if OP is general operand representable on x86_64 44238fd1498Szrj;; as either sign extended or zero extended constant. 44338fd1498Szrj(define_predicate "x86_64_szext_general_operand" 44438fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 44538fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 44638fd1498Szrj (match_operand 0 "x86_64_immediate_operand") 44738fd1498Szrj (match_operand 0 "x86_64_zext_immediate_operand")) 44838fd1498Szrj (match_operand 0 "general_operand"))) 44938fd1498Szrj 45038fd1498Szrj;; Return true if OP is nonmemory operand representable on x86_64. 45138fd1498Szrj(define_predicate "x86_64_nonmemory_operand" 45238fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 45338fd1498Szrj (ior (match_operand 0 "register_operand") 45438fd1498Szrj (match_operand 0 "x86_64_immediate_operand")) 45538fd1498Szrj (match_operand 0 "nonmemory_operand"))) 45638fd1498Szrj 45738fd1498Szrj;; Return true if OP is nonmemory operand representable on x86_64. 45838fd1498Szrj(define_predicate "x86_64_szext_nonmemory_operand" 45938fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 46038fd1498Szrj (ior (match_operand 0 "register_operand") 46138fd1498Szrj (match_operand 0 "x86_64_immediate_operand") 46238fd1498Szrj (match_operand 0 "x86_64_zext_immediate_operand")) 46338fd1498Szrj (match_operand 0 "nonmemory_operand"))) 46438fd1498Szrj 46538fd1498Szrj;; Return true when operand is PIC expression that can be computed by lea 46638fd1498Szrj;; operation. 46738fd1498Szrj(define_predicate "pic_32bit_operand" 46838fd1498Szrj (match_code "const,symbol_ref,label_ref") 46938fd1498Szrj{ 47038fd1498Szrj if (!flag_pic) 47138fd1498Szrj return false; 47238fd1498Szrj 47338fd1498Szrj /* Rule out relocations that translate into 64bit constants. */ 47438fd1498Szrj if (TARGET_64BIT && GET_CODE (op) == CONST) 47538fd1498Szrj { 47638fd1498Szrj op = XEXP (op, 0); 47738fd1498Szrj if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1))) 47838fd1498Szrj op = XEXP (op, 0); 47938fd1498Szrj if (GET_CODE (op) == UNSPEC 48038fd1498Szrj && (XINT (op, 1) == UNSPEC_GOTOFF 48138fd1498Szrj || XINT (op, 1) == UNSPEC_GOT)) 48238fd1498Szrj return false; 48338fd1498Szrj } 48438fd1498Szrj 48538fd1498Szrj return symbolic_operand (op, mode); 48638fd1498Szrj}) 48738fd1498Szrj 48838fd1498Szrj;; Return true if OP is nonmemory operand acceptable by movabs patterns. 48938fd1498Szrj(define_predicate "x86_64_movabs_operand" 49038fd1498Szrj (and (match_operand 0 "nonmemory_operand") 49138fd1498Szrj (not (match_operand 0 "pic_32bit_operand")))) 49238fd1498Szrj 49338fd1498Szrj;; Return true if OP is either a symbol reference or a sum of a symbol 49438fd1498Szrj;; reference and a constant. 49538fd1498Szrj(define_predicate "symbolic_operand" 49638fd1498Szrj (match_code "symbol_ref,label_ref,const") 49738fd1498Szrj{ 49838fd1498Szrj switch (GET_CODE (op)) 49938fd1498Szrj { 50038fd1498Szrj case SYMBOL_REF: 50138fd1498Szrj case LABEL_REF: 50238fd1498Szrj return true; 50338fd1498Szrj 50438fd1498Szrj case CONST: 50538fd1498Szrj op = XEXP (op, 0); 50638fd1498Szrj if (GET_CODE (op) == SYMBOL_REF 50738fd1498Szrj || GET_CODE (op) == LABEL_REF 50838fd1498Szrj || (GET_CODE (op) == UNSPEC 50938fd1498Szrj && (XINT (op, 1) == UNSPEC_GOT 51038fd1498Szrj || XINT (op, 1) == UNSPEC_GOTOFF 51138fd1498Szrj || XINT (op, 1) == UNSPEC_PCREL 51238fd1498Szrj || XINT (op, 1) == UNSPEC_GOTPCREL))) 51338fd1498Szrj return true; 51438fd1498Szrj if (GET_CODE (op) != PLUS 51538fd1498Szrj || !CONST_INT_P (XEXP (op, 1))) 51638fd1498Szrj return false; 51738fd1498Szrj 51838fd1498Szrj op = XEXP (op, 0); 51938fd1498Szrj if (GET_CODE (op) == SYMBOL_REF 52038fd1498Szrj || GET_CODE (op) == LABEL_REF) 52138fd1498Szrj return true; 52238fd1498Szrj /* Only @GOTOFF gets offsets. */ 52338fd1498Szrj if (GET_CODE (op) != UNSPEC 52438fd1498Szrj || XINT (op, 1) != UNSPEC_GOTOFF) 52538fd1498Szrj return false; 52638fd1498Szrj 52738fd1498Szrj op = XVECEXP (op, 0, 0); 52838fd1498Szrj if (GET_CODE (op) == SYMBOL_REF 52938fd1498Szrj || GET_CODE (op) == LABEL_REF) 53038fd1498Szrj return true; 53138fd1498Szrj return false; 53238fd1498Szrj 53338fd1498Szrj default: 53438fd1498Szrj gcc_unreachable (); 53538fd1498Szrj } 53638fd1498Szrj}) 53738fd1498Szrj 53838fd1498Szrj;; Return true if OP is a symbolic operand that resolves locally. 53938fd1498Szrj(define_predicate "local_symbolic_operand" 54038fd1498Szrj (match_code "const,label_ref,symbol_ref") 54138fd1498Szrj{ 54238fd1498Szrj if (GET_CODE (op) == CONST 54338fd1498Szrj && GET_CODE (XEXP (op, 0)) == PLUS 54438fd1498Szrj && CONST_INT_P (XEXP (XEXP (op, 0), 1))) 54538fd1498Szrj op = XEXP (XEXP (op, 0), 0); 54638fd1498Szrj 54738fd1498Szrj if (GET_CODE (op) == LABEL_REF) 54838fd1498Szrj return true; 54938fd1498Szrj 55038fd1498Szrj if (GET_CODE (op) != SYMBOL_REF) 55138fd1498Szrj return false; 55238fd1498Szrj 55338fd1498Szrj if (SYMBOL_REF_TLS_MODEL (op)) 55438fd1498Szrj return false; 55538fd1498Szrj 55638fd1498Szrj /* Dll-imported symbols are always external. */ 55738fd1498Szrj if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op)) 55838fd1498Szrj return false; 55938fd1498Szrj if (SYMBOL_REF_LOCAL_P (op)) 56038fd1498Szrj return true; 56138fd1498Szrj 56238fd1498Szrj /* There is, however, a not insubstantial body of code in the rest of 56338fd1498Szrj the compiler that assumes it can just stick the results of 56438fd1498Szrj ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done. */ 56538fd1498Szrj /* ??? This is a hack. Should update the body of the compiler to 56638fd1498Szrj always create a DECL an invoke targetm.encode_section_info. */ 56738fd1498Szrj if (strncmp (XSTR (op, 0), internal_label_prefix, 56838fd1498Szrj internal_label_prefix_len) == 0) 56938fd1498Szrj return true; 57038fd1498Szrj 57138fd1498Szrj return false; 57238fd1498Szrj}) 57338fd1498Szrj 57438fd1498Szrj;; Test for a legitimate @GOTOFF operand. 57538fd1498Szrj;; 57638fd1498Szrj;; VxWorks does not impose a fixed gap between segments; the run-time 57738fd1498Szrj;; gap can be different from the object-file gap. We therefore can't 57838fd1498Szrj;; use @GOTOFF unless we are absolutely sure that the symbol is in the 57938fd1498Szrj;; same segment as the GOT. Unfortunately, the flexibility of linker 58038fd1498Szrj;; scripts means that we can't be sure of that in general, so assume 58138fd1498Szrj;; that @GOTOFF is never valid on VxWorks. 58238fd1498Szrj(define_predicate "gotoff_operand" 58338fd1498Szrj (and (not (match_test "TARGET_VXWORKS_RTP")) 58438fd1498Szrj (match_operand 0 "local_symbolic_operand"))) 58538fd1498Szrj 58638fd1498Szrj;; Test for various thread-local symbols. 58738fd1498Szrj(define_special_predicate "tls_symbolic_operand" 58838fd1498Szrj (and (match_code "symbol_ref") 58938fd1498Szrj (match_test "SYMBOL_REF_TLS_MODEL (op)"))) 59038fd1498Szrj 59138fd1498Szrj(define_special_predicate "tls_modbase_operand" 59238fd1498Szrj (and (match_code "symbol_ref") 59338fd1498Szrj (match_test "op == ix86_tls_module_base ()"))) 59438fd1498Szrj 59538fd1498Szrj(define_predicate "tls_address_pattern" 59638fd1498Szrj (and (match_code "set,parallel,unspec,unspec_volatile") 59738fd1498Szrj (match_test "ix86_tls_address_pattern_p (op)"))) 59838fd1498Szrj 59938fd1498Szrj;; Test for a pc-relative call operand 60038fd1498Szrj(define_predicate "constant_call_address_operand" 60138fd1498Szrj (match_code "symbol_ref") 60238fd1498Szrj{ 60338fd1498Szrj if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC 60438fd1498Szrj || flag_force_indirect_call) 60538fd1498Szrj return false; 60638fd1498Szrj if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op)) 60738fd1498Szrj return false; 60838fd1498Szrj return true; 60938fd1498Szrj}) 61038fd1498Szrj 61138fd1498Szrj;; P6 processors will jump to the address after the decrement when %esp 61238fd1498Szrj;; is used as a call operand, so they will execute return address as a code. 61338fd1498Szrj;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 61438fd1498Szrj 61538fd1498Szrj(define_predicate "call_register_no_elim_operand" 61638fd1498Szrj (match_operand 0 "register_operand") 61738fd1498Szrj{ 61838fd1498Szrj if (SUBREG_P (op)) 61938fd1498Szrj op = SUBREG_REG (op); 62038fd1498Szrj 62138fd1498Szrj if (!TARGET_64BIT && op == stack_pointer_rtx) 62238fd1498Szrj return false; 62338fd1498Szrj 62438fd1498Szrj return register_no_elim_operand (op, mode); 62538fd1498Szrj}) 62638fd1498Szrj 62738fd1498Szrj;; True for any non-virtual or eliminable register. Used in places where 62838fd1498Szrj;; instantiation of such a register may cause the pattern to not be recognized. 62938fd1498Szrj(define_predicate "register_no_elim_operand" 63038fd1498Szrj (match_operand 0 "register_operand") 63138fd1498Szrj{ 63238fd1498Szrj if (SUBREG_P (op)) 63338fd1498Szrj op = SUBREG_REG (op); 63438fd1498Szrj return !(op == arg_pointer_rtx 63538fd1498Szrj || op == frame_pointer_rtx 63638fd1498Szrj || IN_RANGE (REGNO (op), 63738fd1498Szrj FIRST_PSEUDO_REGISTER, LAST_VIRTUAL_REGISTER)); 63838fd1498Szrj}) 63938fd1498Szrj 64038fd1498Szrj;; Similarly, but include the stack pointer. This is used to prevent esp 64138fd1498Szrj;; from being used as an index reg. 64238fd1498Szrj(define_predicate "index_register_operand" 64338fd1498Szrj (match_operand 0 "register_operand") 64438fd1498Szrj{ 64538fd1498Szrj if (SUBREG_P (op)) 64638fd1498Szrj op = SUBREG_REG (op); 64738fd1498Szrj if (reload_completed) 64838fd1498Szrj return REG_OK_FOR_INDEX_STRICT_P (op); 64938fd1498Szrj else 65038fd1498Szrj return REG_OK_FOR_INDEX_NONSTRICT_P (op); 65138fd1498Szrj}) 65238fd1498Szrj 65338fd1498Szrj;; Return false if this is any eliminable register. Otherwise general_operand. 65438fd1498Szrj(define_predicate "general_no_elim_operand" 65538fd1498Szrj (if_then_else (match_code "reg,subreg") 65638fd1498Szrj (match_operand 0 "register_no_elim_operand") 65738fd1498Szrj (match_operand 0 "general_operand"))) 65838fd1498Szrj 65938fd1498Szrj;; Return false if this is any eliminable register. Otherwise 66038fd1498Szrj;; register_operand or a constant. 66138fd1498Szrj(define_predicate "nonmemory_no_elim_operand" 66238fd1498Szrj (ior (match_operand 0 "register_no_elim_operand") 66338fd1498Szrj (match_operand 0 "immediate_operand"))) 66438fd1498Szrj 66538fd1498Szrj;; Test for a valid operand for indirect branch. 66638fd1498Szrj(define_predicate "indirect_branch_operand" 66738fd1498Szrj (ior (match_operand 0 "register_operand") 66838fd1498Szrj (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) 66938fd1498Szrj (not (match_test "TARGET_X32")) 67038fd1498Szrj (match_operand 0 "memory_operand")))) 67138fd1498Szrj 67238fd1498Szrj;; Return true if OP is a memory operands that can be used in sibcalls. 67338fd1498Szrj;; Since sibcall never returns, we can only use call-clobbered register 67438fd1498Szrj;; as GOT base. Allow GOT slot here only with pseudo register as GOT 67538fd1498Szrj;; base. Properly handle sibcall over GOT slot with *sibcall_GOT_32 67638fd1498Szrj;; and *sibcall_value_GOT_32 patterns. 67738fd1498Szrj(define_predicate "sibcall_memory_operand" 67838fd1498Szrj (match_operand 0 "memory_operand") 67938fd1498Szrj{ 68038fd1498Szrj op = XEXP (op, 0); 68138fd1498Szrj if (CONSTANT_P (op)) 68238fd1498Szrj return true; 68338fd1498Szrj if (GET_CODE (op) == PLUS && REG_P (XEXP (op, 0))) 68438fd1498Szrj { 68538fd1498Szrj int regno = REGNO (XEXP (op, 0)); 68638fd1498Szrj if (!HARD_REGISTER_NUM_P (regno) || call_used_regs[regno]) 68738fd1498Szrj { 68838fd1498Szrj op = XEXP (op, 1); 68938fd1498Szrj if (GOT32_symbol_operand (op, VOIDmode)) 69038fd1498Szrj return true; 69138fd1498Szrj } 69238fd1498Szrj } 69338fd1498Szrj return false; 69438fd1498Szrj}) 69538fd1498Szrj 69638fd1498Szrj;; Return true if OP is a GOT memory operand. 69738fd1498Szrj(define_predicate "GOT_memory_operand" 69838fd1498Szrj (match_operand 0 "memory_operand") 69938fd1498Szrj{ 70038fd1498Szrj op = XEXP (op, 0); 70138fd1498Szrj return (GET_CODE (op) == CONST 70238fd1498Szrj && GET_CODE (XEXP (op, 0)) == UNSPEC 70338fd1498Szrj && XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL); 70438fd1498Szrj}) 70538fd1498Szrj 70638fd1498Szrj;; Test for a valid operand for a call instruction. 70738fd1498Szrj;; Allow constant call address operands in Pmode only. 70838fd1498Szrj(define_special_predicate "call_insn_operand" 70938fd1498Szrj (ior (match_test "constant_call_address_operand 71038fd1498Szrj (op, mode == VOIDmode ? mode : Pmode)") 71138fd1498Szrj (match_operand 0 "call_register_no_elim_operand") 71238fd1498Szrj (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) 71338fd1498Szrj (ior (and (not (match_test "TARGET_X32")) 71438fd1498Szrj (match_operand 0 "memory_operand")) 71538fd1498Szrj (and (match_test "TARGET_X32 && Pmode == DImode") 71638fd1498Szrj (match_operand 0 "GOT_memory_operand")))))) 71738fd1498Szrj 71838fd1498Szrj;; Similarly, but for tail calls, in which we cannot allow memory references. 71938fd1498Szrj(define_special_predicate "sibcall_insn_operand" 72038fd1498Szrj (ior (match_test "constant_call_address_operand 72138fd1498Szrj (op, mode == VOIDmode ? mode : Pmode)") 72238fd1498Szrj (match_operand 0 "register_no_elim_operand") 72338fd1498Szrj (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) 72438fd1498Szrj (ior (and (not (match_test "TARGET_X32")) 72538fd1498Szrj (match_operand 0 "sibcall_memory_operand")) 72638fd1498Szrj (and (match_test "TARGET_X32 && Pmode == DImode") 72738fd1498Szrj (match_operand 0 "GOT_memory_operand")))))) 72838fd1498Szrj 72938fd1498Szrj;; Return true if OP is a 32-bit GOT symbol operand. 73038fd1498Szrj(define_predicate "GOT32_symbol_operand" 73138fd1498Szrj (match_test "GET_CODE (op) == CONST 73238fd1498Szrj && GET_CODE (XEXP (op, 0)) == UNSPEC 73338fd1498Szrj && XINT (XEXP (op, 0), 1) == UNSPEC_GOT")) 73438fd1498Szrj 73538fd1498Szrj;; Match exactly zero. 73638fd1498Szrj(define_predicate "const0_operand" 73738fd1498Szrj (match_code "const_int,const_double,const_vector") 73838fd1498Szrj{ 73938fd1498Szrj if (mode == VOIDmode) 74038fd1498Szrj mode = GET_MODE (op); 74138fd1498Szrj return op == CONST0_RTX (mode); 74238fd1498Szrj}) 74338fd1498Szrj 74438fd1498Szrj;; Match one or a vector with all elements equal to one. 74538fd1498Szrj(define_predicate "const1_operand" 74638fd1498Szrj (match_code "const_int,const_double,const_vector") 74738fd1498Szrj{ 74838fd1498Szrj if (mode == VOIDmode) 74938fd1498Szrj mode = GET_MODE (op); 75038fd1498Szrj return op == CONST1_RTX (mode); 75138fd1498Szrj}) 75238fd1498Szrj 75338fd1498Szrj;; Match exactly -1. 75438fd1498Szrj(define_predicate "constm1_operand" 75538fd1498Szrj (and (match_code "const_int") 75638fd1498Szrj (match_test "op == constm1_rtx"))) 75738fd1498Szrj 75838fd1498Szrj;; Match exactly eight. 75938fd1498Szrj(define_predicate "const8_operand" 76038fd1498Szrj (and (match_code "const_int") 76138fd1498Szrj (match_test "INTVAL (op) == 8"))) 76238fd1498Szrj 76338fd1498Szrj;; Match exactly 128. 76438fd1498Szrj(define_predicate "const128_operand" 76538fd1498Szrj (and (match_code "const_int") 76638fd1498Szrj (match_test "INTVAL (op) == 128"))) 76738fd1498Szrj 76838fd1498Szrj;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation 76938fd1498Szrj(define_predicate "const_32bit_mask" 77038fd1498Szrj (and (match_code "const_int") 77138fd1498Szrj (match_test "trunc_int_for_mode (INTVAL (op), DImode) 77238fd1498Szrj == (HOST_WIDE_INT) 0xffffffff"))) 77338fd1498Szrj 77438fd1498Szrj;; Match 2, 4, or 8. Used for leal multiplicands. 77538fd1498Szrj(define_predicate "const248_operand" 77638fd1498Szrj (match_code "const_int") 77738fd1498Szrj{ 77838fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 77938fd1498Szrj return i == 2 || i == 4 || i == 8; 78038fd1498Szrj}) 78138fd1498Szrj 78238fd1498Szrj;; Match 1, 2, or 3. Used for lea shift amounts. 78338fd1498Szrj(define_predicate "const123_operand" 78438fd1498Szrj (match_code "const_int") 78538fd1498Szrj{ 78638fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 78738fd1498Szrj return i == 1 || i == 2 || i == 3; 78838fd1498Szrj}) 78938fd1498Szrj 79038fd1498Szrj;; Match 2, 3, 6, or 7 79138fd1498Szrj(define_predicate "const2367_operand" 79238fd1498Szrj (match_code "const_int") 79338fd1498Szrj{ 79438fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 79538fd1498Szrj return i == 2 || i == 3 || i == 6 || i == 7; 79638fd1498Szrj}) 79738fd1498Szrj 79838fd1498Szrj;; Match 1, 2, 4, or 8 79938fd1498Szrj(define_predicate "const1248_operand" 80038fd1498Szrj (match_code "const_int") 80138fd1498Szrj{ 80238fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 80338fd1498Szrj return i == 1 || i == 2 || i == 4 || i == 8; 80438fd1498Szrj}) 80538fd1498Szrj 80638fd1498Szrj;; Match 3, 5, or 9. Used for leal multiplicands. 80738fd1498Szrj(define_predicate "const359_operand" 80838fd1498Szrj (match_code "const_int") 80938fd1498Szrj{ 81038fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 81138fd1498Szrj return i == 3 || i == 5 || i == 9; 81238fd1498Szrj}) 81338fd1498Szrj 81438fd1498Szrj;; Match 4 or 8 to 11. Used for embeded rounding. 81538fd1498Szrj(define_predicate "const_4_or_8_to_11_operand" 81638fd1498Szrj (match_code "const_int") 81738fd1498Szrj{ 81838fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 81938fd1498Szrj return i == 4 || (i >= 8 && i <= 11); 82038fd1498Szrj}) 82138fd1498Szrj 82238fd1498Szrj;; Match 4 or 8. Used for SAE. 82338fd1498Szrj(define_predicate "const48_operand" 82438fd1498Szrj (match_code "const_int") 82538fd1498Szrj{ 82638fd1498Szrj HOST_WIDE_INT i = INTVAL (op); 82738fd1498Szrj return i == 4 || i == 8; 82838fd1498Szrj}) 82938fd1498Szrj 83038fd1498Szrj;; Match 0 or 1. 83138fd1498Szrj(define_predicate "const_0_to_1_operand" 83238fd1498Szrj (and (match_code "const_int") 83338fd1498Szrj (ior (match_test "op == const0_rtx") 83438fd1498Szrj (match_test "op == const1_rtx")))) 83538fd1498Szrj 83638fd1498Szrj;; Match 0 to 3. 83738fd1498Szrj(define_predicate "const_0_to_3_operand" 83838fd1498Szrj (and (match_code "const_int") 83938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 3)"))) 84038fd1498Szrj 84138fd1498Szrj;; Match 0 to 4. 84238fd1498Szrj(define_predicate "const_0_to_4_operand" 84338fd1498Szrj (and (match_code "const_int") 84438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 4)"))) 84538fd1498Szrj 84638fd1498Szrj;; Match 0 to 5. 84738fd1498Szrj(define_predicate "const_0_to_5_operand" 84838fd1498Szrj (and (match_code "const_int") 84938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 5)"))) 85038fd1498Szrj 85138fd1498Szrj;; Match 0 to 7. 85238fd1498Szrj(define_predicate "const_0_to_7_operand" 85338fd1498Szrj (and (match_code "const_int") 85438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 7)"))) 85538fd1498Szrj 85638fd1498Szrj;; Match 0 to 15. 85738fd1498Szrj(define_predicate "const_0_to_15_operand" 85838fd1498Szrj (and (match_code "const_int") 85938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) 86038fd1498Szrj 86138fd1498Szrj;; Match 0 to 31. 86238fd1498Szrj(define_predicate "const_0_to_31_operand" 86338fd1498Szrj (and (match_code "const_int") 86438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) 86538fd1498Szrj 86638fd1498Szrj;; Match 0 to 63. 86738fd1498Szrj(define_predicate "const_0_to_63_operand" 86838fd1498Szrj (and (match_code "const_int") 86938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 63)"))) 87038fd1498Szrj 87138fd1498Szrj;; Match 0 to 255. 87238fd1498Szrj(define_predicate "const_0_to_255_operand" 87338fd1498Szrj (and (match_code "const_int") 87438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 0, 255)"))) 87538fd1498Szrj 87638fd1498Szrj;; Match (0 to 255) * 8 87738fd1498Szrj(define_predicate "const_0_to_255_mul_8_operand" 87838fd1498Szrj (match_code "const_int") 87938fd1498Szrj{ 88038fd1498Szrj unsigned HOST_WIDE_INT val = INTVAL (op); 88138fd1498Szrj return val <= 255*8 && val % 8 == 0; 88238fd1498Szrj}) 88338fd1498Szrj 88438fd1498Szrj;; Return true if OP is CONST_INT >= 1 and <= 31 (a valid operand 88538fd1498Szrj;; for shift & compare patterns, as shifting by 0 does not change flags). 88638fd1498Szrj(define_predicate "const_1_to_31_operand" 88738fd1498Szrj (and (match_code "const_int") 88838fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 1, 31)"))) 88938fd1498Szrj 89038fd1498Szrj;; Return true if OP is CONST_INT >= 1 and <= 63 (a valid operand 89138fd1498Szrj;; for 64bit shift & compare patterns, as shifting by 0 does not change flags). 89238fd1498Szrj(define_predicate "const_1_to_63_operand" 89338fd1498Szrj (and (match_code "const_int") 89438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 1, 63)"))) 89538fd1498Szrj 89638fd1498Szrj;; Match 2 or 3. 89738fd1498Szrj(define_predicate "const_2_to_3_operand" 89838fd1498Szrj (and (match_code "const_int") 89938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 2, 3)"))) 90038fd1498Szrj 90138fd1498Szrj;; Match 4 to 5. 90238fd1498Szrj(define_predicate "const_4_to_5_operand" 90338fd1498Szrj (and (match_code "const_int") 90438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 4, 5)"))) 90538fd1498Szrj 90638fd1498Szrj;; Match 4 to 7. 90738fd1498Szrj(define_predicate "const_4_to_7_operand" 90838fd1498Szrj (and (match_code "const_int") 90938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 4, 7)"))) 91038fd1498Szrj 91138fd1498Szrj;; Match 6 to 7. 91238fd1498Szrj(define_predicate "const_6_to_7_operand" 91338fd1498Szrj (and (match_code "const_int") 91438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 6, 7)"))) 91538fd1498Szrj 91638fd1498Szrj;; Match 8 to 9. 91738fd1498Szrj(define_predicate "const_8_to_9_operand" 91838fd1498Szrj (and (match_code "const_int") 91938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 8, 9)"))) 92038fd1498Szrj 92138fd1498Szrj;; Match 8 to 11. 92238fd1498Szrj(define_predicate "const_8_to_11_operand" 92338fd1498Szrj (and (match_code "const_int") 92438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 8, 11)"))) 92538fd1498Szrj 92638fd1498Szrj;; Match 8 to 15. 92738fd1498Szrj(define_predicate "const_8_to_15_operand" 92838fd1498Szrj (and (match_code "const_int") 92938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 8, 15)"))) 93038fd1498Szrj 93138fd1498Szrj;; Match 10 to 11. 93238fd1498Szrj(define_predicate "const_10_to_11_operand" 93338fd1498Szrj (and (match_code "const_int") 93438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 10, 11)"))) 93538fd1498Szrj 93638fd1498Szrj;; Match 12 to 13. 93738fd1498Szrj(define_predicate "const_12_to_13_operand" 93838fd1498Szrj (and (match_code "const_int") 93938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 12, 13)"))) 94038fd1498Szrj 94138fd1498Szrj;; Match 12 to 15. 94238fd1498Szrj(define_predicate "const_12_to_15_operand" 94338fd1498Szrj (and (match_code "const_int") 94438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 12, 15)"))) 94538fd1498Szrj 94638fd1498Szrj;; Match 14 to 15. 94738fd1498Szrj(define_predicate "const_14_to_15_operand" 94838fd1498Szrj (and (match_code "const_int") 94938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 14, 15)"))) 95038fd1498Szrj 95138fd1498Szrj;; Match 16 to 19. 95238fd1498Szrj(define_predicate "const_16_to_19_operand" 95338fd1498Szrj (and (match_code "const_int") 95438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 16, 19)"))) 95538fd1498Szrj 95638fd1498Szrj;; Match 16 to 31. 95738fd1498Szrj(define_predicate "const_16_to_31_operand" 95838fd1498Szrj (and (match_code "const_int") 95938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 16, 31)"))) 96038fd1498Szrj 96138fd1498Szrj;; Match 20 to 23. 96238fd1498Szrj(define_predicate "const_20_to_23_operand" 96338fd1498Szrj (and (match_code "const_int") 96438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 20, 23)"))) 96538fd1498Szrj 96638fd1498Szrj;; Match 24 to 27. 96738fd1498Szrj(define_predicate "const_24_to_27_operand" 96838fd1498Szrj (and (match_code "const_int") 96938fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 24, 27)"))) 97038fd1498Szrj 97138fd1498Szrj;; Match 28 to 31. 97238fd1498Szrj(define_predicate "const_28_to_31_operand" 97338fd1498Szrj (and (match_code "const_int") 97438fd1498Szrj (match_test "IN_RANGE (INTVAL (op), 28, 31)"))) 97538fd1498Szrj 97638fd1498Szrj;; True if this is a constant appropriate for an increment or decrement. 97738fd1498Szrj(define_predicate "incdec_operand" 97838fd1498Szrj (match_code "const_int") 97938fd1498Szrj{ 98038fd1498Szrj /* On Pentium4, the inc and dec operations causes extra dependency on flag 98138fd1498Szrj registers, since carry flag is not set. */ 98238fd1498Szrj if (!TARGET_USE_INCDEC && !optimize_insn_for_size_p ()) 98338fd1498Szrj return false; 98438fd1498Szrj return op == const1_rtx || op == constm1_rtx; 98538fd1498Szrj}) 98638fd1498Szrj 98738fd1498Szrj;; True for registers, or 1 or -1. Used to optimize double-word shifts. 98838fd1498Szrj(define_predicate "reg_or_pm1_operand" 98938fd1498Szrj (ior (match_operand 0 "register_operand") 99038fd1498Szrj (and (match_code "const_int") 99138fd1498Szrj (ior (match_test "op == const1_rtx") 99238fd1498Szrj (match_test "op == constm1_rtx"))))) 99338fd1498Szrj 99438fd1498Szrj;; True if OP is acceptable as operand of DImode shift expander. 99538fd1498Szrj(define_predicate "shiftdi_operand" 99638fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 99738fd1498Szrj (match_operand 0 "nonimmediate_operand") 99838fd1498Szrj (match_operand 0 "register_operand"))) 99938fd1498Szrj 100038fd1498Szrj(define_predicate "ashldi_input_operand" 100138fd1498Szrj (if_then_else (match_test "TARGET_64BIT") 100238fd1498Szrj (match_operand 0 "nonimmediate_operand") 100338fd1498Szrj (match_operand 0 "reg_or_pm1_operand"))) 100438fd1498Szrj 100538fd1498Szrj;; Return true if OP is a vector load from the constant pool with just 100638fd1498Szrj;; the first element nonzero. 100738fd1498Szrj(define_predicate "zero_extended_scalar_load_operand" 100838fd1498Szrj (match_code "mem") 100938fd1498Szrj{ 101038fd1498Szrj unsigned n_elts; 101138fd1498Szrj op = avoid_constant_pool_reference (op); 101238fd1498Szrj 101338fd1498Szrj if (GET_CODE (op) != CONST_VECTOR) 101438fd1498Szrj return false; 101538fd1498Szrj 101638fd1498Szrj n_elts = CONST_VECTOR_NUNITS (op); 101738fd1498Szrj 101838fd1498Szrj for (n_elts--; n_elts > 0; n_elts--) 101938fd1498Szrj { 102038fd1498Szrj rtx elt = CONST_VECTOR_ELT (op, n_elts); 102138fd1498Szrj if (elt != CONST0_RTX (GET_MODE_INNER (GET_MODE (op)))) 102238fd1498Szrj return false; 102338fd1498Szrj } 102438fd1498Szrj return true; 102538fd1498Szrj}) 102638fd1498Szrj 102738fd1498Szrj/* Return true if operand is a vector constant that is all ones. */ 102838fd1498Szrj(define_predicate "vector_all_ones_operand" 102938fd1498Szrj (and (match_code "const_vector") 103038fd1498Szrj (match_test "INTEGRAL_MODE_P (GET_MODE (op))") 103138fd1498Szrj (match_test "op == CONSTM1_RTX (GET_MODE (op))"))) 103238fd1498Szrj 103338fd1498Szrj; Return true when OP is operand acceptable for vector memory operand. 103438fd1498Szrj; Only AVX can have misaligned memory operand. 103538fd1498Szrj(define_predicate "vector_memory_operand" 103638fd1498Szrj (and (match_operand 0 "memory_operand") 103738fd1498Szrj (ior (match_test "TARGET_AVX") 103838fd1498Szrj (match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)")))) 103938fd1498Szrj 104038fd1498Szrj; Return true when OP is register_operand or vector_memory_operand. 104138fd1498Szrj(define_predicate "vector_operand" 104238fd1498Szrj (ior (match_operand 0 "register_operand") 104338fd1498Szrj (match_operand 0 "vector_memory_operand"))) 104438fd1498Szrj 104538fd1498Szrj; Return true when OP is operand acceptable for standard SSE move. 104638fd1498Szrj(define_predicate "vector_move_operand" 104738fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 104838fd1498Szrj (match_operand 0 "const0_operand"))) 104938fd1498Szrj 105038fd1498Szrj;; Return true when OP is either nonimmediate operand, or any 105138fd1498Szrj;; CONST_VECTOR. 105238fd1498Szrj(define_predicate "nonimmediate_or_const_vector_operand" 105338fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 105438fd1498Szrj (match_code "const_vector"))) 105538fd1498Szrj 105638fd1498Szrj;; Return true when OP is nonimmediate or standard SSE constant. 105738fd1498Szrj(define_predicate "nonimmediate_or_sse_const_operand" 105838fd1498Szrj (ior (match_operand 0 "nonimmediate_operand") 105938fd1498Szrj (match_test "standard_sse_constant_p (op, mode)"))) 106038fd1498Szrj 106138fd1498Szrj;; Return true if OP is a register or a zero. 106238fd1498Szrj(define_predicate "reg_or_0_operand" 106338fd1498Szrj (ior (match_operand 0 "register_operand") 106438fd1498Szrj (match_operand 0 "const0_operand"))) 106538fd1498Szrj 106638fd1498Szrj(define_predicate "norex_memory_operand" 106738fd1498Szrj (and (match_operand 0 "memory_operand") 106838fd1498Szrj (not (match_test "x86_extended_reg_mentioned_p (op)")))) 106938fd1498Szrj 107038fd1498Szrj;; Return true for RTX codes that force SImode address. 107138fd1498Szrj(define_predicate "SImode_address_operand" 107238fd1498Szrj (match_code "subreg,zero_extend,and")) 107338fd1498Szrj 107438fd1498Szrj;; Return true if op is a valid address for LEA, and does not contain 107538fd1498Szrj;; a segment override. Defined as a special predicate to allow 107638fd1498Szrj;; mode-less const_int operands pass to address_operand. 107738fd1498Szrj(define_special_predicate "address_no_seg_operand" 107838fd1498Szrj (match_test "address_operand (op, VOIDmode)") 107938fd1498Szrj{ 108038fd1498Szrj struct ix86_address parts; 108138fd1498Szrj int ok; 108238fd1498Szrj 108338fd1498Szrj if (!CONST_INT_P (op) 108438fd1498Szrj && mode != VOIDmode 108538fd1498Szrj && GET_MODE (op) != mode) 108638fd1498Szrj return false; 108738fd1498Szrj 108838fd1498Szrj ok = ix86_decompose_address (op, &parts); 108938fd1498Szrj gcc_assert (ok); 109038fd1498Szrj return parts.seg == ADDR_SPACE_GENERIC; 109138fd1498Szrj}) 109238fd1498Szrj 109338fd1498Szrj;; Return true if op if a valid base register, displacement or 109438fd1498Szrj;; sum of base register and displacement for VSIB addressing. 109538fd1498Szrj(define_predicate "vsib_address_operand" 109638fd1498Szrj (match_test "address_operand (op, VOIDmode)") 109738fd1498Szrj{ 109838fd1498Szrj struct ix86_address parts; 109938fd1498Szrj int ok; 110038fd1498Szrj rtx disp; 110138fd1498Szrj 110238fd1498Szrj ok = ix86_decompose_address (op, &parts); 110338fd1498Szrj gcc_assert (ok); 110438fd1498Szrj if (parts.index || parts.seg != ADDR_SPACE_GENERIC) 110538fd1498Szrj return false; 110638fd1498Szrj 110738fd1498Szrj /* VSIB addressing doesn't support (%rip). */ 110838fd1498Szrj if (parts.disp) 110938fd1498Szrj { 111038fd1498Szrj disp = parts.disp; 111138fd1498Szrj if (GET_CODE (disp) == CONST) 111238fd1498Szrj { 111338fd1498Szrj disp = XEXP (disp, 0); 111438fd1498Szrj if (GET_CODE (disp) == PLUS) 111538fd1498Szrj disp = XEXP (disp, 0); 111638fd1498Szrj if (GET_CODE (disp) == UNSPEC) 111738fd1498Szrj switch (XINT (disp, 1)) 111838fd1498Szrj { 111938fd1498Szrj case UNSPEC_GOTPCREL: 112038fd1498Szrj case UNSPEC_PCREL: 112138fd1498Szrj case UNSPEC_GOTNTPOFF: 112238fd1498Szrj return false; 112338fd1498Szrj } 112438fd1498Szrj } 112538fd1498Szrj if (TARGET_64BIT 112638fd1498Szrj && flag_pic 112738fd1498Szrj && (GET_CODE (disp) == SYMBOL_REF 112838fd1498Szrj || GET_CODE (disp) == LABEL_REF)) 112938fd1498Szrj return false; 113038fd1498Szrj } 113138fd1498Szrj 113238fd1498Szrj return true; 113338fd1498Szrj}) 113438fd1498Szrj 113538fd1498Szrj;; Return true if op is valid MPX address operand without base 113638fd1498Szrj(define_predicate "address_mpx_no_base_operand" 113738fd1498Szrj (match_test "address_operand (op, VOIDmode)") 113838fd1498Szrj{ 113938fd1498Szrj struct ix86_address parts; 114038fd1498Szrj int ok; 114138fd1498Szrj 114238fd1498Szrj ok = ix86_decompose_address (op, &parts); 114338fd1498Szrj gcc_assert (ok); 114438fd1498Szrj 114538fd1498Szrj if (parts.index && parts.base) 114638fd1498Szrj return false; 114738fd1498Szrj 114838fd1498Szrj if (parts.seg != ADDR_SPACE_GENERIC) 114938fd1498Szrj return false; 115038fd1498Szrj 115138fd1498Szrj /* Do not support (%rip). */ 115238fd1498Szrj if (parts.disp && flag_pic && TARGET_64BIT 115338fd1498Szrj && SYMBOLIC_CONST (parts.disp)) 115438fd1498Szrj { 115538fd1498Szrj if (GET_CODE (parts.disp) != CONST 115638fd1498Szrj || GET_CODE (XEXP (parts.disp, 0)) != PLUS 115738fd1498Szrj || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC 115838fd1498Szrj || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1)) 115938fd1498Szrj || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF 116038fd1498Szrj && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF)) 116138fd1498Szrj return false; 116238fd1498Szrj } 116338fd1498Szrj 116438fd1498Szrj return true; 116538fd1498Szrj}) 116638fd1498Szrj 116738fd1498Szrj;; Return true if op is valid MPX address operand without index 116838fd1498Szrj(define_predicate "address_mpx_no_index_operand" 116938fd1498Szrj (match_test "address_operand (op, VOIDmode)") 117038fd1498Szrj{ 117138fd1498Szrj struct ix86_address parts; 117238fd1498Szrj int ok; 117338fd1498Szrj 117438fd1498Szrj ok = ix86_decompose_address (op, &parts); 117538fd1498Szrj gcc_assert (ok); 117638fd1498Szrj 117738fd1498Szrj if (parts.index) 117838fd1498Szrj return false; 117938fd1498Szrj 118038fd1498Szrj if (parts.seg != ADDR_SPACE_GENERIC) 118138fd1498Szrj return false; 118238fd1498Szrj 118338fd1498Szrj /* Do not support (%rip). */ 118438fd1498Szrj if (parts.disp && flag_pic && TARGET_64BIT 118538fd1498Szrj && SYMBOLIC_CONST (parts.disp) 118638fd1498Szrj && (GET_CODE (parts.disp) != CONST 118738fd1498Szrj || GET_CODE (XEXP (parts.disp, 0)) != PLUS 118838fd1498Szrj || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC 118938fd1498Szrj || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1)) 119038fd1498Szrj || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF 119138fd1498Szrj && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF))) 119238fd1498Szrj return false; 119338fd1498Szrj 119438fd1498Szrj return true; 119538fd1498Szrj}) 119638fd1498Szrj 119738fd1498Szrj(define_predicate "vsib_mem_operator" 119838fd1498Szrj (match_code "mem")) 119938fd1498Szrj 120038fd1498Szrj(define_predicate "bnd_mem_operator" 120138fd1498Szrj (match_code "mem")) 120238fd1498Szrj 120338fd1498Szrj;; Return true if the rtx is known to be at least 32 bits aligned. 120438fd1498Szrj(define_predicate "aligned_operand" 120538fd1498Szrj (match_operand 0 "general_operand") 120638fd1498Szrj{ 120738fd1498Szrj struct ix86_address parts; 120838fd1498Szrj int ok; 120938fd1498Szrj 121038fd1498Szrj /* Registers and immediate operands are always "aligned". */ 121138fd1498Szrj if (!MEM_P (op)) 121238fd1498Szrj return true; 121338fd1498Szrj 121438fd1498Szrj /* All patterns using aligned_operand on memory operands ends up 121538fd1498Szrj in promoting memory operand to 64bit and thus causing memory mismatch. */ 121638fd1498Szrj if (TARGET_MEMORY_MISMATCH_STALL && !optimize_insn_for_size_p ()) 121738fd1498Szrj return false; 121838fd1498Szrj 121938fd1498Szrj /* Don't even try to do any aligned optimizations with volatiles. */ 122038fd1498Szrj if (MEM_VOLATILE_P (op)) 122138fd1498Szrj return false; 122238fd1498Szrj 122338fd1498Szrj if (MEM_ALIGN (op) >= 32) 122438fd1498Szrj return true; 122538fd1498Szrj 122638fd1498Szrj op = XEXP (op, 0); 122738fd1498Szrj 122838fd1498Szrj /* Pushes and pops are only valid on the stack pointer. */ 122938fd1498Szrj if (GET_CODE (op) == PRE_DEC 123038fd1498Szrj || GET_CODE (op) == POST_INC) 123138fd1498Szrj return true; 123238fd1498Szrj 123338fd1498Szrj /* Decode the address. */ 123438fd1498Szrj ok = ix86_decompose_address (op, &parts); 123538fd1498Szrj gcc_assert (ok); 123638fd1498Szrj 123738fd1498Szrj if (parts.base && SUBREG_P (parts.base)) 123838fd1498Szrj parts.base = SUBREG_REG (parts.base); 123938fd1498Szrj if (parts.index && SUBREG_P (parts.index)) 124038fd1498Szrj parts.index = SUBREG_REG (parts.index); 124138fd1498Szrj 124238fd1498Szrj /* Look for some component that isn't known to be aligned. */ 124338fd1498Szrj if (parts.index) 124438fd1498Szrj { 124538fd1498Szrj if (REGNO_POINTER_ALIGN (REGNO (parts.index)) * parts.scale < 32) 124638fd1498Szrj return false; 124738fd1498Szrj } 124838fd1498Szrj if (parts.base) 124938fd1498Szrj { 125038fd1498Szrj if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 32) 125138fd1498Szrj return false; 125238fd1498Szrj } 125338fd1498Szrj if (parts.disp) 125438fd1498Szrj { 125538fd1498Szrj if (!CONST_INT_P (parts.disp) 125638fd1498Szrj || (INTVAL (parts.disp) & 3)) 125738fd1498Szrj return false; 125838fd1498Szrj } 125938fd1498Szrj 126038fd1498Szrj /* Didn't find one -- this must be an aligned address. */ 126138fd1498Szrj return true; 126238fd1498Szrj}) 126338fd1498Szrj 126438fd1498Szrj;; Return true if OP is memory operand with a displacement. 126538fd1498Szrj(define_predicate "memory_displacement_operand" 126638fd1498Szrj (match_operand 0 "memory_operand") 126738fd1498Szrj{ 126838fd1498Szrj struct ix86_address parts; 126938fd1498Szrj int ok; 127038fd1498Szrj 127138fd1498Szrj ok = ix86_decompose_address (XEXP (op, 0), &parts); 127238fd1498Szrj gcc_assert (ok); 127338fd1498Szrj return parts.disp != NULL_RTX; 127438fd1498Szrj}) 127538fd1498Szrj 127638fd1498Szrj;; Return true if OP is memory operand with a displacement only. 127738fd1498Szrj(define_predicate "memory_displacement_only_operand" 127838fd1498Szrj (match_operand 0 "memory_operand") 127938fd1498Szrj{ 128038fd1498Szrj struct ix86_address parts; 128138fd1498Szrj int ok; 128238fd1498Szrj 128338fd1498Szrj if (TARGET_64BIT) 128438fd1498Szrj return false; 128538fd1498Szrj 128638fd1498Szrj ok = ix86_decompose_address (XEXP (op, 0), &parts); 128738fd1498Szrj gcc_assert (ok); 128838fd1498Szrj 128938fd1498Szrj if (parts.base || parts.index) 129038fd1498Szrj return false; 129138fd1498Szrj 129238fd1498Szrj return parts.disp != NULL_RTX; 129338fd1498Szrj}) 129438fd1498Szrj 129538fd1498Szrj;; Return true if OP is memory operand that cannot be represented 129638fd1498Szrj;; by the modRM array. 129738fd1498Szrj(define_predicate "long_memory_operand" 129838fd1498Szrj (and (match_operand 0 "memory_operand") 129938fd1498Szrj (match_test "memory_address_length (op, false)"))) 130038fd1498Szrj 130138fd1498Szrj;; Return true if OP is a comparison operator that can be issued by fcmov. 130238fd1498Szrj(define_predicate "fcmov_comparison_operator" 130338fd1498Szrj (match_operand 0 "comparison_operator") 130438fd1498Szrj{ 130538fd1498Szrj machine_mode inmode = GET_MODE (XEXP (op, 0)); 130638fd1498Szrj enum rtx_code code = GET_CODE (op); 130738fd1498Szrj 130838fd1498Szrj if (inmode == CCFPmode) 130938fd1498Szrj { 131038fd1498Szrj if (!ix86_trivial_fp_comparison_operator (op, mode)) 131138fd1498Szrj return false; 131238fd1498Szrj code = ix86_fp_compare_code_to_integer (code); 131338fd1498Szrj } 131438fd1498Szrj /* i387 supports just limited amount of conditional codes. */ 131538fd1498Szrj switch (code) 131638fd1498Szrj { 131738fd1498Szrj case LTU: case GTU: case LEU: case GEU: 131838fd1498Szrj if (inmode == CCmode || inmode == CCFPmode || inmode == CCCmode) 131938fd1498Szrj return true; 132038fd1498Szrj return false; 132138fd1498Szrj case ORDERED: case UNORDERED: 132238fd1498Szrj case EQ: case NE: 132338fd1498Szrj return true; 132438fd1498Szrj default: 132538fd1498Szrj return false; 132638fd1498Szrj } 132738fd1498Szrj}) 132838fd1498Szrj 132938fd1498Szrj;; Return true if OP is a comparison that can be used in the CMPSS/CMPPS insns. 133038fd1498Szrj;; The first set are supported directly; the second set can't be done with 133138fd1498Szrj;; full IEEE support, i.e. NaNs. 133238fd1498Szrj 133338fd1498Szrj(define_predicate "sse_comparison_operator" 133438fd1498Szrj (ior (match_code "eq,ne,lt,le,unordered,unge,ungt,ordered") 133538fd1498Szrj (and (match_test "TARGET_AVX") 133638fd1498Szrj (match_code "ge,gt,uneq,unle,unlt,ltgt")))) 133738fd1498Szrj 133838fd1498Szrj(define_predicate "ix86_comparison_int_operator" 133938fd1498Szrj (match_code "ne,eq,ge,gt,le,lt")) 134038fd1498Szrj 134138fd1498Szrj(define_predicate "ix86_comparison_uns_operator" 134238fd1498Szrj (match_code "ne,eq,geu,gtu,leu,ltu")) 134338fd1498Szrj 134438fd1498Szrj(define_predicate "bt_comparison_operator" 134538fd1498Szrj (match_code "ne,eq")) 134638fd1498Szrj 134738fd1498Szrj;; Return true if OP is a valid comparison operator in valid mode. 134838fd1498Szrj(define_predicate "ix86_comparison_operator" 134938fd1498Szrj (match_operand 0 "comparison_operator") 135038fd1498Szrj{ 135138fd1498Szrj machine_mode inmode = GET_MODE (XEXP (op, 0)); 135238fd1498Szrj enum rtx_code code = GET_CODE (op); 135338fd1498Szrj 135438fd1498Szrj if (inmode == CCFPmode) 135538fd1498Szrj return ix86_trivial_fp_comparison_operator (op, mode); 135638fd1498Szrj 135738fd1498Szrj switch (code) 135838fd1498Szrj { 135938fd1498Szrj case EQ: case NE: 136038fd1498Szrj if (inmode == CCGZmode) 136138fd1498Szrj return false; 136238fd1498Szrj return true; 136338fd1498Szrj case GE: case LT: 136438fd1498Szrj if (inmode == CCmode || inmode == CCGCmode 136538fd1498Szrj || inmode == CCGOCmode || inmode == CCNOmode || inmode == CCGZmode) 136638fd1498Szrj return true; 136738fd1498Szrj return false; 136838fd1498Szrj case GEU: case LTU: 136938fd1498Szrj if (inmode == CCGZmode) 137038fd1498Szrj return true; 137138fd1498Szrj /* FALLTHRU */ 137238fd1498Szrj case GTU: case LEU: 137338fd1498Szrj if (inmode == CCmode || inmode == CCCmode || inmode == CCGZmode) 137438fd1498Szrj return true; 137538fd1498Szrj return false; 137638fd1498Szrj case ORDERED: case UNORDERED: 137738fd1498Szrj if (inmode == CCmode) 137838fd1498Szrj return true; 137938fd1498Szrj return false; 138038fd1498Szrj case GT: case LE: 138138fd1498Szrj if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode) 138238fd1498Szrj return true; 138338fd1498Szrj return false; 138438fd1498Szrj default: 138538fd1498Szrj return false; 138638fd1498Szrj } 138738fd1498Szrj}) 138838fd1498Szrj 138938fd1498Szrj;; Return true if OP is a valid comparison operator 139038fd1498Szrj;; testing carry flag to be set. 139138fd1498Szrj(define_predicate "ix86_carry_flag_operator" 139238fd1498Szrj (match_code "ltu,lt,unlt,gtu,gt,ungt,le,unle,ge,unge,ltgt,uneq") 139338fd1498Szrj{ 139438fd1498Szrj machine_mode inmode = GET_MODE (XEXP (op, 0)); 139538fd1498Szrj enum rtx_code code = GET_CODE (op); 139638fd1498Szrj 139738fd1498Szrj if (inmode == CCFPmode) 139838fd1498Szrj { 139938fd1498Szrj if (!ix86_trivial_fp_comparison_operator (op, mode)) 140038fd1498Szrj return false; 140138fd1498Szrj code = ix86_fp_compare_code_to_integer (code); 140238fd1498Szrj } 140338fd1498Szrj else if (inmode == CCCmode) 140438fd1498Szrj return code == LTU || code == GTU; 140538fd1498Szrj else if (inmode != CCmode) 140638fd1498Szrj return false; 140738fd1498Szrj 140838fd1498Szrj return code == LTU; 140938fd1498Szrj}) 141038fd1498Szrj 141138fd1498Szrj;; Return true if this comparison only requires testing one flag bit. 141238fd1498Szrj(define_predicate "ix86_trivial_fp_comparison_operator" 141338fd1498Szrj (match_code "gt,ge,unlt,unle,uneq,ltgt,ordered,unordered")) 141438fd1498Szrj 141538fd1498Szrj;; Return true if we know how to do this comparison. Others require 141638fd1498Szrj;; testing more than one flag bit, and we let the generic middle-end 141738fd1498Szrj;; code do that. 141838fd1498Szrj(define_predicate "ix86_fp_comparison_operator" 141938fd1498Szrj (if_then_else (match_test "ix86_fp_comparison_strategy (GET_CODE (op)) 142038fd1498Szrj == IX86_FPCMP_ARITH") 142138fd1498Szrj (match_operand 0 "comparison_operator") 142238fd1498Szrj (match_operand 0 "ix86_trivial_fp_comparison_operator"))) 142338fd1498Szrj 142438fd1498Szrj;; Nearly general operand, but accept any const_double, since we wish 142538fd1498Szrj;; to be able to drop them into memory rather than have them get pulled 142638fd1498Szrj;; into registers. 142738fd1498Szrj(define_predicate "cmp_fp_expander_operand" 142838fd1498Szrj (ior (match_code "const_double") 142938fd1498Szrj (match_operand 0 "general_operand"))) 143038fd1498Szrj 143138fd1498Szrj;; Return true if this is a valid binary floating-point operation. 143238fd1498Szrj(define_predicate "binary_fp_operator" 143338fd1498Szrj (match_code "plus,minus,mult,div")) 143438fd1498Szrj 143538fd1498Szrj;; Return true if this is a multiply operation. 143638fd1498Szrj(define_predicate "mult_operator" 143738fd1498Szrj (match_code "mult")) 143838fd1498Szrj 143938fd1498Szrj;; Return true if this is a division operation. 144038fd1498Szrj(define_predicate "div_operator" 144138fd1498Szrj (match_code "div")) 144238fd1498Szrj 144338fd1498Szrj;; Return true if this is a plus, minus, and, ior or xor operation. 144438fd1498Szrj(define_predicate "plusminuslogic_operator" 144538fd1498Szrj (match_code "plus,minus,and,ior,xor")) 144638fd1498Szrj 144738fd1498Szrj;; Return true for ARITHMETIC_P. 144838fd1498Szrj(define_predicate "arith_or_logical_operator" 144938fd1498Szrj (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax,compare,minus,div, 145038fd1498Szrj mod,udiv,umod,ashift,rotate,ashiftrt,lshiftrt,rotatert")) 145138fd1498Szrj 145238fd1498Szrj;; Return true for COMMUTATIVE_P. 145338fd1498Szrj(define_predicate "commutative_operator" 145438fd1498Szrj (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax")) 145538fd1498Szrj 145638fd1498Szrj;; Return true if OP is a binary operator that can be promoted to wider mode. 145738fd1498Szrj(define_predicate "promotable_binary_operator" 145838fd1498Szrj (ior (match_code "plus,minus,and,ior,xor,ashift") 145938fd1498Szrj (and (match_code "mult") 146038fd1498Szrj (match_test "TARGET_TUNE_PROMOTE_HIMODE_IMUL")))) 146138fd1498Szrj 146238fd1498Szrj(define_predicate "compare_operator" 146338fd1498Szrj (match_code "compare")) 146438fd1498Szrj 146538fd1498Szrj(define_predicate "absneg_operator" 146638fd1498Szrj (match_code "abs,neg")) 146738fd1498Szrj 146838fd1498Szrj;; Return true if OP is a memory operand, aligned to 146938fd1498Szrj;; less than its natural alignment. 147038fd1498Szrj(define_predicate "misaligned_operand" 147138fd1498Szrj (and (match_code "mem") 147238fd1498Szrj (match_test "MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)"))) 147338fd1498Szrj 147438fd1498Szrj;; Return true if OP is a emms operation, known to be a PARALLEL. 147538fd1498Szrj(define_predicate "emms_operation" 147638fd1498Szrj (match_code "parallel") 147738fd1498Szrj{ 147838fd1498Szrj unsigned i; 147938fd1498Szrj 148038fd1498Szrj if (XVECLEN (op, 0) != 17) 148138fd1498Szrj return false; 148238fd1498Szrj 148338fd1498Szrj for (i = 0; i < 8; i++) 148438fd1498Szrj { 148538fd1498Szrj rtx elt = XVECEXP (op, 0, i+1); 148638fd1498Szrj 148738fd1498Szrj if (GET_CODE (elt) != CLOBBER 148838fd1498Szrj || GET_CODE (SET_DEST (elt)) != REG 148938fd1498Szrj || GET_MODE (SET_DEST (elt)) != XFmode 149038fd1498Szrj || REGNO (SET_DEST (elt)) != FIRST_STACK_REG + i) 149138fd1498Szrj return false; 149238fd1498Szrj 149338fd1498Szrj elt = XVECEXP (op, 0, i+9); 149438fd1498Szrj 149538fd1498Szrj if (GET_CODE (elt) != CLOBBER 149638fd1498Szrj || GET_CODE (SET_DEST (elt)) != REG 149738fd1498Szrj || GET_MODE (SET_DEST (elt)) != DImode 149838fd1498Szrj || REGNO (SET_DEST (elt)) != FIRST_MMX_REG + i) 149938fd1498Szrj return false; 150038fd1498Szrj } 150138fd1498Szrj return true; 150238fd1498Szrj}) 150338fd1498Szrj 150438fd1498Szrj;; Return true if OP is a vzeroall operation, known to be a PARALLEL. 150538fd1498Szrj(define_predicate "vzeroall_operation" 150638fd1498Szrj (match_code "parallel") 150738fd1498Szrj{ 150838fd1498Szrj unsigned i, nregs = TARGET_64BIT ? 16 : 8; 150938fd1498Szrj 151038fd1498Szrj if ((unsigned) XVECLEN (op, 0) != 1 + nregs) 151138fd1498Szrj return false; 151238fd1498Szrj 151338fd1498Szrj for (i = 0; i < nregs; i++) 151438fd1498Szrj { 151538fd1498Szrj rtx elt = XVECEXP (op, 0, i+1); 151638fd1498Szrj 151738fd1498Szrj if (GET_CODE (elt) != SET 151838fd1498Szrj || GET_CODE (SET_DEST (elt)) != REG 151938fd1498Szrj || GET_MODE (SET_DEST (elt)) != V8SImode 1520*58e805e6Szrj || REGNO (SET_DEST (elt)) != GET_SSE_REGNO (i) 152138fd1498Szrj || SET_SRC (elt) != CONST0_RTX (V8SImode)) 152238fd1498Szrj return false; 152338fd1498Szrj } 152438fd1498Szrj return true; 152538fd1498Szrj}) 152638fd1498Szrj 152738fd1498Szrj;; return true if OP is a vzeroupper operation. 152838fd1498Szrj(define_predicate "vzeroupper_operation" 152938fd1498Szrj (and (match_code "unspec_volatile") 153038fd1498Szrj (match_test "XINT (op, 1) == UNSPECV_VZEROUPPER"))) 153138fd1498Szrj 153238fd1498Szrj;; Return true if OP is an addsub vec_merge operation 153338fd1498Szrj(define_predicate "addsub_vm_operator" 153438fd1498Szrj (match_code "vec_merge") 153538fd1498Szrj{ 153638fd1498Szrj rtx op0, op1; 153738fd1498Szrj int swapped; 153838fd1498Szrj HOST_WIDE_INT mask; 153938fd1498Szrj int nunits, elt; 154038fd1498Szrj 154138fd1498Szrj op0 = XEXP (op, 0); 154238fd1498Szrj op1 = XEXP (op, 1); 154338fd1498Szrj 154438fd1498Szrj /* Sanity check. */ 154538fd1498Szrj if (GET_CODE (op0) == MINUS && GET_CODE (op1) == PLUS) 154638fd1498Szrj swapped = 0; 154738fd1498Szrj else if (GET_CODE (op0) == PLUS && GET_CODE (op1) == MINUS) 154838fd1498Szrj swapped = 1; 154938fd1498Szrj else 155038fd1498Szrj gcc_unreachable (); 155138fd1498Szrj 155238fd1498Szrj mask = INTVAL (XEXP (op, 2)); 155338fd1498Szrj nunits = GET_MODE_NUNITS (mode); 155438fd1498Szrj 155538fd1498Szrj for (elt = 0; elt < nunits; elt++) 155638fd1498Szrj { 155738fd1498Szrj /* bit clear: take from op0, set: take from op1 */ 155838fd1498Szrj int bit = !(mask & (HOST_WIDE_INT_1U << elt)); 155938fd1498Szrj 156038fd1498Szrj if (bit != ((elt & 1) ^ swapped)) 156138fd1498Szrj return false; 156238fd1498Szrj } 156338fd1498Szrj 156438fd1498Szrj return true; 156538fd1498Szrj}) 156638fd1498Szrj 156738fd1498Szrj;; Return true if OP is an addsub vec_select/vec_concat operation 156838fd1498Szrj(define_predicate "addsub_vs_operator" 156938fd1498Szrj (and (match_code "vec_select") 157038fd1498Szrj (match_code "vec_concat" "0")) 157138fd1498Szrj{ 157238fd1498Szrj rtx op0, op1; 157338fd1498Szrj bool swapped; 157438fd1498Szrj int nunits, elt; 157538fd1498Szrj 157638fd1498Szrj op0 = XEXP (XEXP (op, 0), 0); 157738fd1498Szrj op1 = XEXP (XEXP (op, 0), 1); 157838fd1498Szrj 157938fd1498Szrj /* Sanity check. */ 158038fd1498Szrj if (GET_CODE (op0) == MINUS && GET_CODE (op1) == PLUS) 158138fd1498Szrj swapped = false; 158238fd1498Szrj else if (GET_CODE (op0) == PLUS && GET_CODE (op1) == MINUS) 158338fd1498Szrj swapped = true; 158438fd1498Szrj else 158538fd1498Szrj gcc_unreachable (); 158638fd1498Szrj 158738fd1498Szrj nunits = GET_MODE_NUNITS (mode); 158838fd1498Szrj if (XVECLEN (XEXP (op, 1), 0) != nunits) 158938fd1498Szrj return false; 159038fd1498Szrj 159138fd1498Szrj /* We already checked that permutation is suitable for addsub, 159238fd1498Szrj so only look at the first element of the parallel. */ 159338fd1498Szrj elt = INTVAL (XVECEXP (XEXP (op, 1), 0, 0)); 159438fd1498Szrj 159538fd1498Szrj return elt == (swapped ? nunits : 0); 159638fd1498Szrj}) 159738fd1498Szrj 159838fd1498Szrj;; Return true if OP is a parallel for an addsub vec_select. 159938fd1498Szrj(define_predicate "addsub_vs_parallel" 160038fd1498Szrj (and (match_code "parallel") 160138fd1498Szrj (match_code "const_int" "a")) 160238fd1498Szrj{ 160338fd1498Szrj int nelt = XVECLEN (op, 0); 160438fd1498Szrj int elt, i; 160538fd1498Szrj 160638fd1498Szrj if (nelt < 2) 160738fd1498Szrj return false; 160838fd1498Szrj 160938fd1498Szrj /* Check that the permutation is suitable for addsub. 161038fd1498Szrj For example, { 0 9 2 11 4 13 6 15 } or { 8 1 10 3 12 5 14 7 }. */ 161138fd1498Szrj elt = INTVAL (XVECEXP (op, 0, 0)); 161238fd1498Szrj if (elt == 0) 161338fd1498Szrj { 161438fd1498Szrj for (i = 1; i < nelt; ++i) 161538fd1498Szrj if (INTVAL (XVECEXP (op, 0, i)) != (i + (i & 1) * nelt)) 161638fd1498Szrj return false; 161738fd1498Szrj } 161838fd1498Szrj else if (elt == nelt) 161938fd1498Szrj { 162038fd1498Szrj for (i = 1; i < nelt; ++i) 162138fd1498Szrj if (INTVAL (XVECEXP (op, 0, i)) != (elt + i - (i & 1) * nelt)) 162238fd1498Szrj return false; 162338fd1498Szrj } 162438fd1498Szrj else 162538fd1498Szrj return false; 162638fd1498Szrj 162738fd1498Szrj return true; 162838fd1498Szrj}) 162938fd1498Szrj 163038fd1498Szrj;; Return true if OP is a parallel for a vbroadcast permute. 163138fd1498Szrj(define_predicate "avx_vbroadcast_operand" 163238fd1498Szrj (and (match_code "parallel") 163338fd1498Szrj (match_code "const_int" "a")) 163438fd1498Szrj{ 163538fd1498Szrj rtx elt = XVECEXP (op, 0, 0); 163638fd1498Szrj int i, nelt = XVECLEN (op, 0); 163738fd1498Szrj 163838fd1498Szrj /* Don't bother checking there are the right number of operands, 163938fd1498Szrj merely that they're all identical. */ 164038fd1498Szrj for (i = 1; i < nelt; ++i) 164138fd1498Szrj if (XVECEXP (op, 0, i) != elt) 164238fd1498Szrj return false; 164338fd1498Szrj return true; 164438fd1498Szrj}) 164538fd1498Szrj 164638fd1498Szrj;; Return true if OP is a parallel for a palignr permute. 164738fd1498Szrj(define_predicate "palignr_operand" 164838fd1498Szrj (and (match_code "parallel") 164938fd1498Szrj (match_code "const_int" "a")) 165038fd1498Szrj{ 165138fd1498Szrj int elt = INTVAL (XVECEXP (op, 0, 0)); 165238fd1498Szrj int i, nelt = XVECLEN (op, 0); 165338fd1498Szrj 165438fd1498Szrj /* Check that an order in the permutation is suitable for palignr. 165538fd1498Szrj For example, {5 6 7 0 1 2 3 4} is "palignr 5, xmm, xmm". */ 165638fd1498Szrj for (i = 1; i < nelt; ++i) 165738fd1498Szrj if (INTVAL (XVECEXP (op, 0, i)) != ((elt + i) % nelt)) 165838fd1498Szrj return false; 165938fd1498Szrj return true; 166038fd1498Szrj}) 166138fd1498Szrj 166238fd1498Szrj;; Return true if OP is a proper third operand to vpblendw256. 166338fd1498Szrj(define_predicate "avx2_pblendw_operand" 166438fd1498Szrj (match_code "const_int") 166538fd1498Szrj{ 166638fd1498Szrj HOST_WIDE_INT val = INTVAL (op); 166738fd1498Szrj HOST_WIDE_INT low = val & 0xff; 166838fd1498Szrj return val == ((low << 8) | low); 166938fd1498Szrj}) 167038fd1498Szrj 167138fd1498Szrj;; Return true if OP is vector_operand or CONST_VECTOR. 167238fd1498Szrj(define_predicate "general_vector_operand" 167338fd1498Szrj (ior (match_operand 0 "vector_operand") 167438fd1498Szrj (match_code "const_vector"))) 167538fd1498Szrj 167638fd1498Szrj;; Return true if OP is either -1 constant or stored in register. 167738fd1498Szrj(define_predicate "register_or_constm1_operand" 167838fd1498Szrj (ior (match_operand 0 "register_operand") 167938fd1498Szrj (and (match_code "const_int") 168038fd1498Szrj (match_test "op == constm1_rtx")))) 168138fd1498Szrj 168238fd1498Szrj;; Return true if the vector ends with between 12 and 18 register saves using 168338fd1498Szrj;; RAX as the base address. 168438fd1498Szrj(define_predicate "save_multiple" 168538fd1498Szrj (match_code "parallel") 168638fd1498Szrj{ 168738fd1498Szrj const unsigned len = XVECLEN (op, 0); 168838fd1498Szrj unsigned i; 168938fd1498Szrj 169038fd1498Szrj /* Starting from end of vector, count register saves. */ 169138fd1498Szrj for (i = 0; i < len; ++i) 169238fd1498Szrj { 169338fd1498Szrj rtx src, dest, addr; 169438fd1498Szrj rtx e = XVECEXP (op, 0, len - 1 - i); 169538fd1498Szrj 169638fd1498Szrj if (GET_CODE (e) != SET) 169738fd1498Szrj break; 169838fd1498Szrj 169938fd1498Szrj src = SET_SRC (e); 170038fd1498Szrj dest = SET_DEST (e); 170138fd1498Szrj 170238fd1498Szrj if (!REG_P (src) || !MEM_P (dest)) 170338fd1498Szrj break; 170438fd1498Szrj 170538fd1498Szrj addr = XEXP (dest, 0); 170638fd1498Szrj 170738fd1498Szrj /* Good if dest address is in RAX. */ 170838fd1498Szrj if (REG_P (addr) && REGNO (addr) == AX_REG) 170938fd1498Szrj continue; 171038fd1498Szrj 171138fd1498Szrj /* Good if dest address is offset of RAX. */ 171238fd1498Szrj if (GET_CODE (addr) == PLUS 171338fd1498Szrj && REG_P (XEXP (addr, 0)) 171438fd1498Szrj && REGNO (XEXP (addr, 0)) == AX_REG) 171538fd1498Szrj continue; 171638fd1498Szrj 171738fd1498Szrj break; 171838fd1498Szrj } 171938fd1498Szrj return (i >= 12 && i <= 18); 172038fd1498Szrj}) 172138fd1498Szrj 172238fd1498Szrj 172338fd1498Szrj;; Return true if the vector ends with between 12 and 18 register loads using 172438fd1498Szrj;; RSI as the base address. 172538fd1498Szrj(define_predicate "restore_multiple" 172638fd1498Szrj (match_code "parallel") 172738fd1498Szrj{ 172838fd1498Szrj const unsigned len = XVECLEN (op, 0); 172938fd1498Szrj unsigned i; 173038fd1498Szrj 173138fd1498Szrj /* Starting from end of vector, count register restores. */ 173238fd1498Szrj for (i = 0; i < len; ++i) 173338fd1498Szrj { 173438fd1498Szrj rtx src, dest, addr; 173538fd1498Szrj rtx e = XVECEXP (op, 0, len - 1 - i); 173638fd1498Szrj 173738fd1498Szrj if (GET_CODE (e) != SET) 173838fd1498Szrj break; 173938fd1498Szrj 174038fd1498Szrj src = SET_SRC (e); 174138fd1498Szrj dest = SET_DEST (e); 174238fd1498Szrj 174338fd1498Szrj if (!MEM_P (src) || !REG_P (dest)) 174438fd1498Szrj break; 174538fd1498Szrj 174638fd1498Szrj addr = XEXP (src, 0); 174738fd1498Szrj 174838fd1498Szrj /* Good if src address is in RSI. */ 174938fd1498Szrj if (REG_P (addr) && REGNO (addr) == SI_REG) 175038fd1498Szrj continue; 175138fd1498Szrj 175238fd1498Szrj /* Good if src address is offset of RSI. */ 175338fd1498Szrj if (GET_CODE (addr) == PLUS 175438fd1498Szrj && REG_P (XEXP (addr, 0)) 175538fd1498Szrj && REGNO (XEXP (addr, 0)) == SI_REG) 175638fd1498Szrj continue; 175738fd1498Szrj 175838fd1498Szrj break; 175938fd1498Szrj } 176038fd1498Szrj return (i >= 12 && i <= 18); 176138fd1498Szrj}) 1762