;; Predicate definitions for POWER and PowerPC.
-;; Copyright (C) 2005-2019 Free Software Foundation, Inc.
+;; Copyright (C) 2005-2021 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
(and (match_code "const_int")
(match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
+;; Return 1 if op is an unsigned 1-bit constant integer.
+(define_predicate "u1bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 1")))
+
;; Return 1 if op is a unsigned 3-bit constant integer.
(define_predicate "u3bit_cint_operand"
(and (match_code "const_int")
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 127)")))
+;; Return 1 if op is a unsigned 8-bit constant integer.
+(define_predicate "u8bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
+
;; Return 1 if op is a signed 8-bit constant integer.
;; Integer multiplication complete more quickly
(define_predicate "s8bit_cint_operand"
(match_test "(unsigned HOST_WIDE_INT)
(INTVAL (op) + 0x8000) >= 0x10000")))
+;; Return 1 if op is a 32-bit constant signed integer
+(define_predicate "s32bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "(0x80000000 + UINTVAL (op)) >> 32 == 0")))
+
+;; Return 1 if op is a constant 32-bit unsigned
+(define_predicate "c32bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "((UINTVAL (op) >> 32) == 0)")))
+
;; 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")
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 1)")))
+;; Match op = -1, op = 0, or op = 1.
+(define_predicate "const_m1_to_1_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), -1, 1)")))
+
;; Match op = 0..3.
(define_predicate "const_0_to_3_operand"
(and (match_code "const_int")
(define_predicate "cint34_operand"
(match_code "const_int")
{
- if (!TARGET_PREFIXED_ADDR)
+ if (!TARGET_PREFIXED)
return 0;
- return SIGNED_34BIT_OFFSET_P (INTVAL (op));
+ return SIGNED_INTEGER_34BIT_P (INTVAL (op));
})
;; Return 1 if op is a register that is not special.
|| GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == PRE_MODIFY))"))
+;; Anything that matches memory_operand but does not update the address.
+(define_predicate "non_update_memory_operand"
+ (match_code "mem")
+{
+ if (update_address_mem (op, mode))
+ return 0;
+ return memory_operand (op, mode);
+})
+
;; Return 1 if the operand is a MEM with an indexed-form address.
(define_special_predicate "indexed_address_mem"
(match_test "(MEM_P (op)
(define_predicate "add_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_I (op)
- || satisfies_constraint_L (op)")
+ || satisfies_constraint_L (op)
+ || satisfies_constraint_eI (op)")
(match_operand 0 "gpc_reg_operand")))
;; Return 1 if the operand is either a non-special register, or 0, or -1.
return INTVAL (offset) % 4 == 0;
})
+;; Return 1 if the operand is a memory operand that has a valid address for
+;; a DS-form instruction. I.e. the address has to be either just a register,
+;; or register + const where the two low order bits of const are zero.
+(define_predicate "ds_form_mem_operand"
+ (match_code "subreg,mem")
+{
+ if (!any_memory_operand (op, mode))
+ return false;
+
+ rtx addr = XEXP (op, 0);
+
+ return address_to_insn_form (addr, mode, NON_PREFIXED_DS) == INSN_FORM_DS;
+})
+
;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
(define_predicate "symbol_ref_operand"
(and (match_code "symbol_ref")
if (CONST_INT_P (op))
return 1;
if (XINT (op, 1) == UNSPEC_TLSGD)
- return REG_P (XVECEXP (op, 0, 1));
+ return REG_P (XVECEXP (op, 0, 1)) || XVECEXP (op, 0, 1) == const0_rtx;
if (XINT (op, 1) == UNSPEC_TLSLD)
- return REG_P (XVECEXP (op, 0, 0));
+ return REG_P (XVECEXP (op, 0, 0)) || XVECEXP (op, 0, 0) == const0_rtx;
return 0;
})
&& !((DEFAULT_ABI == ABI_AIX
|| DEFAULT_ABI == ABI_ELFv2)
&& (SYMBOL_REF_EXTERNAL_P (op)
- || SYMBOL_REF_WEAK (op)))")))
+ || SYMBOL_REF_WEAK (op)))
+ && !(DEFAULT_ABI == ABI_ELFv2
+ && SYMBOL_REF_DECL (op) != NULL
+ && TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL
+ && (rs6000_fndecl_pcrel_p (SYMBOL_REF_DECL (op))
+ != rs6000_pcrel_p ()))")))
;; Return 1 if this operand is a valid input for a move insn.
(define_predicate "input_operand"
return gpc_reg_operand (op, mode);
})
+;; Return 1 if this operand is valid for a MMA assemble accumulator insn.
+(define_special_predicate "mma_assemble_input_operand"
+ (match_test "(mode == V16QImode
+ && (vsx_register_operand (op, mode)
+ || (MEM_P (op)
+ && (indexed_or_indirect_address (XEXP (op, 0), mode)
+ || quad_address_p (XEXP (op, 0), mode, false)))))"))
+
+;; Return 1 if this operand is valid for an MMA disassemble insn.
+(define_predicate "mma_disassemble_output_operand"
+ (match_code "reg,subreg,mem")
+{
+ if (SUBREG_P (op))
+ op = SUBREG_REG (op);
+ if (!REG_P (op))
+ return true;
+
+ return vsx_register_operand (op, mode);
+})
+
;; Return true if operand is an operator used in rotate-and-mask instructions.
(define_predicate "rotate_mask_operator"
(match_code "rotate,ashift,lshiftrt"))
;; validate_condition_mode is an assertion.
(define_predicate "branch_comparison_operator"
(and (match_operand 0 "comparison_operator")
- (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
- (match_test "validate_condition_mode (GET_CODE (op),
- GET_MODE (XEXP (op, 0))),
- 1"))))
+ (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
+ (if_then_else (match_test "GET_MODE (XEXP (op, 0)) == CCFPmode")
+ (if_then_else (match_test "flag_finite_math_only")
+ (match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
+ (match_code "lt,gt,eq,unordered,unge,unle,ne,ordered"))
+ (match_code "lt,ltu,le,leu,gt,gtu,ge,geu,eq,ne"))
+ (match_test "validate_condition_mode (GET_CODE (op),
+ GET_MODE (XEXP (op, 0))),
+ 1")))
+
+;; Return 1 if OP is a comparison that needs an extra instruction to do (a
+;; crlogical or an extra branch).
+(define_predicate "extra_insn_branch_comparison_operator"
+ (and (match_operand 0 "comparison_operator")
+ (match_test "GET_MODE (XEXP (op, 0)) == CCFPmode")
+ (match_code "ltgt,le,ge,unlt,ungt,uneq")
+ (match_test "validate_condition_mode (GET_CODE (op),
+ GET_MODE (XEXP (op, 0))),
+ 1")))
;; Return 1 if OP is an unsigned comparison operator.
(define_predicate "unsigned_comparison_operator"
(define_predicate "pcrel_local_or_external_address"
(ior (match_operand 0 "pcrel_local_address")
(match_operand 0 "pcrel_external_address")))
+
+;; Return true if the operand is a memory address that uses a prefixed address.
+(define_predicate "prefixed_memory"
+ (match_code "mem")
+{
+ return address_is_prefixed (XEXP (op, 0), mode, NON_PREFIXED_DEFAULT);
+})
+
+;; Return true if the operand is a valid memory operand with a D-form
+;; address that could be merged with the load of a PC-relative external address
+;; with the PCREL_OPT optimization. We don't check here whether or not the
+;; offset needs to be used in a DS-FORM (bottom 2 bits 0) or DQ-FORM (bottom 4
+;; bits 0) instruction.
+(define_predicate "d_form_memory"
+ (match_code "mem")
+{
+ if (!memory_operand (op, mode))
+ return false;
+
+ rtx addr = XEXP (op, 0);
+
+ if (REG_P (addr))
+ return true;
+ if (SUBREG_P (addr) && REG_P (SUBREG_REG (addr)))
+ return true;
+
+ return !indexed_address (addr, mode);
+})
+
+;; Return 1 if this operand is valid as the index for vec_set.
+(define_predicate "vec_set_index_operand"
+ (if_then_else (match_test "TARGET_VSX")
+ (match_operand 0 "reg_or_cint_operand")
+ (match_operand 0 "const_int_operand")))