|
|
1.1 root 1: /* Subroutines used by or related to instruction recognition.
2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include "rtl.h"
24: #include <stdio.h>
25: #include "insn-config.h"
26: #include "recog.h"
27: #include "regs.h"
28: #include "hard-reg-set.h"
29:
30: static int inequality_comparisons_p ();
31:
32: /* Nonzero means allow operands to be volatile.
33: This is 1 if you use recog_memoized, 0 if you don't.
34: init_recog and recog_memoized are responsible for setting it.
35: This way of handling it is not really clean and will be change later. */
36:
37: int volatile_ok;
38:
39: rtx recog_addr_dummy;
40:
41: /* On return from `constrain_operands', indicate which alternative
42: was satisfied. */
43:
44: int which_alternative;
45:
46: /* Initialize data used by the function `recog'.
47: This must be called once in the compilation of a function
48: before any insn recognition may be done in the function. */
49:
50: void
51: init_recog ()
52: {
53: volatile_ok = 0;
54: recog_addr_dummy = gen_rtx (MEM, VOIDmode, 0);
55: }
56:
57: /* Try recognizing the instruction INSN,
58: and return the code number that results.
59: Remeber the code so that repeated calls do not
60: need to spend the time for actual rerecognition.
61:
62: This function is the normal interface to instruction recognition.
63: The automatically-generated function `recog' is normally called
64: through this one. (The only exception is in combine.c.) */
65:
66: int
67: recog_memoized (insn)
68: rtx insn;
69: {
70: volatile_ok = 1;
71: if (INSN_CODE (insn) < 0)
72: INSN_CODE (insn) = recog (PATTERN (insn), insn);
73: return INSN_CODE (insn);
74: }
75:
76: /* Return 1 if the insn following INSN does not contain
77: any ordered tests applied to the condition codes.
78: EQ and NE tests do not count. */
79:
80: int
81: next_insn_tests_no_inequality (insn)
82: rtx insn;
83: {
84: register rtx next = NEXT_INSN (insn);
85:
86: return ((GET_CODE (next) == JUMP_INSN
87: || GET_CODE (next) == INSN
88: || GET_CODE (next) == CALL_INSN)
89: && ! inequality_comparisons_p (PATTERN (next)));
90: }
91:
92: static int
93: inequality_comparisons_p (x)
94: rtx x;
95: {
96: register char *fmt;
97: register int len, i;
98: register enum rtx_code code = GET_CODE (x);
99:
100: switch (code)
101: {
102: case REG:
103: case PC:
104: case CC0:
105: case CONST_INT:
106: case CONST_DOUBLE:
107: case CONST:
108: case LABEL_REF:
109: case SYMBOL_REF:
110: return 0;
111:
112: case LT:
113: case LTU:
114: case GT:
115: case GTU:
116: case LE:
117: case LEU:
118: case GE:
119: case GEU:
120: return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
121: }
122:
123: len = GET_RTX_LENGTH (code);
124: fmt = GET_RTX_FORMAT (code);
125:
126: for (i = 0; i < len; i++)
127: {
128: if (fmt[i] == 'e')
129: {
130: if (inequality_comparisons_p (XEXP (x, i)))
131: return 1;
132: }
133: else if (fmt[i] == 'E')
134: {
135: register int j;
136: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
137: if (inequality_comparisons_p (XVECEXP (x, i, j)))
138: return 1;
139: }
140: }
141:
142: return 0;
143: }
144:
145: /* Return 1 if OP is a valid general operand for machine mode MODE.
146: This is either a register reference, a memory reference,
147: or a constant. In the case of a memory reference, the address
148: is checked for general validity for the target machine.
149:
150: Register and memory references must have mode MODE in order to be valid,
151: but some constants have no machine mode and are valid for any mode.
152:
153: If MODE is VOIDmode, OP is checked for validity for whatever mode
154: it has.
155:
156: The main use of this function is as a predicate in match_operand
157: expressions in the machine description. */
158:
159: int
160: general_operand (op, mode)
161: register rtx op;
162: enum machine_mode mode;
163: {
164: register enum rtx_code code = GET_CODE (op);
165: int mode_altering_drug = 0;
166:
167: if (mode == VOIDmode)
168: mode = GET_MODE (op);
169:
170: if (CONSTANT_P (op))
171: return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
172: && LEGITIMATE_CONSTANT_P (op));
173:
174: /* Except for certain constants with VOIDmode, already checked for,
175: OP's mode must match MODE if MODE specifies a mode. */
176:
177: if (GET_MODE (op) != mode)
178: return 0;
179:
180: while (code == SUBREG)
181: {
182: op = SUBREG_REG (op);
183: code = GET_CODE (op);
184: mode_altering_drug = 1;
185: }
186: if (code == REG)
187: return 1;
188: if (code == CONST_DOUBLE)
189: return LEGITIMATE_CONSTANT_P (op);
190: if (code == MEM)
191: {
192: register rtx y = XEXP (op, 0);
193: if (! volatile_ok && op->volatil)
194: return 0;
195: GO_IF_LEGITIMATE_ADDRESS (mode, y, win);
196: }
197: return 0;
198:
199: win:
200: if (mode_altering_drug)
201: return ! mode_dependent_address_p (XEXP (op, 0));
202: return 1;
203: }
204:
205: /* Return 1 if OP is a valid memory address for a memory reference
206: of mode MODE.
207:
208: The main use of this function is as a predicate in match_operand
209: expressions in the machine description. */
210:
211: int
212: address_operand (op, mode)
213: register rtx op;
214: enum machine_mode mode;
215: {
216: return memory_address_p (mode, op);
217: }
218:
219: /* Return 1 if OP is a register reference of mode MODE.
220: If MODE is VOIDmode, accept a register in any mode.
221:
222: The main use of this function is as a predicate in match_operand
223: expressions in the machine description. */
224:
225: int
226: register_operand (op, mode)
227: register rtx op;
228: enum machine_mode mode;
229: {
230: if (GET_MODE (op) != mode && mode != VOIDmode)
231: return 0;
232:
233: while (GET_CODE (op) == SUBREG)
234: op = SUBREG_REG (op);
235:
236: return GET_CODE (op) == REG;
237: }
238:
239: /* Return 1 if OP is a valid immediate operand for mode MODE.
240:
241: The main use of this function is as a predicate in match_operand
242: expressions in the machine description. */
243:
244: int
245: immediate_operand (op, mode)
246: register rtx op;
247: enum machine_mode mode;
248: {
249: return ((CONSTANT_P (op)
250: || (GET_CODE (op) == CONST_DOUBLE
251: && (GET_MODE (op) == mode || mode == VOIDmode)))
252: && LEGITIMATE_CONSTANT_P (op));
253: }
254:
255: /* Return 1 if OP is a register reference or immediate value of mode MODE. */
256:
257: int
258: nonmemory_operand (op, mode)
259: register rtx op;
260: enum machine_mode mode;
261: {
262: if (CONSTANT_P (op)
263: || (GET_CODE (op) == CONST_DOUBLE
264: && (GET_MODE (op) == mode || mode == VOIDmode)))
265: return LEGITIMATE_CONSTANT_P (op);
266:
267: if (GET_MODE (op) != mode && mode != VOIDmode)
268: return 0;
269:
270: while (GET_CODE (op) == SUBREG)
271: op = SUBREG_REG (op);
272:
273: return GET_CODE (op) == REG;
274: }
275:
276: /* Return 1 if OP is a valid operand that stands for pushing a
277: value of mode MODE onto the stack.
278:
279: The main use of this function is as a predicate in match_operand
280: expressions in the machine description. */
281:
282: int
283: push_operand (op, mode)
284: rtx op;
285: enum machine_mode mode;
286: {
287: if (GET_CODE (op) != MEM)
288: return 0;
289:
290: if (GET_MODE (op) != mode)
291: return 0;
292:
293: op = XEXP (op, 0);
294:
295: #ifdef STACK_GROWS_DOWNWARD
296: if (GET_CODE (op) != PRE_DEC)
297: return 0;
298: #else
299: if (GET_CODE (op) != PRE_INC)
300: return 0;
301: #endif
302: return REGNO (XEXP (op, 0)) == STACK_POINTER_REGNUM;
303: }
304:
305: /* Return 1 if ADDR is a valid memory address for mode MODE. */
306:
307: int
308: memory_address_p (mode, addr)
309: enum machine_mode mode;
310: register rtx addr;
311: {
312: GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
313: return 0;
314:
315: win:
316: return 1;
317: }
318:
319: /* Return 1 if OP is a valid memory reference with mode MODE,
320: including a valid address.
321:
322: The main use of this function is as a predicate in match_operand
323: expressions in the machine description. */
324:
325: int
326: memory_operand (op, mode)
327: register rtx op;
328: enum machine_mode mode;
329: {
330: return GET_CODE (op) == MEM && general_operand (op, mode);
331: }
332:
333: /* If BODY is an insn body that uses ASM_OPERANDS,
334: return the number of operands (both input and output) in the insn.
335: Otherwise return 0. */
336:
337: int
338: asm_noperands (body)
339: rtx body;
340: {
341: int noperands;
342:
343: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
344: /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
345: return XVECLEN (SET_SRC (body), 3) + 1;
346: else if (GET_CODE (body) == PARALLEL
347: && GET_CODE (XVECEXP (body, 0, 0)) == SET
348: && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
349: /* Multiple outputs: BODY is
350: (parallel [(set OUTPUT0 (asm_operands ...)) ...]). */
351: return XVECLEN (SET_SRC (XVECEXP (body, 0, 0)), 3) + XVECLEN (body, 0);
352: else
353: return 0;
354: }
355:
356: /* Assuming BODY is an insn body that uses ASM_OPERANDS,
357: copy its operands (both input and output) into the vector OPERANDS,
358: the locations of the operands within the insn into the vector OPERAND_LOCS,
359: and the constraints for the operands into CONSTRAINTS.
360: Write the modes of the operands into MODES.
361: Return the assembler-template.
362:
363: If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
364: we don't store that info. */
365:
366: char *
367: decode_asm_operands (body, operands, operand_locs, constraints, modes)
368: rtx body;
369: rtx *operands;
370: rtx **operand_locs;
371: char **constraints;
372: enum machine_mode *modes;
373: {
374: register int i;
375: int noperands;
376: char *template;
377:
378: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
379: {
380: rtx asmop = SET_SRC (body);
381: /* Single output operand: BODY is (set OUTPUT (asm_operands ....)). */
382:
383: noperands = XVECLEN (asmop, 3) + 1;
384:
385: /* The input operands are found in the 1st element vector. */
386: /* Constraints for inputs are in the 2nd element vector. */
387: for (i = 1; i < noperands; i++)
388: {
389: if (operand_locs)
390: operand_locs[i] = &XVECEXP (asmop, 3, i - 1);
391: if (operands)
392: operands[i] = XVECEXP (asmop, 3, i - 1);
393: if (constraints)
394: constraints[i] = XSTR (XVECEXP (asmop, 4, i - 1), 0);
395: if (modes)
396: modes[i] = GET_MODE (XVECEXP (asmop, 4, i - 1));
397: }
398:
399: /* The output is in the SET.
400: Its constraint is in the ASM_OPERANDS itself. */
401: if (operands)
402: operands[0] = SET_DEST (body);
403: if (operand_locs)
404: operand_locs[0] = &SET_DEST (body);
405: if (constraints)
406: constraints[0] = XSTR (asmop, 1);
407: if (modes)
408: modes[0] = GET_MODE (SET_DEST (body));
409: template = XSTR (asmop, 0);
410: }
411: else
412: {
413: rtx asmop = SET_SRC (XVECEXP (body, 0, 0));
414: int nout = XVECLEN (body, 0);
415: int nin = XVECLEN (asmop, 3);
416:
417: noperands = XVECLEN (asmop, 3) + XVECLEN (body, 0);
418:
419: /* The input operands are found in the 1st element vector. */
420: /* Constraints for inputs are in the 2nd element vector. */
421: for (i = 0; i < nin; i++)
422: {
423: if (operand_locs)
424: operand_locs[i + nout] = &XVECEXP (asmop, 3, i);
425: if (operands)
426: operands[i + nout] = XVECEXP (asmop, 3, i);
427: if (constraints)
428: constraints[i + nout] = XSTR (XVECEXP (asmop, 4, i), 0);
429: if (modes)
430: modes[i + nout] = GET_MODE (XVECEXP (asmop, 4, i));
431: }
432: /* The outputs are in the SETs.
433: Their constraints are in the ASM_OPERANDS itself. */
434: for (i = 0; i < nout; i++)
435: {
436: if (operands)
437: operands[i] = SET_DEST (XVECEXP (body, 0, i));
438: if (operand_locs)
439: operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
440: if (constraints)
441: constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
442: if (modes)
443: modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
444: }
445: template = XSTR (asmop, 0);
446: }
447:
448: return template;
449: }
450:
451: extern rtx plus_constant ();
452: extern rtx copy_rtx ();
453:
454: /* Given an rtx *P, if it is a sum containing an integer constant term,
455: return the location (type rtx *) of the pointer to that constant term.
456: Otherwise, return a null pointer. */
457:
458: static rtx *
459: find_constant_term_loc (p)
460: rtx *p;
461: {
462: register rtx *tem;
463: register enum rtx_code code = GET_CODE (*p);
464:
465: /* If *P IS such a constant term, P is its location. */
466:
467: if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
468: || code == CONST)
469: return p;
470:
471: /* Otherwise, if not a sum, it has no constant term. */
472:
473: if (GET_CODE (*p) != PLUS)
474: return 0;
475:
476: /* If one of the summands is constant, return its location. */
477:
478: if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
479: && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
480: return p;
481:
482: /* Otherwise, check each summand for containing a constant term. */
483:
484: if (XEXP (*p, 0) != 0)
485: {
486: tem = find_constant_term_loc (&XEXP (*p, 0));
487: if (tem != 0)
488: return tem;
489: }
490:
491: if (XEXP (*p, 1) != 0)
492: {
493: tem = find_constant_term_loc (&XEXP (*p, 1));
494: if (tem != 0)
495: return tem;
496: }
497:
498: return 0;
499: }
500:
501: /* Return 1 if OP is a memory reference
502: whose address contains no side effects
503: and remains valid after the addition
504: of a positive integer less than the
505: size of the object being referenced.
506:
507: We assume that the original address is valid and do not check it. */
508:
509: int
510: offsetable_memref_p (op)
511: rtx op;
512: {
513: return ((GET_CODE (op) == MEM)
514: && offsetable_address_p (GET_MODE (op), XEXP (op, 0)));
515: }
516:
517: /* Return 1 if Y is a memory address which contains no side effects
518: and would remain valid for mode MODE
519: after the addition of a positive integer less than the
520: size of that mode.
521:
522: We assume that the original address is valid and do not check it. */
523:
524: int
525: offsetable_address_p (mode, y)
526: enum machine_mode mode;
527: register rtx y;
528: {
529: register enum rtx_code ycode = GET_CODE (y);
530: register rtx z;
531: rtx y1 = y;
532: rtx *y2;
533:
534: if (CONSTANT_ADDRESS_P (y))
535: return 1;
536:
537: /* If the expression contains a constant term,
538: see if it remains valid when max possible offset is added. */
539:
540: if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
541: {
542: int old = INTVAL (y1 = *y2);
543: int good;
544: INTVAL (y1) += GET_MODE_SIZE (mode) - 1;
545: good = memory_address_p (mode, y);
546: /* In any case, restore old contents of memory. */
547: INTVAL (y1) = old;
548: return good;
549: }
550:
551: if (ycode == PRE_DEC || ycode == PRE_INC
552: || ycode == POST_DEC || ycode == POST_INC)
553: return 0;
554:
555: /* The offset added here is chosen as the maximum offset that
556: any instruction could need to add when operating on something
557: of the specified mode. We assume that if Y and Y+c are
558: valid addresses then so is Y+d for all 0<d<c. */
559:
560: z = plus_constant (y, GET_MODE_SIZE (mode) - 1);
561:
562: return memory_address_p (mode, z);
563: }
564:
565: /* Return 1 if ADDR is an address-expression whose effect depends
566: on the mode of the memory reference it is used in.
567:
568: Autoincrement addressing is a typical example of mode-dependence
569: because the amount of the increment depends on the mode. */
570:
571: int
572: mode_dependent_address_p (addr)
573: rtx addr;
574: {
575: GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
576: return 0;
577: win:
578: return 1;
579: }
580:
581: /* Return 1 if OP is a general operand
582: other than a memory ref with a mode dependent address. */
583:
584: int
585: mode_independent_operand (mode, op)
586: rtx op;
587: {
588: rtx addr;
589:
590: if (! general_operand (mode, op))
591: return 0;
592:
593: if (GET_CODE (op) != MEM)
594: return 1;
595:
596: addr = XEXP (op, 0);
597: GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
598: return 1;
599: lose:
600: return 0;
601: }
602:
603: /* Given an operand OP that is a valid memory reference
604: which satisfies offsetable_memref_p,
605: return a new memory reference whose address has been adjusted by OFFSET.
606: OFFSET should be positive and less than the size of the object referenced.
607: */
608:
609: rtx
610: adj_offsetable_operand (op, offset)
611: rtx op;
612: int offset;
613: {
614: register enum rtx_code code = GET_CODE (op);
615:
616: if (code == MEM)
617: {
618: register rtx y = XEXP (op, 0);
619:
620: if (CONSTANT_ADDRESS_P (y))
621: return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
622:
623: if (GET_CODE (y) == PLUS)
624: {
625: rtx z = y;
626: register rtx *const_loc;
627:
628: op = copy_rtx (op);
629: z = XEXP (op, 0);
630: const_loc = find_constant_term_loc (&z);
631: if (const_loc)
632: {
633: *const_loc = plus_constant (*const_loc, offset);
634: return op;
635: }
636: }
637:
638: return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
639: }
640: abort ();
641: }
642:
643: #ifdef REGISTER_CONSTRAINTS
644:
645: /* Check the operands of an insn (found in recog_operands)
646: against the insn's operand constraints (found via INSN_CODE_NUM)
647: and return 1 if they are valid.
648:
649: WHICH_ALTERNATIVE is set to a number which indicates which
650: alternative of constraints was matched: 0 for the first alternative,
651: 1 for the next, etc.
652:
653: In addition, when two operands are match
654: and it happens that the output operand is (reg) while the
655: input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
656: make the output operand look like the input.
657: This is because the output operand is the one the template will print.
658:
659: This is used in final, just before printing the assembler code. */
660:
661: struct funny_match
662: {
663: int this, other;
664: };
665:
666: int
667: constrain_operands (insn_code_num)
668: int insn_code_num;
669: {
670: char *constraints[MAX_RECOG_OPERANDS];
671: register int c;
672: int noperands = insn_n_operands[insn_code_num];
673:
674: struct funny_match funny_match[MAX_RECOG_OPERANDS];
675: int funny_match_index;
676:
677: if (noperands == 0)
678: return 1;
679:
680: for (c = 0; c < noperands; c++)
681: constraints[c] = insn_operand_constraint[insn_code_num][c];
682:
683: which_alternative = 0;
684:
685: while (*constraints[0])
686: {
687: register int opno;
688: int lose = 0;
689: funny_match_index = 0;
690:
691: for (opno = 0; opno < noperands; opno++)
692: {
693: register rtx op = recog_operand[opno];
694: register char *p = constraints[opno];
695: int win = 0;
696: int val;
697:
698: /* `alter_subreg' should already have converted any SUBREG
699: that appears at the level of an operand. */
700: while (GET_CODE (op) == SUBREG)
701: abort ();
702:
703: while (*p && (c = *p++) != ',')
704: switch (c)
705: {
706: case '=':
707: case '+':
708: case '?':
709: case '#':
710: case '!':
711: case '*':
712: case '%':
713: break;
714:
715: case '0':
716: case '1':
717: case '2':
718: case '3':
719: case '4':
720: /* This operand must be the same as a previous one. */
721: /* This kind of constraint is used for instructions such
722: as add when they take only two operands. */
723: /* Note that the lower-numbered operand is passed first. */
724: val = operands_match_p (recog_operand[c - '0'],
725: recog_operand[opno]);
726: if (val != 0)
727: win = 1;
728: /* If output is *x and input is *--x,
729: arrange later to change the output to *--x as well,
730: since the output op is the one that will be printed. */
731: if (val == 2)
732: {
733: funny_match[funny_match_index].this = opno;
734: funny_match[funny_match_index++].other = c - '0';
735: }
736: break;
737:
738: case 'p':
739: /* p is used for address_operands, and everything
740: that must be checked was checked already. */
741: win = 1;
742: break;
743:
744: /* No need to check general_operand again;
745: it was done in insn-recog.c. */
746: case 'g':
747: /* Anything goes unless it is a REG and really has a hard reg
748: but the hard reg is not in the class GENERAL_REGS. */
749: if (GENERAL_REGS == ALL_REGS
750: || GET_CODE (op) != REG
751: || (REGNO (op) >= FIRST_PSEUDO_REGISTER
752: && reg_renumber[REGNO (op)] < 0)
753: || reg_renumbered_fits_class_p (op, GENERAL_REGS, 0,
754: GET_MODE (op)))
755: win = 1;
756: break;
757:
758: case 'r':
759: if (GET_CODE (op) == REG
760: && (GENERAL_REGS == ALL_REGS
761: || reg_renumbered_fits_class_p (op, GENERAL_REGS,
762: 0, GET_MODE (op))))
763: win = 1;
764: break;
765:
766: case 'm':
767: if (GET_CODE (op) == MEM)
768: win = 1;
769: break;
770:
771: case '<':
772: if (GET_CODE (op) == MEM
773: && (GET_CODE (XEXP (op, 0)) == PRE_DEC
774: || GET_CODE (XEXP (op, 0)) == POST_DEC))
775: win = 1;
776: break;
777:
778: case '>':
779: if (GET_CODE (op) == MEM
780: && (GET_CODE (XEXP (op, 0)) == PRE_INC
781: || GET_CODE (XEXP (op, 0)) == POST_INC))
782: win = 1;
783: break;
784:
785: case 'F':
786: if (GET_CODE (op) == CONST_DOUBLE)
787: win = 1;
788: break;
789:
790: case 'G':
791: case 'H':
792: if (GET_CODE (op) == CONST_DOUBLE
793: && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
794: win = 1;
795: break;
796:
797: case 's':
798: if (GET_CODE (op) == CONST_INT)
799: break;
800: case 'i':
801: if (CONSTANT_P (op))
802: win = 1;
803: break;
804:
805: case 'n':
806: if (GET_CODE (op) == CONST_INT)
807: win = 1;
808: break;
809:
810: case 'I':
811: case 'J':
812: case 'K':
813: case 'L':
814: case 'M':
815: if (GET_CODE (op) == CONST_INT
816: && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
817: win = 1;
818: break;
819:
820: case 'o':
821: if (offsetable_memref_p (op))
822: win = 1;
823: break;
824:
825: default:
826: if (GET_CODE (op) == REG
827: && reg_renumbered_fits_class_p (op,
828: REG_CLASS_FROM_LETTER (c),
829: 0, GET_MODE (op)))
830: win = 1;
831: }
832:
833: constraints[opno] = p;
834: /* If this operand did not win somehow,
835: this alternative loses. */
836: if (! win)
837: lose = 1;
838: }
839: /* This alternative won; the operands are ok.
840: Change whichever operands this alternative says to change. */
841: if (! lose)
842: {
843: while (--funny_match_index >= 0)
844: {
845: recog_operand[funny_match[funny_match_index].other]
846: = recog_operand[funny_match[funny_match_index].this];
847: }
848: return 1;
849: }
850:
851: which_alternative++;
852: }
853: return 0;
854: }
855:
856: /* Return 1 iff OPERAND (assumed to be a REG rtx)
857: is a hard reg in class CLASS when its regno is offsetted by OFFSET
858: and changed to mode MODE,
859: or is a pseudo reg allocated into such a hard reg.
860: If REG occupies multiple hard regs, all of them must by in CLASS. */
861:
862: int
863: reg_renumbered_fits_class_p (operand, class, offset, mode)
864: rtx operand;
865: register enum reg_class class;
866: int offset;
867: enum machine_mode mode;
868: {
869: if (GET_CODE (operand) == REG)
870: {
871: register int regno = REGNO (operand);
872: if (reg_renumber[regno] >= 0)
873: regno = reg_renumber[regno];
874: if (regno < FIRST_PSEUDO_REGISTER
875: && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
876: regno + offset))
877: {
878: register int sr;
879: regno += offset;
880: for (sr = HARD_REGNO_NREGS (regno, mode) - 1;
881: sr > 0; sr--)
882: if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
883: regno + sr))
884: break;
885: return sr == 0;
886: }
887: }
888: return 0;
889: }
890:
891: #endif /* REGISTER_CONSTRAINTS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.