xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/microblaze/predicates.md (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1;; Predicate definitions for Xilinx MicroBlaze
2;; Copyright (C) 2009-2020 Free Software Foundation, Inc.
3;;
4;; Contributed by Michael Eager <eager@eagercon.com>.
5;;
6;; This file is part of GCC.
7;;
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 3, or (at your option)
11;; any later version.
12;;
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.
21
22
23;; Return whether OP can be used as an operands in arithmetic.
24(define_predicate "arith_operand"
25  (ior (match_code "const_int,const_double")
26       (match_operand 0 "register_operand")))
27
28(define_predicate "arith_operand32"
29  (ior (match_operand 0 "register_operand")
30       (and (match_code "const_int,const_double")
31	    (match_test "LARGE_INT (op)"))))
32
33(define_predicate "arith_plus_operand"
34 (match_operand 0 "general_operand")
35{
36  switch (GET_CODE (op))
37    {
38      default:
39        return 0;
40      case CONST_INT:
41      case REG:
42        return 1;
43      case SYMBOL_REF:
44      case LABEL_REF:
45        if (flag_pic || microblaze_tls_referenced_p(op))
46          return 0;
47        return 1;
48      case CONST:
49        {
50          rtx const0;
51          const0 = XEXP (op, 0);
52
53          switch (GET_CODE(const0))
54            {
55              default:
56                return 0;
57              case UNSPEC :
58                return 1;
59
60              case PLUS :
61                {
62                  rtx p0, p1;
63                  p0 = XEXP (const0, 0);
64                  p1 = XEXP (const0, 1);
65
66                  if ((GET_CODE(p0) == SYMBOL_REF
67                       || GET_CODE (p0) == LABEL_REF)
68                      && GET_CODE(p1) == CONST_INT)
69                    {
70                      return arith_plus_operand (p0, GET_MODE(p0));
71                    }
72                }
73            }
74        }
75    }
76  return 0;
77})
78
79(define_predicate "const_0_operand"
80  (and (match_code "const_int,const_double")
81       (match_test "op == CONST0_RTX (GET_MODE (op))")))
82
83;; Return whether OP is a register or the constant 0.
84(define_predicate "reg_or_0_operand"
85  (ior (match_operand 0 "const_0_operand")
86       (match_operand 0 "register_operand")))
87
88(define_predicate "reg_or_mem_operand"
89  (ior (match_operand 0 "memory_operand")
90       (match_operand 0 "register_operand")))
91
92;;  Return if the operand is either the PC or a label_ref.
93(define_special_predicate "pc_or_label_operand"
94  (ior (match_code "pc,label_ref")
95       (and (match_code "symbol_ref")
96            (match_test "!(strcmp ((XSTR (op, 0)), \"_stack_overflow_exit\"))"))))
97
98;; Test for valid call operand
99(define_predicate "call_insn_operand"
100  (match_test "CALL_INSN_OP (op)"))
101
102(define_predicate "call_insn_simple_operand"
103  (and (match_test "CALL_INSN_OP (op)")
104       (match_test "GET_CODE (op) == REG || GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST_INT")))
105
106;; Return if OPERAND is valid as a source operand for a move instruction.
107(define_predicate "move_src_operand"
108  (and (
109     not (
110       and (match_code "plus")
111           (not (match_test "(GET_CODE (XEXP (op, 0)) == REG) ^ (GET_CODE (XEXP (op,1)) == REG)"))
112	 )
113       )
114       (match_operand 0 "general_operand"))
115{
116  if (microblaze_tls_referenced_p(op)
117      || (flag_pic && (symbol_mentioned_p(op) || label_mentioned_p(op))))
118    return false;
119
120  return true;
121})
122
123;; Test for valid PIC call operand
124(define_predicate "call_insn_plt_operand"
125  (match_test "PLT_ADDR_P (op)"))
126
127;; Return if the code of this rtx pattern is a comparison.
128(define_predicate "cmp_op"
129  (match_code "gt,ge,gtu,geu,lt,le,ltu,leu"))
130