|
|
1.1 ! root 1: /* Subroutines used by or related to instruction recognition. ! 2: Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC 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 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC 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 GNU CC; see the file COPYING. If not, write to ! 18: the 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 "insn-attr.h" ! 26: #include "insn-flags.h" ! 27: #include "insn-codes.h" ! 28: #include "recog.h" ! 29: #include "regs.h" ! 30: #include "hard-reg-set.h" ! 31: #include "flags.h" ! 32: #include "real.h" ! 33: ! 34: #ifndef STACK_PUSH_CODE ! 35: #ifdef STACK_GROWS_DOWNWARD ! 36: #define STACK_PUSH_CODE PRE_DEC ! 37: #else ! 38: #define STACK_PUSH_CODE PRE_INC ! 39: #endif ! 40: #endif ! 41: ! 42: /* Import from final.c: */ ! 43: extern rtx alter_subreg (); ! 44: ! 45: int strict_memory_address_p (); ! 46: int memory_address_p (); ! 47: ! 48: /* Nonzero means allow operands to be volatile. ! 49: This should be 0 if you are generating rtl, such as if you are calling ! 50: the functions in optabs.c and expmed.c (most of the time). ! 51: This should be 1 if all valid insns need to be recognized, ! 52: such as in regclass.c and final.c and reload.c. ! 53: ! 54: init_recog and init_recog_no_volatile are responsible for setting this. */ ! 55: ! 56: int volatile_ok; ! 57: ! 58: /* On return from `constrain_operands', indicate which alternative ! 59: was satisfied. */ ! 60: ! 61: int which_alternative; ! 62: ! 63: /* Nonzero after end of reload pass. ! 64: Set to 1 or 0 by toplev.c. ! 65: Controls the significance of (SUBREG (MEM)). */ ! 66: ! 67: int reload_completed; ! 68: ! 69: /* Initialize data used by the function `recog'. ! 70: This must be called once in the compilation of a function ! 71: before any insn recognition may be done in the function. */ ! 72: ! 73: void ! 74: init_recog_no_volatile () ! 75: { ! 76: volatile_ok = 0; ! 77: } ! 78: ! 79: void ! 80: init_recog () ! 81: { ! 82: volatile_ok = 1; ! 83: } ! 84: ! 85: /* Try recognizing the instruction INSN, ! 86: and return the code number that results. ! 87: Remeber the code so that repeated calls do not ! 88: need to spend the time for actual rerecognition. ! 89: ! 90: This function is the normal interface to instruction recognition. ! 91: The automatically-generated function `recog' is normally called ! 92: through this one. (The only exception is in combine.c.) */ ! 93: ! 94: int ! 95: recog_memoized (insn) ! 96: rtx insn; ! 97: { ! 98: if (INSN_CODE (insn) < 0) ! 99: INSN_CODE (insn) = recog (PATTERN (insn), insn, 0); ! 100: return INSN_CODE (insn); ! 101: } ! 102: ! 103: /* Check that X is an insn-body for an `asm' with operands ! 104: and that the operands mentioned in it are legitimate. */ ! 105: ! 106: int ! 107: check_asm_operands (x) ! 108: rtx x; ! 109: { ! 110: int noperands = asm_noperands (x); ! 111: rtx *operands; ! 112: int i; ! 113: ! 114: if (noperands < 0) ! 115: return 0; ! 116: if (noperands == 0) ! 117: return 1; ! 118: ! 119: operands = (rtx *) alloca (noperands * sizeof (rtx)); ! 120: decode_asm_operands (x, operands, 0, 0, 0); ! 121: ! 122: for (i = 0; i < noperands; i++) ! 123: if (!general_operand (operands[i], VOIDmode)) ! 124: return 0; ! 125: ! 126: return 1; ! 127: } ! 128: ! 129: /* Static data for the next two routines. ! 130: ! 131: The maximum number of changes supported is defined as the maximum ! 132: number of operands times 5. This allows for repeated substitutions ! 133: inside complex indexed address, or, alternatively, changes in up ! 134: to 5 insns. */ ! 135: ! 136: #define MAX_CHANGE_LOCS (MAX_RECOG_OPERANDS * 5) ! 137: ! 138: static rtx change_objects[MAX_CHANGE_LOCS]; ! 139: static int change_old_codes[MAX_CHANGE_LOCS]; ! 140: static rtx *change_locs[MAX_CHANGE_LOCS]; ! 141: static rtx change_olds[MAX_CHANGE_LOCS]; ! 142: ! 143: static int num_changes = 0; ! 144: ! 145: /* Validate a proposed change to OBJECT. LOC is the location in the rtl for ! 146: at which NEW will be placed. If OBJECT is zero, no validation is done, ! 147: the change is simply made. ! 148: ! 149: Two types of objects are supported: If OBJECT is a MEM, memory_address_p ! 150: will be called with the address and mode as parameters. If OBJECT is ! 151: an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with ! 152: the change in place. ! 153: ! 154: IN_GROUP is non-zero if this is part of a group of changes that must be ! 155: performed as a group. In that case, the changes will be stored. The ! 156: function `apply_change_group' will validate and apply the changes. ! 157: ! 158: If IN_GROUP is zero, this is a single change. Try to recognize the insn ! 159: or validate the memory reference with the change applied. If the result ! 160: is not valid for the machine, suppress the change and return zero. ! 161: Otherwise, perform the change and return 1. */ ! 162: ! 163: int ! 164: validate_change (object, loc, new, in_group) ! 165: rtx object; ! 166: rtx *loc; ! 167: rtx new; ! 168: int in_group; ! 169: { ! 170: rtx old = *loc; ! 171: ! 172: if (old == new || rtx_equal_p (old, new)) ! 173: return 1; ! 174: ! 175: if (num_changes >= MAX_CHANGE_LOCS ! 176: || (in_group == 0 && num_changes != 0)) ! 177: abort (); ! 178: ! 179: *loc = new; ! 180: ! 181: /* Save the information describing this change. */ ! 182: change_objects[num_changes] = object; ! 183: change_locs[num_changes] = loc; ! 184: change_olds[num_changes] = old; ! 185: ! 186: if (object && GET_CODE (object) != MEM) ! 187: { ! 188: /* Set INSN_CODE to force rerecognition of insn. Save old code in ! 189: case invalid. */ ! 190: change_old_codes[num_changes] = INSN_CODE (object); ! 191: INSN_CODE (object) = -1; ! 192: } ! 193: ! 194: num_changes++; ! 195: ! 196: /* If we are making a group of changes, return 1. Otherwise, validate the ! 197: change group we made. */ ! 198: ! 199: if (in_group) ! 200: return 1; ! 201: else ! 202: return apply_change_group (); ! 203: } ! 204: ! 205: /* Apply a group of changes previously issued with `validate_change'. ! 206: Return 1 if all changes are valid, zero otherwise. */ ! 207: ! 208: int ! 209: apply_change_group () ! 210: { ! 211: int i; ! 212: ! 213: /* The changes have been applied and all INSN_CODEs have been reset to force ! 214: rerecognition. ! 215: ! 216: The changes are valid if we aren't given an object, or if we are ! 217: given a MEM and it still is a valid address, or if this is in insn ! 218: and it is recognized. In the latter case, if reload has completed, ! 219: we also require that the operands meet the constraints for ! 220: the insn. We do not allow modifying an ASM_OPERANDS after reload ! 221: has completed because verifying the constraints is too difficult. */ ! 222: ! 223: for (i = 0; i < num_changes; i++) ! 224: { ! 225: rtx object = change_objects[i]; ! 226: ! 227: if (object == 0) ! 228: continue; ! 229: ! 230: if (GET_CODE (object) == MEM) ! 231: { ! 232: if (! memory_address_p (GET_MODE (object), XEXP (object, 0))) ! 233: break; ! 234: } ! 235: else if ((recog_memoized (object) < 0 ! 236: && (asm_noperands (PATTERN (object)) < 0 ! 237: || ! check_asm_operands (PATTERN (object)) ! 238: || reload_completed)) ! 239: || (reload_completed ! 240: && (insn_extract (object), ! 241: ! constrain_operands (INSN_CODE (object), 1)))) ! 242: { ! 243: rtx pat = PATTERN (object); ! 244: ! 245: /* Perhaps we couldn't recognize the insn because there were ! 246: extra CLOBBERs at the end. If so, try to re-recognize ! 247: without the last CLOBBER (later iterations will cause each of ! 248: them to be eliminated, in turn). But don't do this if we ! 249: have an ASM_OPERAND. */ ! 250: if (GET_CODE (pat) == PARALLEL ! 251: && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER ! 252: && asm_noperands (PATTERN (object)) < 0) ! 253: { ! 254: rtx newpat; ! 255: ! 256: if (XVECLEN (pat, 0) == 2) ! 257: newpat = XVECEXP (pat, 0, 0); ! 258: else ! 259: { ! 260: int j; ! 261: ! 262: newpat = gen_rtx (PARALLEL, VOIDmode, ! 263: gen_rtvec (XVECLEN (pat, 0) - 1)); ! 264: for (j = 0; j < XVECLEN (newpat, 0); j++) ! 265: XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j); ! 266: } ! 267: ! 268: /* Add a new change to this group to replace the pattern ! 269: with this new pattern. Then consider this change ! 270: as having succeeded. The change we added will ! 271: cause the entire call to fail if things remain invalid. ! 272: ! 273: Note that this can lose if a later change than the one ! 274: we are processing specified &XVECEXP (PATTERN (object), 0, X) ! 275: but this shouldn't occur. */ ! 276: ! 277: validate_change (object, &PATTERN (object), newpat, 1); ! 278: } ! 279: else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER) ! 280: /* If this insn is a CLOBBER or USE, it is always valid, but is ! 281: never recognized. */ ! 282: continue; ! 283: else ! 284: break; ! 285: } ! 286: } ! 287: ! 288: if (i == num_changes) ! 289: { ! 290: num_changes = 0; ! 291: return 1; ! 292: } ! 293: else ! 294: { ! 295: cancel_changes (0); ! 296: return 0; ! 297: } ! 298: } ! 299: ! 300: /* Return the number of changes so far in the current group. */ ! 301: ! 302: int ! 303: num_validated_changes () ! 304: { ! 305: return num_changes; ! 306: } ! 307: ! 308: /* Retract the changes numbered NUM and up. */ ! 309: ! 310: void ! 311: cancel_changes (num) ! 312: int num; ! 313: { ! 314: int i; ! 315: ! 316: /* Back out all the changes. Do this in the opposite order in which ! 317: they were made. */ ! 318: for (i = num_changes - 1; i >= num; i--) ! 319: { ! 320: *change_locs[i] = change_olds[i]; ! 321: if (change_objects[i] && GET_CODE (change_objects[i]) != MEM) ! 322: INSN_CODE (change_objects[i]) = change_old_codes[i]; ! 323: } ! 324: num_changes = num; ! 325: } ! 326: ! 327: /* Replace every occurrence of FROM in X with TO. Mark each change with ! 328: validate_change passing OBJECT. */ ! 329: ! 330: static void ! 331: validate_replace_rtx_1 (loc, from, to, object) ! 332: rtx *loc; ! 333: rtx from, to, object; ! 334: { ! 335: register int i, j; ! 336: register char *fmt; ! 337: register rtx x = *loc; ! 338: enum rtx_code code = GET_CODE (x); ! 339: ! 340: /* X matches FROM if it is the same rtx or they are both referring to the ! 341: same register in the same mode. Avoid calling rtx_equal_p unless the ! 342: operands look similar. */ ! 343: ! 344: if (x == from ! 345: || (GET_CODE (x) == REG && GET_CODE (from) == REG ! 346: && GET_MODE (x) == GET_MODE (from) ! 347: && REGNO (x) == REGNO (from)) ! 348: || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from) ! 349: && rtx_equal_p (x, from))) ! 350: { ! 351: validate_change (object, loc, to, 1); ! 352: return; ! 353: } ! 354: ! 355: /* For commutative or comparison operations, try replacing each argument ! 356: separately and seeing if we made any changes. If so, put a constant ! 357: argument last.*/ ! 358: if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c') ! 359: { ! 360: int prev_changes = num_changes; ! 361: ! 362: validate_replace_rtx_1 (&XEXP (x, 0), from, to, object); ! 363: validate_replace_rtx_1 (&XEXP (x, 1), from, to, object); ! 364: if (prev_changes != num_changes && CONSTANT_P (XEXP (x, 0))) ! 365: { ! 366: validate_change (object, loc, ! 367: gen_rtx (GET_RTX_CLASS (code) == 'c' ? code ! 368: : swap_condition (code), ! 369: GET_MODE (x), XEXP (x, 1), XEXP (x, 0)), ! 370: 1); ! 371: x = *loc; ! 372: code = GET_CODE (x); ! 373: } ! 374: } ! 375: ! 376: switch (code) ! 377: { ! 378: case PLUS: ! 379: /* If we have have a PLUS whose second operand is now a CONST_INT, use ! 380: plus_constant to try to simplify it. */ ! 381: if (GET_CODE (XEXP (x, 1)) == CONST_INT && XEXP (x, 1) == to) ! 382: validate_change (object, loc, ! 383: plus_constant (XEXP (x, 0), INTVAL (XEXP (x, 1))), 1); ! 384: return; ! 385: ! 386: case ZERO_EXTEND: ! 387: case SIGN_EXTEND: ! 388: /* In these cases, the operation to be performed depends on the mode ! 389: of the operand. If we are replacing the operand with a VOIDmode ! 390: constant, we lose the information. So try to simplify the operation ! 391: in that case. If it fails, substitute in something that we know ! 392: won't be recogized. */ ! 393: if (GET_MODE (to) == VOIDmode ! 394: && (XEXP (x, 0) == from ! 395: || (GET_CODE (XEXP (x, 0)) == REG && GET_CODE (from) == REG ! 396: && GET_MODE (XEXP (x, 0)) == GET_MODE (from) ! 397: && REGNO (XEXP (x, 0)) == REGNO (from)))) ! 398: { ! 399: rtx new = simplify_unary_operation (code, GET_MODE (x), to, ! 400: GET_MODE (from)); ! 401: if (new == 0) ! 402: new = gen_rtx (CLOBBER, GET_MODE (x), const0_rtx); ! 403: ! 404: validate_change (object, loc, new, 1); ! 405: return; ! 406: } ! 407: break; ! 408: ! 409: case SUBREG: ! 410: /* If we have a SUBREG of a register that we are replacing and we are ! 411: replacing it with a MEM, make a new MEM and try replacing the ! 412: SUBREG with it. Don't do this if the MEM has a mode-dependent address ! 413: or if we would be widening it. */ ! 414: ! 415: if (SUBREG_REG (x) == from ! 416: && GET_CODE (from) == REG ! 417: && GET_CODE (to) == MEM ! 418: && ! mode_dependent_address_p (XEXP (to, 0)) ! 419: && ! MEM_VOLATILE_P (to) ! 420: && GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (GET_MODE (to))) ! 421: { ! 422: int offset = SUBREG_WORD (x) * UNITS_PER_WORD; ! 423: enum machine_mode mode = GET_MODE (x); ! 424: rtx new; ! 425: ! 426: #if BYTES_BIG_ENDIAN ! 427: offset += (MIN (UNITS_PER_WORD, ! 428: GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) ! 429: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))); ! 430: #endif ! 431: ! 432: new = gen_rtx (MEM, mode, plus_constant (XEXP (to, 0), offset)); ! 433: MEM_VOLATILE_P (new) = MEM_VOLATILE_P (to); ! 434: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (to); ! 435: MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (to); ! 436: validate_change (object, loc, new, 1); ! 437: return; ! 438: } ! 439: break; ! 440: ! 441: case ZERO_EXTRACT: ! 442: case SIGN_EXTRACT: ! 443: /* If we are replacing a register with memory, try to change the memory ! 444: to be the mode required for memory in extract operations (this isn't ! 445: likely to be an insertion operation; if it was, nothing bad will ! 446: happen, we might just fail in some cases). */ ! 447: ! 448: if (XEXP (x, 0) == from && GET_CODE (from) == REG && GET_CODE (to) == MEM ! 449: && GET_CODE (XEXP (x, 1)) == CONST_INT ! 450: && GET_CODE (XEXP (x, 2)) == CONST_INT ! 451: && ! mode_dependent_address_p (XEXP (to, 0)) ! 452: && ! MEM_VOLATILE_P (to)) ! 453: { ! 454: enum machine_mode wanted_mode = VOIDmode; ! 455: enum machine_mode is_mode = GET_MODE (to); ! 456: int width = INTVAL (XEXP (x, 1)); ! 457: int pos = INTVAL (XEXP (x, 2)); ! 458: ! 459: #ifdef HAVE_extzv ! 460: if (code == ZERO_EXTRACT) ! 461: wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; ! 462: #endif ! 463: #ifdef HAVE_extv ! 464: if (code == SIGN_EXTRACT) ! 465: wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1]; ! 466: #endif ! 467: ! 468: /* If we have a narrower mode, we can do someting. */ ! 469: if (wanted_mode != VOIDmode ! 470: && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode)) ! 471: { ! 472: int offset = pos / BITS_PER_UNIT; ! 473: rtx newmem; ! 474: ! 475: /* If the bytes and bits are counted differently, we ! 476: must adjust the offset. */ ! 477: #if BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN ! 478: offset = (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode) ! 479: - offset); ! 480: #endif ! 481: ! 482: pos %= GET_MODE_BITSIZE (wanted_mode); ! 483: ! 484: newmem = gen_rtx (MEM, wanted_mode, ! 485: plus_constant (XEXP (to, 0), offset)); ! 486: RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (to); ! 487: MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (to); ! 488: MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (to); ! 489: ! 490: validate_change (object, &XEXP (x, 2), ! 491: gen_rtx (CONST_INT, VOIDmode, pos), 1); ! 492: validate_change (object, &XEXP (x, 0), newmem, 1); ! 493: } ! 494: } ! 495: ! 496: break; ! 497: } ! 498: ! 499: fmt = GET_RTX_FORMAT (code); ! 500: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 501: { ! 502: if (fmt[i] == 'e') ! 503: validate_replace_rtx_1 (&XEXP (x, i), from, to, object); ! 504: else if (fmt[i] == 'E') ! 505: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 506: validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object); ! 507: } ! 508: } ! 509: ! 510: /* Try replacing every occurrence of FROM in INSN with TO. After all ! 511: changes have been made, validate by seeing if INSN is still valid. */ ! 512: ! 513: int ! 514: validate_replace_rtx (from, to, insn) ! 515: rtx from, to, insn; ! 516: { ! 517: validate_replace_rtx_1 (&PATTERN (insn), from, to, insn); ! 518: return apply_change_group (); ! 519: } ! 520: ! 521: #ifdef HAVE_cc0 ! 522: /* Return 1 if the insn using CC0 set by INSN does not contain ! 523: any ordered tests applied to the condition codes. ! 524: EQ and NE tests do not count. */ ! 525: ! 526: int ! 527: next_insn_tests_no_inequality (insn) ! 528: rtx insn; ! 529: { ! 530: register rtx next = next_cc0_user (insn); ! 531: ! 532: /* If there is no next insn, we have to take the conservative choice. */ ! 533: if (next == 0) ! 534: return 0; ! 535: ! 536: return ((GET_CODE (next) == JUMP_INSN ! 537: || GET_CODE (next) == INSN ! 538: || GET_CODE (next) == CALL_INSN) ! 539: && ! inequality_comparisons_p (PATTERN (next))); ! 540: } ! 541: ! 542: #if 0 /* This is useless since the insn that sets the cc's ! 543: must be followed immediately by the use of them. */ ! 544: /* Return 1 if the CC value set up by INSN is not used. */ ! 545: ! 546: int ! 547: next_insns_test_no_inequality (insn) ! 548: rtx insn; ! 549: { ! 550: register rtx next = NEXT_INSN (insn); ! 551: ! 552: for (; next != 0; next = NEXT_INSN (next)) ! 553: { ! 554: if (GET_CODE (next) == CODE_LABEL ! 555: || GET_CODE (next) == BARRIER) ! 556: return 1; ! 557: if (GET_CODE (next) == NOTE) ! 558: continue; ! 559: if (inequality_comparisons_p (PATTERN (next))) ! 560: return 0; ! 561: if (sets_cc0_p (PATTERN (next)) == 1) ! 562: return 1; ! 563: if (! reg_mentioned_p (cc0_rtx, PATTERN (next))) ! 564: return 1; ! 565: } ! 566: return 1; ! 567: } ! 568: #endif ! 569: #endif ! 570: ! 571: /* This is used by find_single_use to locate an rtx that contains exactly one ! 572: use of DEST, which is typically either a REG or CC0. It returns a ! 573: pointer to the innermost rtx expression containing DEST. Appearances of ! 574: DEST that are being used to totally replace it are not counted. */ ! 575: ! 576: static rtx * ! 577: find_single_use_1 (dest, loc) ! 578: rtx dest; ! 579: rtx *loc; ! 580: { ! 581: rtx x = *loc; ! 582: enum rtx_code code = GET_CODE (x); ! 583: rtx *result = 0; ! 584: rtx *this_result; ! 585: int i; ! 586: char *fmt; ! 587: ! 588: switch (code) ! 589: { ! 590: case CONST_INT: ! 591: case CONST: ! 592: case LABEL_REF: ! 593: case SYMBOL_REF: ! 594: case CONST_DOUBLE: ! 595: case CLOBBER: ! 596: return 0; ! 597: ! 598: case SET: ! 599: /* If the destination is anything other than CC0, PC, a REG or a SUBREG ! 600: of a REG that occupies all of the REG, the insn uses DEST if ! 601: it is mentioned in the destination or the source. Otherwise, we ! 602: need just check the source. */ ! 603: if (GET_CODE (SET_DEST (x)) != CC0 ! 604: && GET_CODE (SET_DEST (x)) != PC ! 605: && GET_CODE (SET_DEST (x)) != REG ! 606: && ! (GET_CODE (SET_DEST (x)) == SUBREG ! 607: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG ! 608: && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x)))) ! 609: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) ! 610: == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x))) ! 611: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))) ! 612: break; ! 613: ! 614: return find_single_use_1 (dest, &SET_SRC (x)); ! 615: ! 616: case MEM: ! 617: case SUBREG: ! 618: return find_single_use_1 (dest, &XEXP (x, 0)); ! 619: } ! 620: ! 621: /* If it wasn't one of the common cases above, check each expression and ! 622: vector of this code. Look for a unique usage of DEST. */ ! 623: ! 624: fmt = GET_RTX_FORMAT (code); ! 625: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 626: { ! 627: if (fmt[i] == 'e') ! 628: { ! 629: if (dest == XEXP (x, i) ! 630: || (GET_CODE (dest) == REG && GET_CODE (XEXP (x, i)) == REG ! 631: && REGNO (dest) == REGNO (XEXP (x, i)))) ! 632: this_result = loc; ! 633: else ! 634: this_result = find_single_use_1 (dest, &XEXP (x, i)); ! 635: ! 636: if (result == 0) ! 637: result = this_result; ! 638: else if (this_result) ! 639: /* Duplicate usage. */ ! 640: return 0; ! 641: } ! 642: else if (fmt[i] == 'E') ! 643: { ! 644: int j; ! 645: ! 646: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 647: { ! 648: if (XVECEXP (x, i, j) == dest ! 649: || (GET_CODE (dest) == REG ! 650: && GET_CODE (XVECEXP (x, i, j)) == REG ! 651: && REGNO (XVECEXP (x, i, j)) == REGNO (dest))) ! 652: this_result = loc; ! 653: else ! 654: this_result = find_single_use_1 (dest, &XVECEXP (x, i, j)); ! 655: ! 656: if (result == 0) ! 657: result = this_result; ! 658: else if (this_result) ! 659: return 0; ! 660: } ! 661: } ! 662: } ! 663: ! 664: return result; ! 665: } ! 666: ! 667: /* See if DEST, produced in INSN, is used only a single time in the ! 668: sequel. If so, return a pointer to the innermost rtx expression in which ! 669: it is used. ! 670: ! 671: If PLOC is non-zero, *PLOC is set to the insn containing the single use. ! 672: ! 673: This routine will return usually zero either before flow is called (because ! 674: there will be no LOG_LINKS notes) or after reload (because the REG_DEAD ! 675: note can't be trusted). ! 676: ! 677: If DEST is cc0_rtx, we look only at the next insn. In that case, we don't ! 678: care about REG_DEAD notes or LOG_LINKS. ! 679: ! 680: Otherwise, we find the single use by finding an insn that has a ! 681: LOG_LINKS pointing at INSN and has a REG_DEAD note for DEST. If DEST is ! 682: only referenced once in that insn, we know that it must be the first ! 683: and last insn referencing DEST. */ ! 684: ! 685: rtx * ! 686: find_single_use (dest, insn, ploc) ! 687: rtx dest; ! 688: rtx insn; ! 689: rtx *ploc; ! 690: { ! 691: rtx next; ! 692: rtx *result; ! 693: rtx link; ! 694: ! 695: #ifdef HAVE_cc0 ! 696: if (dest == cc0_rtx) ! 697: { ! 698: next = NEXT_INSN (insn); ! 699: if (next == 0 ! 700: || (GET_CODE (next) != INSN && GET_CODE (next) != JUMP_INSN)) ! 701: return 0; ! 702: ! 703: result = find_single_use_1 (dest, &PATTERN (next)); ! 704: if (result && ploc) ! 705: *ploc = next; ! 706: return result; ! 707: } ! 708: #endif ! 709: ! 710: if (reload_completed || reload_in_progress || GET_CODE (dest) != REG) ! 711: return 0; ! 712: ! 713: for (next = next_nonnote_insn (insn); ! 714: next != 0 && GET_CODE (next) != CODE_LABEL; ! 715: next = next_nonnote_insn (next)) ! 716: if (GET_RTX_CLASS (GET_CODE (next)) == 'i' && dead_or_set_p (next, dest)) ! 717: { ! 718: for (link = LOG_LINKS (next); link; link = XEXP (link, 1)) ! 719: if (XEXP (link, 0) == insn) ! 720: break; ! 721: ! 722: if (link) ! 723: { ! 724: result = find_single_use_1 (dest, &PATTERN (next)); ! 725: if (ploc) ! 726: *ploc = next; ! 727: return result; ! 728: } ! 729: } ! 730: ! 731: return 0; ! 732: } ! 733: ! 734: /* Return 1 if OP is a valid general operand for machine mode MODE. ! 735: This is either a register reference, a memory reference, ! 736: or a constant. In the case of a memory reference, the address ! 737: is checked for general validity for the target machine. ! 738: ! 739: Register and memory references must have mode MODE in order to be valid, ! 740: but some constants have no machine mode and are valid for any mode. ! 741: ! 742: If MODE is VOIDmode, OP is checked for validity for whatever mode ! 743: it has. ! 744: ! 745: The main use of this function is as a predicate in match_operand ! 746: expressions in the machine description. ! 747: ! 748: For an explaination of this function's behavior for registers of ! 749: class NO_REGS, see the comment for `register_operand'. */ ! 750: ! 751: int ! 752: general_operand (op, mode) ! 753: register rtx op; ! 754: enum machine_mode mode; ! 755: { ! 756: register enum rtx_code code = GET_CODE (op); ! 757: int mode_altering_drug = 0; ! 758: ! 759: if (mode == VOIDmode) ! 760: mode = GET_MODE (op); ! 761: ! 762: /* Don't accept CONST_INT or anything similar ! 763: if the caller wants something floating. */ ! 764: if (GET_MODE (op) == VOIDmode && mode != VOIDmode ! 765: && GET_MODE_CLASS (mode) != MODE_INT) ! 766: return 0; ! 767: ! 768: if (CONSTANT_P (op)) ! 769: return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode) ! 770: #ifdef LEGITIMATE_PIC_OPERAND_P ! 771: && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)) ! 772: #endif ! 773: && LEGITIMATE_CONSTANT_P (op)); ! 774: ! 775: /* Except for certain constants with VOIDmode, already checked for, ! 776: OP's mode must match MODE if MODE specifies a mode. */ ! 777: ! 778: if (GET_MODE (op) != mode) ! 779: return 0; ! 780: ! 781: if (code == SUBREG) ! 782: { ! 783: #ifdef INSN_SCHEDULING ! 784: /* On machines that have insn scheduling, we want all memory ! 785: reference to be explicit, so outlaw paradoxical SUBREGs. */ ! 786: if (GET_CODE (SUBREG_REG (op)) == MEM ! 787: && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) ! 788: return 0; ! 789: #endif ! 790: ! 791: op = SUBREG_REG (op); ! 792: code = GET_CODE (op); ! 793: #if 0 ! 794: /* No longer needed, since (SUBREG (MEM...)) ! 795: will load the MEM into a reload reg in the MEM's own mode. */ ! 796: mode_altering_drug = 1; ! 797: #endif ! 798: } ! 799: ! 800: if (code == REG) ! 801: /* A register whose class is NO_REGS is not a general operand. */ ! 802: return (REGNO (op) >= FIRST_PSEUDO_REGISTER ! 803: || REGNO_REG_CLASS (REGNO (op)) != NO_REGS); ! 804: ! 805: if (code == MEM) ! 806: { ! 807: register rtx y = XEXP (op, 0); ! 808: if (! volatile_ok && MEM_VOLATILE_P (op)) ! 809: return 0; ! 810: /* Use the mem's mode, since it will be reloaded thus. */ ! 811: mode = GET_MODE (op); ! 812: GO_IF_LEGITIMATE_ADDRESS (mode, y, win); ! 813: } ! 814: return 0; ! 815: ! 816: win: ! 817: if (mode_altering_drug) ! 818: return ! mode_dependent_address_p (XEXP (op, 0)); ! 819: return 1; ! 820: } ! 821: ! 822: /* Return 1 if OP is a valid memory address for a memory reference ! 823: of mode MODE. ! 824: ! 825: The main use of this function is as a predicate in match_operand ! 826: expressions in the machine description. */ ! 827: ! 828: int ! 829: address_operand (op, mode) ! 830: register rtx op; ! 831: enum machine_mode mode; ! 832: { ! 833: return memory_address_p (mode, op); ! 834: } ! 835: ! 836: /* Return 1 if OP is a register reference of mode MODE. ! 837: If MODE is VOIDmode, accept a register in any mode. ! 838: ! 839: The main use of this function is as a predicate in match_operand ! 840: expressions in the machine description. ! 841: ! 842: As a special exception, registers whose class is NO_REGS are ! 843: not accepted by `register_operand'. The reason for this change ! 844: is to allow the representation of special architecture artifacts ! 845: (such as a condition code register) without extending the rtl ! 846: definitions. Since registers of class NO_REGS cannot be used ! 847: as registers in any case where register classes are examined, ! 848: it is most consistent to keep this function from accepting them. */ ! 849: ! 850: int ! 851: register_operand (op, mode) ! 852: register rtx op; ! 853: enum machine_mode mode; ! 854: { ! 855: if (GET_MODE (op) != mode && mode != VOIDmode) ! 856: return 0; ! 857: ! 858: if (GET_CODE (op) == SUBREG) ! 859: { ! 860: /* Before reload, we can allow (SUBREG (MEM...)) as a register operand ! 861: because it is guaranteed to be reloaded into one. ! 862: Just make sure the MEM is valid in itself. ! 863: (Ideally, (SUBREG (MEM)...) should not exist after reload, ! 864: but currently it does result from (SUBREG (REG)...) where the ! 865: reg went on the stack.) */ ! 866: if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM) ! 867: return general_operand (op, mode); ! 868: op = SUBREG_REG (op); ! 869: } ! 870: ! 871: /* We don't consider registers whose class is NO_REGS ! 872: to be a register operand. */ ! 873: return (GET_CODE (op) == REG ! 874: && (REGNO (op) >= FIRST_PSEUDO_REGISTER ! 875: || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); ! 876: } ! 877: ! 878: /* Return 1 if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH ! 879: or a hard register. */ ! 880: ! 881: int ! 882: scratch_operand (op, mode) ! 883: register rtx op; ! 884: enum machine_mode mode; ! 885: { ! 886: return (GET_MODE (op) == mode ! 887: && (GET_CODE (op) == SCRATCH ! 888: || (GET_CODE (op) == REG ! 889: && REGNO (op) < FIRST_PSEUDO_REGISTER))); ! 890: } ! 891: ! 892: /* Return 1 if OP is a valid immediate operand for mode MODE. ! 893: ! 894: The main use of this function is as a predicate in match_operand ! 895: expressions in the machine description. */ ! 896: ! 897: int ! 898: immediate_operand (op, mode) ! 899: register rtx op; ! 900: enum machine_mode mode; ! 901: { ! 902: /* Don't accept CONST_INT or anything similar ! 903: if the caller wants something floating. */ ! 904: if (GET_MODE (op) == VOIDmode && mode != VOIDmode ! 905: && GET_MODE_CLASS (mode) != MODE_INT) ! 906: return 0; ! 907: ! 908: return (CONSTANT_P (op) ! 909: && (GET_MODE (op) == mode || mode == VOIDmode ! 910: || GET_MODE (op) == VOIDmode) ! 911: #ifdef LEGITIMATE_PIC_OPERAND_P ! 912: && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)) ! 913: #endif ! 914: && LEGITIMATE_CONSTANT_P (op)); ! 915: } ! 916: ! 917: /* Returns 1 if OP is an operand that is a CONST_INT. */ ! 918: ! 919: int ! 920: const_int_operand (op, mode) ! 921: register rtx op; ! 922: enum machine_mode mode; ! 923: { ! 924: return GET_CODE (op) == CONST_INT; ! 925: } ! 926: ! 927: /* Returns 1 if OP is an operand that is a constant integer or constant ! 928: floating-point number. */ ! 929: ! 930: int ! 931: const_double_operand (op, mode) ! 932: register rtx op; ! 933: enum machine_mode mode; ! 934: { ! 935: /* Don't accept CONST_INT or anything similar ! 936: if the caller wants something floating. */ ! 937: if (GET_MODE (op) == VOIDmode && mode != VOIDmode ! 938: && GET_MODE_CLASS (mode) != MODE_INT) ! 939: return 0; ! 940: ! 941: return ((GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT) ! 942: && (mode == VOIDmode || GET_MODE (op) == mode ! 943: || GET_MODE (op) == VOIDmode)); ! 944: } ! 945: ! 946: /* Return 1 if OP is a general operand that is not an immediate operand. */ ! 947: ! 948: int ! 949: nonimmediate_operand (op, mode) ! 950: register rtx op; ! 951: enum machine_mode mode; ! 952: { ! 953: return (general_operand (op, mode) && ! CONSTANT_P (op)); ! 954: } ! 955: ! 956: /* Return 1 if OP is a register reference or immediate value of mode MODE. */ ! 957: ! 958: int ! 959: nonmemory_operand (op, mode) ! 960: register rtx op; ! 961: enum machine_mode mode; ! 962: { ! 963: if (CONSTANT_P (op)) ! 964: { ! 965: /* Don't accept CONST_INT or anything similar ! 966: if the caller wants something floating. */ ! 967: if (GET_MODE (op) == VOIDmode && mode != VOIDmode ! 968: && GET_MODE_CLASS (mode) != MODE_INT) ! 969: return 0; ! 970: ! 971: return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode) ! 972: #ifdef LEGITIMATE_PIC_OPERAND_P ! 973: && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)) ! 974: #endif ! 975: && LEGITIMATE_CONSTANT_P (op)); ! 976: } ! 977: ! 978: if (GET_MODE (op) != mode && mode != VOIDmode) ! 979: return 0; ! 980: ! 981: if (GET_CODE (op) == SUBREG) ! 982: { ! 983: /* Before reload, we can allow (SUBREG (MEM...)) as a register operand ! 984: because it is guaranteed to be reloaded into one. ! 985: Just make sure the MEM is valid in itself. ! 986: (Ideally, (SUBREG (MEM)...) should not exist after reload, ! 987: but currently it does result from (SUBREG (REG)...) where the ! 988: reg went on the stack.) */ ! 989: if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM) ! 990: return general_operand (op, mode); ! 991: op = SUBREG_REG (op); ! 992: } ! 993: ! 994: /* We don't consider registers whose class is NO_REGS ! 995: to be a register operand. */ ! 996: return (GET_CODE (op) == REG ! 997: && (REGNO (op) >= FIRST_PSEUDO_REGISTER ! 998: || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); ! 999: } ! 1000: ! 1001: /* Return 1 if OP is a valid operand that stands for pushing a ! 1002: value of mode MODE onto the stack. ! 1003: ! 1004: The main use of this function is as a predicate in match_operand ! 1005: expressions in the machine description. */ ! 1006: ! 1007: int ! 1008: push_operand (op, mode) ! 1009: rtx op; ! 1010: enum machine_mode mode; ! 1011: { ! 1012: if (GET_CODE (op) != MEM) ! 1013: return 0; ! 1014: ! 1015: if (GET_MODE (op) != mode) ! 1016: return 0; ! 1017: ! 1018: op = XEXP (op, 0); ! 1019: ! 1020: if (GET_CODE (op) != STACK_PUSH_CODE) ! 1021: return 0; ! 1022: ! 1023: return XEXP (op, 0) == stack_pointer_rtx; ! 1024: } ! 1025: ! 1026: /* Return 1 if ADDR is a valid memory address for mode MODE. */ ! 1027: ! 1028: int ! 1029: memory_address_p (mode, addr) ! 1030: enum machine_mode mode; ! 1031: register rtx addr; ! 1032: { ! 1033: GO_IF_LEGITIMATE_ADDRESS (mode, addr, win); ! 1034: return 0; ! 1035: ! 1036: win: ! 1037: return 1; ! 1038: } ! 1039: ! 1040: /* Return 1 if OP is a valid memory reference with mode MODE, ! 1041: including a valid address. ! 1042: ! 1043: The main use of this function is as a predicate in match_operand ! 1044: expressions in the machine description. */ ! 1045: ! 1046: int ! 1047: memory_operand (op, mode) ! 1048: register rtx op; ! 1049: enum machine_mode mode; ! 1050: { ! 1051: rtx inner; ! 1052: ! 1053: if (! reload_completed) ! 1054: /* Note that no SUBREG is a memory operand before end of reload pass, ! 1055: because (SUBREG (MEM...)) forces reloading into a register. */ ! 1056: return GET_CODE (op) == MEM && general_operand (op, mode); ! 1057: ! 1058: if (mode != VOIDmode && GET_MODE (op) != mode) ! 1059: return 0; ! 1060: ! 1061: inner = op; ! 1062: if (GET_CODE (inner) == SUBREG) ! 1063: inner = SUBREG_REG (inner); ! 1064: ! 1065: return (GET_CODE (inner) == MEM && general_operand (op, mode)); ! 1066: } ! 1067: ! 1068: /* Return 1 if OP is a valid indirect memory reference with mode MODE; ! 1069: that is, a memory reference whose address is a general_operand. */ ! 1070: ! 1071: int ! 1072: indirect_operand (op, mode) ! 1073: register rtx op; ! 1074: enum machine_mode mode; ! 1075: { ! 1076: /* Before reload, a SUBREG isn't in memory (see memory_operand, above). */ ! 1077: if (! reload_completed ! 1078: && GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == MEM) ! 1079: { ! 1080: register int offset = SUBREG_WORD (op) * UNITS_PER_WORD; ! 1081: rtx inner = SUBREG_REG (op); ! 1082: ! 1083: #if BYTES_BIG_ENDIAN ! 1084: offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op))) ! 1085: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (inner)))); ! 1086: #endif ! 1087: ! 1088: /* The only way that we can have a general_operand as the resulting ! 1089: address is if OFFSET is zero and the address already is an operand ! 1090: or if the address is (plus Y (const_int -OFFSET)) and Y is an ! 1091: operand. */ ! 1092: ! 1093: return ((offset == 0 && general_operand (XEXP (inner, 0), Pmode)) ! 1094: || (GET_CODE (XEXP (inner, 0)) == PLUS ! 1095: && GET_CODE (XEXP (XEXP (inner, 0), 1)) == CONST_INT ! 1096: && INTVAL (XEXP (XEXP (inner, 0), 1)) == -offset ! 1097: && general_operand (XEXP (XEXP (inner, 0), 0), Pmode))); ! 1098: } ! 1099: ! 1100: return (GET_CODE (op) == MEM ! 1101: && memory_operand (op, mode) ! 1102: && general_operand (XEXP (op, 0), Pmode)); ! 1103: } ! 1104: ! 1105: /* Return 1 if this is a comparison operator. This allows the use of ! 1106: MATCH_OPERATOR to recognize all the branch insns. */ ! 1107: ! 1108: int ! 1109: comparison_operator (op, mode) ! 1110: register rtx op; ! 1111: enum machine_mode mode; ! 1112: { ! 1113: return ((mode == VOIDmode || GET_MODE (op) == mode) ! 1114: && GET_RTX_CLASS (GET_CODE (op)) == '<'); ! 1115: } ! 1116: ! 1117: /* If BODY is an insn body that uses ASM_OPERANDS, ! 1118: return the number of operands (both input and output) in the insn. ! 1119: Otherwise return -1. */ ! 1120: ! 1121: int ! 1122: asm_noperands (body) ! 1123: rtx body; ! 1124: { ! 1125: if (GET_CODE (body) == ASM_OPERANDS) ! 1126: /* No output operands: return number of input operands. */ ! 1127: return ASM_OPERANDS_INPUT_LENGTH (body); ! 1128: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 1129: /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */ ! 1130: return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)) + 1; ! 1131: else if (GET_CODE (body) == PARALLEL ! 1132: && GET_CODE (XVECEXP (body, 0, 0)) == SET ! 1133: && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS) ! 1134: { ! 1135: /* Multiple output operands, or 1 output plus some clobbers: ! 1136: body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */ ! 1137: int i; ! 1138: int n_sets; ! 1139: ! 1140: /* Count backwards through CLOBBERs to determine number of SETs. */ ! 1141: for (i = XVECLEN (body, 0); i > 0; i--) ! 1142: { ! 1143: if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET) ! 1144: break; ! 1145: if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER) ! 1146: return -1; ! 1147: } ! 1148: ! 1149: /* N_SETS is now number of output operands. */ ! 1150: n_sets = i; ! 1151: ! 1152: /* Verify that all the SETs we have ! 1153: came from a single original asm_operands insn ! 1154: (so that invalid combinations are blocked). */ ! 1155: for (i = 0; i < n_sets; i++) ! 1156: { ! 1157: rtx elt = XVECEXP (body, 0, i); ! 1158: if (GET_CODE (elt) != SET) ! 1159: return -1; ! 1160: if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS) ! 1161: return -1; ! 1162: /* If these ASM_OPERANDS rtx's came from different original insns ! 1163: then they aren't allowed together. */ ! 1164: if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt)) ! 1165: != ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (body, 0, 0)))) ! 1166: return -1; ! 1167: } ! 1168: return (ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0))) ! 1169: + n_sets); ! 1170: } ! 1171: else if (GET_CODE (body) == PARALLEL ! 1172: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 1173: { ! 1174: /* 0 outputs, but some clobbers: ! 1175: body is [(asm_operands ...) (clobber (reg ...))...]. */ ! 1176: int i; ! 1177: ! 1178: /* Make sure all the other parallel things really are clobbers. */ ! 1179: for (i = XVECLEN (body, 0) - 1; i > 0; i--) ! 1180: if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER) ! 1181: return -1; ! 1182: ! 1183: return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0)); ! 1184: } ! 1185: else ! 1186: return -1; ! 1187: } ! 1188: ! 1189: /* Assuming BODY is an insn body that uses ASM_OPERANDS, ! 1190: copy its operands (both input and output) into the vector OPERANDS, ! 1191: the locations of the operands within the insn into the vector OPERAND_LOCS, ! 1192: and the constraints for the operands into CONSTRAINTS. ! 1193: Write the modes of the operands into MODES. ! 1194: Return the assembler-template. ! 1195: ! 1196: If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0, ! 1197: we don't store that info. */ ! 1198: ! 1199: char * ! 1200: decode_asm_operands (body, operands, operand_locs, constraints, modes) ! 1201: rtx body; ! 1202: rtx *operands; ! 1203: rtx **operand_locs; ! 1204: char **constraints; ! 1205: enum machine_mode *modes; ! 1206: { ! 1207: register int i; ! 1208: int noperands; ! 1209: char *template = 0; ! 1210: ! 1211: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 1212: { ! 1213: rtx asmop = SET_SRC (body); ! 1214: /* Single output operand: BODY is (set OUTPUT (asm_operands ....)). */ ! 1215: ! 1216: noperands = ASM_OPERANDS_INPUT_LENGTH (asmop) + 1; ! 1217: ! 1218: for (i = 1; i < noperands; i++) ! 1219: { ! 1220: if (operand_locs) ! 1221: operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i - 1); ! 1222: if (operands) ! 1223: operands[i] = ASM_OPERANDS_INPUT (asmop, i - 1); ! 1224: if (constraints) ! 1225: constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i - 1); ! 1226: if (modes) ! 1227: modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i - 1); ! 1228: } ! 1229: ! 1230: /* The output is in the SET. ! 1231: Its constraint is in the ASM_OPERANDS itself. */ ! 1232: if (operands) ! 1233: operands[0] = SET_DEST (body); ! 1234: if (operand_locs) ! 1235: operand_locs[0] = &SET_DEST (body); ! 1236: if (constraints) ! 1237: constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop); ! 1238: if (modes) ! 1239: modes[0] = GET_MODE (SET_DEST (body)); ! 1240: template = ASM_OPERANDS_TEMPLATE (asmop); ! 1241: } ! 1242: else if (GET_CODE (body) == ASM_OPERANDS) ! 1243: { ! 1244: rtx asmop = body; ! 1245: /* No output operands: BODY is (asm_operands ....). */ ! 1246: ! 1247: noperands = ASM_OPERANDS_INPUT_LENGTH (asmop); ! 1248: ! 1249: /* The input operands are found in the 1st element vector. */ ! 1250: /* Constraints for inputs are in the 2nd element vector. */ ! 1251: for (i = 0; i < noperands; i++) ! 1252: { ! 1253: if (operand_locs) ! 1254: operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i); ! 1255: if (operands) ! 1256: operands[i] = ASM_OPERANDS_INPUT (asmop, i); ! 1257: if (constraints) ! 1258: constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i); ! 1259: if (modes) ! 1260: modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i); ! 1261: } ! 1262: template = ASM_OPERANDS_TEMPLATE (asmop); ! 1263: } ! 1264: else if (GET_CODE (body) == PARALLEL ! 1265: && GET_CODE (XVECEXP (body, 0, 0)) == SET) ! 1266: { ! 1267: rtx asmop = SET_SRC (XVECEXP (body, 0, 0)); ! 1268: int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */ ! 1269: int nin = ASM_OPERANDS_INPUT_LENGTH (asmop); ! 1270: int nout = 0; /* Does not include CLOBBERs. */ ! 1271: ! 1272: /* At least one output, plus some CLOBBERs. */ ! 1273: ! 1274: /* The outputs are in the SETs. ! 1275: Their constraints are in the ASM_OPERANDS itself. */ ! 1276: for (i = 0; i < nparallel; i++) ! 1277: { ! 1278: if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) ! 1279: break; /* Past last SET */ ! 1280: ! 1281: if (operands) ! 1282: operands[i] = SET_DEST (XVECEXP (body, 0, i)); ! 1283: if (operand_locs) ! 1284: operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i)); ! 1285: if (constraints) ! 1286: constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1); ! 1287: if (modes) ! 1288: modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i))); ! 1289: nout++; ! 1290: } ! 1291: ! 1292: for (i = 0; i < nin; i++) ! 1293: { ! 1294: if (operand_locs) ! 1295: operand_locs[i + nout] = &ASM_OPERANDS_INPUT (asmop, i); ! 1296: if (operands) ! 1297: operands[i + nout] = ASM_OPERANDS_INPUT (asmop, i); ! 1298: if (constraints) ! 1299: constraints[i + nout] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i); ! 1300: if (modes) ! 1301: modes[i + nout] = ASM_OPERANDS_INPUT_MODE (asmop, i); ! 1302: } ! 1303: ! 1304: template = ASM_OPERANDS_TEMPLATE (asmop); ! 1305: } ! 1306: else if (GET_CODE (body) == PARALLEL ! 1307: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 1308: { ! 1309: /* No outputs, but some CLOBBERs. */ ! 1310: ! 1311: rtx asmop = XVECEXP (body, 0, 0); ! 1312: int nin = ASM_OPERANDS_INPUT_LENGTH (asmop); ! 1313: ! 1314: for (i = 0; i < nin; i++) ! 1315: { ! 1316: if (operand_locs) ! 1317: operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i); ! 1318: if (operands) ! 1319: operands[i] = ASM_OPERANDS_INPUT (asmop, i); ! 1320: if (constraints) ! 1321: constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i); ! 1322: if (modes) ! 1323: modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i); ! 1324: } ! 1325: ! 1326: template = ASM_OPERANDS_TEMPLATE (asmop); ! 1327: } ! 1328: ! 1329: return template; ! 1330: } ! 1331: ! 1332: extern rtx plus_constant_for_output (); ! 1333: extern rtx copy_rtx (); ! 1334: ! 1335: /* Given an rtx *P, if it is a sum containing an integer constant term, ! 1336: return the location (type rtx *) of the pointer to that constant term. ! 1337: Otherwise, return a null pointer. */ ! 1338: ! 1339: static rtx * ! 1340: find_constant_term_loc (p) ! 1341: rtx *p; ! 1342: { ! 1343: register rtx *tem; ! 1344: register enum rtx_code code = GET_CODE (*p); ! 1345: ! 1346: /* If *P IS such a constant term, P is its location. */ ! 1347: ! 1348: if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF ! 1349: || code == CONST) ! 1350: return p; ! 1351: ! 1352: /* Otherwise, if not a sum, it has no constant term. */ ! 1353: ! 1354: if (GET_CODE (*p) != PLUS) ! 1355: return 0; ! 1356: ! 1357: /* If one of the summands is constant, return its location. */ ! 1358: ! 1359: if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0)) ! 1360: && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1))) ! 1361: return p; ! 1362: ! 1363: /* Otherwise, check each summand for containing a constant term. */ ! 1364: ! 1365: if (XEXP (*p, 0) != 0) ! 1366: { ! 1367: tem = find_constant_term_loc (&XEXP (*p, 0)); ! 1368: if (tem != 0) ! 1369: return tem; ! 1370: } ! 1371: ! 1372: if (XEXP (*p, 1) != 0) ! 1373: { ! 1374: tem = find_constant_term_loc (&XEXP (*p, 1)); ! 1375: if (tem != 0) ! 1376: return tem; ! 1377: } ! 1378: ! 1379: return 0; ! 1380: } ! 1381: ! 1382: /* Return 1 if OP is a memory reference ! 1383: whose address contains no side effects ! 1384: and remains valid after the addition ! 1385: of a positive integer less than the ! 1386: size of the object being referenced. ! 1387: ! 1388: We assume that the original address is valid and do not check it. ! 1389: ! 1390: This uses strict_memory_address_p as a subroutine, so ! 1391: don't use it before reload. */ ! 1392: ! 1393: int ! 1394: offsettable_memref_p (op) ! 1395: rtx op; ! 1396: { ! 1397: return ((GET_CODE (op) == MEM) ! 1398: && offsettable_address_p (1, GET_MODE (op), XEXP (op, 0))); ! 1399: } ! 1400: ! 1401: /* Similar, but don't require a strictly valid mem ref: ! 1402: consider pseudo-regs valid as index or base regs. */ ! 1403: ! 1404: int ! 1405: offsettable_nonstrict_memref_p (op) ! 1406: rtx op; ! 1407: { ! 1408: return ((GET_CODE (op) == MEM) ! 1409: && offsettable_address_p (0, GET_MODE (op), XEXP (op, 0))); ! 1410: } ! 1411: ! 1412: /* Return 1 if Y is a memory address which contains no side effects ! 1413: and would remain valid after the addition of a positive integer ! 1414: less than the size of that mode. ! 1415: ! 1416: We assume that the original address is valid and do not check it. ! 1417: We do check that it is valid for narrower modes. ! 1418: ! 1419: If STRICTP is nonzero, we require a strictly valid address, ! 1420: for the sake of use in reload.c. */ ! 1421: ! 1422: int ! 1423: offsettable_address_p (strictp, mode, y) ! 1424: int strictp; ! 1425: enum machine_mode mode; ! 1426: register rtx y; ! 1427: { ! 1428: register enum rtx_code ycode = GET_CODE (y); ! 1429: register rtx z; ! 1430: rtx y1 = y; ! 1431: rtx *y2; ! 1432: int (*addressp) () = (strictp ? strict_memory_address_p : memory_address_p); ! 1433: ! 1434: if (CONSTANT_ADDRESS_P (y)) ! 1435: return 1; ! 1436: ! 1437: /* Adjusting an offsettable address involves changing to a narrower mode. ! 1438: Make sure that's OK. */ ! 1439: ! 1440: if (mode_dependent_address_p (y)) ! 1441: return 0; ! 1442: ! 1443: /* If the expression contains a constant term, ! 1444: see if it remains valid when max possible offset is added. */ ! 1445: ! 1446: if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1))) ! 1447: { ! 1448: int good; ! 1449: ! 1450: y1 = *y2; ! 1451: *y2 = plus_constant (*y2, GET_MODE_SIZE (mode) - 1); ! 1452: /* Use QImode because an odd displacement may be automatically invalid ! 1453: for any wider mode. But it should be valid for a single byte. */ ! 1454: good = (*addressp) (QImode, y); ! 1455: ! 1456: /* In any case, restore old contents of memory. */ ! 1457: *y2 = y1; ! 1458: return good; ! 1459: } ! 1460: ! 1461: if (ycode == PRE_DEC || ycode == PRE_INC ! 1462: || ycode == POST_DEC || ycode == POST_INC) ! 1463: return 0; ! 1464: ! 1465: /* The offset added here is chosen as the maximum offset that ! 1466: any instruction could need to add when operating on something ! 1467: of the specified mode. We assume that if Y and Y+c are ! 1468: valid addresses then so is Y+d for all 0<d<c. */ ! 1469: ! 1470: z = plus_constant_for_output (y, GET_MODE_SIZE (mode) - 1); ! 1471: ! 1472: /* Use QImode because an odd displacement may be automatically invalid ! 1473: for any wider mode. But it should be valid for a single byte. */ ! 1474: return (*addressp) (QImode, z); ! 1475: } ! 1476: ! 1477: /* Return 1 if ADDR is an address-expression whose effect depends ! 1478: on the mode of the memory reference it is used in. ! 1479: ! 1480: Autoincrement addressing is a typical example of mode-dependence ! 1481: because the amount of the increment depends on the mode. */ ! 1482: ! 1483: int ! 1484: mode_dependent_address_p (addr) ! 1485: rtx addr; ! 1486: { ! 1487: GO_IF_MODE_DEPENDENT_ADDRESS (addr, win); ! 1488: return 0; ! 1489: win: ! 1490: return 1; ! 1491: } ! 1492: ! 1493: /* Return 1 if OP is a general operand ! 1494: other than a memory ref with a mode dependent address. */ ! 1495: ! 1496: int ! 1497: mode_independent_operand (op, mode) ! 1498: enum machine_mode mode; ! 1499: rtx op; ! 1500: { ! 1501: rtx addr; ! 1502: ! 1503: if (! general_operand (op, mode)) ! 1504: return 0; ! 1505: ! 1506: if (GET_CODE (op) != MEM) ! 1507: return 1; ! 1508: ! 1509: addr = XEXP (op, 0); ! 1510: GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose); ! 1511: return 1; ! 1512: lose: ! 1513: return 0; ! 1514: } ! 1515: ! 1516: /* Given an operand OP that is a valid memory reference ! 1517: which satisfies offsettable_memref_p, ! 1518: return a new memory reference whose address has been adjusted by OFFSET. ! 1519: OFFSET should be positive and less than the size of the object referenced. ! 1520: */ ! 1521: ! 1522: rtx ! 1523: adj_offsettable_operand (op, offset) ! 1524: rtx op; ! 1525: int offset; ! 1526: { ! 1527: register enum rtx_code code = GET_CODE (op); ! 1528: ! 1529: if (code == MEM) ! 1530: { ! 1531: register rtx y = XEXP (op, 0); ! 1532: register rtx new; ! 1533: ! 1534: if (CONSTANT_ADDRESS_P (y)) ! 1535: { ! 1536: new = gen_rtx (MEM, GET_MODE (op), plus_constant_for_output (y, offset)); ! 1537: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op); ! 1538: return new; ! 1539: } ! 1540: ! 1541: if (GET_CODE (y) == PLUS) ! 1542: { ! 1543: rtx z = y; ! 1544: register rtx *const_loc; ! 1545: ! 1546: op = copy_rtx (op); ! 1547: z = XEXP (op, 0); ! 1548: const_loc = find_constant_term_loc (&z); ! 1549: if (const_loc) ! 1550: { ! 1551: *const_loc = plus_constant_for_output (*const_loc, offset); ! 1552: return op; ! 1553: } ! 1554: } ! 1555: ! 1556: new = gen_rtx (MEM, GET_MODE (op), plus_constant_for_output (y, offset)); ! 1557: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op); ! 1558: return new; ! 1559: } ! 1560: abort (); ! 1561: } ! 1562: ! 1563: #ifdef REGISTER_CONSTRAINTS ! 1564: ! 1565: /* Check the operands of an insn (found in recog_operands) ! 1566: against the insn's operand constraints (found via INSN_CODE_NUM) ! 1567: and return 1 if they are valid. ! 1568: ! 1569: WHICH_ALTERNATIVE is set to a number which indicates which ! 1570: alternative of constraints was matched: 0 for the first alternative, ! 1571: 1 for the next, etc. ! 1572: ! 1573: In addition, when two operands are match ! 1574: and it happens that the output operand is (reg) while the ! 1575: input operand is --(reg) or ++(reg) (a pre-inc or pre-dec), ! 1576: make the output operand look like the input. ! 1577: This is because the output operand is the one the template will print. ! 1578: ! 1579: This is used in final, just before printing the assembler code and by ! 1580: the routines that determine an insn's attribute. ! 1581: ! 1582: If STRICT is a positive non-zero value, it means that we have been ! 1583: called after reload has been completed. In that case, we must ! 1584: do all checks strictly. If it is zero, it means that we have been called ! 1585: before reload has completed. In that case, we first try to see if we can ! 1586: find an alternative that matches strictly. If not, we try again, this ! 1587: time assuming that reload will fix up the insn. This provides a "best ! 1588: guess" for the alternative and is used to compute attributes of insns prior ! 1589: to reload. A negative value of STRICT is used for this internal call. */ ! 1590: ! 1591: struct funny_match ! 1592: { ! 1593: int this, other; ! 1594: }; ! 1595: ! 1596: int ! 1597: constrain_operands (insn_code_num, strict) ! 1598: int insn_code_num; ! 1599: int strict; ! 1600: { ! 1601: char *constraints[MAX_RECOG_OPERANDS]; ! 1602: register int c; ! 1603: int noperands = insn_n_operands[insn_code_num]; ! 1604: ! 1605: struct funny_match funny_match[MAX_RECOG_OPERANDS]; ! 1606: int funny_match_index; ! 1607: int nalternatives = insn_n_alternatives[insn_code_num]; ! 1608: ! 1609: if (noperands == 0 || nalternatives == 0) ! 1610: return 1; ! 1611: ! 1612: for (c = 0; c < noperands; c++) ! 1613: constraints[c] = insn_operand_constraint[insn_code_num][c]; ! 1614: ! 1615: which_alternative = 0; ! 1616: ! 1617: while (which_alternative < nalternatives) ! 1618: { ! 1619: register int opno; ! 1620: int lose = 0; ! 1621: funny_match_index = 0; ! 1622: ! 1623: for (opno = 0; opno < noperands; opno++) ! 1624: { ! 1625: register rtx op = recog_operand[opno]; ! 1626: enum machine_mode mode = GET_MODE (op); ! 1627: register char *p = constraints[opno]; ! 1628: int offset = 0; ! 1629: int win = 0; ! 1630: int val; ! 1631: ! 1632: if (GET_CODE (op) == SUBREG) ! 1633: { ! 1634: if (GET_CODE (SUBREG_REG (op)) == REG ! 1635: && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER) ! 1636: offset = SUBREG_WORD (op); ! 1637: op = SUBREG_REG (op); ! 1638: } ! 1639: ! 1640: /* An empty constraint or empty alternative ! 1641: allows anything which matched the pattern. */ ! 1642: if (*p == 0 || *p == ',') ! 1643: win = 1; ! 1644: ! 1645: while (*p && (c = *p++) != ',') ! 1646: switch (c) ! 1647: { ! 1648: case '=': ! 1649: case '+': ! 1650: case '?': ! 1651: case '#': ! 1652: case '&': ! 1653: case '!': ! 1654: case '*': ! 1655: case '%': ! 1656: break; ! 1657: ! 1658: case '0': ! 1659: case '1': ! 1660: case '2': ! 1661: case '3': ! 1662: case '4': ! 1663: /* This operand must be the same as a previous one. ! 1664: This kind of constraint is used for instructions such ! 1665: as add when they take only two operands. ! 1666: ! 1667: Note that the lower-numbered operand is passed first. ! 1668: ! 1669: If we are not testing strictly, assume that this constraint ! 1670: will be satisfied. */ ! 1671: if (strict < 0) ! 1672: val = 1; ! 1673: else ! 1674: val = operands_match_p (recog_operand[c - '0'], ! 1675: recog_operand[opno]); ! 1676: ! 1677: if (val != 0) ! 1678: win = 1; ! 1679: /* If output is *x and input is *--x, ! 1680: arrange later to change the output to *--x as well, ! 1681: since the output op is the one that will be printed. */ ! 1682: if (val == 2 && strict > 0) ! 1683: { ! 1684: funny_match[funny_match_index].this = opno; ! 1685: funny_match[funny_match_index++].other = c - '0'; ! 1686: } ! 1687: break; ! 1688: ! 1689: case 'p': ! 1690: /* p is used for address_operands. When we are called by ! 1691: gen_input_reload, no one will have checked that the ! 1692: address is strictly valid, i.e., that all pseudos ! 1693: requiring hard regs have gotten them. */ ! 1694: if (strict <= 0 ! 1695: || (strict_memory_address_p ! 1696: (insn_operand_mode[insn_code_num][opno], op))) ! 1697: win = 1; ! 1698: break; ! 1699: ! 1700: /* No need to check general_operand again; ! 1701: it was done in insn-recog.c. */ ! 1702: case 'g': ! 1703: /* Anything goes unless it is a REG and really has a hard reg ! 1704: but the hard reg is not in the class GENERAL_REGS. */ ! 1705: if (strict < 0 ! 1706: || GENERAL_REGS == ALL_REGS ! 1707: || GET_CODE (op) != REG ! 1708: || reg_fits_class_p (op, GENERAL_REGS, offset, mode)) ! 1709: win = 1; ! 1710: break; ! 1711: ! 1712: case 'r': ! 1713: if (strict < 0 ! 1714: || (strict == 0 ! 1715: && GET_CODE (op) == REG ! 1716: && REGNO (op) >= FIRST_PSEUDO_REGISTER) ! 1717: || (strict == 0 && GET_CODE (op) == SCRATCH) ! 1718: || (GET_CODE (op) == REG ! 1719: && (GENERAL_REGS == ALL_REGS ! 1720: || reg_fits_class_p (op, GENERAL_REGS, ! 1721: offset, mode)))) ! 1722: win = 1; ! 1723: break; ! 1724: ! 1725: case 'X': ! 1726: /* This is used for a MATCH_SCRATCH in the cases when we ! 1727: don't actually need anything. So anything goes any time. */ ! 1728: win = 1; ! 1729: break; ! 1730: ! 1731: case 'm': ! 1732: if (GET_CODE (op) == MEM ! 1733: /* Before reload, accept what reload can turn into mem. */ ! 1734: || (strict < 0 && CONSTANT_P (op))) ! 1735: win = 1; ! 1736: break; ! 1737: ! 1738: case '<': ! 1739: if (GET_CODE (op) == MEM ! 1740: && (GET_CODE (XEXP (op, 0)) == PRE_DEC ! 1741: || GET_CODE (XEXP (op, 0)) == POST_DEC)) ! 1742: win = 1; ! 1743: break; ! 1744: ! 1745: case '>': ! 1746: if (GET_CODE (op) == MEM ! 1747: && (GET_CODE (XEXP (op, 0)) == PRE_INC ! 1748: || GET_CODE (XEXP (op, 0)) == POST_INC)) ! 1749: win = 1; ! 1750: break; ! 1751: ! 1752: case 'E': ! 1753: /* Match any CONST_DOUBLE, but only if ! 1754: we can examine the bits of it reliably. */ ! 1755: if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT ! 1756: || HOST_BITS_PER_INT != BITS_PER_WORD) ! 1757: && GET_CODE (op) != VOIDmode && ! flag_pretend_float) ! 1758: break; ! 1759: if (GET_CODE (op) == CONST_DOUBLE) ! 1760: win = 1; ! 1761: break; ! 1762: ! 1763: case 'F': ! 1764: if (GET_CODE (op) == CONST_DOUBLE) ! 1765: win = 1; ! 1766: break; ! 1767: ! 1768: case 'G': ! 1769: case 'H': ! 1770: if (GET_CODE (op) == CONST_DOUBLE ! 1771: && CONST_DOUBLE_OK_FOR_LETTER_P (op, c)) ! 1772: win = 1; ! 1773: break; ! 1774: ! 1775: case 's': ! 1776: if (GET_CODE (op) == CONST_INT ! 1777: || (GET_CODE (op) == CONST_DOUBLE ! 1778: && GET_MODE (op) == VOIDmode)) ! 1779: break; ! 1780: case 'i': ! 1781: if (CONSTANT_P (op)) ! 1782: win = 1; ! 1783: break; ! 1784: ! 1785: case 'n': ! 1786: if (GET_CODE (op) == CONST_INT ! 1787: || (GET_CODE (op) == CONST_DOUBLE ! 1788: && GET_MODE (op) == VOIDmode)) ! 1789: win = 1; ! 1790: break; ! 1791: ! 1792: case 'I': ! 1793: case 'J': ! 1794: case 'K': ! 1795: case 'L': ! 1796: case 'M': ! 1797: case 'N': ! 1798: case 'O': ! 1799: case 'P': ! 1800: if (GET_CODE (op) == CONST_INT ! 1801: && CONST_OK_FOR_LETTER_P (INTVAL (op), c)) ! 1802: win = 1; ! 1803: break; ! 1804: ! 1805: #ifdef EXTRA_CONSTRAINT ! 1806: case 'Q': ! 1807: case 'R': ! 1808: case 'S': ! 1809: case 'T': ! 1810: case 'U': ! 1811: if (EXTRA_CONSTRAINT (op, c)) ! 1812: win = 1; ! 1813: break; ! 1814: #endif ! 1815: ! 1816: case 'V': ! 1817: if (GET_CODE (op) == MEM ! 1818: && ! offsettable_memref_p (op)) ! 1819: win = 1; ! 1820: break; ! 1821: ! 1822: case 'o': ! 1823: if ((strict > 0 && offsettable_memref_p (op)) ! 1824: || (strict == 0 && offsettable_nonstrict_memref_p (op)) ! 1825: /* Before reload, accept what reload can handle. */ ! 1826: || (strict < 0 ! 1827: && (CONSTANT_P (op) || GET_CODE (op) == MEM))) ! 1828: win = 1; ! 1829: break; ! 1830: ! 1831: default: ! 1832: if (strict < 0 ! 1833: || (strict == 0 ! 1834: && GET_CODE (op) == REG ! 1835: && REGNO (op) >= FIRST_PSEUDO_REGISTER) ! 1836: || (strict == 0 && GET_CODE (op) == SCRATCH) ! 1837: || (GET_CODE (op) == REG ! 1838: && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c), ! 1839: offset, mode))) ! 1840: win = 1; ! 1841: } ! 1842: ! 1843: constraints[opno] = p; ! 1844: /* If this operand did not win somehow, ! 1845: this alternative loses. */ ! 1846: if (! win) ! 1847: lose = 1; ! 1848: } ! 1849: /* This alternative won; the operands are ok. ! 1850: Change whichever operands this alternative says to change. */ ! 1851: if (! lose) ! 1852: { ! 1853: while (--funny_match_index >= 0) ! 1854: { ! 1855: recog_operand[funny_match[funny_match_index].other] ! 1856: = recog_operand[funny_match[funny_match_index].this]; ! 1857: } ! 1858: return 1; ! 1859: } ! 1860: ! 1861: which_alternative++; ! 1862: } ! 1863: ! 1864: /* If we are about to reject this, but we are not to test strictly, ! 1865: try a very loose test. Only return failure if it fails also. */ ! 1866: if (strict == 0) ! 1867: return constrain_operands (insn_code_num, -1); ! 1868: else ! 1869: return 0; ! 1870: } ! 1871: ! 1872: /* Return 1 iff OPERAND (assumed to be a REG rtx) ! 1873: is a hard reg in class CLASS when its regno is offsetted by OFFSET ! 1874: and changed to mode MODE. ! 1875: If REG occupies multiple hard regs, all of them must be in CLASS. */ ! 1876: ! 1877: int ! 1878: reg_fits_class_p (operand, class, offset, mode) ! 1879: rtx operand; ! 1880: register enum reg_class class; ! 1881: int offset; ! 1882: enum machine_mode mode; ! 1883: { ! 1884: register int regno = REGNO (operand); ! 1885: if (regno < FIRST_PSEUDO_REGISTER ! 1886: && TEST_HARD_REG_BIT (reg_class_contents[(int) class], ! 1887: regno + offset)) ! 1888: { ! 1889: register int sr; ! 1890: regno += offset; ! 1891: for (sr = HARD_REGNO_NREGS (regno, mode) - 1; ! 1892: sr > 0; sr--) ! 1893: if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], ! 1894: regno + sr)) ! 1895: break; ! 1896: return sr == 0; ! 1897: } ! 1898: ! 1899: return 0; ! 1900: } ! 1901: ! 1902: #endif /* REGISTER_CONSTRAINTS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.