]>
Commit | Line | Data |
---|---|---|
526b7aee | 1 | ;; Constraint definitions for Synopsys DesignWare ARC. |
5624e564 | 2 | ;; Copyright (C) 2007-2015 Free Software Foundation, Inc. |
526b7aee SV |
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 | ;; Register constraints | |
21 | ||
22 | ; Most instructions accept arbitrary core registers for their inputs, even | |
23 | ; if the core register in question cannot be written to, like the multiply | |
fb155425 | 24 | ; result registers of ARC600. |
526b7aee SV |
25 | ; First, define a class for core registers that can be read cheaply. This |
26 | ; is most or all core registers for ARC600, but only r0-r31 for ARC700 | |
27 | (define_register_constraint "c" "CHEAP_CORE_REGS" | |
28 | "core register @code{r0}-@code{r31}, @code{ap},@code{pcl}") | |
29 | ||
30 | ; All core regs - e.g. for when we must have a way to reload a register. | |
31 | (define_register_constraint "Rac" "ALL_CORE_REGS" | |
32 | "core register @code{r0}-@code{r60}, @code{ap},@code{pcl}") | |
33 | ||
34 | ; Some core registers (.e.g lp_count) aren't general registers because they | |
35 | ; can't be used as the destination of a multi-cycle operation like | |
36 | ; load and/or multiply, yet they are still writable in the sense that | |
37 | ; register-register moves and single-cycle arithmetic (e.g "add", "and", | |
38 | ; but not "mpy") can write to them. | |
39 | (define_register_constraint "w" "WRITABLE_CORE_REGS" | |
40 | "writable core register: @code{r0}-@code{r31}, @code{r60}, nonfixed core register") | |
41 | ||
42 | (define_register_constraint "W" "MPY_WRITABLE_CORE_REGS" | |
43 | "writable core register except @code{LP_COUNT} (@code{r60}): @code{r0}-@code{r31}, nonfixed core register") | |
44 | ||
45 | (define_register_constraint "l" "LPCOUNT_REG" | |
46 | "@internal | |
47 | Loop count register @code{r60}") | |
48 | ||
49 | (define_register_constraint "x" "R0_REGS" | |
50 | "@code{R0} register.") | |
51 | ||
52 | (define_register_constraint "Rgp" "GP_REG" | |
53 | "@internal | |
54 | Global Pointer register @code{r26}") | |
55 | ||
56 | (define_register_constraint "f" "FP_REG" | |
57 | "@internal | |
58 | Frame Pointer register @code{r27}") | |
59 | ||
60 | (define_register_constraint "b" "SP_REGS" | |
61 | "@internal | |
62 | Stack Pointer register @code{r28}") | |
63 | ||
64 | (define_register_constraint "k" "LINK_REGS" | |
65 | "@internal | |
66 | Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30}, | |
67 | @code{blink}:@code{r31},") | |
68 | ||
69 | (define_register_constraint "q" "ARCOMPACT16_REGS" | |
70 | "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, | |
71 | @code{r12}-@code{r15}") | |
72 | ||
73 | (define_register_constraint "e" "AC16_BASE_REGS" | |
74 | "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory | |
75 | instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}") | |
76 | ||
77 | (define_register_constraint "D" "DOUBLE_REGS" | |
78 | "ARC FPX (dpfp) 64-bit registers. @code{D0}, @code{D1}") | |
79 | ||
80 | (define_register_constraint "d" "SIMD_DMA_CONFIG_REGS" | |
81 | "@internal | |
82 | ARC SIMD DMA configuration registers @code{di0}-@code{di7}, | |
83 | @code{do0}-@code{do7}") | |
84 | ||
85 | (define_register_constraint "v" "SIMD_VR_REGS" | |
86 | "ARC SIMD 128-bit registers @code{VR0}-@code{VR23}") | |
87 | ||
88 | ; We could allow call-saved registers for sibling calls if we restored them | |
89 | ; in the delay slot of the call. However, that would not allow to adjust the | |
90 | ; stack pointer afterwards, so the call-saved register would have to be | |
91 | ; restored from a call-used register that was just loaded with the value | |
92 | ; before. So sticking to call-used registers for sibcalls will likely | |
93 | ; generate better code overall. | |
94 | (define_register_constraint "Rsc" "SIBCALL_REGS" | |
95 | "@internal | |
96 | Sibling call register") | |
97 | ||
98 | ;; Integer constraints | |
99 | ||
100 | (define_constraint "I" | |
101 | "@internal | |
102 | A signed 12-bit integer constant." | |
103 | (and (match_code "const_int") | |
104 | (match_test "SIGNED_INT12 (ival)"))) | |
105 | ||
106 | (define_constraint "K" | |
107 | "@internal | |
108 | A 3-bit unsigned integer constant" | |
109 | (and (match_code "const_int") | |
110 | (match_test "UNSIGNED_INT3 (ival)"))) | |
111 | ||
112 | (define_constraint "L" | |
113 | "@internal | |
114 | A 6-bit unsigned integer constant" | |
115 | (and (match_code "const_int") | |
116 | (match_test "UNSIGNED_INT6 (ival)"))) | |
117 | ||
118 | (define_constraint "CnL" | |
119 | "@internal | |
120 | One's complement of a 6-bit unsigned integer constant" | |
121 | (and (match_code "const_int") | |
122 | (match_test "UNSIGNED_INT6 (~ival)"))) | |
123 | ||
124 | (define_constraint "CmL" | |
125 | "@internal | |
126 | Two's complement of a 6-bit unsigned integer constant" | |
127 | (and (match_code "const_int") | |
128 | (match_test "UNSIGNED_INT6 (-ival)"))) | |
129 | ||
130 | (define_constraint "M" | |
131 | "@internal | |
132 | A 5-bit unsigned integer constant" | |
133 | (and (match_code "const_int") | |
134 | (match_test "UNSIGNED_INT5 (ival)"))) | |
135 | ||
136 | (define_constraint "N" | |
137 | "@internal | |
138 | Integer constant 1" | |
139 | (and (match_code "const_int") | |
140 | (match_test "IS_ONE (ival)"))) | |
141 | ||
142 | (define_constraint "O" | |
143 | "@internal | |
144 | A 7-bit unsigned integer constant" | |
145 | (and (match_code "const_int") | |
146 | (match_test "UNSIGNED_INT7 (ival)"))) | |
147 | ||
148 | (define_constraint "P" | |
149 | "@internal | |
150 | An 8-bit unsigned integer constant" | |
151 | (and (match_code "const_int") | |
152 | (match_test "UNSIGNED_INT8 (ival)"))) | |
153 | ||
154 | (define_constraint "C_0" | |
155 | "@internal | |
156 | Zero" | |
157 | (and (match_code "const_int") | |
158 | (match_test "ival == 0"))) | |
159 | ||
160 | (define_constraint "Cn0" | |
161 | "@internal | |
162 | Negative or zero" | |
163 | (and (match_code "const_int") | |
164 | (match_test "ival <= 0"))) | |
165 | ||
166 | (define_constraint "Cca" | |
167 | "@internal | |
168 | Conditional or three-address add / sub constant" | |
169 | (and (match_code "const_int") | |
c419f71c | 170 | (match_test "ival == (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 31) |
526b7aee SV |
171 | || (ival >= -0x1f8 && ival <= 0x1f8 |
172 | && ((ival >= 0 ? ival : -ival) | |
173 | <= 0x3f * (ival & -ival)))"))) | |
174 | ||
175 | ; intersection of "O" and "Cca". | |
176 | (define_constraint "CL2" | |
177 | "@internal | |
178 | A 6-bit unsigned integer constant times 2" | |
179 | (and (match_code "const_int") | |
180 | (match_test "!(ival & ~126)"))) | |
181 | ||
182 | (define_constraint "CM4" | |
183 | "@internal | |
184 | A 5-bit unsigned integer constant times 4" | |
185 | (and (match_code "const_int") | |
186 | (match_test "!(ival & ~124)"))) | |
187 | ||
188 | (define_constraint "Csp" | |
189 | "@internal | |
190 | A valid stack pointer offset for a short add" | |
191 | (and (match_code "const_int") | |
192 | (match_test "!(ival & ~124) || !(-ival & ~124)"))) | |
193 | ||
194 | (define_constraint "C2a" | |
195 | "@internal | |
196 | Unconditional two-address add / sub constant" | |
197 | (and (match_code "const_int") | |
4e671509 | 198 | (match_test "ival == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31) |
526b7aee SV |
199 | || (ival >= -0x4000 && ival <= 0x4000 |
200 | && ((ival >= 0 ? ival : -ival) | |
201 | <= 0x7ff * (ival & -ival)))"))) | |
202 | ||
203 | (define_constraint "C0p" | |
204 | "@internal | |
205 | power of two" | |
206 | (and (match_code "const_int") | |
207 | (match_test "IS_POWEROF2_P (ival)"))) | |
208 | ||
209 | (define_constraint "C1p" | |
210 | "@internal | |
211 | constant such that x+1 is a power of two, and x != 0" | |
212 | (and (match_code "const_int") | |
213 | (match_test "ival && IS_POWEROF2_P (ival + 1)"))) | |
214 | ||
215 | (define_constraint "Ccp" | |
216 | "@internal | |
217 | constant such that ~x (one's Complement) is a power of two" | |
218 | (and (match_code "const_int") | |
219 | (match_test "IS_POWEROF2_P (~ival)"))) | |
220 | ||
221 | (define_constraint "Cux" | |
222 | "@internal | |
223 | constant such that AND gives an unsigned extension" | |
224 | (and (match_code "const_int") | |
225 | (match_test "ival == 0xff || ival == 0xffff"))) | |
226 | ||
227 | (define_constraint "Crr" | |
228 | "@internal | |
229 | constant that can be loaded with ror b,u6" | |
230 | (and (match_code "const_int") | |
231 | (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()"))) | |
232 | ||
233 | ;; Floating-point constraints | |
234 | ||
235 | (define_constraint "G" | |
236 | "@internal | |
237 | A 32-bit constant double value" | |
238 | (and (match_code "const_double") | |
239 | (match_test "arc_double_limm_p (op)"))) | |
240 | ||
241 | (define_constraint "H" | |
242 | "@internal | |
243 | All const_double values (including 64-bit values)" | |
244 | (and (match_code "const_double") | |
245 | (match_test "1"))) | |
246 | ||
247 | ;; Memory constraints | |
248 | (define_memory_constraint "T" | |
249 | "@internal | |
250 | A valid memory operand for ARCompact load instructions" | |
251 | (and (match_code "mem") | |
252 | (match_test "compact_load_memory_operand (op, VOIDmode)"))) | |
253 | ||
254 | (define_memory_constraint "S" | |
255 | "@internal | |
256 | A valid memory operand for ARCompact store instructions" | |
257 | (and (match_code "mem") | |
258 | (match_test "compact_store_memory_operand (op, VOIDmode)"))) | |
259 | ||
260 | (define_memory_constraint "Usd" | |
261 | "@internal | |
262 | A valid _small-data_ memory operand for ARCompact instructions" | |
263 | (and (match_code "mem") | |
264 | (match_test "compact_sda_memory_operand (op, VOIDmode)"))) | |
265 | ||
266 | (define_memory_constraint "Usc" | |
267 | "@internal | |
268 | A valid memory operand for storing constants" | |
269 | (and (match_code "mem") | |
270 | (match_test "!CONSTANT_P (XEXP (op,0))") | |
271 | ;; ??? the assembler rejects stores of immediates to small data. | |
272 | (match_test "!compact_sda_memory_operand (op, VOIDmode)"))) | |
273 | ||
274 | (define_memory_constraint "Us<" | |
275 | "@internal | |
276 | Stack pre-decrement" | |
277 | (and (match_code "mem") | |
278 | (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC") | |
279 | (match_test "REG_P (XEXP (XEXP (op, 0), 0))") | |
280 | (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))) | |
281 | ||
282 | (define_memory_constraint "Us>" | |
283 | "@internal | |
284 | Stack post-increment" | |
285 | (and (match_code "mem") | |
286 | (match_test "GET_CODE (XEXP (op, 0)) == POST_INC") | |
287 | (match_test "REG_P (XEXP (XEXP (op, 0), 0))") | |
288 | (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))) | |
289 | ||
290 | ;; General constraints | |
291 | ||
292 | (define_constraint "Cbr" | |
293 | "Branch destination" | |
294 | (ior (and (match_code "symbol_ref") | |
295 | (match_test "!arc_is_longcall_p (op)")) | |
296 | (match_code "label_ref"))) | |
297 | ||
298 | (define_constraint "Cbp" | |
299 | "predicable branch/call destination" | |
300 | (ior (and (match_code "symbol_ref") | |
301 | (match_test "arc_is_shortcall_p (op)")) | |
302 | (match_code "label_ref"))) | |
303 | ||
304 | (define_constraint "Cpc" | |
305 | "pc-relative constant" | |
306 | (match_test "arc_legitimate_pc_offset_p (op)")) | |
307 | ||
308 | (define_constraint "Clb" | |
309 | "label" | |
310 | (and (match_code "label_ref") | |
b32d5189 | 311 | (match_test "arc_text_label (as_a <rtx_insn *> (XEXP (op, 0)))"))) |
526b7aee SV |
312 | |
313 | (define_constraint "Cal" | |
314 | "constant for arithmetic/logical operations" | |
315 | (match_test "immediate_operand (op, VOIDmode) && !arc_legitimate_pc_offset_p (op)")) | |
316 | ||
317 | (define_constraint "C32" | |
318 | "32 bit constant for arithmetic/logical operations" | |
319 | (match_test "immediate_operand (op, VOIDmode) | |
320 | && !arc_legitimate_pc_offset_p (op) | |
321 | && !satisfies_constraint_I (op)")) | |
322 | ||
323 | ; Note that the 'cryptic' register constraints will not make reload use the | |
324 | ; associated class to reload into, but this will not penalize reloading of any | |
325 | ; other operands, or using an alternate part of the same alternative. | |
326 | ||
327 | ; Rcq is different in three important ways from a register class constraint: | |
328 | ; - It does not imply a register class, hence reload will not use it to drive | |
329 | ; reloads. | |
330 | ; - It matches even when there is no register class to describe its accepted | |
331 | ; set; not having such a set again lessens the impact on register allocation. | |
332 | ; - It won't match when the instruction is conditionalized by the ccfsm. | |
333 | (define_constraint "Rcq" | |
334 | "@internal | |
335 | Cryptic q - for short insn generation while not affecting register allocation | |
336 | Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, | |
337 | @code{r12}-@code{r15}" | |
8da140e0 | 338 | (and (match_code "reg") |
526b7aee SV |
339 | (match_test "TARGET_Rcq |
340 | && !arc_ccfsm_cond_exec_p () | |
036def0f | 341 | && IN_RANGE (REGNO (op) ^ 4, 4, 11)"))) |
526b7aee SV |
342 | |
343 | ; If we need a reload, we generally want to steer reload to use three-address | |
344 | ; alternatives in preference of two-address alternatives, unless the | |
345 | ; three-address alternative introduces a LIMM that is unnecessary for the | |
346 | ; two-address alternative. | |
347 | (define_constraint "Rcw" | |
348 | "@internal | |
349 | Cryptic w - for use in early alternatives with matching constraint" | |
8da140e0 | 350 | (and (match_code "reg") |
526b7aee SV |
351 | (match_test |
352 | "TARGET_Rcw | |
353 | && REGNO (op) < FIRST_PSEUDO_REGISTER | |
354 | && TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], | |
355 | REGNO (op))"))) | |
356 | ||
357 | (define_constraint "Rcr" | |
358 | "@internal | |
359 | Cryptic r - for use in early alternatives with matching constraint" | |
8da140e0 | 360 | (and (match_code "reg") |
526b7aee SV |
361 | (match_test |
362 | "TARGET_Rcw | |
363 | && REGNO (op) < FIRST_PSEUDO_REGISTER | |
364 | && TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], | |
365 | REGNO (op))"))) | |
366 | ||
367 | (define_constraint "Rcb" | |
368 | "@internal | |
369 | Stack Pointer register @code{r28} - do not reload into its class" | |
8da140e0 | 370 | (and (match_code "reg") |
526b7aee SV |
371 | (match_test "REGNO (op) == 28"))) |
372 | ||
373 | (define_constraint "Rck" | |
374 | "@internal | |
375 | blink (usful for push_s / pop_s)" | |
8da140e0 | 376 | (and (match_code "reg") |
526b7aee SV |
377 | (match_test "REGNO (op) == 31"))) |
378 | ||
379 | (define_constraint "Rs5" | |
380 | "@internal | |
381 | sibcall register - only allow one of the five available 16 bit isnsn. | |
382 | Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, | |
383 | @code{r12}" | |
8da140e0 | 384 | (and (match_code "reg") |
526b7aee SV |
385 | (match_test "!arc_ccfsm_cond_exec_p ()") |
386 | (ior (match_test "(unsigned) REGNO (op) <= 3") | |
387 | (match_test "REGNO (op) == 12")))) | |
388 | ||
389 | (define_constraint "Rcc" | |
390 | "@internal | |
391 | Condition Codes" | |
8da140e0 | 392 | (and (match_code "reg") (match_test "cc_register (op, VOIDmode)"))) |
526b7aee SV |
393 | |
394 | ||
395 | (define_constraint "Q" | |
396 | "@internal | |
397 | Integer constant zero" | |
398 | (and (match_code "const_int") | |
399 | (match_test "IS_ZERO (ival)"))) |