1;; Predicate definitions for S/390 and zSeries. 2;; Copyright (C) 2005-2013 Free Software Foundation, Inc. 3;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and 4;; Ulrich Weigand (uweigand@de.ibm.com). 5;; 6;; This file is part of GCC. 7;; 8;; GCC is free software; you can redistribute it and/or modify 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 3, or (at your option) 11;; any later version. 12;; 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22;; OP is the current operation. 23;; MODE is the current operation mode. 24 25;; operands -------------------------------------------------------------- 26 27;; Return true if OP a (const_int 0) operand. 28 29(define_predicate "const0_operand" 30 (and (match_code "const_int, const_double") 31 (match_test "op == CONST0_RTX (mode)"))) 32 33;; Return true if OP is constant. 34 35(define_special_predicate "consttable_operand" 36 (and (match_code "symbol_ref, label_ref, const, const_int, const_double") 37 (match_test "CONSTANT_P (op)"))) 38 39;; Return true if OP is a valid S-type operand. 40 41(define_predicate "s_operand" 42 (and (match_code "subreg, mem") 43 (match_operand 0 "general_operand")) 44{ 45 /* Just like memory_operand, allow (subreg (mem ...)) 46 after reload. */ 47 if (reload_completed 48 && GET_CODE (op) == SUBREG 49 && GET_CODE (SUBREG_REG (op)) == MEM) 50 op = SUBREG_REG (op); 51 52 if (GET_CODE (op) != MEM) 53 return false; 54 if (!s390_legitimate_address_without_index_p (op)) 55 return false; 56 57 return true; 58}) 59 60;; Return true if OP is a valid operand for the BRAS instruction. 61;; Allow SYMBOL_REFs and @PLT stubs. 62 63(define_special_predicate "bras_sym_operand" 64 (ior (and (match_code "symbol_ref") 65 (match_test "!flag_pic || SYMBOL_REF_LOCAL_P (op)")) 66 (and (match_code "const") 67 (and (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC") 68 (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_PLT"))))) 69 70;; Return true if OP is a PLUS that is not a legitimate 71;; operand for the LA instruction. 72 73(define_predicate "s390_plus_operand" 74 (and (match_code "plus") 75 (and (match_test "mode == Pmode") 76 (match_test "!legitimate_la_operand_p (op)")))) 77 78;; Return true if OP is a valid operand as shift count or setmem. 79 80(define_predicate "shift_count_or_setmem_operand" 81 (match_code "reg, subreg, plus, const_int") 82{ 83 HOST_WIDE_INT offset; 84 rtx base; 85 86 /* Extract base register and offset. */ 87 if (!s390_decompose_shift_count (op, &base, &offset)) 88 return false; 89 90 /* Don't allow any non-base hard registers. Doing so without 91 confusing reload and/or regrename would be tricky, and doesn't 92 buy us much anyway. */ 93 if (base && REGNO (base) < FIRST_PSEUDO_REGISTER && !ADDR_REG_P (base)) 94 return false; 95 96 /* Unfortunately we have to reject constants that are invalid 97 for an address, or else reload will get confused. */ 98 if (!DISP_IN_RANGE (offset)) 99 return false; 100 101 return true; 102}) 103 104(define_predicate "nonzero_shift_count_operand" 105 (and (match_code "const_int") 106 (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)"))) 107 108;; Return true if OP a valid operand for the LARL instruction. 109 110(define_predicate "larl_operand" 111 (match_code "label_ref, symbol_ref, const, const_int, const_double") 112{ 113 /* Allow labels and local symbols. */ 114 if (GET_CODE (op) == LABEL_REF) 115 return true; 116 if (GET_CODE (op) == SYMBOL_REF) 117 return (!SYMBOL_REF_ALIGN1_P (op) 118 && SYMBOL_REF_TLS_MODEL (op) == 0 119 && (!flag_pic || SYMBOL_REF_LOCAL_P (op))); 120 121 /* Everything else must have a CONST, so strip it. */ 122 if (GET_CODE (op) != CONST) 123 return false; 124 op = XEXP (op, 0); 125 126 /* Allow adding *even* in-range constants. */ 127 if (GET_CODE (op) == PLUS) 128 { 129 if (GET_CODE (XEXP (op, 1)) != CONST_INT 130 || (INTVAL (XEXP (op, 1)) & 1) != 0) 131 return false; 132 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 31 133 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 31)) 134 return false; 135 op = XEXP (op, 0); 136 } 137 138 /* Labels and local symbols allowed here as well. */ 139 if (GET_CODE (op) == LABEL_REF) 140 return true; 141 if (GET_CODE (op) == SYMBOL_REF) 142 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0 143 && SYMBOL_REF_TLS_MODEL (op) == 0 144 && (!flag_pic || SYMBOL_REF_LOCAL_P (op))); 145 146 /* Now we must have a @GOTENT offset or @PLT stub 147 or an @INDNTPOFF TLS offset. */ 148 if (GET_CODE (op) == UNSPEC 149 && XINT (op, 1) == UNSPEC_GOTENT) 150 return true; 151 if (GET_CODE (op) == UNSPEC 152 && XINT (op, 1) == UNSPEC_PLT) 153 return true; 154 if (GET_CODE (op) == UNSPEC 155 && XINT (op, 1) == UNSPEC_INDNTPOFF) 156 return true; 157 158 return false; 159}) 160 161(define_predicate "contiguous_bitmask_operand" 162 (match_code "const_int") 163{ 164 return s390_contiguous_bitmask_p (INTVAL (op), GET_MODE_BITSIZE (mode), NULL, NULL); 165}) 166 167;; operators -------------------------------------------------------------- 168 169;; Return nonzero if OP is a valid comparison operator 170;; for a branch condition. 171 172(define_predicate "s390_comparison" 173 (match_code "eq, ne, lt, gt, le, ge, ltu, gtu, leu, geu, 174 uneq, unlt, ungt, unle, unge, ltgt, 175 unordered, ordered") 176{ 177 if (GET_CODE (XEXP (op, 0)) != REG 178 || REGNO (XEXP (op, 0)) != CC_REGNUM 179 || (XEXP (op, 1) != const0_rtx 180 && !(CONST_INT_P (XEXP (op, 1)) 181 && GET_MODE (XEXP (op, 0)) == CCRAWmode 182 && INTVAL (XEXP (op, 1)) >= 0 183 && INTVAL (XEXP (op, 1)) <= 15))) 184 return false; 185 186 return (s390_branch_condition_mask (op) >= 0); 187}) 188 189;; Return true if op is the cc register. 190(define_predicate "cc_reg_operand" 191 (and (match_code "reg") 192 (match_test "REGNO (op) == CC_REGNUM"))) 193 194(define_predicate "s390_signed_integer_comparison" 195 (match_code "eq, ne, lt, gt, le, ge") 196{ 197 return (s390_compare_and_branch_condition_mask (op) >= 0); 198}) 199 200(define_predicate "s390_unsigned_integer_comparison" 201 (match_code "eq, ne, ltu, gtu, leu, geu") 202{ 203 return (s390_compare_and_branch_condition_mask (op) >= 0); 204}) 205 206;; Return nonzero if OP is a valid comparison operator for the 207;; cstore expanders -- respectively cstorecc4 and integer cstore. 208(define_predicate "s390_eqne_operator" 209 (match_code "eq, ne")) 210 211(define_predicate "s390_scond_operator" 212 (match_code "ltu, gtu, leu, geu")) 213 214(define_predicate "s390_brx_operator" 215 (match_code "le, gt")) 216 217;; Return nonzero if OP is a valid comparison operator 218;; for an ALC condition. 219 220(define_predicate "s390_alc_comparison" 221 (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu") 222{ 223 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND) 224 op = XEXP (op, 0); 225 226 if (!COMPARISON_P (op)) 227 return false; 228 229 if (GET_CODE (XEXP (op, 0)) != REG 230 || REGNO (XEXP (op, 0)) != CC_REGNUM 231 || (XEXP (op, 1) != const0_rtx 232 && !(CONST_INT_P (XEXP (op, 1)) 233 && GET_MODE (XEXP (op, 0)) == CCRAWmode 234 && INTVAL (XEXP (op, 1)) >= 0 235 && INTVAL (XEXP (op, 1)) <= 15))) 236 return false; 237 238 switch (GET_MODE (XEXP (op, 0))) 239 { 240 case CCL1mode: 241 return GET_CODE (op) == LTU; 242 243 case CCL2mode: 244 return GET_CODE (op) == LEU; 245 246 case CCL3mode: 247 return GET_CODE (op) == GEU; 248 249 case CCUmode: 250 return GET_CODE (op) == GTU; 251 252 case CCURmode: 253 return GET_CODE (op) == LTU; 254 255 case CCSmode: 256 return GET_CODE (op) == UNGT; 257 258 case CCSRmode: 259 return GET_CODE (op) == UNLT; 260 261 default: 262 return false; 263 } 264}) 265 266;; Return nonzero if OP is a valid comparison operator 267;; for an SLB condition. 268 269(define_predicate "s390_slb_comparison" 270 (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu") 271{ 272 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND) 273 op = XEXP (op, 0); 274 275 if (!COMPARISON_P (op)) 276 return false; 277 278 if (GET_CODE (XEXP (op, 0)) != REG 279 || REGNO (XEXP (op, 0)) != CC_REGNUM 280 || XEXP (op, 1) != const0_rtx) 281 return false; 282 283 switch (GET_MODE (XEXP (op, 0))) 284 { 285 case CCL1mode: 286 return GET_CODE (op) == GEU; 287 288 case CCL2mode: 289 return GET_CODE (op) == GTU; 290 291 case CCL3mode: 292 return GET_CODE (op) == LTU; 293 294 case CCUmode: 295 return GET_CODE (op) == LEU; 296 297 case CCURmode: 298 return GET_CODE (op) == GEU; 299 300 case CCSmode: 301 return GET_CODE (op) == LE; 302 303 case CCSRmode: 304 return GET_CODE (op) == GE; 305 306 default: 307 return false; 308 } 309}) 310 311;; Return true if OP is a load multiple operation. It is known to be a 312;; PARALLEL and the first section will be tested. 313 314(define_special_predicate "load_multiple_operation" 315 (match_code "parallel") 316{ 317 enum machine_mode elt_mode; 318 int count = XVECLEN (op, 0); 319 unsigned int dest_regno; 320 rtx src_addr; 321 int i, off; 322 323 /* Perform a quick check so we don't blow up below. */ 324 if (count <= 1 325 || GET_CODE (XVECEXP (op, 0, 0)) != SET 326 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 327 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 328 return false; 329 330 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 331 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 332 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0))); 333 334 /* Check, is base, or base + displacement. */ 335 336 if (GET_CODE (src_addr) == REG) 337 off = 0; 338 else if (GET_CODE (src_addr) == PLUS 339 && GET_CODE (XEXP (src_addr, 0)) == REG 340 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT) 341 { 342 off = INTVAL (XEXP (src_addr, 1)); 343 src_addr = XEXP (src_addr, 0); 344 } 345 else 346 return false; 347 348 for (i = 1; i < count; i++) 349 { 350 rtx elt = XVECEXP (op, 0, i); 351 352 if (GET_CODE (elt) != SET 353 || GET_CODE (SET_DEST (elt)) != REG 354 || GET_MODE (SET_DEST (elt)) != elt_mode 355 || REGNO (SET_DEST (elt)) != dest_regno + i 356 || GET_CODE (SET_SRC (elt)) != MEM 357 || GET_MODE (SET_SRC (elt)) != elt_mode 358 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS 359 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) 360 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT 361 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) 362 != off + i * GET_MODE_SIZE (elt_mode)) 363 return false; 364 } 365 366 return true; 367}) 368 369;; For an execute pattern the target instruction is embedded into the 370;; RTX but will not get checked for validity by recog automatically. 371;; The execute_operation predicate extracts the target RTX and invokes 372;; recog. 373(define_special_predicate "execute_operation" 374 (match_code "parallel") 375{ 376 rtx pattern = op; 377 rtx insn; 378 int icode; 379 380 /* This is redundant but since this predicate is evaluated 381 first when recognizing the insn we can prevent the more 382 expensive code below from being executed for many cases. */ 383 if (GET_CODE (XVECEXP (pattern, 0, 0)) != UNSPEC 384 || XINT (XVECEXP (pattern, 0, 0), 1) != UNSPEC_EXECUTE) 385 return false; 386 387 /* Keep in sync with s390_execute_target. */ 388 if (XVECLEN (pattern, 0) == 2) 389 { 390 pattern = copy_rtx (XVECEXP (pattern, 0, 1)); 391 } 392 else 393 { 394 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1); 395 int i; 396 397 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++) 398 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1)); 399 400 pattern = gen_rtx_PARALLEL (VOIDmode, vec); 401 } 402 403 /* Since we do not have the wrapping insn here we have to build one. */ 404 insn = make_insn_raw (pattern); 405 icode = recog_memoized (insn); 406 if (icode < 0) 407 return false; 408 409 extract_insn (insn); 410 constrain_operands (1); 411 412 return which_alternative >= 0; 413}) 414 415;; Return true if OP is a store multiple operation. It is known to be a 416;; PARALLEL and the first section will be tested. 417 418(define_special_predicate "store_multiple_operation" 419 (match_code "parallel") 420{ 421 enum machine_mode elt_mode; 422 int count = XVECLEN (op, 0); 423 unsigned int src_regno; 424 rtx dest_addr; 425 int i, off; 426 427 /* Perform a quick check so we don't blow up below. */ 428 if (count <= 1 429 || GET_CODE (XVECEXP (op, 0, 0)) != SET 430 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 431 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 432 return false; 433 434 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 435 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 436 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0))); 437 438 /* Check, is base, or base + displacement. */ 439 440 if (GET_CODE (dest_addr) == REG) 441 off = 0; 442 else if (GET_CODE (dest_addr) == PLUS 443 && GET_CODE (XEXP (dest_addr, 0)) == REG 444 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT) 445 { 446 off = INTVAL (XEXP (dest_addr, 1)); 447 dest_addr = XEXP (dest_addr, 0); 448 } 449 else 450 return false; 451 452 for (i = 1; i < count; i++) 453 { 454 rtx elt = XVECEXP (op, 0, i); 455 456 if (GET_CODE (elt) != SET 457 || GET_CODE (SET_SRC (elt)) != REG 458 || GET_MODE (SET_SRC (elt)) != elt_mode 459 || REGNO (SET_SRC (elt)) != src_regno + i 460 || GET_CODE (SET_DEST (elt)) != MEM 461 || GET_MODE (SET_DEST (elt)) != elt_mode 462 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS 463 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) 464 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT 465 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) 466 != off + i * GET_MODE_SIZE (elt_mode)) 467 return false; 468 } 469 return true; 470}) 471