1*404b540aSrobert;; Predicate definitions for Motorola MCore. 2*404b540aSrobert;; Copyright (C) 2005 Free Software Foundation, Inc. 3*404b540aSrobert;; 4*404b540aSrobert;; This file is part of GCC. 5*404b540aSrobert;; 6*404b540aSrobert;; GCC is free software; you can redistribute it and/or modify 7*404b540aSrobert;; it under the terms of the GNU General Public License as published by 8*404b540aSrobert;; the Free Software Foundation; either version 2, or (at your option) 9*404b540aSrobert;; any later version. 10*404b540aSrobert;; 11*404b540aSrobert;; GCC is distributed in the hope that it will be useful, 12*404b540aSrobert;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13*404b540aSrobert;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*404b540aSrobert;; GNU General Public License for more details. 15*404b540aSrobert;; 16*404b540aSrobert;; You should have received a copy of the GNU General Public License 17*404b540aSrobert;; along with GCC; see the file COPYING. If not, write to 18*404b540aSrobert;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19*404b540aSrobert;; Boston, MA 02110-1301, USA. 20*404b540aSrobert 21*404b540aSrobert;; Nonzero if OP is a normal arithmetic register. 22*404b540aSrobert 23*404b540aSrobert(define_predicate "mcore_arith_reg_operand" 24*404b540aSrobert (match_code "reg,subreg") 25*404b540aSrobert{ 26*404b540aSrobert if (! register_operand (op, mode)) 27*404b540aSrobert return 0; 28*404b540aSrobert 29*404b540aSrobert if (GET_CODE (op) == SUBREG) 30*404b540aSrobert op = SUBREG_REG (op); 31*404b540aSrobert 32*404b540aSrobert if (GET_CODE (op) == REG) 33*404b540aSrobert return REGNO (op) != CC_REG; 34*404b540aSrobert 35*404b540aSrobert return 1; 36*404b540aSrobert}) 37*404b540aSrobert 38*404b540aSrobert;; Nonzero if OP can be source of a simple move operation. 39*404b540aSrobert 40*404b540aSrobert(define_predicate "mcore_general_movsrc_operand" 41*404b540aSrobert (match_code "mem,const_int,reg,subreg,symbol_ref,label_ref") 42*404b540aSrobert{ 43*404b540aSrobert /* Any (MEM LABEL_REF) is OK. That is a pc-relative load. */ 44*404b540aSrobert if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF) 45*404b540aSrobert return 1; 46*404b540aSrobert 47*404b540aSrobert return general_operand (op, mode); 48*404b540aSrobert}) 49*404b540aSrobert 50*404b540aSrobert;; Nonzero if OP can be destination of a simple move operation. 51*404b540aSrobert 52*404b540aSrobert(define_predicate "mcore_general_movdst_operand" 53*404b540aSrobert (match_code "mem,const_int,reg,subreg") 54*404b540aSrobert{ 55*404b540aSrobert if (GET_CODE (op) == REG && REGNO (op) == CC_REG) 56*404b540aSrobert return 0; 57*404b540aSrobert 58*404b540aSrobert return general_operand (op, mode); 59*404b540aSrobert}) 60*404b540aSrobert 61*404b540aSrobert;; Nonzero if OP should be recognized during reload for an ixh/ixw 62*404b540aSrobert;; operand. See the ixh/ixw patterns. 63*404b540aSrobert 64*404b540aSrobert(define_predicate "mcore_reload_operand" 65*404b540aSrobert (match_code "mem,reg,subreg") 66*404b540aSrobert{ 67*404b540aSrobert if (mcore_arith_reg_operand (op, mode)) 68*404b540aSrobert return 1; 69*404b540aSrobert 70*404b540aSrobert if (! reload_in_progress) 71*404b540aSrobert return 0; 72*404b540aSrobert 73*404b540aSrobert return GET_CODE (op) == MEM; 74*404b540aSrobert}) 75*404b540aSrobert 76*404b540aSrobert;; Nonzero if OP is a valid source operand for an arithmetic insn. 77*404b540aSrobert 78*404b540aSrobert(define_predicate "mcore_arith_J_operand" 79*404b540aSrobert (match_code "const_int,reg,subreg") 80*404b540aSrobert{ 81*404b540aSrobert if (register_operand (op, mode)) 82*404b540aSrobert return 1; 83*404b540aSrobert 84*404b540aSrobert if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op))) 85*404b540aSrobert return 1; 86*404b540aSrobert 87*404b540aSrobert return 0; 88*404b540aSrobert}) 89*404b540aSrobert 90*404b540aSrobert;; Nonzero if OP is a valid source operand for an arithmetic insn. 91*404b540aSrobert 92*404b540aSrobert(define_predicate "mcore_arith_K_operand" 93*404b540aSrobert (match_code "const_int,reg,subreg") 94*404b540aSrobert{ 95*404b540aSrobert if (register_operand (op, mode)) 96*404b540aSrobert return 1; 97*404b540aSrobert 98*404b540aSrobert if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op))) 99*404b540aSrobert return 1; 100*404b540aSrobert 101*404b540aSrobert return 0; 102*404b540aSrobert}) 103*404b540aSrobert 104*404b540aSrobert;; Nonzero if OP is a valid source operand for a shift or rotate insn. 105*404b540aSrobert 106*404b540aSrobert(define_predicate "mcore_arith_K_operand_not_0" 107*404b540aSrobert (match_code "const_int,reg,subreg") 108*404b540aSrobert{ 109*404b540aSrobert if (register_operand (op, mode)) 110*404b540aSrobert return 1; 111*404b540aSrobert 112*404b540aSrobert if ( GET_CODE (op) == CONST_INT 113*404b540aSrobert && CONST_OK_FOR_K (INTVAL (op)) 114*404b540aSrobert && INTVAL (op) != 0) 115*404b540aSrobert return 1; 116*404b540aSrobert 117*404b540aSrobert return 0; 118*404b540aSrobert}) 119*404b540aSrobert 120*404b540aSrobert;; TODO: Add a comment here. 121*404b540aSrobert 122*404b540aSrobert(define_predicate "mcore_arith_M_operand" 123*404b540aSrobert (match_code "const_int,reg,subreg") 124*404b540aSrobert{ 125*404b540aSrobert if (register_operand (op, mode)) 126*404b540aSrobert return 1; 127*404b540aSrobert 128*404b540aSrobert if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op))) 129*404b540aSrobert return 1; 130*404b540aSrobert 131*404b540aSrobert return 0; 132*404b540aSrobert}) 133*404b540aSrobert 134*404b540aSrobert;; TODO: Add a comment here. 135*404b540aSrobert 136*404b540aSrobert(define_predicate "mcore_arith_K_S_operand" 137*404b540aSrobert (match_code "const_int,reg,subreg") 138*404b540aSrobert{ 139*404b540aSrobert if (register_operand (op, mode)) 140*404b540aSrobert return 1; 141*404b540aSrobert 142*404b540aSrobert if (GET_CODE (op) == CONST_INT) 143*404b540aSrobert { 144*404b540aSrobert if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op))) 145*404b540aSrobert return 1; 146*404b540aSrobert } 147*404b540aSrobert 148*404b540aSrobert return 0; 149*404b540aSrobert}) 150*404b540aSrobert 151*404b540aSrobert;; Nonzero if OP is a valid source operand for a cmov with two consts 152*404b540aSrobert;; +/- 1. 153*404b540aSrobert 154*404b540aSrobert(define_predicate "mcore_arith_O_operand" 155*404b540aSrobert (match_code "const_int,reg,subreg") 156*404b540aSrobert{ 157*404b540aSrobert if (register_operand (op, mode)) 158*404b540aSrobert return 1; 159*404b540aSrobert 160*404b540aSrobert if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_O (INTVAL (op))) 161*404b540aSrobert return 1; 162*404b540aSrobert 163*404b540aSrobert return 0; 164*404b540aSrobert}) 165*404b540aSrobert 166*404b540aSrobert;; Nonzero if OP is a valid source operand for loading. 167*404b540aSrobert 168*404b540aSrobert(define_predicate "mcore_arith_imm_operand" 169*404b540aSrobert (match_code "const_int,reg,subreg") 170*404b540aSrobert{ 171*404b540aSrobert if (register_operand (op, mode)) 172*404b540aSrobert return 1; 173*404b540aSrobert 174*404b540aSrobert if (GET_CODE (op) == CONST_INT && const_ok_for_mcore (INTVAL (op))) 175*404b540aSrobert return 1; 176*404b540aSrobert 177*404b540aSrobert return 0; 178*404b540aSrobert}) 179*404b540aSrobert 180*404b540aSrobert;; TODO: Add a comment here. 181*404b540aSrobert 182*404b540aSrobert(define_predicate "mcore_arith_any_imm_operand" 183*404b540aSrobert (match_code "const_int,reg,subreg") 184*404b540aSrobert{ 185*404b540aSrobert if (register_operand (op, mode)) 186*404b540aSrobert return 1; 187*404b540aSrobert 188*404b540aSrobert if (GET_CODE (op) == CONST_INT) 189*404b540aSrobert return 1; 190*404b540aSrobert 191*404b540aSrobert return 0; 192*404b540aSrobert}) 193*404b540aSrobert 194*404b540aSrobert;; Nonzero if OP is a valid source operand for a btsti. 195*404b540aSrobert 196*404b540aSrobert(define_predicate "mcore_literal_K_operand" 197*404b540aSrobert (match_code "const_int") 198*404b540aSrobert{ 199*404b540aSrobert if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op))) 200*404b540aSrobert return 1; 201*404b540aSrobert 202*404b540aSrobert return 0; 203*404b540aSrobert}) 204*404b540aSrobert 205*404b540aSrobert;; Nonzero if OP is a valid source operand for an add/sub insn. 206*404b540aSrobert 207*404b540aSrobert(define_predicate "mcore_addsub_operand" 208*404b540aSrobert (match_code "const_int,reg,subreg") 209*404b540aSrobert{ 210*404b540aSrobert if (register_operand (op, mode)) 211*404b540aSrobert return 1; 212*404b540aSrobert 213*404b540aSrobert if (GET_CODE (op) == CONST_INT) 214*404b540aSrobert { 215*404b540aSrobert return 1; 216*404b540aSrobert 217*404b540aSrobert /* The following is removed because it precludes large constants from being 218*404b540aSrobert returned as valid source operands for and add/sub insn. While large 219*404b540aSrobert constants may not directly be used in an add/sub, they may if first loaded 220*404b540aSrobert into a register. Thus, this predicate should indicate that they are valid, 221*404b540aSrobert and the constraint in mcore.md should control whether an additional load to 222*404b540aSrobert register is needed. (see mcore.md, addsi). -- DAC 4/2/1998 */ 223*404b540aSrobert /* 224*404b540aSrobert if (CONST_OK_FOR_J(INTVAL(op)) || CONST_OK_FOR_L(INTVAL(op))) 225*404b540aSrobert return 1; 226*404b540aSrobert */ 227*404b540aSrobert } 228*404b540aSrobert 229*404b540aSrobert return 0; 230*404b540aSrobert}) 231*404b540aSrobert 232*404b540aSrobert;; Nonzero if OP is a valid source operand for a compare operation. 233*404b540aSrobert 234*404b540aSrobert(define_predicate "mcore_compare_operand" 235*404b540aSrobert (match_code "const_int,reg,subreg") 236*404b540aSrobert{ 237*404b540aSrobert if (register_operand (op, mode)) 238*404b540aSrobert return 1; 239*404b540aSrobert 240*404b540aSrobert if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0) 241*404b540aSrobert return 1; 242*404b540aSrobert 243*404b540aSrobert return 0; 244*404b540aSrobert}) 245*404b540aSrobert 246*404b540aSrobert;; Return 1 if OP is a load multiple operation. It is known to be a 247*404b540aSrobert;; PARALLEL and the first section will be tested. 248*404b540aSrobert 249*404b540aSrobert(define_predicate "mcore_load_multiple_operation" 250*404b540aSrobert (match_code "parallel") 251*404b540aSrobert{ 252*404b540aSrobert int count = XVECLEN (op, 0); 253*404b540aSrobert int dest_regno; 254*404b540aSrobert rtx src_addr; 255*404b540aSrobert int i; 256*404b540aSrobert 257*404b540aSrobert /* Perform a quick check so we don't blow up below. */ 258*404b540aSrobert if (count <= 1 259*404b540aSrobert || GET_CODE (XVECEXP (op, 0, 0)) != SET 260*404b540aSrobert || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 261*404b540aSrobert || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 262*404b540aSrobert return 0; 263*404b540aSrobert 264*404b540aSrobert dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 265*404b540aSrobert src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 266*404b540aSrobert 267*404b540aSrobert for (i = 1; i < count; i++) 268*404b540aSrobert { 269*404b540aSrobert rtx elt = XVECEXP (op, 0, i); 270*404b540aSrobert 271*404b540aSrobert if (GET_CODE (elt) != SET 272*404b540aSrobert || GET_CODE (SET_DEST (elt)) != REG 273*404b540aSrobert || GET_MODE (SET_DEST (elt)) != SImode 274*404b540aSrobert || REGNO (SET_DEST (elt)) != (unsigned) (dest_regno + i) 275*404b540aSrobert || GET_CODE (SET_SRC (elt)) != MEM 276*404b540aSrobert || GET_MODE (SET_SRC (elt)) != SImode 277*404b540aSrobert || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS 278*404b540aSrobert || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) 279*404b540aSrobert || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT 280*404b540aSrobert || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) 281*404b540aSrobert return 0; 282*404b540aSrobert } 283*404b540aSrobert 284*404b540aSrobert return 1; 285*404b540aSrobert}) 286*404b540aSrobert 287*404b540aSrobert;; Similar, but tests for store multiple. 288*404b540aSrobert 289*404b540aSrobert(define_predicate "mcore_store_multiple_operation" 290*404b540aSrobert (match_code "parallel") 291*404b540aSrobert{ 292*404b540aSrobert int count = XVECLEN (op, 0); 293*404b540aSrobert int src_regno; 294*404b540aSrobert rtx dest_addr; 295*404b540aSrobert int i; 296*404b540aSrobert 297*404b540aSrobert /* Perform a quick check so we don't blow up below. */ 298*404b540aSrobert if (count <= 1 299*404b540aSrobert || GET_CODE (XVECEXP (op, 0, 0)) != SET 300*404b540aSrobert || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 301*404b540aSrobert || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 302*404b540aSrobert return 0; 303*404b540aSrobert 304*404b540aSrobert src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 305*404b540aSrobert dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 306*404b540aSrobert 307*404b540aSrobert for (i = 1; i < count; i++) 308*404b540aSrobert { 309*404b540aSrobert rtx elt = XVECEXP (op, 0, i); 310*404b540aSrobert 311*404b540aSrobert if (GET_CODE (elt) != SET 312*404b540aSrobert || GET_CODE (SET_SRC (elt)) != REG 313*404b540aSrobert || GET_MODE (SET_SRC (elt)) != SImode 314*404b540aSrobert || REGNO (SET_SRC (elt)) != (unsigned) (src_regno + i) 315*404b540aSrobert || GET_CODE (SET_DEST (elt)) != MEM 316*404b540aSrobert || GET_MODE (SET_DEST (elt)) != SImode 317*404b540aSrobert || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS 318*404b540aSrobert || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) 319*404b540aSrobert || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT 320*404b540aSrobert || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) 321*404b540aSrobert return 0; 322*404b540aSrobert } 323*404b540aSrobert 324*404b540aSrobert return 1; 325*404b540aSrobert}) 326*404b540aSrobert 327*404b540aSrobert;; TODO: Add a comment here. 328*404b540aSrobert 329*404b540aSrobert(define_predicate "mcore_call_address_operand" 330*404b540aSrobert (match_code "reg,subreg,const_int,symbol_ref") 331*404b540aSrobert{ 332*404b540aSrobert return register_operand (op, mode) || CONSTANT_P (op); 333*404b540aSrobert}) 334