0
|
1 ;; Predicate definitions for Motorola 68HC11 and 68HC12.
|
|
2 ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
|
3 ;;
|
|
4 ;; This file is part of GCC.
|
|
5 ;;
|
|
6 ;; GCC is free software; you can redistribute it and/or modify
|
|
7 ;; it under the terms of the GNU General Public License as published by
|
|
8 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
9 ;; any later version.
|
|
10 ;;
|
|
11 ;; GCC is distributed in the hope that it will be useful,
|
|
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 ;; GNU General Public License for more details.
|
|
15 ;;
|
|
16 ;; You should have received a copy of the GNU General Public License
|
|
17 ;; along with GCC; see the file COPYING3. If not see
|
|
18 ;; <http://www.gnu.org/licenses/>.
|
|
19
|
|
20 ;; TODO: Add a comment here.
|
|
21
|
|
22 (define_predicate "stack_register_operand"
|
|
23 (match_code "subreg,reg")
|
|
24 {
|
|
25 return SP_REG_P (op);
|
|
26 })
|
|
27
|
|
28 ;; TODO: Add a comment here.
|
|
29
|
|
30 (define_predicate "d_register_operand"
|
|
31 (match_code "subreg,reg")
|
|
32 {
|
|
33 if (GET_MODE (op) != mode && mode != VOIDmode)
|
|
34 return 0;
|
|
35
|
|
36 if (GET_CODE (op) == SUBREG)
|
|
37 op = XEXP (op, 0);
|
|
38
|
|
39 return GET_CODE (op) == REG
|
|
40 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
|
41 || REGNO (op) == HARD_D_REGNUM
|
|
42 || (mode == QImode && REGNO (op) == HARD_B_REGNUM));
|
|
43 })
|
|
44
|
|
45 ;; TODO: Add a comment here.
|
|
46
|
|
47 (define_predicate "hard_addr_reg_operand"
|
|
48 (match_code "subreg,reg")
|
|
49 {
|
|
50 if (GET_MODE (op) != mode && mode != VOIDmode)
|
|
51 return 0;
|
|
52
|
|
53 if (GET_CODE (op) == SUBREG)
|
|
54 op = XEXP (op, 0);
|
|
55
|
|
56 return GET_CODE (op) == REG
|
|
57 && (REGNO (op) == HARD_X_REGNUM
|
|
58 || REGNO (op) == HARD_Y_REGNUM
|
|
59 || REGNO (op) == HARD_Z_REGNUM);
|
|
60 })
|
|
61
|
|
62 ;; TODO: Add a comment here.
|
|
63
|
|
64 (define_predicate "hard_reg_operand"
|
|
65 (match_code "subreg,reg")
|
|
66 {
|
|
67 if (GET_MODE (op) != mode && mode != VOIDmode)
|
|
68 return 0;
|
|
69
|
|
70 if (GET_CODE (op) == SUBREG)
|
|
71 op = XEXP (op, 0);
|
|
72
|
|
73 return GET_CODE (op) == REG
|
|
74 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
|
75 || H_REGNO_P (REGNO (op)));
|
|
76 })
|
|
77
|
|
78 ;; TODO: Add a comment here.
|
|
79
|
|
80 (define_predicate "m68hc11_logical_operator"
|
|
81 (match_code "and,ior,xor")
|
|
82 {
|
|
83 return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
|
|
84 })
|
|
85
|
|
86 ;; TODO: Add a comment here.
|
|
87
|
|
88 (define_predicate "m68hc11_arith_operator"
|
|
89 (match_code "and,ior,xor,plus,minus,ashift,ashiftrt,lshiftrt,rotate,rotatert")
|
|
90 {
|
|
91 return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR
|
|
92 || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS
|
|
93 || GET_CODE (op) == ASHIFT || GET_CODE (op) == ASHIFTRT
|
|
94 || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ROTATE
|
|
95 || GET_CODE (op) == ROTATERT;
|
|
96 })
|
|
97
|
|
98 ;; TODO: Add a comment here.
|
|
99
|
|
100 (define_predicate "m68hc11_non_shift_operator"
|
|
101 (match_code "and,ior,xor,plus,minus")
|
|
102 {
|
|
103 return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR
|
|
104 || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS;
|
|
105 })
|
|
106
|
|
107 ;; TODO: Add a comment here.
|
|
108
|
|
109 (define_predicate "m68hc11_unary_operator"
|
|
110 (match_code "neg,not,sign_extend,zero_extend")
|
|
111 {
|
|
112 return GET_CODE (op) == NEG || GET_CODE (op) == NOT
|
|
113 || GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
|
|
114 })
|
|
115
|
|
116 ;; Return true if op is a shift operator.
|
|
117
|
|
118 (define_predicate "m68hc11_shift_operator"
|
|
119 (match_code "ashift,ashiftrt,lshiftrt,rotate,rotatert")
|
|
120 {
|
|
121 return GET_CODE (op) == ROTATE || GET_CODE (op) == ROTATERT
|
|
122 || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFT
|
|
123 || GET_CODE (op) == ASHIFTRT;
|
|
124 })
|
|
125
|
|
126 ;; TODO: Add a comment here.
|
|
127
|
|
128 (define_predicate "m68hc11_eq_compare_operator"
|
|
129 (match_code "eq,ne")
|
|
130 {
|
|
131 return GET_CODE (op) == EQ || GET_CODE (op) == NE;
|
|
132 })
|
|
133
|
|
134 ;; TODO: Add a comment here.
|
|
135
|
|
136 (define_predicate "non_push_operand"
|
|
137 (match_code "subreg,reg,mem")
|
|
138 {
|
|
139 if (general_operand (op, mode) == 0)
|
|
140 return 0;
|
|
141
|
|
142 if (push_operand (op, mode) == 1)
|
|
143 return 0;
|
|
144 return 1;
|
|
145 })
|
|
146
|
|
147 ;; TODO: Add a comment here.
|
|
148
|
|
149 (define_predicate "splitable_operand"
|
|
150 (match_code "subreg,reg,mem,symbol_ref,label_ref,const_int,const_double")
|
|
151 {
|
|
152 if (general_operand (op, mode) == 0)
|
|
153 return 0;
|
|
154
|
|
155 if (push_operand (op, mode) == 1)
|
|
156 return 0;
|
|
157
|
|
158 /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand
|
|
159 need to split such addresses to access the low and high part but it
|
|
160 is not possible to express a valid address for the low part. */
|
|
161 if (mode != QImode && GET_CODE (op) == MEM
|
|
162 && GET_CODE (XEXP (op, 0)) == MEM)
|
|
163 return 0;
|
|
164 return 1;
|
|
165 })
|
|
166
|
|
167 ;; TODO: Add a comment here.
|
|
168
|
|
169 (define_predicate "reg_or_some_mem_operand"
|
|
170 (match_code "subreg,reg,mem")
|
|
171 {
|
|
172 if (GET_CODE (op) == MEM)
|
|
173 {
|
|
174 rtx op0 = XEXP (op, 0);
|
|
175 int addr_mode;
|
|
176
|
|
177 if (symbolic_memory_operand (op0, mode))
|
|
178 return 1;
|
|
179
|
|
180 if (IS_STACK_PUSH (op))
|
|
181 return 1;
|
|
182
|
|
183 if (GET_CODE (op) == REG && reload_in_progress
|
|
184 && REGNO (op) >= FIRST_PSEUDO_REGISTER
|
|
185 && reg_equiv_memory_loc[REGNO (op)])
|
|
186 {
|
|
187 op = reg_equiv_memory_loc[REGNO (op)];
|
|
188 op = eliminate_regs (op, 0, NULL_RTX);
|
|
189 }
|
|
190 if (GET_CODE (op) != MEM)
|
|
191 return 0;
|
|
192
|
|
193 op0 = XEXP (op, 0);
|
|
194 addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
|
|
195 addr_mode &= ~ADDR_INDIRECT;
|
|
196 return m68hc11_valid_addressing_p (op0, mode, addr_mode);
|
|
197 }
|
|
198
|
|
199 return register_operand (op, mode);
|
|
200 })
|
|
201
|
|
202 ;; TODO: Add a comment here.
|
|
203
|
|
204 (define_predicate "tst_operand"
|
|
205 (match_code "subreg,reg,mem")
|
|
206 {
|
|
207 if (GET_CODE (op) == MEM && reload_completed == 0)
|
|
208 {
|
|
209 rtx addr = XEXP (op, 0);
|
|
210 if (m68hc11_auto_inc_p (addr))
|
|
211 return 0;
|
|
212 }
|
|
213 return nonimmediate_operand (op, mode);
|
|
214 })
|
|
215
|
|
216 ;; TODO: Add a comment here.
|
|
217
|
|
218 (define_predicate "cmp_operand"
|
|
219 (match_code "subreg,reg,mem,symbol_ref,label_ref,const_int,const_double")
|
|
220 {
|
|
221 if (GET_CODE (op) == MEM)
|
|
222 {
|
|
223 rtx addr = XEXP (op, 0);
|
|
224 if (m68hc11_auto_inc_p (addr))
|
|
225 return 0;
|
|
226 }
|
|
227 return general_operand (op, mode);
|
|
228 })
|