]>
Commit | Line | Data |
---|---|---|
80ad92e9 | 1 | ;; Predicate definitions for Vitesse IQ2000. |
2f83c7d6 | 2 | ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc. |
80ad92e9 KH |
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 | |
2f83c7d6 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
80ad92e9 KH |
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 | |
2f83c7d6 NC |
17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. | |
80ad92e9 | 19 | |
a7b376ee | 20 | ;; Return 1 if OP can be used as an operand where a register or 16-bit |
80ad92e9 KH |
21 | ;; unsigned integer is needed. |
22 | ||
23 | (define_predicate "uns_arith_operand" | |
24 | (match_code "reg,const_int,subreg") | |
25 | { | |
26 | if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op)) | |
27 | return 1; | |
28 | ||
29 | return register_operand (op, mode); | |
30 | }) | |
31 | ||
a7b376ee | 32 | ;; Return 1 if OP can be used as an operand where a 16-bit integer is |
80ad92e9 KH |
33 | ;; needed. |
34 | ||
35 | (define_predicate "arith_operand" | |
36 | (match_code "reg,const_int,subreg") | |
37 | { | |
38 | if (GET_CODE (op) == CONST_INT && SMALL_INT (op)) | |
39 | return 1; | |
40 | ||
41 | return register_operand (op, mode); | |
42 | }) | |
43 | ||
44 | ;; Return 1 if OP is a integer which fits in 16 bits. | |
45 | ||
46 | (define_predicate "small_int" | |
47 | (match_code "const_int") | |
48 | { | |
49 | return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); | |
50 | }) | |
51 | ||
a7b376ee | 52 | ;; Return 1 if OP is a 32-bit integer which is too big to be loaded |
80ad92e9 KH |
53 | ;; with one instruction. |
54 | ||
55 | (define_predicate "large_int" | |
56 | (match_code "const_int") | |
57 | { | |
58 | HOST_WIDE_INT value; | |
59 | ||
60 | if (GET_CODE (op) != CONST_INT) | |
61 | return 0; | |
62 | ||
63 | value = INTVAL (op); | |
64 | ||
65 | /* IOR reg,$r0,value. */ | |
66 | if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0) | |
67 | return 0; | |
68 | ||
69 | /* SUBU reg,$r0,value. */ | |
70 | if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767) | |
71 | return 0; | |
72 | ||
73 | /* LUI reg,value >> 16. */ | |
74 | if ((value & 0x0000ffff) == 0) | |
75 | return 0; | |
76 | ||
77 | return 1; | |
78 | }) | |
79 | ||
80 | ;; Return 1 if OP is a register or the constant 0. | |
81 | ||
82 | (define_predicate "reg_or_0_operand" | |
83 | (match_code "reg,const_int,const_double,subreg") | |
84 | { | |
85 | switch (GET_CODE (op)) | |
86 | { | |
87 | case CONST_INT: | |
88 | return INTVAL (op) == 0; | |
89 | ||
90 | case CONST_DOUBLE: | |
91 | return op == CONST0_RTX (mode); | |
92 | ||
93 | case REG: | |
94 | case SUBREG: | |
95 | return register_operand (op, mode); | |
96 | ||
97 | default: | |
98 | break; | |
99 | } | |
100 | ||
101 | return 0; | |
102 | }) | |
103 | ||
104 | ;; Return 1 if OP is a memory operand that fits in a single | |
105 | ;; instruction (i.e., register + small offset). | |
106 | ||
107 | (define_predicate "simple_memory_operand" | |
108 | (match_code "mem,subreg") | |
109 | { | |
110 | rtx addr, plus0, plus1; | |
111 | ||
112 | /* Eliminate non-memory operations. */ | |
113 | if (GET_CODE (op) != MEM) | |
114 | return 0; | |
115 | ||
116 | /* Dword operations really put out 2 instructions, so eliminate them. */ | |
117 | if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD) | |
118 | return 0; | |
119 | ||
120 | /* Decode the address now. */ | |
121 | addr = XEXP (op, 0); | |
122 | switch (GET_CODE (addr)) | |
123 | { | |
124 | case REG: | |
125 | case LO_SUM: | |
126 | return 1; | |
127 | ||
128 | case CONST_INT: | |
129 | return SMALL_INT (addr); | |
130 | ||
131 | case PLUS: | |
132 | plus0 = XEXP (addr, 0); | |
133 | plus1 = XEXP (addr, 1); | |
134 | if (GET_CODE (plus0) == REG | |
135 | && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1) | |
136 | && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */) | |
137 | return 1; | |
138 | ||
139 | else if (GET_CODE (plus1) == REG | |
140 | && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0) | |
141 | && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */) | |
142 | return 1; | |
143 | ||
144 | else | |
145 | return 0; | |
146 | ||
147 | case SYMBOL_REF: | |
148 | return 0; | |
149 | ||
150 | default: | |
151 | break; | |
152 | } | |
153 | ||
154 | return 0; | |
155 | }) | |
156 | ||
157 | ;; Return nonzero if the code of this rtx pattern is EQ or NE. | |
158 | ||
159 | (define_predicate "equality_op" | |
160 | (match_code "eq,ne") | |
161 | { | |
162 | if (mode != GET_MODE (op)) | |
163 | return 0; | |
164 | ||
165 | return GET_CODE (op) == EQ || GET_CODE (op) == NE; | |
166 | }) | |
167 | ||
168 | ;; Return nonzero if the code is a relational operations (EQ, LE, | |
169 | ;; etc). | |
170 | ||
171 | (define_predicate "cmp_op" | |
172 | (match_code "eq,ne,gt,ge,gtu,geu,lt,le,ltu,leu") | |
173 | { | |
174 | if (mode != GET_MODE (op)) | |
175 | return 0; | |
176 | ||
177 | return COMPARISON_P (op); | |
178 | }) | |
179 | ||
180 | ;; Return nonzero if the operand is either the PC or a label_ref. | |
181 | ||
182 | (define_special_predicate "pc_or_label_operand" | |
183 | (match_code "pc,label_ref") | |
184 | { | |
185 | if (op == pc_rtx) | |
186 | return 1; | |
187 | ||
188 | if (GET_CODE (op) == LABEL_REF) | |
189 | return 1; | |
190 | ||
191 | return 0; | |
192 | }) | |
193 | ||
194 | ;; Return nonzero if OP is a valid operand for a call instruction. | |
195 | ||
196 | (define_predicate "call_insn_operand" | |
197 | (match_code "const_int,const,symbol_ref,reg") | |
198 | { | |
199 | return (CONSTANT_ADDRESS_P (op) | |
200 | || (GET_CODE (op) == REG && op != arg_pointer_rtx | |
201 | && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
202 | && REGNO (op) <= LAST_VIRTUAL_REGISTER))); | |
203 | }) | |
204 | ||
205 | ;; Return nonzero if OP is valid as a source operand for a move | |
206 | ;; instruction. | |
207 | ||
208 | (define_predicate "move_operand" | |
209 | (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem") | |
210 | { | |
211 | /* Accept any general operand after reload has started; doing so | |
212 | avoids losing if reload does an in-place replacement of a register | |
213 | with a SYMBOL_REF or CONST. */ | |
214 | return (general_operand (op, mode) | |
215 | && (! (iq2000_check_split (op, mode)) | |
216 | || reload_in_progress || reload_completed)); | |
217 | }) | |
218 | ||
219 | ;; Return nonzero if OP is a constant power of 2. | |
220 | ||
221 | (define_predicate "power_of_2_operand" | |
222 | (match_code "const_int") | |
223 | { | |
224 | int intval; | |
225 | ||
226 | if (GET_CODE (op) != CONST_INT) | |
227 | return 0; | |
228 | else | |
229 | intval = INTVAL (op); | |
230 | ||
231 | return ((intval & ((unsigned)(intval) - 1)) == 0); | |
232 | }) |