1;; Predicate definitions for TMS320C[34]x. 2;; Copyright (C) 2005 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 2, 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 COPYING. If not, write to 18;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19;; Boston, MA 02110-1301, USA. 20 21;; Nonzero if OP is a floating point value with value 0.0. 22 23(define_predicate "fp_zero_operand" 24 (match_code "const_double") 25{ 26 REAL_VALUE_TYPE r; 27 28 if (GET_CODE (op) != CONST_DOUBLE) 29 return 0; 30 REAL_VALUE_FROM_CONST_DOUBLE (r, op); 31 return REAL_VALUES_EQUAL (r, dconst0); 32}) 33 34;; TODO: Add a comment here. 35 36(define_predicate "const_operand" 37 (match_code "const_int,const_double") 38{ 39 switch (mode) 40 { 41 case QFmode: 42 case HFmode: 43 if (GET_CODE (op) != CONST_DOUBLE 44 || GET_MODE (op) != mode 45 || GET_MODE_CLASS (mode) != MODE_FLOAT) 46 return 0; 47 48 return c4x_immed_float_p (op); 49 50#if Pmode != QImode 51 case Pmode: 52#endif 53 case QImode: 54 if (GET_CODE (op) != CONST_INT 55 || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode) 56 || GET_MODE_CLASS (mode) != MODE_INT) 57 return 0; 58 59 return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op)); 60 61 case HImode: 62 return 0; 63 64 default: 65 return 0; 66 } 67}) 68 69;; TODO: Add a comment here. 70 71(define_predicate "stik_const_operand" 72 (match_code "const_int") 73{ 74 return c4x_K_constant (op); 75}) 76 77;; TODO: Add a comment here. 78 79(define_predicate "not_const_operand" 80 (match_code "const_int") 81{ 82 return c4x_N_constant (op); 83}) 84 85;; TODO: Add a comment here. 86 87(define_predicate "reg_operand" 88 (match_code "reg,subreg") 89{ 90 if (GET_CODE (op) == SUBREG 91 && GET_MODE (op) == QFmode) 92 return 0; 93 return register_operand (op, mode); 94}) 95 96;; TODO: Add a comment here. 97 98(define_predicate "reg_or_const_operand" 99 (match_code "reg,subreg,const_int,const_double") 100{ 101 return reg_operand (op, mode) || const_operand (op, mode); 102}) 103 104;; Extended precision register R0-R1. 105 106(define_predicate "r0r1_reg_operand" 107 (match_code "reg,subreg") 108{ 109 if (! reg_operand (op, mode)) 110 return 0; 111 if (GET_CODE (op) == SUBREG) 112 op = SUBREG_REG (op); 113 return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op); 114}) 115 116;; Extended precision register R2-R3. 117 118(define_predicate "r2r3_reg_operand" 119 (match_code "reg,subreg") 120{ 121 if (! reg_operand (op, mode)) 122 return 0; 123 if (GET_CODE (op) == SUBREG) 124 op = SUBREG_REG (op); 125 return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op); 126}) 127 128;; Low extended precision register R0-R7. 129 130(define_predicate "ext_low_reg_operand" 131 (match_code "reg,subreg") 132{ 133 if (! reg_operand (op, mode)) 134 return 0; 135 if (GET_CODE (op) == SUBREG) 136 op = SUBREG_REG (op); 137 return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op); 138}) 139 140;; Extended precision register. 141 142(define_predicate "ext_reg_operand" 143 (match_code "reg,subreg") 144{ 145 if (! reg_operand (op, mode)) 146 return 0; 147 if (GET_CODE (op) == SUBREG) 148 op = SUBREG_REG (op); 149 if (! REG_P (op)) 150 return 0; 151 return IS_EXT_OR_PSEUDO_REG (op); 152}) 153 154;; Standard precision register. 155 156(define_predicate "std_reg_operand" 157 (match_code "reg,subreg") 158{ 159 if (! reg_operand (op, mode)) 160 return 0; 161 if (GET_CODE (op) == SUBREG) 162 op = SUBREG_REG (op); 163 return REG_P (op) && IS_STD_OR_PSEUDO_REG (op); 164}) 165 166;; Standard precision or normal register. 167 168(define_predicate "std_or_reg_operand" 169 (match_code "reg,subreg") 170{ 171 if (reload_in_progress) 172 return std_reg_operand (op, mode); 173 return reg_operand (op, mode); 174}) 175 176;; Address register. 177 178(define_predicate "addr_reg_operand" 179 (match_code "reg,subreg") 180{ 181 if (! reg_operand (op, mode)) 182 return 0; 183 return c4x_a_register (op); 184}) 185 186;; Index register. 187 188(define_predicate "index_reg_operand" 189 (match_code "reg,subreg") 190{ 191 if (! reg_operand (op, mode)) 192 return 0; 193 if (GET_CODE (op) == SUBREG) 194 op = SUBREG_REG (op); 195 return c4x_x_register (op); 196}) 197 198;; DP register. 199 200(define_predicate "dp_reg_operand" 201 (match_code "reg") 202{ 203 return REG_P (op) && IS_DP_OR_PSEUDO_REG (op); 204}) 205 206;; SP register. 207 208(define_predicate "sp_reg_operand" 209 (match_code "reg") 210{ 211 return REG_P (op) && IS_SP_OR_PSEUDO_REG (op); 212}) 213 214;; ST register. 215 216(define_predicate "st_reg_operand" 217 (match_code "reg") 218{ 219 return REG_P (op) && IS_ST_OR_PSEUDO_REG (op); 220}) 221 222;; RC register. 223 224(define_predicate "rc_reg_operand" 225 (match_code "reg") 226{ 227 return REG_P (op) && IS_RC_OR_PSEUDO_REG (op); 228}) 229 230;; TODO: Add a comment here. 231 232(define_predicate "call_address_operand" 233 (match_code "reg,symbol_ref,label_ref,const") 234{ 235 return (REG_P (op) || symbolic_address_operand (op, mode)); 236}) 237 238;; Check dst operand of a move instruction. 239 240(define_predicate "dst_operand" 241 (match_code "subreg,reg,mem") 242{ 243 if (GET_CODE (op) == SUBREG 244 && mixed_subreg_operand (op, mode)) 245 return 0; 246 247 if (REG_P (op)) 248 return reg_operand (op, mode); 249 250 return nonimmediate_operand (op, mode); 251}) 252 253;; Check src operand of two operand arithmetic instructions. 254 255(define_predicate "src_operand" 256 (match_code "subreg,reg,mem,const_int,const_double") 257{ 258 if (GET_CODE (op) == SUBREG 259 && mixed_subreg_operand (op, mode)) 260 return 0; 261 262 if (REG_P (op)) 263 return reg_operand (op, mode); 264 265 if (mode == VOIDmode) 266 mode = GET_MODE (op); 267 268 if (GET_CODE (op) == CONST_INT) 269 return (mode == QImode || mode == Pmode || mode == HImode) 270 && c4x_I_constant (op); 271 272 /* We don't like CONST_DOUBLE integers. */ 273 if (GET_CODE (op) == CONST_DOUBLE) 274 return c4x_H_constant (op); 275 276 /* Disallow symbolic addresses. Only the predicate 277 symbolic_address_operand will match these. */ 278 if (GET_CODE (op) == SYMBOL_REF 279 || GET_CODE (op) == LABEL_REF 280 || GET_CODE (op) == CONST) 281 return 0; 282 283 /* If TARGET_LOAD_DIRECT_MEMS is nonzero, disallow direct memory 284 access to symbolic addresses. These operands will get forced 285 into a register and the movqi expander will generate a 286 HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is nonzero. */ 287 if (GET_CODE (op) == MEM 288 && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF 289 || GET_CODE (XEXP (op, 0)) == LABEL_REF 290 || GET_CODE (XEXP (op, 0)) == CONST))) 291 return !TARGET_EXPOSE_LDP && 292 ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode; 293 294 return general_operand (op, mode); 295}) 296 297;; TODO: Add a comment here. 298 299(define_predicate "src_hi_operand" 300 (match_code "subreg,reg,mem,const_double") 301{ 302 if (c4x_O_constant (op)) 303 return 1; 304 return src_operand (op, mode); 305}) 306 307;; Check src operand of two operand logical instructions. 308 309(define_predicate "lsrc_operand" 310 (match_code "subreg,reg,mem,const_int,const_double") 311{ 312 if (mode == VOIDmode) 313 mode = GET_MODE (op); 314 315 if (mode != QImode && mode != Pmode) 316 fatal_insn ("mode not QImode", op); 317 318 if (GET_CODE (op) == CONST_INT) 319 return c4x_L_constant (op) || c4x_J_constant (op); 320 321 return src_operand (op, mode); 322}) 323 324;; Check src operand of two operand tricky instructions. 325 326(define_predicate "tsrc_operand" 327 (match_code "subreg,reg,mem,const_int,const_double") 328{ 329 if (mode == VOIDmode) 330 mode = GET_MODE (op); 331 332 if (mode != QImode && mode != Pmode) 333 fatal_insn ("mode not QImode", op); 334 335 if (GET_CODE (op) == CONST_INT) 336 return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op); 337 338 return src_operand (op, mode); 339}) 340 341;; Check src operand of two operand non immediate instructions. 342 343(define_predicate "nonimmediate_src_operand" 344 (match_code "subreg,reg,mem") 345{ 346 if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) 347 return 0; 348 349 return src_operand (op, mode); 350}) 351 352;; Check logical src operand of two operand non immediate instructions. 353 354(define_predicate "nonimmediate_lsrc_operand" 355 (match_code "subreg,reg,mem") 356{ 357 if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) 358 return 0; 359 360 return lsrc_operand (op, mode); 361}) 362 363;; Match any operand. 364 365(define_predicate "any_operand" 366 (match_code "subreg,reg,mem,const_int,const_double") 367{ 368 return 1; 369}) 370 371;; Check for indirect operands allowable in parallel instruction. 372 373(define_predicate "par_ind_operand" 374 (match_code "mem") 375{ 376 if (mode != VOIDmode && mode != GET_MODE (op)) 377 return 0; 378 379 return c4x_S_indirect (op); 380}) 381 382;; Check for operands allowable in parallel instruction. 383 384(define_predicate "parallel_operand" 385 (match_code "subreg,reg,mem") 386{ 387 return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode); 388}) 389 390;; Symbolic address operand. 391 392(define_predicate "symbolic_address_operand" 393 (match_code "symbol_ref,label_ref,const") 394{ 395 switch (GET_CODE (op)) 396 { 397 case CONST: 398 case SYMBOL_REF: 399 case LABEL_REF: 400 return 1; 401 default: 402 return 0; 403 } 404}) 405