⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 predicates.md

📁 linux下编程用 编译软件
💻 MD
📖 第 1 页 / 共 3 页
字号:
;; Predicate definitions for POWER and PowerPC.;; Copyright (C) 2005 Free Software Foundation, Inc.;;;; This file is part of GCC.;;;; GCC is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 2, or (at your option);; any later version.;;;; GCC is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;;;; You should have received a copy of the GNU General Public License;; along with GCC; see the file COPYING.  If not, write to;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,;; Boston, MA 02110-1301, USA.;; Return 1 for anything except PARALLEL.(define_predicate "any_operand"  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem"));; Return 1 for any PARALLEL.(define_predicate "any_parallel_operand"  (match_code "parallel"));; Return 1 if op is COUNT register.(define_predicate "count_register_operand"  (and (match_code "reg")       (match_test "REGNO (op) == COUNT_REGISTER_REGNUM		    || REGNO (op) > LAST_VIRTUAL_REGISTER")))  ;; Return 1 if op is an Altivec register.(define_predicate "altivec_register_operand"   (and (match_operand 0 "register_operand")	(match_test "GET_CODE (op) != REG		     || ALTIVEC_REGNO_P (REGNO (op))		     || REGNO (op) > LAST_VIRTUAL_REGISTER")));; Return 1 if op is XER register.(define_predicate "xer_operand"  (and (match_code "reg")       (match_test "XER_REGNO_P (REGNO (op))")));; Return 1 if op is a signed 5-bit constant integer.(define_predicate "s5bit_cint_operand"  (and (match_code "const_int")       (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")));; Return 1 if op is a unsigned 5-bit constant integer.(define_predicate "u5bit_cint_operand"  (and (match_code "const_int")       (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31")));; Return 1 if op is a signed 8-bit constant integer.;; Integer multiplication complete more quickly(define_predicate "s8bit_cint_operand"  (and (match_code "const_int")       (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127")));; Return 1 if op is a constant integer that can fit in a D field.(define_predicate "short_cint_operand"  (and (match_code "const_int")       (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')")));; Return 1 if op is a constant integer that can fit in an unsigned D field.(define_predicate "u_short_cint_operand"  (and (match_code "const_int")       (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')")));; Return 1 if op is a constant integer that cannot fit in a signed D field.(define_predicate "non_short_cint_operand"  (and (match_code "const_int")       (match_test "(unsigned HOST_WIDE_INT)		    (INTVAL (op) + 0x8000) >= 0x10000")));; Return 1 if op is a positive constant integer that is an exact power of 2.(define_predicate "exact_log2_cint_operand"  (and (match_code "const_int")       (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0")));; Return 1 if op is a register that is not special.(define_predicate "gpc_reg_operand"   (and (match_operand 0 "register_operand")	(match_test "GET_CODE (op) != REG		     || (REGNO (op) >= ARG_POINTER_REGNUM			 && !XER_REGNO_P (REGNO (op)))		     || REGNO (op) < MQ_REGNO")));; Return 1 if op is a register that is a condition register field.(define_predicate "cc_reg_operand"   (and (match_operand 0 "register_operand")	(match_test "GET_CODE (op) != REG		     || REGNO (op) > LAST_VIRTUAL_REGISTER		     || CR_REGNO_P (REGNO (op))")));; Return 1 if op is a register that is a condition register field not cr0.(define_predicate "cc_reg_not_cr0_operand"   (and (match_operand 0 "register_operand")	(match_test "GET_CODE (op) != REG		     || REGNO (op) > LAST_VIRTUAL_REGISTER		     || CR_REGNO_NOT_CR0_P (REGNO (op))")));; Return 1 if op is a constant integer valid for D field;; or non-special register register.(define_predicate "reg_or_short_operand"  (if_then_else (match_code "const_int")    (match_operand 0 "short_cint_operand")    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is a constant integer valid whose negation is valid for;; D field or non-special register register.;; Do not allow a constant zero because all patterns that call this;; predicate use "addic r1,r2,-const" to set carry when r2 is greater than;; or equal to const, which does not work for zero.(define_predicate "reg_or_neg_short_operand"  (if_then_else (match_code "const_int")    (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'P')		 && INTVAL (op) != 0")    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is a constant integer valid for DS field;; or non-special register.(define_predicate "reg_or_aligned_short_operand"  (if_then_else (match_code "const_int")    (and (match_operand 0 "short_cint_operand")	 (match_test "!(INTVAL (op) & 3)"))    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is a constant integer whose high-order 16 bits are zero;; or non-special register.(define_predicate "reg_or_u_short_operand"  (if_then_else (match_code "const_int")    (match_operand 0 "u_short_cint_operand")    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is any constant integer ;; or non-special register.(define_predicate "reg_or_cint_operand"  (ior (match_code "const_int")       (match_operand 0 "gpc_reg_operand")));; Return 1 if op is a constant integer valid for addition;; or non-special register.(define_predicate "reg_or_add_cint_operand"  (if_then_else (match_code "const_int")    (match_test "(HOST_BITS_PER_WIDE_INT == 32		  && (mode == SImode || INTVAL (op) < 0x7fff8000))		 || ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)		     < (unsigned HOST_WIDE_INT) 0x100000000ll)")    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is a constant integer valid for subtraction;; or non-special register.(define_predicate "reg_or_sub_cint_operand"  (if_then_else (match_code "const_int")    (match_test "(HOST_BITS_PER_WIDE_INT == 32		  && (mode == SImode || - INTVAL (op) < 0x7fff8000))		 || ((unsigned HOST_WIDE_INT) (- INTVAL (op) 					       + (mode == SImode						  ? 0x80000000 : 0x80008000))		     < (unsigned HOST_WIDE_INT) 0x100000000ll)")    (match_operand 0 "gpc_reg_operand")));; Return 1 if op is any 32-bit unsigned constant integer;; or non-special register.(define_predicate "reg_or_logical_cint_operand"  (if_then_else (match_code "const_int")    (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT		  && INTVAL (op) >= 0)		 || ((INTVAL (op) & GET_MODE_MASK (mode)		      & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)")    (if_then_else (match_code "const_double")      (match_test "GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT		   && mode == DImode		   && CONST_DOUBLE_HIGH (op) == 0")      (match_operand 0 "gpc_reg_operand"))));; Return 1 if operand is a CONST_DOUBLE that can be set in a register;; with no more than one instruction per word.(define_predicate "easy_fp_constant"  (match_code "const_double"){  long k[4];  REAL_VALUE_TYPE rv;  if (GET_MODE (op) != mode      || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))    return 0;  /* Consider all constants with -msoft-float to be easy.  */  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)      && mode != DImode)    return 1;  /* If we are using V.4 style PIC, consider all constants to be hard.  */  if (flag_pic && DEFAULT_ABI == ABI_V4)    return 0;#ifdef TARGET_RELOCATABLE  /* Similarly if we are using -mrelocatable, consider all constants     to be hard.  */  if (TARGET_RELOCATABLE)    return 0;#endif  switch (mode)    {    case TFmode:      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);      REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);      return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1	      && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1	      && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1	      && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);    case DFmode:      /* Force constants to memory before reload to utilize	 compress_float_constant.	 Avoid this when flag_unsafe_math_optimizations is enabled	 because RDIV division to reciprocal optimization is not able	 to regenerate the division.  */      if (TARGET_E500_DOUBLE          || (!reload_in_progress && !reload_completed	      && !flag_unsafe_math_optimizations))        return 0;      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);      REAL_VALUE_TO_TARGET_DOUBLE (rv, k);      return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1	      && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);    case SFmode:      /* The constant 0.f is easy.  */      if (op == CONST0_RTX (SFmode))	return 1;      /* Force constants to memory before reload to utilize	 compress_float_constant.	 Avoid this when flag_unsafe_math_optimizations is enabled	 because RDIV division to reciprocal optimization is not able	 to regenerate the division.  */      if (!reload_in_progress && !reload_completed          && !flag_unsafe_math_optimizations)	return 0;      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);      REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]);      return num_insns_constant_wide (k[0]) == 1;  case DImode:    return ((TARGET_POWERPC64	     && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)	    || (num_insns_constant (op, DImode) <= 2));  case SImode:    return 1;  default:    gcc_unreachable ();  }});; Return 1 if the operand is a CONST_VECTOR and can be loaded into a;; vector register without using memory.(define_predicate "easy_vector_constant"  (match_code "const_vector"){  if (ALTIVEC_VECTOR_MODE (mode))    {      if (zero_constant (op, mode))        return true;      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)        return false;      return easy_altivec_constant (op, mode);    }  if (SPE_VECTOR_MODE (mode))    {      int cst, cst2;      if (zero_constant (op, mode))	return true;      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)        return false;      /* Limit SPE vectors to 15 bits signed.  These we can generate with:	   li r0, CONSTANT1	   evmergelo r0, r0, r0	   li r0, CONSTANT2	 I don't know how efficient it would be to allow bigger constants,	 considering we'll have an extra 'ori' for every 'li'.  I doubt 5	 instructions is better than a 64-bit memory load, but I don't	 have the e500 timing specs.  */      if (mode == V2SImode)	{	  cst  = INTVAL (CONST_VECTOR_ELT (op, 0));	  cst2 = INTVAL (CONST_VECTOR_ELT (op, 1));	  return cst  >= -0x7fff && cst <= 0x7fff	         && cst2 >= -0x7fff && cst2 <= 0x7fff;	}    }  return false;});; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF.(define_predicate "easy_vector_constant_add_self"  (and (match_code "const_vector")       (and (match_test "TARGET_ALTIVEC")	    (match_test "easy_altivec_constant (op, mode)"))){  rtx last = CONST_VECTOR_ELT (op, GET_MODE_NUNITS (mode) - 1);  HOST_WIDE_INT val = ((INTVAL (last) & 0xff) ^ 0x80) - 0x80;  return EASY_VECTOR_15_ADD_SELF (val);});; Return 1 if operand is constant zero (scalars and vectors).(define_predicate "zero_constant"  (and (match_code "const_int,const_double,const_vector")       (match_test "op == CONST0_RTX (mode)")));; Return 1 if operand is 0.0.;; or non-special register register field no cr0(define_predicate "zero_fp_constant"  (and (match_code "const_double")       (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT		    && op == CONST0_RTX (mode)")));; Return 1 if the operand is in volatile memory.  Note that during the;; RTL generation phase, memory_operand does not return TRUE for volatile;; memory references.  So this function allows us to recognize volatile;; references where it's safe.(define_predicate "volatile_mem_operand"  (and (and (match_code "mem")	    (match_test "MEM_VOLATILE_P (op)"))       (if_then_else (match_test "reload_completed")         (match_operand 0 "memory_operand")         (if_then_else (match_test "reload_in_progress")	   (match_test "strict_memory_address_p (mode, XEXP (op, 0))")	   (match_test "memory_address_p (mode, XEXP (op, 0))")))));; Return 1 if the operand is an offsettable memory operand.(define_predicate "offsettable_mem_operand"  (and (match_code "mem")       (match_test "offsettable_address_p (reload_completed					   || reload_in_progress,					   mode, XEXP (op, 0))")));; Return 1 if the operand is a memory operand with an address divisible by 4(define_predicate "word_offset_memref_operand"  (and (match_operand 0 "memory_operand")       (match_test "GET_CODE (XEXP (op, 0)) != PLUS		    || ! REG_P (XEXP (XEXP (op, 0), 0)) 		    || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT		    || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")));; Return 1 if the operand is an indexed or indirect memory operand.(define_predicate "indexed_or_indirect_operand"  (match_code "mem"){  op = XEXP (op, 0);  if (TARGET_ALTIVEC      && ALTIVEC_VECTOR_MODE (mode)      && GET_CODE (op) == AND      && GET_CODE (XEXP (op, 1)) == CONST_INT      && INTVAL (XEXP (op, 1)) == -16)    op = XEXP (op, 0);  return indexed_or_indirect_address (op, mode);});; Return 1 if the operand is an indexed or indirect address.(define_special_predicate "indexed_or_indirect_address"  (and (match_test "REG_P (op)		    || (GET_CODE (op) == PLUS			/* Omit testing REG_P (XEXP (op, 0)).  */			&& REG_P (XEXP (op, 1)))")       (match_operand 0 "address_operand")));; Used for the destination of the fix_truncdfsi2 expander.;; If stfiwx will be used, the result goes to memory; otherwise,;; we're going to emit a store and a load of a subreg, so the dest is a;; register.(define_predicate "fix_trunc_dest_operand"  (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT")   (match_operand 0 "memory_operand")   (match_operand 0 "gpc_reg_operand")));; Return 1 if the operand is either a non-special register or can be used;; as the operand of a `mode' add insn.(define_predicate "add_operand"  (if_then_else (match_code "const_int")    (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')		 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')")    (match_operand 0 "gpc_reg_operand")));; Return 1 if OP is a constant but not a valid add_operand.(define_predicate "non_add_cint_operand"  (and (match_code "const_int")       (match_test "!CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')		    && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')")));; Return 1 if the operand is a constant that can be used as the operand;; of an OR or XOR.(define_predicate "logical_const_operand"  (match_code "const_int,const_double"){  HOST_WIDE_INT opl, oph;  if (GET_CODE (op) == CONST_INT)    {      opl = INTVAL (op) & GET_MODE_MASK (mode);      if (HOST_BITS_PER_WIDE_INT <= 32	  && GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)	return 0;    }  else if (GET_CODE (op) == CONST_DOUBLE)    {      gcc_assert (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT);      opl = CONST_DOUBLE_LOW (op);      oph = CONST_DOUBLE_HIGH (op);      if (oph != 0)	return 0;    }  else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -