386BSD 0.0 development
[unix-history] / usr / src / usr.bin / gcc / cc1 / recog.c
CommitLineData
bac2423a
WJ
1/* Subroutines used by or related to instruction recognition.
2 Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "rtl.h"
23#include <stdio.h>
24#include "insn-config.h"
25#include "recog.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29
30
31static int inequality_comparisons_p ();
32int strict_memory_address_p ();
33int memory_address_p ();
34
35/* Nonzero means allow operands to be volatile.
36 This is 1 if you use recog_memoized, 0 if you don't.
37 init_recog and recog_memoized are responsible for setting it.
38 This way of handling it is not really clean and will be change later. */
39
40int volatile_ok;
41
42rtx recog_addr_dummy;
43
44/* On return from `constrain_operands', indicate which alternative
45 was satisfied. */
46
47int which_alternative;
48
49/* Nonzero after end of reload pass.
50 Set to 1 or 0 by toplev.c.
51 Controls the significance of (SUBREG (MEM)). */
52
53int reload_completed;
54
55/* Initialize data used by the function `recog'.
56 This must be called once in the compilation of a function
57 before any insn recognition may be done in the function. */
58
59void
60init_recog ()
61{
62 volatile_ok = 0;
63 recog_addr_dummy = gen_rtx (MEM, VOIDmode, 0);
64}
65
66/* Try recognizing the instruction INSN,
67 and return the code number that results.
68 Remeber the code so that repeated calls do not
69 need to spend the time for actual rerecognition.
70
71 This function is the normal interface to instruction recognition.
72 The automatically-generated function `recog' is normally called
73 through this one. (The only exception is in combine.c.) */
74
75int
76recog_memoized (insn)
77 rtx insn;
78{
79 volatile_ok = 1;
80 if (INSN_CODE (insn) < 0)
81 INSN_CODE (insn) = recog (PATTERN (insn), insn);
82 return INSN_CODE (insn);
83}
84\f
85/* Return 1 if the insn following INSN does not contain
86 any ordered tests applied to the condition codes.
87 EQ and NE tests do not count. */
88
89int
90next_insn_tests_no_inequality (insn)
91 rtx insn;
92{
93 register rtx next = NEXT_INSN (insn);
94
95 return ((GET_CODE (next) == JUMP_INSN
96 || GET_CODE (next) == INSN
97 || GET_CODE (next) == CALL_INSN)
98 && ! inequality_comparisons_p (PATTERN (next)));
99}
100
101/* Return 1 if the CC value set up by INSN is not used. */
102
103int
104next_insns_test_no_inequality (insn)
105 rtx insn;
106{
107 register rtx next = NEXT_INSN (insn);
108
109 for (; next != 0; next = NEXT_INSN (next))
110 {
111 if (GET_CODE (next) == CODE_LABEL
112 || GET_CODE (next) == BARRIER)
113 return 1;
114 if (GET_CODE (next) == NOTE)
115 continue;
116 if (inequality_comparisons_p (PATTERN (next)))
117 return 0;
118 if (GET_CODE (PATTERN (next)) == SET
119 && SET_DEST (PATTERN (next)) == cc0_rtx)
120 return 1;
121 if (! reg_mentioned_p (cc0_rtx, PATTERN (next)))
122 return 1;
123 }
124 return 1;
125}
126
127static int
128inequality_comparisons_p (x)
129 rtx x;
130{
131 register char *fmt;
132 register int len, i;
133 register enum rtx_code code = GET_CODE (x);
134
135 switch (code)
136 {
137 case REG:
138 case PC:
139 case CC0:
140 case CONST_INT:
141 case CONST_DOUBLE:
142 case CONST:
143 case LABEL_REF:
144 case SYMBOL_REF:
145 return 0;
146
147 case LT:
148 case LTU:
149 case GT:
150 case GTU:
151 case LE:
152 case LEU:
153 case GE:
154 case GEU:
155 return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
156 }
157
158 len = GET_RTX_LENGTH (code);
159 fmt = GET_RTX_FORMAT (code);
160
161 for (i = 0; i < len; i++)
162 {
163 if (fmt[i] == 'e')
164 {
165 if (inequality_comparisons_p (XEXP (x, i)))
166 return 1;
167 }
168 else if (fmt[i] == 'E')
169 {
170 register int j;
171 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
172 if (inequality_comparisons_p (XVECEXP (x, i, j)))
173 return 1;
174 }
175 }
176
177 return 0;
178}
179\f
180/* Return 1 if OP is a valid general operand for machine mode MODE.
181 This is either a register reference, a memory reference,
182 or a constant. In the case of a memory reference, the address
183 is checked for general validity for the target machine.
184
185 Register and memory references must have mode MODE in order to be valid,
186 but some constants have no machine mode and are valid for any mode.
187
188 If MODE is VOIDmode, OP is checked for validity for whatever mode
189 it has.
190
191 The main use of this function is as a predicate in match_operand
192 expressions in the machine description. */
193
194int
195general_operand (op, mode)
196 register rtx op;
197 enum machine_mode mode;
198{
199 register enum rtx_code code = GET_CODE (op);
200 int mode_altering_drug = 0;
201
202 if (mode == VOIDmode)
203 mode = GET_MODE (op);
204
205 if (CONSTANT_P (op))
206 return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
207 && LEGITIMATE_CONSTANT_P (op));
208
209 /* Except for certain constants with VOIDmode, already checked for,
210 OP's mode must match MODE if MODE specifies a mode. */
211
212 if (GET_MODE (op) != mode)
213 return 0;
214
215 while (code == SUBREG)
216 {
217 op = SUBREG_REG (op);
218 code = GET_CODE (op);
219#if 0
220 /* No longer needed, since (SUBREG (MEM...))
221 will load the MEM into a reload reg in the MEM's own mode. */
222 mode_altering_drug = 1;
223#endif
224 }
225 if (code == REG)
226 return 1;
227 if (code == CONST_DOUBLE)
228 return LEGITIMATE_CONSTANT_P (op);
229 if (code == MEM)
230 {
231 register rtx y = XEXP (op, 0);
232 if (! volatile_ok && MEM_VOLATILE_P (op))
233 return 0;
234 /* Use the mem's mode, since it will be reloaded thus. */
235 mode = GET_MODE (op);
236 GO_IF_LEGITIMATE_ADDRESS (mode, y, win);
237 }
238 return 0;
239
240 win:
241 if (mode_altering_drug)
242 return ! mode_dependent_address_p (XEXP (op, 0));
243 return 1;
244}
245\f
246/* Return 1 if OP is a valid memory address for a memory reference
247 of mode MODE.
248
249 The main use of this function is as a predicate in match_operand
250 expressions in the machine description. */
251
252int
253address_operand (op, mode)
254 register rtx op;
255 enum machine_mode mode;
256{
257 return (memory_address_p (mode, op)
258 && (GET_CODE (op) != MEM || !MEM_VOLATILE_P (op) || volatile_ok));
259}
260
261/* Return 1 if OP is a register reference of mode MODE.
262 If MODE is VOIDmode, accept a register in any mode.
263
264 The main use of this function is as a predicate in match_operand
265 expressions in the machine description. */
266
267int
268register_operand (op, mode)
269 register rtx op;
270 enum machine_mode mode;
271{
272 if (GET_MODE (op) != mode && mode != VOIDmode)
273 return 0;
274
275 if (GET_CODE (op) == SUBREG)
276 {
277 /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
278 because it is guaranteed to be reloaded into one.
279 Just make sure the MEM is valid in itself.
280 (Ideally, (SUBREG (MEM)...) should not exist after reload,
281 but currently it does result from (SUBREG (REG)...) where the
282 reg went on the stack.) */
283 if (! reload_completed)
284 return general_operand (op, mode);
285 }
286
287 while (GET_CODE (op) == SUBREG)
288 op = SUBREG_REG (op);
289
290 return GET_CODE (op) == REG;
291}
292
293/* Return 1 if OP is a valid immediate operand for mode MODE.
294
295 The main use of this function is as a predicate in match_operand
296 expressions in the machine description. */
297
298int
299immediate_operand (op, mode)
300 register rtx op;
301 enum machine_mode mode;
302{
303 return ((CONSTANT_P (op)
304 || (GET_CODE (op) == CONST_DOUBLE
305 && (GET_MODE (op) == mode || mode == VOIDmode)))
306 && LEGITIMATE_CONSTANT_P (op));
307}
308
309/* Return 1 if OP is a general operand that is not an immediate operand. */
310
311int
312nonimmediate_operand (op, mode)
313 register rtx op;
314 enum machine_mode mode;
315{
316 return (general_operand (op, mode)
317 && ! CONSTANT_P (op) && GET_CODE (op) != CONST_DOUBLE);
318}
319
320/* Return 1 if OP is a register reference or immediate value of mode MODE. */
321
322int
323nonmemory_operand (op, mode)
324 register rtx op;
325 enum machine_mode mode;
326{
327 if (CONSTANT_P (op) || GET_CODE (op) == CONST_DOUBLE)
328 return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
329 && LEGITIMATE_CONSTANT_P (op));
330
331 if (GET_MODE (op) != mode && mode != VOIDmode)
332 return 0;
333
334 if (GET_CODE (op) == SUBREG)
335 {
336 /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
337 because it is guaranteed to be reloaded into one.
338 Just make sure the MEM is valid in itself.
339 (Ideally, (SUBREG (MEM)...) should not exist after reload,
340 but currently it does result from (SUBREG (REG)...) where the
341 reg went on the stack.) */
342 if (! reload_completed)
343 return general_operand (op, mode);
344 }
345
346 while (GET_CODE (op) == SUBREG)
347 op = SUBREG_REG (op);
348
349 return GET_CODE (op) == REG;
350}
351
352/* Return 1 if OP is a valid operand that stands for pushing a
353 value of mode MODE onto the stack.
354
355 The main use of this function is as a predicate in match_operand
356 expressions in the machine description. */
357
358int
359push_operand (op, mode)
360 rtx op;
361 enum machine_mode mode;
362{
363 if (GET_CODE (op) != MEM)
364 return 0;
365
366 if (GET_MODE (op) != mode)
367 return 0;
368
369 op = XEXP (op, 0);
370
371#ifdef STACK_GROWS_DOWNWARD
372 if (GET_CODE (op) != PRE_DEC)
373 return 0;
374#else
375 if (GET_CODE (op) != PRE_INC)
376 return 0;
377#endif
378 return XEXP (op, 0) == stack_pointer_rtx;
379}
380
381/* Return 1 if ADDR is a valid memory address for mode MODE. */
382
383int
384memory_address_p (mode, addr)
385 enum machine_mode mode;
386 register rtx addr;
387{
388 GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
389 return 0;
390
391 win:
392 return 1;
393}
394
395/* Return 1 if OP is a valid memory reference with mode MODE,
396 including a valid address.
397
398 The main use of this function is as a predicate in match_operand
399 expressions in the machine description. */
400
401int
402memory_operand (op, mode)
403 register rtx op;
404 enum machine_mode mode;
405{
406 rtx inner;
407 int mode_altering_drug = 0;
408
409 if (! reload_completed)
410 /* Note that no SUBREG is a memory operand before end of reload pass,
411 because (SUBREG (MEM...)) forces reloading into a register. */
412 return GET_CODE (op) == MEM && general_operand (op, mode);
413
414 if (mode != VOIDmode && GET_MODE (op) != mode)
415 return 0;
416
417 inner = op;
418 while (GET_CODE (inner) == SUBREG)
419 inner = SUBREG_REG (inner);
420
421 return (GET_CODE (inner) == MEM && general_operand (op, mode));
422}
423
424/* Return 1 if OP is a valid indirect memory reference with mode MODE;
425 that is, a memory reference whose address is a general_operand. */
426
427int
428indirect_operand (op, mode)
429 register rtx op;
430 enum machine_mode mode;
431{
432 return (GET_MODE (op) == mode && memory_operand (op, mode)
433 && general_operand (XEXP (op, 0), Pmode));
434}
435\f
436/* If BODY is an insn body that uses ASM_OPERANDS,
437 return the number of operands (both input and output) in the insn.
438 Otherwise return -1. */
439
440int
441asm_noperands (body)
442 rtx body;
443{
444 if (GET_CODE (body) == ASM_OPERANDS)
445 /* No output operands: return number of input operands. */
446 return XVECLEN (body, 3);
447 if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
448 /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
449 return XVECLEN (SET_SRC (body), 3) + 1;
450 else if (GET_CODE (body) == PARALLEL
451 && GET_CODE (XVECEXP (body, 0, 0)) == SET
452 && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
453 {
454 /* Multiple output operands, or 1 output plus some clobbers:
455 body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */
456 int i;
457 int n_sets;
458
459 /* Count backwards through CLOBBERs to determine number of SETs. */
460 for (i = XVECLEN (body, 0); i > 0; i--)
461 {
462 if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
463 break;
464 if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
465 return -1;
466 }
467
468 /* N_SETS is now number of output operands. */
469 n_sets = i;
470
471 /* Verify that all the SETs we have
472 came from a single original asm_operands insn
473 (so that invalid combinations are blocked). */
474 for (i = 0; i < n_sets; i++)
475 {
476 rtx elt = XVECEXP (body, 0, i);
477 if (GET_CODE (elt) != SET)
478 return -1;
479 if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
480 return -1;
481 /* If these ASM_OPERANDS rtx's came from different original insns
482 then they aren't allowed together. */
483 if (XVEC (SET_SRC (elt), 3)
484 != XVEC (SET_SRC (XVECEXP (body, 0, 0)), 3))
485 return -1;
486 }
487 return XVECLEN (SET_SRC (XVECEXP (body, 0, 0)), 3) + n_sets;
488 }
489 else if (GET_CODE (body) == PARALLEL
490 && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
491 {
492 /* 0 outputs, but some clobbers:
493 body is [(asm_operands ...) (clobber (reg ...))...]. */
494 int i;
495 int n_sets;
496
497 /* Make sure all the other parallel things really are clobbers. */
498 for (i = XVECLEN (body, 0) - 1; i > 0; i--)
499 if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
500 return -1;
501
502 return XVECLEN (XVECEXP (body, 0, 0), 3);
503 }
504 else
505 return -1;
506}
507
508/* Assuming BODY is an insn body that uses ASM_OPERANDS,
509 copy its operands (both input and output) into the vector OPERANDS,
510 the locations of the operands within the insn into the vector OPERAND_LOCS,
511 and the constraints for the operands into CONSTRAINTS.
512 Write the modes of the operands into MODES.
513 Return the assembler-template.
514
515 If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
516 we don't store that info. */
517
518char *
519decode_asm_operands (body, operands, operand_locs, constraints, modes)
520 rtx body;
521 rtx *operands;
522 rtx **operand_locs;
523 char **constraints;
524 enum machine_mode *modes;
525{
526 register int i;
527 int noperands;
528 char *template = 0;
529
530 if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
531 {
532 rtx asmop = SET_SRC (body);
533 /* Single output operand: BODY is (set OUTPUT (asm_operands ....)). */
534
535 noperands = XVECLEN (asmop, 3) + 1;
536
537 /* The input operands are found in the 1st element vector. */
538 /* Constraints for inputs are in the 2nd element vector. */
539 for (i = 1; i < noperands; i++)
540 {
541 if (operand_locs)
542 operand_locs[i] = &XVECEXP (asmop, 3, i - 1);
543 if (operands)
544 operands[i] = XVECEXP (asmop, 3, i - 1);
545 if (constraints)
546 constraints[i] = XSTR (XVECEXP (asmop, 4, i - 1), 0);
547 if (modes)
548 modes[i] = GET_MODE (XVECEXP (asmop, 4, i - 1));
549 }
550
551 /* The output is in the SET.
552 Its constraint is in the ASM_OPERANDS itself. */
553 if (operands)
554 operands[0] = SET_DEST (body);
555 if (operand_locs)
556 operand_locs[0] = &SET_DEST (body);
557 if (constraints)
558 constraints[0] = XSTR (asmop, 1);
559 if (modes)
560 modes[0] = GET_MODE (SET_DEST (body));
561 template = XSTR (asmop, 0);
562 }
563 else if (GET_CODE (body) == ASM_OPERANDS)
564 {
565 rtx asmop = body;
566 /* No output operands: BODY is (asm_operands ....). */
567
568 noperands = XVECLEN (asmop, 3);
569
570 /* The input operands are found in the 1st element vector. */
571 /* Constraints for inputs are in the 2nd element vector. */
572 for (i = 0; i < noperands; i++)
573 {
574 if (operand_locs)
575 operand_locs[i] = &XVECEXP (asmop, 3, i);
576 if (operands)
577 operands[i] = XVECEXP (asmop, 3, i);
578 if (constraints)
579 constraints[i] = XSTR (XVECEXP (asmop, 4, i), 0);
580 if (modes)
581 modes[i] = GET_MODE (XVECEXP (asmop, 4, i));
582 }
583 template = XSTR (asmop, 0);
584 }
585 else if (GET_CODE (body) == PARALLEL
586 && GET_CODE (XVECEXP (body, 0, 0)) == SET)
587 {
588 rtx asmop = SET_SRC (XVECEXP (body, 0, 0));
589 int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
590 int nin = XVECLEN (asmop, 3);
591 int nout = 0; /* Does not include CLOBBERs. */
592
593 /* At least one output, plus some CLOBBERs. */
594
595 /* The outputs are in the SETs.
596 Their constraints are in the ASM_OPERANDS itself. */
597 for (i = 0; i < nparallel; i++)
598 {
599 if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
600 break; /* Past last SET */
601
602 if (operands)
603 operands[i] = SET_DEST (XVECEXP (body, 0, i));
604 if (operand_locs)
605 operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
606 if (constraints)
607 constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
608 if (modes)
609 modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
610 nout++;
611 }
612
613 /* The input operands are found in the 1st element vector. */
614 /* Constraints for inputs are in the 2nd element vector. */
615 for (i = 0; i < nin; i++)
616 {
617 if (operand_locs)
618 operand_locs[i + nout] = &XVECEXP (asmop, 3, i);
619 if (operands)
620 operands[i + nout] = XVECEXP (asmop, 3, i);
621 if (constraints)
622 constraints[i + nout] = XSTR (XVECEXP (asmop, 4, i), 0);
623 if (modes)
624 modes[i + nout] = GET_MODE (XVECEXP (asmop, 4, i));
625 }
626
627 template = XSTR (asmop, 0);
628 }
629 else if (GET_CODE (body) == PARALLEL
630 && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
631 {
632 /* No outputs, but some CLOBBERs. */
633
634 rtx asmop = XVECEXP (body, 0, 0);
635 int nin = XVECLEN (asmop, 3);
636
637 /* The input operands are found in the 1st element vector. */
638 /* Constraints for inputs are in the 2nd element vector. */
639 for (i = 0; i < nin; i++)
640 {
641 if (operand_locs)
642 operand_locs[i] = &XVECEXP (asmop, 3, i);
643 if (operands)
644 operands[i] = XVECEXP (asmop, 3, i);
645 if (constraints)
646 constraints[i] = XSTR (XVECEXP (asmop, 4, i), 0);
647 if (modes)
648 modes[i] = GET_MODE (XVECEXP (asmop, 4, i));
649 }
650
651 template = XSTR (asmop, 0);
652 }
653
654 return template;
655}
656\f
657extern rtx plus_constant ();
658extern rtx copy_rtx ();
659
660/* Given an rtx *P, if it is a sum containing an integer constant term,
661 return the location (type rtx *) of the pointer to that constant term.
662 Otherwise, return a null pointer. */
663
664static rtx *
665find_constant_term_loc (p)
666 rtx *p;
667{
668 register rtx *tem;
669 register enum rtx_code code = GET_CODE (*p);
670
671 /* If *P IS such a constant term, P is its location. */
672
673 if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
674 || code == CONST)
675 return p;
676
677 /* Otherwise, if not a sum, it has no constant term. */
678
679 if (GET_CODE (*p) != PLUS)
680 return 0;
681
682 /* If one of the summands is constant, return its location. */
683
684 if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
685 && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
686 return p;
687
688 /* Otherwise, check each summand for containing a constant term. */
689
690 if (XEXP (*p, 0) != 0)
691 {
692 tem = find_constant_term_loc (&XEXP (*p, 0));
693 if (tem != 0)
694 return tem;
695 }
696
697 if (XEXP (*p, 1) != 0)
698 {
699 tem = find_constant_term_loc (&XEXP (*p, 1));
700 if (tem != 0)
701 return tem;
702 }
703
704 return 0;
705}
706\f
707/* Return 1 if OP is a memory reference
708 whose address contains no side effects
709 and remains valid after the addition
710 of a positive integer less than the
711 size of the object being referenced.
712
713 We assume that the original address is valid and do not check it.
714
715 This uses strict_memory_address_p as a subroutine, so
716 don't use it before reload. */
717
718int
719offsettable_memref_p (op)
720 rtx op;
721{
722 return ((GET_CODE (op) == MEM)
723 && offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)));
724}
725
726/* Return 1 if Y is a memory address which contains no side effects
727 and would remain valid for mode MODE
728 after the addition of a positive integer less than the
729 size of that mode.
730
731 We assume that the original address is valid and do not check it.
732
733 If STRICTP is nonzero, we require a strictly valid address,
734 for the sake of use in reload.c. */
735
736int
737offsettable_address_p (strictp, mode, y)
738 int strictp;
739 enum machine_mode mode;
740 register rtx y;
741{
742 register enum rtx_code ycode = GET_CODE (y);
743 register rtx z;
744 rtx y1 = y;
745 rtx *y2;
746 int (*addressp) () = (strictp ? strict_memory_address_p : memory_address_p);
747
748 if (CONSTANT_ADDRESS_P (y))
749 return 1;
750
751#ifdef OFFSETTABLE_ADDRESS_P
752 return OFFSETTABLE_ADDRESS_P (mode, y);
753#else
754 /* If the expression contains a constant term,
755 see if it remains valid when max possible offset is added. */
756
757 if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
758 {
759 int old = INTVAL (y1 = *y2);
760 int good;
761 INTVAL (y1) += GET_MODE_SIZE (mode) - 1;
762 good = (*addressp) (mode, y);
763 /* In any case, restore old contents of memory. */
764 INTVAL (y1) = old;
765 return good;
766 }
767
768 if (ycode == PRE_DEC || ycode == PRE_INC
769 || ycode == POST_DEC || ycode == POST_INC)
770 return 0;
771
772 /* The offset added here is chosen as the maximum offset that
773 any instruction could need to add when operating on something
774 of the specified mode. We assume that if Y and Y+c are
775 valid addresses then so is Y+d for all 0<d<c. */
776
777 z = plus_constant (y, GET_MODE_SIZE (mode) - 1);
778
779 return (*addressp) (mode, z);
780#endif
781}
782
783/* Return 1 if ADDR is an address-expression whose effect depends
784 on the mode of the memory reference it is used in.
785
786 Autoincrement addressing is a typical example of mode-dependence
787 because the amount of the increment depends on the mode. */
788
789int
790mode_dependent_address_p (addr)
791 rtx addr;
792{
793 GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
794 return 0;
795 win:
796 return 1;
797}
798
799/* Return 1 if OP is a general operand
800 other than a memory ref with a mode dependent address. */
801
802int
803mode_independent_operand (op, mode)
804 enum machine_mode mode;
805 rtx op;
806{
807 rtx addr;
808
809 if (! general_operand (op, mode))
810 return 0;
811
812 if (GET_CODE (op) != MEM)
813 return 1;
814
815 addr = XEXP (op, 0);
816 GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
817 return 1;
818 lose:
819 return 0;
820}
821
822/* Given an operand OP that is a valid memory reference
823 which satisfies offsettable_memref_p,
824 return a new memory reference whose address has been adjusted by OFFSET.
825 OFFSET should be positive and less than the size of the object referenced.
826*/
827
828rtx
829adj_offsettable_operand (op, offset)
830 rtx op;
831 int offset;
832{
833 register enum rtx_code code = GET_CODE (op);
834
835 if (code == MEM)
836 {
837 register rtx y = XEXP (op, 0);
838
839 if (CONSTANT_ADDRESS_P (y))
840 return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
841
842 if (GET_CODE (y) == PLUS)
843 {
844 rtx z = y;
845 register rtx *const_loc;
846
847 op = copy_rtx (op);
848 z = XEXP (op, 0);
849 const_loc = find_constant_term_loc (&z);
850 if (const_loc)
851 {
852 *const_loc = plus_constant (*const_loc, offset);
853 return op;
854 }
855 }
856
857 return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
858 }
859 abort ();
860}
861\f
862#ifdef REGISTER_CONSTRAINTS
863
864/* Check the operands of an insn (found in recog_operands)
865 against the insn's operand constraints (found via INSN_CODE_NUM)
866 and return 1 if they are valid.
867
868 WHICH_ALTERNATIVE is set to a number which indicates which
869 alternative of constraints was matched: 0 for the first alternative,
870 1 for the next, etc.
871
872 In addition, when two operands are match
873 and it happens that the output operand is (reg) while the
874 input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
875 make the output operand look like the input.
876 This is because the output operand is the one the template will print.
877
878 This is used in final, just before printing the assembler code. */
879
880struct funny_match
881{
882 int this, other;
883};
884
885int
886constrain_operands (insn_code_num)
887 int insn_code_num;
888{
889 char *constraints[MAX_RECOG_OPERANDS];
890 register int c;
891 int noperands = insn_n_operands[insn_code_num];
892
893 struct funny_match funny_match[MAX_RECOG_OPERANDS];
894 int funny_match_index;
895 int nalternatives = insn_n_alternatives[insn_code_num];
896
897 if (noperands == 0 || nalternatives == 0)
898 return 1;
899
900 for (c = 0; c < noperands; c++)
901 constraints[c] = insn_operand_constraint[insn_code_num][c];
902
903 which_alternative = 0;
904
905 while (which_alternative < nalternatives)
906 {
907 register int opno;
908 int lose = 0;
909 funny_match_index = 0;
910
911 for (opno = 0; opno < noperands; opno++)
912 {
913 register rtx op = recog_operand[opno];
914 register char *p = constraints[opno];
915 int win = 0;
916 int val;
917
918 /* `alter_subreg' should already have converted any SUBREG
919 that appears at the level of an operand. */
920 while (GET_CODE (op) == SUBREG)
921 abort ();
922
923 /* An empty constraint or empty alternative
924 allows anything which matched the pattern. */
925 if (*p == 0 || *p == ',')
926 win = 1;
927
928 while (*p && (c = *p++) != ',')
929 switch (c)
930 {
931 case '=':
932 case '+':
933 case '?':
934 case '#':
935 case '&':
936 case '!':
937 case '*':
938 case '%':
939 break;
940
941 case '0':
942 case '1':
943 case '2':
944 case '3':
945 case '4':
946 /* This operand must be the same as a previous one. */
947 /* This kind of constraint is used for instructions such
948 as add when they take only two operands. */
949 /* Note that the lower-numbered operand is passed first. */
950 val = operands_match_p (recog_operand[c - '0'],
951 recog_operand[opno]);
952 if (val != 0)
953 win = 1;
954 /* If output is *x and input is *--x,
955 arrange later to change the output to *--x as well,
956 since the output op is the one that will be printed. */
957 if (val == 2)
958 {
959 funny_match[funny_match_index].this = opno;
960 funny_match[funny_match_index++].other = c - '0';
961 }
962 break;
963
964 case 'p':
965 /* p is used for address_operands, and everything
966 that must be checked was checked already. */
967 win = 1;
968 break;
969
970 /* No need to check general_operand again;
971 it was done in insn-recog.c. */
972 case 'g':
973 /* Anything goes unless it is a REG and really has a hard reg
974 but the hard reg is not in the class GENERAL_REGS. */
975 if (GENERAL_REGS == ALL_REGS
976 || GET_CODE (op) != REG
977 || reg_fits_class_p (op, GENERAL_REGS, 0, GET_MODE (op)))
978 win = 1;
979 break;
980
981 case 'r':
982 if (GET_CODE (op) == REG
983 && (GENERAL_REGS == ALL_REGS
984 || reg_fits_class_p (op, GENERAL_REGS, 0, GET_MODE (op))))
985 win = 1;
986 break;
987
988 case 'm':
989 if (GET_CODE (op) == MEM)
990 win = 1;
991 break;
992
993 case '<':
994 if (GET_CODE (op) == MEM
995 && (GET_CODE (XEXP (op, 0)) == PRE_DEC
996 || GET_CODE (XEXP (op, 0)) == POST_DEC))
997 win = 1;
998 break;
999
1000 case '>':
1001 if (GET_CODE (op) == MEM
1002 && (GET_CODE (XEXP (op, 0)) == PRE_INC
1003 || GET_CODE (XEXP (op, 0)) == POST_INC))
1004 win = 1;
1005 break;
1006
1007 case 'F':
1008 if (GET_CODE (op) == CONST_DOUBLE)
1009 win = 1;
1010 break;
1011
1012 case 'G':
1013 case 'H':
1014 if (GET_CODE (op) == CONST_DOUBLE
1015 && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
1016 win = 1;
1017 break;
1018
1019 case 's':
1020 if (GET_CODE (op) == CONST_INT)
1021 break;
1022 case 'i':
1023 if (CONSTANT_P (op))
1024 win = 1;
1025 break;
1026
1027 case 'n':
1028 if (GET_CODE (op) == CONST_INT)
1029 win = 1;
1030 break;
1031
1032 case 'I':
1033 case 'J':
1034 case 'K':
1035 case 'L':
1036 case 'M':
1037 if (GET_CODE (op) == CONST_INT
1038 && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
1039 win = 1;
1040 break;
1041
1042 case 'o':
1043 if (offsettable_memref_p (op))
1044 win = 1;
1045 break;
1046
1047 default:
1048 if (GET_CODE (op) == REG
1049 && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
1050 0, GET_MODE (op)))
1051 win = 1;
1052 }
1053
1054 constraints[opno] = p;
1055 /* If this operand did not win somehow,
1056 this alternative loses. */
1057 if (! win)
1058 lose = 1;
1059 }
1060 /* This alternative won; the operands are ok.
1061 Change whichever operands this alternative says to change. */
1062 if (! lose)
1063 {
1064 while (--funny_match_index >= 0)
1065 {
1066 recog_operand[funny_match[funny_match_index].other]
1067 = recog_operand[funny_match[funny_match_index].this];
1068 }
1069 return 1;
1070 }
1071
1072 which_alternative++;
1073 }
1074 return 0;
1075}
1076
1077/* Return 1 iff OPERAND (assumed to be a REG rtx)
1078 is a hard reg in class CLASS when its regno is offsetted by OFFSET
1079 and changed to mode MODE.
1080 If REG occupies multiple hard regs, all of them must be in CLASS. */
1081
1082int
1083reg_fits_class_p (operand, class, offset, mode)
1084 rtx operand;
1085 register enum reg_class class;
1086 int offset;
1087 enum machine_mode mode;
1088{
1089 register int regno = REGNO (operand);
1090 if (regno < FIRST_PSEUDO_REGISTER
1091 && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
1092 regno + offset))
1093 {
1094 register int sr;
1095 regno += offset;
1096 for (sr = HARD_REGNO_NREGS (regno, mode) - 1;
1097 sr > 0; sr--)
1098 if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
1099 regno + sr))
1100 break;
1101 return sr == 0;
1102 }
1103 return 0;
1104}
1105
1106#endif /* REGISTER_CONSTRAINTS */