📄 predicates.md
字号:
;; Predicate definitions for DEC Alpha.;; Copyright (C) 2004, 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, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;; Return 1 if OP is the zero constant for MODE.(define_predicate "const0_operand" (and (match_code "const_int,const_double,const_vector") (match_test "op == CONST0_RTX (mode)")));; Returns true if OP is either the constant zero or a register.(define_predicate "reg_or_0_operand" (ior (match_operand 0 "register_operand") (match_operand 0 "const0_operand")));; Return 1 if OP is a constant in the range of 0-63 (for a shift) or;; any register.(define_predicate "reg_or_6bit_operand" (if_then_else (match_code "const_int") (match_test "INTVAL (op) >= 0 && INTVAL (op) < 64") (match_operand 0 "register_operand")));; Return 1 if OP is an 8-bit constant.(define_predicate "cint8_operand" (and (match_code "const_int") (match_test "INTVAL (op) >= 0 && INTVAL (op) < 256")));; Return 1 if OP is an 8-bit constant or any register.(define_predicate "reg_or_8bit_operand" (if_then_else (match_code "const_int") (match_test "INTVAL (op) >= 0 && INTVAL (op) < 256") (match_operand 0 "register_operand")));; Return 1 if OP is a constant or any register.(define_predicate "reg_or_cint_operand" (ior (match_operand 0 "register_operand") (match_operand 0 "const_int_operand")));; Return 1 if the operand is a valid second operand to an add insn.(define_predicate "add_operand" (if_then_else (match_code "const_int") (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'K') || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')") (match_operand 0 "register_operand")));; Return 1 if the operand is a valid second operand to a;; sign-extending add insn.(define_predicate "sext_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), 'O')") (match_operand 0 "register_operand")));; Return 1 if the operand is a non-symbolic constant operand that;; does not satisfy add_operand.(define_predicate "non_add_const_operand" (and (match_code "const_int,const_double,const_vector") (not (match_operand 0 "add_operand"))));; Return 1 if the operand is a non-symbolic, non-zero constant operand.(define_predicate "non_zero_const_operand" (and (match_code "const_int,const_double,const_vector") (match_test "op != CONST0_RTX (mode)")));; Return 1 if OP is the constant 4 or 8.(define_predicate "const48_operand" (and (match_code "const_int") (match_test "INTVAL (op) == 4 || INTVAL (op) == 8")));; Return 1 if OP is a valid first operand to an AND insn.(define_predicate "and_operand" (if_then_else (match_code "const_int") (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100 || zap_mask (INTVAL (op))") (if_then_else (match_code "const_double") (match_test "zap_mask (CONST_DOUBLE_LOW (op)) && zap_mask (CONST_DOUBLE_HIGH (op))") (match_operand 0 "register_operand"))));; Return 1 if OP is a valid first operand to an IOR or XOR insn.(define_predicate "or_operand" (if_then_else (match_code "const_int") (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100") (match_operand 0 "register_operand")));; Return 1 if OP is a constant that is the width, in bits, of an integral;; mode not larger than DImode.(define_predicate "mode_width_operand" (match_code "const_int"){ HOST_WIDE_INT i = INTVAL (op); return i == 8 || i == 16 || i == 32 || i == 64;});; Return 1 if OP is a constant that is a mask of ones of width of an;; integral machine mode not larger than DImode.(define_predicate "mode_mask_operand" (match_code "const_int,const_double"){ if (GET_CODE (op) == CONST_INT) { HOST_WIDE_INT value = INTVAL (op); if (value == 0xff) return 1; if (value == 0xffff) return 1; if (value == 0xffffffff) return 1; if (value == -1) return 1; } else if (HOST_BITS_PER_WIDE_INT == 32 && GET_CODE (op) == CONST_DOUBLE) { if (CONST_DOUBLE_LOW (op) == 0xffffffff && CONST_DOUBLE_HIGH (op) == 0) return 1; } return 0;});; Return 1 if OP is a multiple of 8 less than 64.(define_predicate "mul8_operand" (match_code "const_int"){ unsigned HOST_WIDE_INT i = INTVAL (op); return i < 64 && i % 8 == 0;});; Return 1 if OP is a hard floating-point register.(define_predicate "hard_fp_register_operand" (match_operand 0 "register_operand"){ if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); return REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;});; Return 1 if OP is a hard general register.(define_predicate "hard_int_register_operand" (match_operand 0 "register_operand"){ if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); return REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;});; Return 1 if OP is something that can be reloaded into a register;;; if it is a MEM, it need not be valid.(define_predicate "some_operand" (ior (match_code "reg,mem,const_int,const_double,const_vector, label_ref,symbol_ref,const,high") (and (match_code "subreg") (match_test "some_operand (SUBREG_REG (op), VOIDmode)"))));; Likewise, but don't accept constants.(define_predicate "some_ni_operand" (ior (match_code "reg,mem") (and (match_code "subreg") (match_test "some_ni_operand (SUBREG_REG (op), VOIDmode)"))));; Return 1 if OP is a valid operand for the source of a move insn.(define_predicate "input_operand" (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem, const_double,const_vector,const_int"){ switch (GET_CODE (op)) { case LABEL_REF: case SYMBOL_REF: case CONST: if (TARGET_EXPLICIT_RELOCS) { /* We don't split symbolic operands into something unintelligable until after reload, but we do not wish non-small, non-global symbolic operands to be reconstructed from their high/lo_sum form. */ return (small_symbolic_operand (op, mode) || global_symbolic_operand (op, mode) || gotdtp_symbolic_operand (op, mode) || gottp_symbolic_operand (op, mode)); } /* This handles both the Windows/NT and OSF cases. */ return mode == ptr_mode || mode == DImode; case HIGH: return (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (XEXP (op, 0), mode)); case REG: return 1; case SUBREG: if (register_operand (op, mode)) return 1; /* ... fall through ... */ case MEM: return ((TARGET_BWX || (mode != HImode && mode != QImode)) && general_operand (op, mode)); case CONST_DOUBLE: return op == CONST0_RTX (mode); case CONST_VECTOR: if (reload_in_progress || reload_completed) return alpha_legitimate_constant_p (op); return op == CONST0_RTX (mode); case CONST_INT: if (mode == QImode || mode == HImode) return true; if (reload_in_progress || reload_completed) return alpha_legitimate_constant_p (op); return add_operand (op, mode); default: abort (); } return 0;});; Return 1 if OP is a SYMBOL_REF for a function known to be in this;; file, and in the same section as the current function.(define_predicate "samegp_function_operand" (match_code "symbol_ref"){ /* Easy test for recursion. */ if (op == XEXP (DECL_RTL (current_function_decl), 0)) return true; /* Functions that are not local can be overridden, and thus may not share the same gp. */ if (! SYMBOL_REF_LOCAL_P (op)) return false; /* If -msmall-data is in effect, assume that there is only one GP for the module, and so any local symbol has this property. We need explicit relocations to be able to enforce this for symbols not defined in this unit of translation, however. */ if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA) return true; /* Functions that are not external are defined in this UoT, and thus must share the same gp. */ return ! SYMBOL_REF_EXTERNAL_P (op);});; Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr.(define_predicate "direct_call_operand" (match_operand 0 "samegp_function_operand"){ tree op_decl, cfun_sec, op_sec; /* If profiling is implemented via linker tricks, we can't jump to the nogp alternate entry point. Note that current_function_profile would not be correct, since that doesn't indicate if the target function uses profiling. */ /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test, but is approximately correct for the OSF ABIs. Don't know what to do for VMS, NT, or UMK. */ if (!TARGET_PROFILING_NEEDS_GP && profile_flag) return false; /* Must be a function. In some cases folks create thunks in static data structures and then make calls to them. If we allow the direct call, we'll get an error from the linker about !samegp reloc against a symbol without a .prologue directive. */ if (!SYMBOL_REF_FUNCTION_P (op)) return false; /* Must be "near" so that the branch is assumed to reach. With -msmall-text, this is assumed true of all local symbols. Since we've already checked samegp, locality is already assured. */ if (TARGET_SMALL_TEXT) return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -