annotate gcc/config/sh/predicates.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 ;; Predicate definitions for Renesas / SuperH SH.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 ;; Copyright (C) 2005-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 ;;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 ;; This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 ;;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 ;; GCC is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 ;; it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 ;; the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 ;; any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 ;;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 ;; GCC is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ;; GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 ;;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 ;; You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 ;; along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 ;; <http://www.gnu.org/licenses/>.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 ;; Returns 1 if OP is a normal arithmetic register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 (define_predicate "arith_reg_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 (match_code "subreg,reg,sign_extend")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 if (register_operand (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 int regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
29 if (REG_P (op))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 regno = REGNO (op);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
31 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 regno = REGNO (SUBREG_REG (op));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 return (regno != T_REG && regno != PR_REG
111
kono
parents: 63
diff changeset
37 && regno != FPUL_REG && regno != FPSCR_REG
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 && regno != MACH_REG && regno != MACL_REG);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 /* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 We allow SImode here, as not using an FP register is just a matter of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 proper register allocation. */
111
kono
parents: 63
diff changeset
43
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 && GET_MODE (XEXP (op, 0)) == HImode
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
47 && REG_P (XEXP (op, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 return register_operand (XEXP (op, 0), VOIDmode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 && GET_CODE (op) == SUBREG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 && GET_MODE (SUBREG_REG (op)) == DImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
111
kono
parents: 63
diff changeset
61 ;; Like above, but for DImode destinations: forbid paradoxical DImode
kono
parents: 63
diff changeset
62 ;; subregs, because this would lead to missing sign extensions when
kono
parents: 63
diff changeset
63 ;; truncating from DImode to SImode.
kono
parents: 63
diff changeset
64 (define_predicate "arith_reg_dest"
kono
parents: 63
diff changeset
65 (and (match_code "subreg,reg")
kono
parents: 63
diff changeset
66 (match_operand 0 "arith_reg_operand")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
111
kono
parents: 63
diff changeset
68 ;; Returns true if OP is a valid source operand for an arithmetic insn.
kono
parents: 63
diff changeset
69 (define_predicate "arith_operand"
kono
parents: 63
diff changeset
70 (and (match_code "subreg,reg,const_int,truncate")
kono
parents: 63
diff changeset
71 (ior (match_operand 0 "arith_reg_operand")
kono
parents: 63
diff changeset
72 (match_test "satisfies_constraint_I08 (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73
111
kono
parents: 63
diff changeset
74 ;; Likewise arith_operand but always permits const_int.
kono
parents: 63
diff changeset
75 (define_predicate "arith_or_int_operand"
kono
parents: 63
diff changeset
76 (and (match_code "subreg,reg,const_int,const_vector")
kono
parents: 63
diff changeset
77 (ior (match_operand 0 "arith_operand")
kono
parents: 63
diff changeset
78 (match_operand 0 "const_int_operand"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
111
kono
parents: 63
diff changeset
80 ;; Returns true if OP is a valid source operand for a compare insn.
kono
parents: 63
diff changeset
81 (define_predicate "arith_reg_or_0_operand"
kono
parents: 63
diff changeset
82 (and (match_code "subreg,reg,const_int,const_vector")
kono
parents: 63
diff changeset
83 (ior (match_operand 0 "arith_reg_operand")
kono
parents: 63
diff changeset
84 (match_test "satisfies_constraint_Z (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
111
kono
parents: 63
diff changeset
86 ;; Returns true if OP is either a register or constant 0 or constant 1.
kono
parents: 63
diff changeset
87 (define_predicate "arith_reg_or_0_or_1_operand"
kono
parents: 63
diff changeset
88 (and (match_code "subreg,reg,const_int,const_vector")
kono
parents: 63
diff changeset
89 (ior (match_operand 0 "arith_reg_or_0_operand")
kono
parents: 63
diff changeset
90 (match_test "satisfies_constraint_M (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91
111
kono
parents: 63
diff changeset
92 ;; Returns true if OP is a suitable constant for the minimum value of a
kono
parents: 63
diff changeset
93 ;; clips.b or clips.w insn.
kono
parents: 63
diff changeset
94 (define_predicate "clips_min_const_int"
kono
parents: 63
diff changeset
95 (and (match_code "const_int")
kono
parents: 63
diff changeset
96 (ior (match_test "INTVAL (op) == -128")
kono
parents: 63
diff changeset
97 (match_test "INTVAL (op) == -32768"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98
111
kono
parents: 63
diff changeset
99 ;; Returns true if OP is a suitable constant for the maximum value of a
kono
parents: 63
diff changeset
100 ;; clips.b or clips.w insn.
kono
parents: 63
diff changeset
101 (define_predicate "clips_max_const_int"
kono
parents: 63
diff changeset
102 (and (match_code "const_int")
kono
parents: 63
diff changeset
103 (ior (match_test "INTVAL (op) == 127")
kono
parents: 63
diff changeset
104 (match_test "INTVAL (op) == 32767"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
111
kono
parents: 63
diff changeset
106 ;; Returns true if OP is a suitable constant for the maximum value of a
kono
parents: 63
diff changeset
107 ;; clipu.b or clipu.w insn.
kono
parents: 63
diff changeset
108 (define_predicate "clipu_max_const_int"
kono
parents: 63
diff changeset
109 (and (match_code "const_int")
kono
parents: 63
diff changeset
110 (ior (match_test "INTVAL (op) == 255")
kono
parents: 63
diff changeset
111 (match_test "INTVAL (op) == 65535"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
111
kono
parents: 63
diff changeset
113 ;; Returns true if OP is a floating point register that can be used in floating
kono
parents: 63
diff changeset
114 ;; point arithmetic operations.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 (define_predicate "fp_arith_reg_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 (match_code "subreg,reg")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 if (register_operand (op, mode))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 int regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
122 if (REG_P (op))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 regno = REGNO (op);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
124 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 regno = REGNO (SUBREG_REG (op));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 return (regno >= FIRST_PSEUDO_REGISTER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 || FP_REGISTER_P (regno));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
111
kono
parents: 63
diff changeset
135 ;; Returns true if OP is the FPSCR.
kono
parents: 63
diff changeset
136 (define_predicate "fpscr_operand"
kono
parents: 63
diff changeset
137 (and (match_code "reg")
kono
parents: 63
diff changeset
138 (match_test "REGNO (op) == FPSCR_REG")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
111
kono
parents: 63
diff changeset
140 ;; Returns true if OP is a valid source operand for a FPSCR move insn.
kono
parents: 63
diff changeset
141 (define_predicate "fpscr_movsrc_operand"
kono
parents: 63
diff changeset
142 (match_code "reg,subreg,mem")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 {
111
kono
parents: 63
diff changeset
144 if (arith_reg_operand (op, mode))
kono
parents: 63
diff changeset
145 return true;
kono
parents: 63
diff changeset
146
kono
parents: 63
diff changeset
147 return MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
111
kono
parents: 63
diff changeset
150 ;; Returns true if OP is a valid destination operand for a FPSCR move insn.
kono
parents: 63
diff changeset
151 (define_predicate "fpscr_movdst_operand"
kono
parents: 63
diff changeset
152 (match_code "reg,subreg,mem")
kono
parents: 63
diff changeset
153 {
kono
parents: 63
diff changeset
154 if (arith_reg_dest (op, mode))
kono
parents: 63
diff changeset
155 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
111
kono
parents: 63
diff changeset
157 return MEM_P (op) && GET_CODE (XEXP (op, 0)) == PRE_DEC;
kono
parents: 63
diff changeset
158 })
kono
parents: 63
diff changeset
159
kono
parents: 63
diff changeset
160 ;; Returns true if OP is an operand that is either the fpul hard reg or
kono
parents: 63
diff changeset
161 ;; a pseudo. This prevents combine from propagating function arguments
kono
parents: 63
diff changeset
162 ;; in hard regs into insns that need the operand in fpul. If it's a pseudo
kono
parents: 63
diff changeset
163 ;; reload can fix it up.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 (define_predicate "fpul_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 (match_code "reg")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 {
111
kono
parents: 63
diff changeset
167 return REG_P (op)
kono
parents: 63
diff changeset
168 && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
kono
parents: 63
diff changeset
169 && GET_MODE (op) == mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
111
kono
parents: 63
diff changeset
172 ;; Returns true if OP is a valid fpul input operand for the fsca insn.
kono
parents: 63
diff changeset
173 ;; The value in fpul is a fixed-point value and its scaling is described
kono
parents: 63
diff changeset
174 ;; in the fsca insn by a mult:SF. To allow pre-scaled fixed-point inputs
kono
parents: 63
diff changeset
175 ;; in fpul we have to permit things like
kono
parents: 63
diff changeset
176 ;; (reg:SI)
kono
parents: 63
diff changeset
177 ;; (fix:SF (float:SF (reg:SI)))
kono
parents: 63
diff changeset
178 (define_predicate "fpul_fsca_operand"
kono
parents: 63
diff changeset
179 (match_code "fix,reg")
kono
parents: 63
diff changeset
180 {
kono
parents: 63
diff changeset
181 if (fpul_operand (op, SImode))
kono
parents: 63
diff changeset
182 return true;
kono
parents: 63
diff changeset
183 if (GET_CODE (op) == FIX && GET_MODE (op) == SImode
kono
parents: 63
diff changeset
184 && GET_CODE (XEXP (op, 0)) == FLOAT && GET_MODE (XEXP (op, 0)) == SFmode)
kono
parents: 63
diff changeset
185 return fpul_fsca_operand (XEXP (XEXP (op, 0), 0),
kono
parents: 63
diff changeset
186 GET_MODE (XEXP (XEXP (op, 0), 0)));
kono
parents: 63
diff changeset
187 return false;
kono
parents: 63
diff changeset
188 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189
111
kono
parents: 63
diff changeset
190 ;; Returns true if OP is a valid constant scale factor for the fsca insn.
kono
parents: 63
diff changeset
191 (define_predicate "fsca_scale_factor"
kono
parents: 63
diff changeset
192 (and (match_code "const_double")
kono
parents: 63
diff changeset
193 (match_test "op == sh_fsca_int2sf ()")))
kono
parents: 63
diff changeset
194
kono
parents: 63
diff changeset
195 ;; Returns true if OP is an operand that is zero extended during an operation.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 (define_predicate "general_extend_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 (match_code "subreg,reg,mem,truncate")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 {
111
kono
parents: 63
diff changeset
199 if (reload_completed && GET_CODE (op) == TRUNCATE)
kono
parents: 63
diff changeset
200 return arith_operand (op, mode);
kono
parents: 63
diff changeset
201
kono
parents: 63
diff changeset
202 if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))
kono
parents: 63
diff changeset
203 return general_movsrc_operand (op, mode);
kono
parents: 63
diff changeset
204
kono
parents: 63
diff changeset
205 return nonimmediate_operand (op, mode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
111
kono
parents: 63
diff changeset
208 ;; Returns 1 if OP is a simple register address.
kono
parents: 63
diff changeset
209 (define_predicate "simple_mem_operand"
kono
parents: 63
diff changeset
210 (and (match_code "mem")
kono
parents: 63
diff changeset
211 (match_code "reg" "0")
kono
parents: 63
diff changeset
212 (match_test "arith_reg_operand (XEXP (op, 0), SImode)")))
kono
parents: 63
diff changeset
213
kono
parents: 63
diff changeset
214 ;; Returns 1 if OP is a valid displacement address.
kono
parents: 63
diff changeset
215 (define_predicate "displacement_mem_operand"
kono
parents: 63
diff changeset
216 (and (match_code "mem")
kono
parents: 63
diff changeset
217 (match_code "plus" "0")
kono
parents: 63
diff changeset
218 (match_code "reg" "00")
kono
parents: 63
diff changeset
219 (match_test "arith_reg_operand (XEXP (XEXP (op, 0), 0), SImode)")
kono
parents: 63
diff changeset
220 (match_test "sh_legitimate_index_p (GET_MODE (op),
kono
parents: 63
diff changeset
221 XEXP (XEXP (op, 0), 1),
kono
parents: 63
diff changeset
222 TARGET_SH2A, true)")))
kono
parents: 63
diff changeset
223
kono
parents: 63
diff changeset
224 ;; Returns true if OP is a displacement address that can fit into a
kono
parents: 63
diff changeset
225 ;; 16 bit (non-SH2A) memory load / store insn.
kono
parents: 63
diff changeset
226 (define_predicate "short_displacement_mem_operand"
kono
parents: 63
diff changeset
227 (and (match_code "mem")
kono
parents: 63
diff changeset
228 (match_operand 0 "displacement_mem_operand")
kono
parents: 63
diff changeset
229 (match_test "sh_disp_addr_displacement (op)
kono
parents: 63
diff changeset
230 <= sh_max_mov_insn_displacement (GET_MODE (op), false)")))
kono
parents: 63
diff changeset
231
kono
parents: 63
diff changeset
232 ;; Returns true if OP is a displacement address that does not fit into
kono
parents: 63
diff changeset
233 ;; a 16 bit (non-SH2A) memory load / store insn.
kono
parents: 63
diff changeset
234 (define_predicate "long_displacement_mem_operand"
kono
parents: 63
diff changeset
235 (and (match_operand 0 "displacement_mem_operand")
kono
parents: 63
diff changeset
236 (not (match_operand 0 "short_displacement_mem_operand"))))
kono
parents: 63
diff changeset
237
kono
parents: 63
diff changeset
238 ;; Returns true if OP is a post-increment addressing mode memory reference.
kono
parents: 63
diff changeset
239 (define_predicate "post_inc_mem"
kono
parents: 63
diff changeset
240 (and (match_code "mem")
kono
parents: 63
diff changeset
241 (match_code "post_inc" "0")
kono
parents: 63
diff changeset
242 (match_code "reg" "00")))
kono
parents: 63
diff changeset
243
kono
parents: 63
diff changeset
244 ;; Returns true if OP is a pre-decrement addressing mode memory reference.
kono
parents: 63
diff changeset
245 (define_predicate "pre_dec_mem"
kono
parents: 63
diff changeset
246 (and (match_code "mem")
kono
parents: 63
diff changeset
247 (match_code "pre_dec" "0")
kono
parents: 63
diff changeset
248 (match_code "reg" "00")))
kono
parents: 63
diff changeset
249
kono
parents: 63
diff changeset
250 ;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
kono
parents: 63
diff changeset
251 (define_predicate "zero_extend_movu_operand"
kono
parents: 63
diff changeset
252 (and (ior (match_operand 0 "displacement_mem_operand")
kono
parents: 63
diff changeset
253 (match_operand 0 "simple_mem_operand"))
kono
parents: 63
diff changeset
254 (ior (match_test "GET_MODE (op) == QImode")
kono
parents: 63
diff changeset
255 (match_test "GET_MODE (op) == HImode"))))
kono
parents: 63
diff changeset
256
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 ;; Returns 1 if OP can be source of a simple move operation. Same as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 ;; are subregs of system registers.
111
kono
parents: 63
diff changeset
260 (define_predicate "general_movsrc_operand"
kono
parents: 63
diff changeset
261 (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,
kono
parents: 63
diff changeset
262 const,const_vector")
kono
parents: 63
diff changeset
263 {
kono
parents: 63
diff changeset
264 if (t_reg_operand (op, mode))
kono
parents: 63
diff changeset
265 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266
111
kono
parents: 63
diff changeset
267 if (fpscr_operand (op, mode))
kono
parents: 63
diff changeset
268 return false;
kono
parents: 63
diff changeset
269
kono
parents: 63
diff changeset
270 /* Disallow PC relative QImode loads, since these is no insn to do that
kono
parents: 63
diff changeset
271 and an imm8 load should be used instead. */
kono
parents: 63
diff changeset
272 if (IS_PC_RELATIVE_LOAD_ADDR_P (op) && GET_MODE (op) == QImode)
kono
parents: 63
diff changeset
273 return false;
kono
parents: 63
diff changeset
274
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
275 if (MEM_P (op))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 rtx inside = XEXP (op, 0);
111
kono
parents: 63
diff changeset
278
kono
parents: 63
diff changeset
279 /* Disallow mems with GBR address here. They have to go through
kono
parents: 63
diff changeset
280 separate special patterns. */
kono
parents: 63
diff changeset
281 if ((REG_P (inside) && REGNO (inside) == GBR_REG)
kono
parents: 63
diff changeset
282 || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0))
kono
parents: 63
diff changeset
283 && REGNO (XEXP (inside, 0)) == GBR_REG))
kono
parents: 63
diff changeset
284 return 0;
kono
parents: 63
diff changeset
285
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 if (GET_CODE (inside) == CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 inside = XEXP (inside, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 if (GET_CODE (inside) == LABEL_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 if (GET_CODE (inside) == PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 && GET_CODE (XEXP (inside, 0)) == LABEL_REF
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
294 && CONST_INT_P (XEXP (inside, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 /* Only post inc allowed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 if (GET_CODE (inside) == PRE_DEC)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301
111
kono
parents: 63
diff changeset
302 if (mode == GET_MODE (op)
kono
parents: 63
diff changeset
303 && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
kono
parents: 63
diff changeset
304 {
kono
parents: 63
diff changeset
305 rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
kono
parents: 63
diff changeset
306 rtx x = XEXP (mem_rtx, 0);
kono
parents: 63
diff changeset
307
kono
parents: 63
diff changeset
308 if (GET_CODE (x) == PLUS)
kono
parents: 63
diff changeset
309 {
kono
parents: 63
diff changeset
310 rtx y = XEXP (x, 0);
kono
parents: 63
diff changeset
311
kono
parents: 63
diff changeset
312 if (! REG_P (y)
kono
parents: 63
diff changeset
313 && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
kono
parents: 63
diff changeset
314 return false;
kono
parents: 63
diff changeset
315 y = XEXP (x, 1);
kono
parents: 63
diff changeset
316 if (! REG_P (y)
kono
parents: 63
diff changeset
317 && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
kono
parents: 63
diff changeset
318 && ! CONST_INT_P (y))
kono
parents: 63
diff changeset
319 return false;
kono
parents: 63
diff changeset
320 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321
111
kono
parents: 63
diff changeset
322 /* LRA will try to satisfy the constraints for the memory displacements
kono
parents: 63
diff changeset
323 and thus we must not reject invalid displacements in the predicate,
kono
parents: 63
diff changeset
324 or else LRA will bail out.
kono
parents: 63
diff changeset
325 FIXME: maybe remove this check completely? */
kono
parents: 63
diff changeset
326 if (!lra_in_progress && (mode == QImode || mode == HImode)
kono
parents: 63
diff changeset
327 && GET_CODE (x) == PLUS
kono
parents: 63
diff changeset
328 && REG_P (XEXP (x, 0))
kono
parents: 63
diff changeset
329 && CONST_INT_P (XEXP (x, 1)))
kono
parents: 63
diff changeset
330 return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331
111
kono
parents: 63
diff changeset
332 /* Allow reg+reg addressing here without validating the register
kono
parents: 63
diff changeset
333 numbers. Usually one of the regs must be R0 or a pseudo reg.
kono
parents: 63
diff changeset
334 In some cases it can happen that arguments from hard regs are
kono
parents: 63
diff changeset
335 propagated directly into address expressions. In this cases reload
kono
parents: 63
diff changeset
336 will have to fix it up later. However, allow this only for native
kono
parents: 63
diff changeset
337 1, 2 or 4 byte addresses. */
kono
parents: 63
diff changeset
338 if (can_create_pseudo_p () && GET_CODE (x) == PLUS
kono
parents: 63
diff changeset
339 && GET_MODE_SIZE (mode) <= 4
kono
parents: 63
diff changeset
340 && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
kono
parents: 63
diff changeset
341 return true;
kono
parents: 63
diff changeset
342
kono
parents: 63
diff changeset
343 /* 'general_operand' does not allow volatile mems during RTL expansion to
kono
parents: 63
diff changeset
344 avoid matching arithmetic that operates on mems, it seems.
kono
parents: 63
diff changeset
345 On SH this leads to redundant sign extensions for QImode or HImode
kono
parents: 63
diff changeset
346 loads. Thus we mimic the behavior but allow volatile mems. */
kono
parents: 63
diff changeset
347 if (memory_address_addr_space_p (GET_MODE (mem_rtx), x,
kono
parents: 63
diff changeset
348 MEM_ADDR_SPACE (mem_rtx)))
kono
parents: 63
diff changeset
349 return true;
kono
parents: 63
diff changeset
350 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 return general_operand (op, mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354
111
kono
parents: 63
diff changeset
355 ;; Returns true if OP is a MEM that does not use displacement addressing.
kono
parents: 63
diff changeset
356 (define_predicate "movsrc_no_disp_mem_operand"
kono
parents: 63
diff changeset
357 (and (match_code "mem")
kono
parents: 63
diff changeset
358 (match_operand 0 "general_movsrc_operand")
kono
parents: 63
diff changeset
359 (match_test "satisfies_constraint_Snd (op)")))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
360
111
kono
parents: 63
diff changeset
361 ;; Returns 1 if OP can be a destination of a move. Same as
kono
parents: 63
diff changeset
362 ;; general_operand, but no preinc allowed.
kono
parents: 63
diff changeset
363 (define_predicate "general_movdst_operand"
kono
parents: 63
diff changeset
364 (match_code "subreg,reg,mem")
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
365 {
111
kono
parents: 63
diff changeset
366 if (t_reg_operand (op, mode))
kono
parents: 63
diff changeset
367 return 0;
kono
parents: 63
diff changeset
368
kono
parents: 63
diff changeset
369 if (fpscr_operand (op, mode))
kono
parents: 63
diff changeset
370 return false;
kono
parents: 63
diff changeset
371
kono
parents: 63
diff changeset
372 if (MEM_P (op))
kono
parents: 63
diff changeset
373 {
kono
parents: 63
diff changeset
374 rtx inside = XEXP (op, 0);
kono
parents: 63
diff changeset
375 /* Disallow mems with GBR address here. They have to go through
kono
parents: 63
diff changeset
376 separate special patterns. */
kono
parents: 63
diff changeset
377 if ((REG_P (inside) && REGNO (inside) == GBR_REG)
kono
parents: 63
diff changeset
378 || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0))
kono
parents: 63
diff changeset
379 && REGNO (XEXP (inside, 0)) == GBR_REG))
kono
parents: 63
diff changeset
380 return 0;
kono
parents: 63
diff changeset
381 }
kono
parents: 63
diff changeset
382
kono
parents: 63
diff changeset
383 /* Only pre dec allowed. */
kono
parents: 63
diff changeset
384 if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
kono
parents: 63
diff changeset
385 return 0;
kono
parents: 63
diff changeset
386
kono
parents: 63
diff changeset
387 if (mode == GET_MODE (op)
kono
parents: 63
diff changeset
388 && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
kono
parents: 63
diff changeset
389 {
kono
parents: 63
diff changeset
390 rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
kono
parents: 63
diff changeset
391 rtx x = XEXP (mem_rtx, 0);
kono
parents: 63
diff changeset
392
kono
parents: 63
diff changeset
393 if (GET_CODE (x) == PLUS)
kono
parents: 63
diff changeset
394 {
kono
parents: 63
diff changeset
395 rtx y = XEXP (x, 0);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
396
111
kono
parents: 63
diff changeset
397 if (! REG_P (y)
kono
parents: 63
diff changeset
398 && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
kono
parents: 63
diff changeset
399 return false;
kono
parents: 63
diff changeset
400 y = XEXP (x, 1);
kono
parents: 63
diff changeset
401 if (! REG_P (y)
kono
parents: 63
diff changeset
402 && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
kono
parents: 63
diff changeset
403 && ! CONST_INT_P (y))
kono
parents: 63
diff changeset
404 return false;
kono
parents: 63
diff changeset
405 }
kono
parents: 63
diff changeset
406
kono
parents: 63
diff changeset
407 /* LRA will try to satisfy the constraints for the memory displacements
kono
parents: 63
diff changeset
408 and thus we must not reject invalid displacements in the predicate,
kono
parents: 63
diff changeset
409 or else LRA will bail out.
kono
parents: 63
diff changeset
410 FIXME: maybe remove this check completely? */
kono
parents: 63
diff changeset
411 if (!lra_in_progress && (mode == QImode || mode == HImode)
kono
parents: 63
diff changeset
412 && GET_CODE (x) == PLUS
kono
parents: 63
diff changeset
413 && REG_P (XEXP (x, 0))
kono
parents: 63
diff changeset
414 && CONST_INT_P (XEXP (x, 1)))
kono
parents: 63
diff changeset
415 return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
416
111
kono
parents: 63
diff changeset
417 /* Allow reg+reg addressing here without validating the register
kono
parents: 63
diff changeset
418 numbers. Usually one of the regs must be R0 or a pseudo reg.
kono
parents: 63
diff changeset
419 In some cases it can happen that arguments from hard regs are
kono
parents: 63
diff changeset
420 propagated directly into address expressions. In this cases reload
kono
parents: 63
diff changeset
421 will have to fix it up later. However, allow this only for native
kono
parents: 63
diff changeset
422 1, 2 or 4 byte addresses. */
kono
parents: 63
diff changeset
423 if (can_create_pseudo_p () && GET_CODE (x) == PLUS
kono
parents: 63
diff changeset
424 && GET_MODE_SIZE (mode) <= 4
kono
parents: 63
diff changeset
425 && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
kono
parents: 63
diff changeset
426 return true;
kono
parents: 63
diff changeset
427
kono
parents: 63
diff changeset
428 /* 'general_operand' does not allow volatile mems during RTL expansion to
kono
parents: 63
diff changeset
429 avoid matching arithmetic that operates on mems, it seems.
kono
parents: 63
diff changeset
430 On SH this leads to redundant sign extensions for QImode or HImode
kono
parents: 63
diff changeset
431 stores. Thus we mimic the behavior but allow volatile mems. */
kono
parents: 63
diff changeset
432 if (memory_address_addr_space_p (GET_MODE (mem_rtx), x,
kono
parents: 63
diff changeset
433 MEM_ADDR_SPACE (mem_rtx)))
kono
parents: 63
diff changeset
434 return true;
kono
parents: 63
diff changeset
435 }
kono
parents: 63
diff changeset
436
kono
parents: 63
diff changeset
437 return general_operand (op, mode);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
438 })
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
439
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 ;; Returns 1 if OP is a MEM that can be source of a simple move operation.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 (define_predicate "unaligned_load_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 (match_code "mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 rtx inside;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
446 if (!MEM_P (op) || GET_MODE (op) != mode)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 inside = XEXP (op, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 if (GET_CODE (inside) == POST_INC)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 inside = XEXP (inside, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
454 if (REG_P (inside))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459
111
kono
parents: 63
diff changeset
460 ;; Returns 1 if OP is a MEM that can be used in "index_disp" combiner
kono
parents: 63
diff changeset
461 ;; patterns.
kono
parents: 63
diff changeset
462 (define_predicate "mem_index_disp_operand"
kono
parents: 63
diff changeset
463 (match_code "mem")
kono
parents: 63
diff changeset
464 {
kono
parents: 63
diff changeset
465 rtx plus0_rtx, plus1_rtx, mult_rtx;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466
111
kono
parents: 63
diff changeset
467 plus0_rtx = XEXP (op, 0);
kono
parents: 63
diff changeset
468 if (GET_CODE (plus0_rtx) != PLUS)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
111
kono
parents: 63
diff changeset
471 plus1_rtx = XEXP (plus0_rtx, 0);
kono
parents: 63
diff changeset
472 if (GET_CODE (plus1_rtx) != PLUS)
kono
parents: 63
diff changeset
473 return 0;
kono
parents: 63
diff changeset
474 if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1))))
kono
parents: 63
diff changeset
475 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476
111
kono
parents: 63
diff changeset
477 mult_rtx = XEXP (plus1_rtx, 0);
kono
parents: 63
diff changeset
478 if (GET_CODE (mult_rtx) != MULT)
kono
parents: 63
diff changeset
479 return 0;
kono
parents: 63
diff changeset
480 if (! arith_reg_operand (XEXP (mult_rtx, 0), GET_MODE (XEXP (mult_rtx, 0)))
kono
parents: 63
diff changeset
481 || ! CONST_INT_P (XEXP (mult_rtx, 1)))
kono
parents: 63
diff changeset
482 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483
111
kono
parents: 63
diff changeset
484 return exact_log2 (INTVAL (XEXP (mult_rtx, 1))) > 0
kono
parents: 63
diff changeset
485 && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487
111
kono
parents: 63
diff changeset
488 ;; Returns true if OP is a valid source operand for a logical operation.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 (define_predicate "logical_operand"
111
kono
parents: 63
diff changeset
490 (and (match_code "subreg,reg,const_int")
kono
parents: 63
diff changeset
491 (ior (match_operand 0 "arith_reg_operand")
kono
parents: 63
diff changeset
492 (match_test "satisfies_constraint_K08 (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493
111
kono
parents: 63
diff changeset
494 ;; Returns true if OP is a valid constant source operand for a logical
kono
parents: 63
diff changeset
495 ;; operations tst/and/or/xor #imm,r0.
kono
parents: 63
diff changeset
496 (define_predicate "const_logical_operand"
kono
parents: 63
diff changeset
497 (and (match_code "const_int")
kono
parents: 63
diff changeset
498 (match_test "satisfies_constraint_K08 (op)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499
111
kono
parents: 63
diff changeset
500 ;; Like logical_operand but allows additional constant values which can be
kono
parents: 63
diff changeset
501 ;; done with zero extensions. Used for the second operand of and insns.
kono
parents: 63
diff changeset
502 (define_predicate "logical_and_operand"
kono
parents: 63
diff changeset
503 (and (match_code "subreg,reg,const_int")
kono
parents: 63
diff changeset
504 (ior (match_operand 0 "logical_operand")
kono
parents: 63
diff changeset
505 (match_test "satisfies_constraint_Jmb (op)")
kono
parents: 63
diff changeset
506 (match_test "satisfies_constraint_Jmw (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507
111
kono
parents: 63
diff changeset
508 ;; Returns true if OP is a logical operator.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 (define_predicate "logical_operator"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 (match_code "and,ior,xor"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511
111
kono
parents: 63
diff changeset
512 ;; Returns true if OP is a constant vector.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 (define_predicate "sh_const_vec"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 (match_code "const_vector")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 {
111
kono
parents: 63
diff changeset
516 for (int i = XVECLEN (op, 0) - 1; i >= 0; i--)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
517 if (!CONST_INT_P (XVECEXP (op, 0, i)))
111
kono
parents: 63
diff changeset
518 return false;
kono
parents: 63
diff changeset
519 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 ;; Determine if OP is a constant vector matching MODE with only one
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 ;; element that is not a sign extension. Two byte-sized elements
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 ;; count as one.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 (define_predicate "sh_1el_vec"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 (match_code "const_vector")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 /* Determine numbers of last and of least significant elements. */
111
kono
parents: 63
diff changeset
529 int last = XVECLEN (op, 0) - 1;
kono
parents: 63
diff changeset
530 int least = TARGET_LITTLE_ENDIAN ? 0 : last;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
531 if (!CONST_INT_P (XVECEXP (op, 0, least)))
111
kono
parents: 63
diff changeset
532 return false;
kono
parents: 63
diff changeset
533 int sign_ix = least;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 if (GET_MODE_UNIT_SIZE (mode) == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
536 if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
111
kono
parents: 63
diff changeset
537 return false;
kono
parents: 63
diff changeset
538 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
kono
parents: 63
diff changeset
539 rtx sign = INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
kono
parents: 63
diff changeset
540 ? constm1_rtx : const0_rtx;
kono
parents: 63
diff changeset
541 int i = XVECLEN (op, 0) - 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 while (--i);
111
kono
parents: 63
diff changeset
546 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548
111
kono
parents: 63
diff changeset
549 ;; Returns true if OP is a vector which is composed of one element that is
kono
parents: 63
diff changeset
550 ;; repeated.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 (define_predicate "sh_rep_vec"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 (match_code "const_vector,parallel")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 {
111
kono
parents: 63
diff changeset
554 int i = XVECLEN (op, 0) - 2;
kono
parents: 63
diff changeset
555 rtx x = XVECEXP (op, 0, i + 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 if (GET_MODE_UNIT_SIZE (mode) == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 {
111
kono
parents: 63
diff changeset
558 rtx y = XVECEXP (op, 0, i);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 for (i -= 2; i >= 0; i -= 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 || ! rtx_equal_p (XVECEXP (op, 0, i), y))
111
kono
parents: 63
diff changeset
562 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 for (; i >= 0; i--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 if (XVECEXP (op, 0, i) != x)
111
kono
parents: 63
diff changeset
567 return false;
kono
parents: 63
diff changeset
568 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570
111
kono
parents: 63
diff changeset
571 ;; Returns true if OP is a valid shift count operand for shift operations.
kono
parents: 63
diff changeset
572 (define_predicate "shift_count_operand"
kono
parents: 63
diff changeset
573 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,
kono
parents: 63
diff changeset
574 zero_extend,sign_extend")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 {
111
kono
parents: 63
diff changeset
576 /* Allow T_REG as shift count for dynamic shifts, although it is not
kono
parents: 63
diff changeset
577 really possible. It will then be copied to a general purpose reg. */
kono
parents: 63
diff changeset
578 return const_int_operand (op, mode) || arith_reg_operand (op, mode)
kono
parents: 63
diff changeset
579 || (TARGET_DYNSHIFT && t_reg_operand (op, mode));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581
111
kono
parents: 63
diff changeset
582 ;; Predicates for matching operands that are constant shift
kono
parents: 63
diff changeset
583 ;; amounts 1, 2, 8, 16.
kono
parents: 63
diff changeset
584 (define_predicate "p27_shift_count_operand"
kono
parents: 63
diff changeset
585 (and (match_code "const_int")
kono
parents: 63
diff changeset
586 (match_test "satisfies_constraint_P27 (op)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587
111
kono
parents: 63
diff changeset
588 (define_predicate "not_p27_shift_count_operand"
kono
parents: 63
diff changeset
589 (and (match_code "const_int")
kono
parents: 63
diff changeset
590 (match_test "! satisfies_constraint_P27 (op)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591
111
kono
parents: 63
diff changeset
592 ;; For right shifts the constant 1 is a special case because the shlr insn
kono
parents: 63
diff changeset
593 ;; clobbers the T_REG and is handled by the T_REG clobbering version of the
kono
parents: 63
diff changeset
594 ;; insn, which is also used for non-P27 shift sequences.
kono
parents: 63
diff changeset
595 (define_predicate "p27_rshift_count_operand"
kono
parents: 63
diff changeset
596 (and (match_code "const_int")
kono
parents: 63
diff changeset
597 (match_test "satisfies_constraint_P27 (op)")
kono
parents: 63
diff changeset
598 (match_test "! satisfies_constraint_M (op)")))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
111
kono
parents: 63
diff changeset
600 (define_predicate "not_p27_rshift_count_operand"
kono
parents: 63
diff changeset
601 (and (match_code "const_int")
kono
parents: 63
diff changeset
602 (ior (match_test "! satisfies_constraint_P27 (op)")
kono
parents: 63
diff changeset
603 (match_test "satisfies_constraint_M (op)"))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604
111
kono
parents: 63
diff changeset
605 ;; Returns true if OP is a symbol reference.
kono
parents: 63
diff changeset
606 (define_predicate "symbol_ref_operand"
kono
parents: 63
diff changeset
607 (match_code "symbol_ref"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 (define_predicate "bitwise_memory_operand"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 (match_code "mem")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
612 if (MEM_P (op))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 if (REG_P (XEXP (op, 0)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 if (GET_CODE (XEXP (op, 0)) == PLUS
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
618 && REG_P (XEXP (XEXP (op, 0), 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 })
111
kono
parents: 63
diff changeset
624
kono
parents: 63
diff changeset
625 ;; A predicate that matches any expression for which there is an
kono
parents: 63
diff changeset
626 ;; insn pattern that sets the T bit.
kono
parents: 63
diff changeset
627 (define_predicate "treg_set_expr"
kono
parents: 63
diff changeset
628 (match_test "sh_recog_treg_set_expr (op, mode)"))
kono
parents: 63
diff changeset
629
kono
parents: 63
diff changeset
630 ;; Same as treg_set_expr but disallow constants 0 and 1 which can be loaded
kono
parents: 63
diff changeset
631 ;; into the T bit.
kono
parents: 63
diff changeset
632 (define_predicate "treg_set_expr_not_const01"
kono
parents: 63
diff changeset
633 (and (match_test "op != const0_rtx")
kono
parents: 63
diff changeset
634 (match_test "op != const1_rtx")
kono
parents: 63
diff changeset
635 (match_operand 0 "treg_set_expr")))
kono
parents: 63
diff changeset
636
kono
parents: 63
diff changeset
637 ;; A predicate describing the T bit register in any form.
kono
parents: 63
diff changeset
638 (define_predicate "t_reg_operand"
kono
parents: 63
diff changeset
639 (match_code "reg,subreg,sign_extend,zero_extend,ne,eq")
kono
parents: 63
diff changeset
640 {
kono
parents: 63
diff changeset
641 switch (GET_CODE (op))
kono
parents: 63
diff changeset
642 {
kono
parents: 63
diff changeset
643 case EQ:
kono
parents: 63
diff changeset
644 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
kono
parents: 63
diff changeset
645 && XEXP (op, 1) == const1_rtx;
kono
parents: 63
diff changeset
646
kono
parents: 63
diff changeset
647 case NE:
kono
parents: 63
diff changeset
648 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
kono
parents: 63
diff changeset
649 && XEXP (op, 1) == const0_rtx;
kono
parents: 63
diff changeset
650
kono
parents: 63
diff changeset
651 case REG:
kono
parents: 63
diff changeset
652 return REGNO (op) == T_REG;
kono
parents: 63
diff changeset
653
kono
parents: 63
diff changeset
654 case SUBREG:
kono
parents: 63
diff changeset
655 return REG_P (SUBREG_REG (op)) && REGNO (SUBREG_REG (op)) == T_REG;
kono
parents: 63
diff changeset
656
kono
parents: 63
diff changeset
657 case ZERO_EXTEND:
kono
parents: 63
diff changeset
658 case SIGN_EXTEND:
kono
parents: 63
diff changeset
659 if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG)
kono
parents: 63
diff changeset
660 return true;
kono
parents: 63
diff changeset
661 return GET_CODE (XEXP (op, 0)) == SUBREG
kono
parents: 63
diff changeset
662 && REG_P (SUBREG_REG (XEXP (op, 0)))
kono
parents: 63
diff changeset
663 && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;
kono
parents: 63
diff changeset
664
kono
parents: 63
diff changeset
665 default:
kono
parents: 63
diff changeset
666 return 0;
kono
parents: 63
diff changeset
667 }
kono
parents: 63
diff changeset
668 })
kono
parents: 63
diff changeset
669
kono
parents: 63
diff changeset
670 ;; A predicate describing a negated T bit register.
kono
parents: 63
diff changeset
671 (define_predicate "negt_reg_operand"
kono
parents: 63
diff changeset
672 (match_code "subreg,xor,ne,eq")
kono
parents: 63
diff changeset
673 {
kono
parents: 63
diff changeset
674 switch (GET_CODE (op))
kono
parents: 63
diff changeset
675 {
kono
parents: 63
diff changeset
676 case EQ:
kono
parents: 63
diff changeset
677 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
kono
parents: 63
diff changeset
678 && XEXP (op, 1) == const0_rtx;
kono
parents: 63
diff changeset
679
kono
parents: 63
diff changeset
680 case NE:
kono
parents: 63
diff changeset
681 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
kono
parents: 63
diff changeset
682 && XEXP (op, 1) == const1_rtx;
kono
parents: 63
diff changeset
683
kono
parents: 63
diff changeset
684 case XOR:
kono
parents: 63
diff changeset
685 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
kono
parents: 63
diff changeset
686 && XEXP (op, 1) == const1_rtx;
kono
parents: 63
diff changeset
687
kono
parents: 63
diff changeset
688 case SUBREG:
kono
parents: 63
diff changeset
689 return negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
kono
parents: 63
diff changeset
690
kono
parents: 63
diff changeset
691 default:
kono
parents: 63
diff changeset
692 return 0;
kono
parents: 63
diff changeset
693 }
kono
parents: 63
diff changeset
694 })
kono
parents: 63
diff changeset
695
kono
parents: 63
diff changeset
696 ;; Returns true if OP is an operand that can be used as the first operand in
kono
parents: 63
diff changeset
697 ;; the cstoresi4 expander pattern.
kono
parents: 63
diff changeset
698 (define_predicate "cmpsi_operand"
kono
parents: 63
diff changeset
699 (and (match_code "subreg,reg,const_int")
kono
parents: 63
diff changeset
700 (ior (match_operand:SI 0 "t_reg_operand")
kono
parents: 63
diff changeset
701 (match_operand 0 "arith_operand"))))
kono
parents: 63
diff changeset
702
kono
parents: 63
diff changeset
703 ;; A predicate that returns true if OP is a valid construct around the T bit
kono
parents: 63
diff changeset
704 ;; that can be used as an operand for conditional branches.
kono
parents: 63
diff changeset
705 (define_predicate "cbranch_treg_value"
kono
parents: 63
diff changeset
706 (and (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
kono
parents: 63
diff changeset
707 (match_test "sh_eval_treg_value (op) >= 0")))
kono
parents: 63
diff changeset
708
kono
parents: 63
diff changeset
709 ;; Returns true if OP is arith_reg_operand or t_reg_operand.
kono
parents: 63
diff changeset
710 (define_predicate "arith_reg_or_t_reg_operand"
kono
parents: 63
diff changeset
711 (ior (match_operand 0 "arith_reg_operand")
kono
parents: 63
diff changeset
712 (match_operand 0 "t_reg_operand")))
kono
parents: 63
diff changeset
713
kono
parents: 63
diff changeset
714 (define_predicate "arith_reg_or_treg_set_expr"
kono
parents: 63
diff changeset
715 (ior (match_operand 0 "arith_reg_operand")
kono
parents: 63
diff changeset
716 (match_operand 0 "treg_set_expr")))
kono
parents: 63
diff changeset
717
kono
parents: 63
diff changeset
718 ;; A predicate describing the negated value of the T bit register shifted
kono
parents: 63
diff changeset
719 ;; left by 31.
kono
parents: 63
diff changeset
720 (define_predicate "negt_reg_shl31_operand"
kono
parents: 63
diff changeset
721 (match_code "plus,minus,if_then_else")
kono
parents: 63
diff changeset
722 {
kono
parents: 63
diff changeset
723 /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
kono
parents: 63
diff changeset
724 (ashift:SI (match_operand:SI 1 "t_reg_operand")
kono
parents: 63
diff changeset
725 (const_int 31)))
kono
parents: 63
diff changeset
726 */
kono
parents: 63
diff changeset
727 if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0))
kono
parents: 63
diff changeset
728 && GET_CODE (XEXP (op, 1)) == ASHIFT
kono
parents: 63
diff changeset
729 && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
kono
parents: 63
diff changeset
730 && CONST_INT_P (XEXP (XEXP (op, 1), 1))
kono
parents: 63
diff changeset
731 && INTVAL (XEXP (XEXP (op, 1), 1)) == 31)
kono
parents: 63
diff changeset
732 return true;
kono
parents: 63
diff changeset
733
kono
parents: 63
diff changeset
734 /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand")
kono
parents: 63
diff changeset
735 (const_int 31))
kono
parents: 63
diff changeset
736 (const_int -2147483648)) ;; 0xffffffff80000000
kono
parents: 63
diff changeset
737 */
kono
parents: 63
diff changeset
738 if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
kono
parents: 63
diff changeset
739 && GET_CODE (XEXP (op, 0)) == ASHIFT
kono
parents: 63
diff changeset
740 && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
kono
parents: 63
diff changeset
741 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
kono
parents: 63
diff changeset
742 && INTVAL (XEXP (XEXP (op, 0), 1)) == 31)
kono
parents: 63
diff changeset
743 return true;
kono
parents: 63
diff changeset
744
kono
parents: 63
diff changeset
745 /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
kono
parents: 63
diff changeset
746 (const_int -2147483648)) ;; 0xffffffff80000000
kono
parents: 63
diff changeset
747 (const_int -2147483648))
kono
parents: 63
diff changeset
748 */
kono
parents: 63
diff changeset
749 if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
kono
parents: 63
diff changeset
750 && GET_CODE (XEXP (op, 0)) == MULT
kono
parents: 63
diff changeset
751 && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
kono
parents: 63
diff changeset
752 && satisfies_constraint_Jhb (XEXP (XEXP (op, 0), 1)))
kono
parents: 63
diff changeset
753 return true;
kono
parents: 63
diff changeset
754
kono
parents: 63
diff changeset
755 /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
kono
parents: 63
diff changeset
756 (mult:SI (match_operand:SI 1 "t_reg_operand")
kono
parents: 63
diff changeset
757 (const_int -2147483648)))
kono
parents: 63
diff changeset
758 */
kono
parents: 63
diff changeset
759 if (GET_CODE (op) == MINUS
kono
parents: 63
diff changeset
760 && satisfies_constraint_Jhb (XEXP (op, 0))
kono
parents: 63
diff changeset
761 && GET_CODE (XEXP (op, 1)) == MULT
kono
parents: 63
diff changeset
762 && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
kono
parents: 63
diff changeset
763 && satisfies_constraint_Jhb (XEXP (XEXP (op, 1), 1)))
kono
parents: 63
diff changeset
764 return true;
kono
parents: 63
diff changeset
765
kono
parents: 63
diff changeset
766 /* (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
kono
parents: 63
diff changeset
767 (const_int 0)
kono
parents: 63
diff changeset
768 (const_int -2147483648)) ;; 0xffffffff80000000
kono
parents: 63
diff changeset
769 */
kono
parents: 63
diff changeset
770 if (GET_CODE (op) == IF_THEN_ELSE && t_reg_operand (XEXP (op, 0), SImode)
kono
parents: 63
diff changeset
771 && satisfies_constraint_Z (XEXP (op, 1))
kono
parents: 63
diff changeset
772 && satisfies_constraint_Jhb (XEXP (op, 2)))
kono
parents: 63
diff changeset
773 return true;
kono
parents: 63
diff changeset
774
kono
parents: 63
diff changeset
775 return false;
kono
parents: 63
diff changeset
776 })
kono
parents: 63
diff changeset
777
kono
parents: 63
diff changeset
778 ;; A predicate that determines whether a given constant is a valid
kono
parents: 63
diff changeset
779 ;; displacement for a GBR load/store of the specified mode.
kono
parents: 63
diff changeset
780 (define_predicate "gbr_displacement"
kono
parents: 63
diff changeset
781 (match_code "const_int")
kono
parents: 63
diff changeset
782 {
kono
parents: 63
diff changeset
783 const int mode_sz = GET_MODE_SIZE (mode);
kono
parents: 63
diff changeset
784 const int move_sz = mode_sz > GET_MODE_SIZE (SImode)
kono
parents: 63
diff changeset
785 ? GET_MODE_SIZE (SImode)
kono
parents: 63
diff changeset
786 : mode_sz;
kono
parents: 63
diff changeset
787 int max_disp = 255 * move_sz;
kono
parents: 63
diff changeset
788 if (mode_sz > move_sz)
kono
parents: 63
diff changeset
789 max_disp -= mode_sz - move_sz;
kono
parents: 63
diff changeset
790
kono
parents: 63
diff changeset
791 return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
kono
parents: 63
diff changeset
792 })
kono
parents: 63
diff changeset
793
kono
parents: 63
diff changeset
794 ;; A predicate that determines whether OP is a valid GBR addressing mode
kono
parents: 63
diff changeset
795 ;; memory reference.
kono
parents: 63
diff changeset
796 (define_predicate "gbr_address_mem"
kono
parents: 63
diff changeset
797 (match_code "mem")
kono
parents: 63
diff changeset
798 {
kono
parents: 63
diff changeset
799 rtx addr = XEXP (op, 0);
kono
parents: 63
diff changeset
800
kono
parents: 63
diff changeset
801 if (REG_P (addr) && REGNO (addr) == GBR_REG)
kono
parents: 63
diff changeset
802 return true;
kono
parents: 63
diff changeset
803 if (GET_CODE (addr) == PLUS
kono
parents: 63
diff changeset
804 && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG
kono
parents: 63
diff changeset
805 && gbr_displacement (XEXP (addr, 1), mode))
kono
parents: 63
diff changeset
806 return true;
kono
parents: 63
diff changeset
807
kono
parents: 63
diff changeset
808 return false;
kono
parents: 63
diff changeset
809 })