1;; Predicate definitions for Renesas / SuperH SH. 2;; Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 3;; 4;; This file is part of GCC. 5;; 6;; GCC is free software; you can redistribute it and/or modify 7;; it under the terms of the GNU General Public License as published by 8;; the Free Software Foundation; either version 3, or (at your option) 9;; any later version. 10;; 11;; GCC is distributed in the hope that it will be useful, 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15;; 16;; You should have received a copy of the GNU General Public License 17;; along with GCC; see the file COPYING3. If not see 18;; <http://www.gnu.org/licenses/>. 19 20;; TODO: Add a comment here. 21 22(define_predicate "trapping_target_operand" 23 (match_code "if_then_else") 24{ 25 rtx cond, mem, res, tar, and_expr; 26 27 if (GET_MODE (op) != PDImode) 28 return 0; 29 cond = XEXP (op, 0); 30 mem = XEXP (op, 1); 31 res = XEXP (op, 2); 32 if (!MEM_P (mem) 33 || (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE)) 34 return 0; 35 tar = XEXP (res, 0); 36 if (!rtx_equal_p (XEXP (mem, 0), tar) 37 || GET_MODE (tar) != Pmode) 38 return 0; 39 if (GET_CODE (cond) == CONST) 40 { 41 cond = XEXP (cond, 0); 42 if (!satisfies_constraint_Csy (tar)) 43 return 0; 44 if (GET_CODE (tar) == CONST) 45 tar = XEXP (tar, 0); 46 } 47 else if (!arith_reg_operand (tar, VOIDmode) 48 && ! satisfies_constraint_Csy (tar)) 49 return 0; 50 if (GET_CODE (cond) != EQ) 51 return 0; 52 and_expr = XEXP (cond, 0); 53 return (GET_CODE (and_expr) == AND 54 && rtx_equal_p (XEXP (and_expr, 0), tar) 55 && CONST_INT_P (XEXP (and_expr, 1)) 56 && CONST_INT_P (XEXP (cond, 1)) 57 && INTVAL (XEXP (and_expr, 1)) == 3 58 && INTVAL (XEXP (cond, 1)) == 3); 59}) 60 61;; TODO: Add a comment here. 62 63(define_predicate "and_operand" 64 (match_code "subreg,reg,const_int") 65{ 66 if (logical_operand (op, mode)) 67 return 1; 68 69 /* Check mshflo.l / mshflhi.l opportunities. */ 70 if (TARGET_SHMEDIA 71 && mode == DImode 72 && satisfies_constraint_J16 (op)) 73 return 1; 74 75 return 0; 76}) 77 78;; Like arith_reg_dest, but this predicate is defined with 79;; define_special_predicate, not define_predicate. 80 81(define_special_predicate "any_arith_reg_dest" 82 (match_code "subreg,reg") 83{ 84 return arith_reg_dest (op, mode); 85}) 86 87;; Like register_operand, but this predicate is defined with 88;; define_special_predicate, not define_predicate. 89 90(define_special_predicate "any_register_operand" 91 (match_code "subreg,reg") 92{ 93 return register_operand (op, mode); 94}) 95 96;; Returns 1 if OP is a valid source operand for an arithmetic insn. 97 98(define_predicate "arith_operand" 99 (match_code "subreg,reg,const_int,truncate") 100{ 101 if (arith_reg_operand (op, mode)) 102 return 1; 103 104 if (TARGET_SHMEDIA) 105 { 106 /* FIXME: We should be checking whether the CONST_INT fits in a 107 signed 16-bit here, but this causes reload_cse to crash when 108 attempting to transform a sequence of two 64-bit sets of the 109 same register from literal constants into a set and an add, 110 when the difference is too wide for an add. */ 111 if (CONST_INT_P (op) 112 || satisfies_constraint_Css (op)) 113 return 1; 114 else if (GET_CODE (op) == TRUNCATE 115 && REG_P (XEXP (op, 0)) 116 && ! system_reg_operand (XEXP (op, 0), VOIDmode) 117 && (mode == VOIDmode || mode == GET_MODE (op)) 118 && (GET_MODE_SIZE (GET_MODE (op)) 119 < GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) 120 && (! FP_REGISTER_P (REGNO (XEXP (op, 0))) 121 || GET_MODE_SIZE (GET_MODE (op)) == 4)) 122 return register_operand (XEXP (op, 0), VOIDmode); 123 else 124 return 0; 125 } 126 else if (satisfies_constraint_I08 (op)) 127 return 1; 128 129 return 0; 130}) 131 132;; Like above, but for DImode destinations: forbid paradoxical DImode 133;; subregs, because this would lead to missing sign extensions when 134;; truncating from DImode to SImode. 135 136(define_predicate "arith_reg_dest" 137 (match_code "subreg,reg") 138{ 139 if (mode == DImode && GET_CODE (op) == SUBREG 140 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 141 && TARGET_SHMEDIA) 142 return 0; 143 return arith_reg_operand (op, mode); 144}) 145 146;; Returns 1 if OP is a normal arithmetic register. 147 148(define_predicate "arith_reg_operand" 149 (match_code "subreg,reg,sign_extend") 150{ 151 if (register_operand (op, mode)) 152 { 153 int regno; 154 155 if (REG_P (op)) 156 regno = REGNO (op); 157 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 158 regno = REGNO (SUBREG_REG (op)); 159 else 160 return 1; 161 162 return (regno != T_REG && regno != PR_REG 163 && ! TARGET_REGISTER_P (regno) 164 && (regno != FPUL_REG || TARGET_SH4) 165 && regno != MACH_REG && regno != MACL_REG); 166 } 167 /* Allow a no-op sign extension - compare LOAD_EXTEND_OP. 168 We allow SImode here, as not using an FP register is just a matter of 169 proper register allocation. */ 170 if (TARGET_SHMEDIA 171 && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND 172 && GET_MODE (XEXP (op, 0)) == SImode 173 && GET_CODE (XEXP (op, 0)) != SUBREG) 174 return register_operand (XEXP (op, 0), VOIDmode); 175#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */ 176 if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND 177 && GET_MODE (XEXP (op, 0)) == HImode 178 && REG_P (XEXP (op, 0)) 179 && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG) 180 return register_operand (XEXP (op, 0), VOIDmode); 181#endif 182 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT 183 && GET_CODE (op) == SUBREG 184 && GET_MODE (SUBREG_REG (op)) == DImode 185 && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND 186 && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode 187 && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG) 188 return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode); 189 return 0; 190}) 191 192;; Returns 1 if OP is a valid source operand for a compare insn. 193 194(define_predicate "arith_reg_or_0_operand" 195 (match_code "subreg,reg,const_int,const_vector") 196{ 197 if (arith_reg_operand (op, mode)) 198 return 1; 199 200 if (satisfies_constraint_Z (op)) 201 return 1; 202 203 return 0; 204}) 205 206;; TODO: Add a comment here. 207 208(define_predicate "binary_float_operator" 209 (and (match_code "plus,minus,mult,div") 210 (match_test "GET_MODE (op) == mode"))) 211 212;; TODO: Add a comment here. 213 214(define_predicate "binary_logical_operator" 215 (and (match_code "and,ior,xor") 216 (match_test "GET_MODE (op) == mode"))) 217 218;; Return 1 of OP is an address suitable for a cache manipulation operation. 219;; MODE has the meaning as in address_operand. 220 221(define_special_predicate "cache_address_operand" 222 (match_code "plus,reg") 223{ 224 if (GET_CODE (op) == PLUS) 225 { 226 if (!REG_P (XEXP (op, 0))) 227 return 0; 228 if (!CONST_INT_P (XEXP (op, 1)) 229 || (INTVAL (XEXP (op, 1)) & 31)) 230 return 0; 231 } 232 else if (!REG_P (op)) 233 return 0; 234 return address_operand (op, mode); 235}) 236 237;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu. 238 239(define_predicate "cmp_operand" 240 (match_code "subreg,reg,const_int") 241{ 242 if (satisfies_constraint_N (op)) 243 return 1; 244 if (TARGET_SHMEDIA 245 && mode != DImode && GET_CODE (op) == SUBREG 246 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) 247 return 0; 248 return arith_reg_operand (op, mode); 249}) 250 251;; TODO: Add a comment here. 252 253(define_predicate "cmpsi_operand" 254 (match_code "subreg,reg,const_int") 255{ 256 if (REG_P (op) && REGNO (op) == T_REG 257 && GET_MODE (op) == SImode 258 && TARGET_SH1) 259 return 1; 260 return arith_operand (op, mode); 261}) 262 263;; TODO: Add a comment here. 264 265(define_predicate "commutative_float_operator" 266 (and (match_code "plus,mult") 267 (match_test "GET_MODE (op) == mode"))) 268 269;; TODO: Add a comment here. 270 271(define_predicate "equality_comparison_operator" 272 (match_code "eq,ne")) 273 274;; TODO: Add a comment here. 275 276(define_predicate "extend_reg_operand" 277 (match_code "subreg,reg,truncate") 278{ 279 return (GET_CODE (op) == TRUNCATE 280 ? arith_operand 281 : arith_reg_operand) (op, mode); 282}) 283 284;; TODO: Add a comment here. 285 286(define_predicate "extend_reg_or_0_operand" 287 (match_code "subreg,reg,truncate,const_int") 288{ 289 return (GET_CODE (op) == TRUNCATE 290 ? arith_operand 291 : arith_reg_or_0_operand) (op, mode); 292}) 293 294;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND. 295 296(define_predicate "ext_dest_operand" 297 (match_code "subreg,reg") 298{ 299 return arith_reg_operand (op, mode); 300}) 301 302;; TODO: Add a comment here. 303 304(define_predicate "fp_arith_reg_dest" 305 (match_code "subreg,reg") 306{ 307 if (mode == DImode && GET_CODE (op) == SUBREG 308 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8) 309 return 0; 310 return fp_arith_reg_operand (op, mode); 311}) 312 313;; TODO: Add a comment here. 314 315(define_predicate "fp_arith_reg_operand" 316 (match_code "subreg,reg") 317{ 318 if (register_operand (op, mode)) 319 { 320 int regno; 321 322 if (REG_P (op)) 323 regno = REGNO (op); 324 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 325 regno = REGNO (SUBREG_REG (op)); 326 else 327 return 1; 328 329 return (regno >= FIRST_PSEUDO_REGISTER 330 || FP_REGISTER_P (regno)); 331 } 332 return 0; 333}) 334 335;; TODO: Add a comment here. 336 337(define_predicate "fpscr_operand" 338 (match_code "reg") 339{ 340 return (REG_P (op) 341 && (REGNO (op) == FPSCR_REG 342 || (REGNO (op) >= FIRST_PSEUDO_REGISTER 343 && !(reload_in_progress || reload_completed))) 344 && GET_MODE (op) == PSImode); 345}) 346 347;; TODO: Add a comment here. 348 349(define_predicate "fpul_operand" 350 (match_code "reg") 351{ 352 if (TARGET_SHMEDIA) 353 return fp_arith_reg_operand (op, mode); 354 355 return (REG_P (op) 356 && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER) 357 && GET_MODE (op) == mode); 358}) 359 360;; TODO: Add a comment here. 361 362(define_predicate "general_extend_operand" 363 (match_code "subreg,reg,mem,truncate") 364{ 365 return (GET_CODE (op) == TRUNCATE 366 ? arith_operand 367 : nonimmediate_operand) (op, mode); 368}) 369 370;; Returns 1 if OP can be source of a simple move operation. Same as 371;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as 372;; are subregs of system registers. 373 374(define_predicate "general_movsrc_operand" 375 (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector") 376{ 377 if (MEM_P (op)) 378 { 379 rtx inside = XEXP (op, 0); 380 if (GET_CODE (inside) == CONST) 381 inside = XEXP (inside, 0); 382 383 if (GET_CODE (inside) == LABEL_REF) 384 return 1; 385 386 if (GET_CODE (inside) == PLUS 387 && GET_CODE (XEXP (inside, 0)) == LABEL_REF 388 && CONST_INT_P (XEXP (inside, 1))) 389 return 1; 390 391 /* Only post inc allowed. */ 392 if (GET_CODE (inside) == PRE_DEC) 393 return 0; 394 } 395 396 if (TARGET_SHMEDIA 397 && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR) 398 && sh_rep_vec (op, mode)) 399 return 1; 400 if (TARGET_SHMEDIA && 1 401 && GET_CODE (op) == SUBREG && GET_MODE (op) == mode 402 && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op)) 403 /* FIXME */ abort (); /* return 1; */ 404 return general_operand (op, mode); 405}) 406 407;; Returns 1 if OP can be a destination of a move. Same as 408;; general_operand, but no preinc allowed. 409 410(define_predicate "general_movdst_operand" 411 (match_code "subreg,reg,mem") 412{ 413 /* Only pre dec allowed. */ 414 if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC) 415 return 0; 416 if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG 417 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 418 && ! (high_life_started || reload_completed)) 419 return 0; 420 421 return general_operand (op, mode); 422}) 423 424;; Returns 1 if OP is a MEM that can be source of a simple move operation. 425 426(define_predicate "unaligned_load_operand" 427 (match_code "mem") 428{ 429 rtx inside; 430 431 if (!MEM_P (op) || GET_MODE (op) != mode) 432 return 0; 433 434 inside = XEXP (op, 0); 435 436 if (GET_CODE (inside) == POST_INC) 437 inside = XEXP (inside, 0); 438 439 if (REG_P (inside)) 440 return 1; 441 442 return 0; 443}) 444 445;; TODO: Add a comment here. 446 447(define_predicate "greater_comparison_operator" 448 (match_code "gt,ge,gtu,geu")) 449 450;; TODO: Add a comment here. 451 452(define_predicate "inqhi_operand" 453 (match_code "truncate") 454{ 455 if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op)) 456 return 0; 457 op = XEXP (op, 0); 458 /* Can't use true_regnum here because copy_cost wants to know about 459 SECONDARY_INPUT_RELOAD_CLASS. */ 460 return REG_P (op) && FP_REGISTER_P (REGNO (op)); 461}) 462 463;; TODO: Add a comment here. 464 465(define_special_predicate "int_gpr_dest" 466 (match_code "subreg,reg") 467{ 468 enum machine_mode op_mode = GET_MODE (op); 469 470 if (GET_MODE_CLASS (op_mode) != MODE_INT 471 || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD) 472 return 0; 473 if (! reload_completed) 474 return 0; 475 return true_regnum (op) <= LAST_GENERAL_REG; 476}) 477 478;; TODO: Add a comment here. 479 480(define_predicate "less_comparison_operator" 481 (match_code "lt,le,ltu,leu")) 482 483;; Returns 1 if OP is a valid source operand for a logical operation. 484 485(define_predicate "logical_operand" 486 (match_code "subreg,reg,const_int") 487{ 488 if (TARGET_SHMEDIA 489 && mode != DImode && GET_CODE (op) == SUBREG 490 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) 491 return 0; 492 493 if (arith_reg_operand (op, mode)) 494 return 1; 495 496 if (TARGET_SHMEDIA) 497 { 498 if (satisfies_constraint_I10 (op)) 499 return 1; 500 else 501 return 0; 502 } 503 else if (satisfies_constraint_K08 (op)) 504 return 1; 505 506 return 0; 507}) 508 509;; TODO: Add a comment here. 510 511(define_predicate "logical_operator" 512 (match_code "and,ior,xor")) 513 514;; Like arith_reg_operand, but for register source operands of narrow 515;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs. 516 517(define_predicate "logical_reg_operand" 518 (match_code "subreg,reg") 519{ 520 if (TARGET_SHMEDIA 521 && GET_CODE (op) == SUBREG 522 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4 523 && mode != DImode) 524 return 0; 525 return arith_reg_operand (op, mode); 526}) 527 528;; TODO: Add a comment here. 529 530(define_predicate "mextr_bit_offset" 531 (match_code "const_int") 532{ 533 HOST_WIDE_INT i; 534 535 if (!CONST_INT_P (op)) 536 return 0; 537 i = INTVAL (op); 538 return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0; 539}) 540 541;; TODO: Add a comment here. 542 543(define_predicate "minuend_operand" 544 (match_code "subreg,reg,truncate,const_int") 545{ 546 return op == constm1_rtx || extend_reg_or_0_operand (op, mode); 547}) 548 549;; TODO: Add a comment here. 550 551(define_predicate "noncommutative_float_operator" 552 (and (match_code "minus,div") 553 (match_test "GET_MODE (op) == mode"))) 554 555;; UNORDERED is only supported on SHMEDIA. 556 557(define_predicate "sh_float_comparison_operator" 558 (ior (match_operand 0 "ordered_comparison_operator") 559 (and (match_test "TARGET_SHMEDIA") 560 (match_code "unordered")))) 561 562(define_predicate "shmedia_cbranch_comparison_operator" 563 (ior (match_operand 0 "equality_comparison_operator") 564 (match_operand 0 "greater_comparison_operator"))) 565 566;; TODO: Add a comment here. 567 568(define_predicate "sh_const_vec" 569 (match_code "const_vector") 570{ 571 int i; 572 573 if (GET_CODE (op) != CONST_VECTOR 574 || (GET_MODE (op) != mode && mode != VOIDmode)) 575 return 0; 576 i = XVECLEN (op, 0) - 1; 577 for (; i >= 0; i--) 578 if (!CONST_INT_P (XVECEXP (op, 0, i))) 579 return 0; 580 return 1; 581}) 582 583;; Determine if OP is a constant vector matching MODE with only one 584;; element that is not a sign extension. Two byte-sized elements 585;; count as one. 586 587(define_predicate "sh_1el_vec" 588 (match_code "const_vector") 589{ 590 int unit_size; 591 int i, last, least, sign_ix; 592 rtx sign; 593 594 if (GET_CODE (op) != CONST_VECTOR 595 || (GET_MODE (op) != mode && mode != VOIDmode)) 596 return 0; 597 /* Determine numbers of last and of least significant elements. */ 598 last = XVECLEN (op, 0) - 1; 599 least = TARGET_LITTLE_ENDIAN ? 0 : last; 600 if (!CONST_INT_P (XVECEXP (op, 0, least))) 601 return 0; 602 sign_ix = least; 603 if (GET_MODE_UNIT_SIZE (mode) == 1) 604 sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1; 605 if (!CONST_INT_P (XVECEXP (op, 0, sign_ix))) 606 return 0; 607 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op)); 608 sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1) 609 ? constm1_rtx : const0_rtx); 610 i = XVECLEN (op, 0) - 1; 611 do 612 if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign) 613 return 0; 614 while (--i); 615 return 1; 616}) 617 618;; Like register_operand, but take into account that SHMEDIA can use 619;; the constant zero like a general register. 620 621(define_predicate "sh_register_operand" 622 (match_code "reg,subreg,const_int,const_double") 623{ 624 if (op == CONST0_RTX (mode) && TARGET_SHMEDIA) 625 return 1; 626 return register_operand (op, mode); 627}) 628 629;; TODO: Add a comment here. 630 631(define_predicate "sh_rep_vec" 632 (match_code "const_vector,parallel") 633{ 634 int i; 635 rtx x, y; 636 637 if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL) 638 || (GET_MODE (op) != mode && mode != VOIDmode)) 639 return 0; 640 i = XVECLEN (op, 0) - 2; 641 x = XVECEXP (op, 0, i + 1); 642 if (GET_MODE_UNIT_SIZE (mode) == 1) 643 { 644 y = XVECEXP (op, 0, i); 645 for (i -= 2; i >= 0; i -= 2) 646 if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x) 647 || ! rtx_equal_p (XVECEXP (op, 0, i), y)) 648 return 0; 649 } 650 else 651 for (; i >= 0; i--) 652 if (XVECEXP (op, 0, i) != x) 653 return 0; 654 return 1; 655}) 656 657;; TODO: Add a comment here. 658 659(define_predicate "shift_count_operand" 660 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend") 661{ 662 return (CONSTANT_P (op) 663 ? (CONST_INT_P (op) 664 ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode) 665 : nonmemory_operand (op, mode)) 666 : shift_count_reg_operand (op, mode)); 667}) 668 669;; TODO: Add a comment here. 670 671(define_predicate "shift_count_reg_operand" 672 (match_code "subreg,reg,zero_extend,sign_extend") 673{ 674 if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND 675 || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0)) 676 && (mode == VOIDmode || mode == GET_MODE (op)) 677 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 678 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT) 679 { 680 mode = VOIDmode; 681 do 682 op = XEXP (op, 0); 683 while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND 684 || GET_CODE (op) == TRUNCATE) 685 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 686 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT); 687 688 } 689 return arith_reg_operand (op, mode); 690}) 691 692;; TODO: Add a comment here. 693 694(define_predicate "shift_operator" 695 (match_code "ashift,ashiftrt,lshiftrt")) 696 697;; TODO: Add a comment here. 698 699(define_predicate "symbol_ref_operand" 700 (match_code "symbol_ref")) 701 702;; Same as target_reg_operand, except that label_refs and symbol_refs 703;; are accepted before reload. 704 705(define_special_predicate "target_operand" 706 (match_code "subreg,reg,label_ref,symbol_ref,const,unspec") 707{ 708 if (mode != VOIDmode && mode != Pmode) 709 return 0; 710 711 if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode) 712 && satisfies_constraint_Csy (op)) 713 return ! reload_completed; 714 715 return target_reg_operand (op, mode); 716}) 717 718;; Accept pseudos and branch target registers. 719 720(define_special_predicate "target_reg_operand" 721 (match_code "subreg,reg") 722{ 723 if (mode == VOIDmode 724 ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode 725 : mode != GET_MODE (op)) 726 return 0; 727 728 if (GET_CODE (op) == SUBREG) 729 op = XEXP (op, 0); 730 731 if (!REG_P (op)) 732 return 0; 733 734 /* We must protect ourselves from matching pseudos that are virtual 735 register, because they will eventually be replaced with hardware 736 registers that aren't branch-target registers. */ 737 if (REGNO (op) > LAST_VIRTUAL_REGISTER 738 || TARGET_REGISTER_P (REGNO (op))) 739 return 1; 740 741 return 0; 742}) 743 744;; TODO: Add a comment here. 745 746(define_special_predicate "trunc_hi_operand" 747 (match_code "subreg,reg,truncate") 748{ 749 enum machine_mode op_mode = GET_MODE (op); 750 751 if (op_mode != SImode && op_mode != DImode 752 && op_mode != V4HImode && op_mode != V2SImode) 753 return 0; 754 return extend_reg_operand (op, mode); 755}) 756 757;; Return 1 of OP is an address suitable for an unaligned access instruction. 758 759(define_special_predicate "ua_address_operand" 760 (match_code "subreg,reg,plus") 761{ 762 if (GET_CODE (op) == PLUS 763 && (! satisfies_constraint_I06 (XEXP (op, 1)))) 764 return 0; 765 return address_operand (op, QImode); 766}) 767 768;; TODO: Add a comment here. 769 770(define_predicate "ua_offset" 771 (match_code "const_int") 772{ 773 return satisfies_constraint_I06 (op); 774}) 775 776;; TODO: Add a comment here. 777 778(define_predicate "unary_float_operator" 779 (and (match_code "abs,neg,sqrt") 780 (match_test "GET_MODE (op) == mode"))) 781 782;; Return 1 if OP is a valid source operand for xor. 783 784(define_predicate "xor_operand" 785 (match_code "subreg,reg,const_int") 786{ 787 if (CONST_INT_P (op)) 788 return (TARGET_SHMEDIA 789 ? (satisfies_constraint_I06 (op) 790 || (!can_create_pseudo_p () && INTVAL (op) == 0xff)) 791 : satisfies_constraint_K08 (op)); 792 if (TARGET_SHMEDIA 793 && mode != DImode && GET_CODE (op) == SUBREG 794 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) 795 return 0; 796 return arith_reg_operand (op, mode); 797}) 798 799(define_predicate "bitwise_memory_operand" 800 (match_code "mem") 801{ 802 if (MEM_P (op)) 803 { 804 if (REG_P (XEXP (op, 0))) 805 return 1; 806 807 if (GET_CODE (XEXP (op, 0)) == PLUS 808 && REG_P (XEXP (XEXP (op, 0), 0)) 809 && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))) 810 return 1; 811 } 812 return 0; 813}) 814