1 /* Predicate functions of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2015 Free Software Foundation, Inc. 3 Contributed by Andes Technology Corporation. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 /* ------------------------------------------------------------------------ */ 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "tm.h" 27 #include "hash-set.h" 28 #include "machmode.h" 29 #include "vec.h" 30 #include "double-int.h" 31 #include "input.h" 32 #include "alias.h" 33 #include "symtab.h" 34 #include "wide-int.h" 35 #include "inchash.h" 36 #include "tree.h" 37 #include "stor-layout.h" 38 #include "varasm.h" 39 #include "calls.h" 40 #include "rtl.h" 41 #include "regs.h" 42 #include "hard-reg-set.h" 43 #include "insn-config.h" /* Required by recog.h. */ 44 #include "conditions.h" 45 #include "output.h" 46 #include "insn-attr.h" /* For DFA state_t. */ 47 #include "insn-codes.h" /* For CODE_FOR_xxx. */ 48 #include "reload.h" /* For push_reload(). */ 49 #include "flags.h" 50 #include "function.h" 51 #include "hashtab.h" 52 #include "statistics.h" 53 #include "real.h" 54 #include "fixed-value.h" 55 #include "insn-config.h" 56 #include "expmed.h" 57 #include "dojump.h" 58 #include "explow.h" 59 #include "emit-rtl.h" 60 #include "stmt.h" 61 #include "expr.h" 62 #include "recog.h" 63 #include "diagnostic-core.h" 64 #include "dominance.h" 65 #include "cfg.h" 66 #include "cfgrtl.h" 67 #include "cfganal.h" 68 #include "lcm.h" 69 #include "cfgbuild.h" 70 #include "cfgcleanup.h" 71 #include "predict.h" 72 #include "basic-block.h" 73 #include "df.h" 74 #include "tm_p.h" 75 #include "tm-constrs.h" 76 #include "optabs.h" /* For GEN_FCN. */ 77 #include "target.h" 78 #include "target-def.h" 79 #include "langhooks.h" /* For add_builtin_function(). */ 80 #include "ggc.h" 81 #include "builtins.h" 82 83 /* ------------------------------------------------------------------------ */ 84 85 /* A subroutine that checks multiple load and store 86 using consecutive registers. 87 OP is a parallel rtx we would like to check. 88 LOAD_P indicates whether we are checking load operation. 89 PAR_INDEX is starting element of parallel rtx. 90 FIRST_ELT_REGNO is used to tell starting register number. 91 COUNT helps us to check consecutive register numbers. */ 92 static bool 93 nds32_consecutive_registers_load_store_p (rtx op, 94 bool load_p, 95 int par_index, 96 int first_elt_regno, 97 int count) 98 { 99 int i; 100 int check_regno; 101 rtx elt; 102 rtx elt_reg; 103 rtx elt_mem; 104 105 for (i = 0; i < count; i++) 106 { 107 /* Pick up each element from parallel rtx. */ 108 elt = XVECEXP (op, 0, i + par_index); 109 110 /* If this element is not a 'set' rtx, return false immediately. */ 111 if (GET_CODE (elt) != SET) 112 return false; 113 114 /* Pick up reg and mem of this element. */ 115 elt_reg = load_p ? SET_DEST (elt) : SET_SRC (elt); 116 elt_mem = load_p ? SET_SRC (elt) : SET_DEST (elt); 117 118 /* If elt_reg is not a expected reg rtx, return false. */ 119 if (GET_CODE (elt_reg) != REG || GET_MODE (elt_reg) != SImode) 120 return false; 121 /* If elt_mem is not a expected mem rtx, return false. */ 122 if (GET_CODE (elt_mem) != MEM || GET_MODE (elt_mem) != SImode) 123 return false; 124 125 /* The consecutive registers should be in (Rb,Rb+1...Re) order. */ 126 check_regno = first_elt_regno + i; 127 128 /* If the register number is not continuous, return false. */ 129 if (REGNO (elt_reg) != (unsigned int) check_regno) 130 return false; 131 } 132 133 return true; 134 } 135 136 /* Function to check whether the OP is a valid load/store operation. 137 This is a helper function for the predicates: 138 'nds32_load_multiple_operation' and 'nds32_store_multiple_operation' 139 in predicates.md file. 140 141 The OP is supposed to be a parallel rtx. 142 For each element within this parallel rtx: 143 (set (reg) (mem addr)) is the form for load operation. 144 (set (mem addr) (reg)) is the form for store operation. 145 We have to extract reg and mem of every element and 146 check if the information is valid for multiple load/store operation. */ 147 bool 148 nds32_valid_multiple_load_store (rtx op, bool load_p) 149 { 150 int count; 151 int first_elt_regno; 152 rtx elt; 153 154 /* Get the counts of elements in the parallel rtx. */ 155 count = XVECLEN (op, 0); 156 /* Pick up the first element. */ 157 elt = XVECEXP (op, 0, 0); 158 159 /* Perform some quick check for the first element in the parallel rtx. */ 160 if (GET_CODE (elt) != SET 161 || count <= 1 162 || count > 8) 163 return false; 164 165 /* Pick up regno of first element for further detail checking. 166 Note that the form is different between load and store operation. */ 167 if (load_p) 168 { 169 if (GET_CODE (SET_DEST (elt)) != REG 170 || GET_CODE (SET_SRC (elt)) != MEM) 171 return false; 172 173 first_elt_regno = REGNO (SET_DEST (elt)); 174 } 175 else 176 { 177 if (GET_CODE (SET_SRC (elt)) != REG 178 || GET_CODE (SET_DEST (elt)) != MEM) 179 return false; 180 181 first_elt_regno = REGNO (SET_SRC (elt)); 182 } 183 184 /* Perform detail check for each element. 185 Refer to nds32-multiple.md for more information 186 about following checking. 187 The starting element of parallel rtx is index 0. */ 188 if (!nds32_consecutive_registers_load_store_p (op, load_p, 0, 189 first_elt_regno, 190 count)) 191 return false; 192 193 /* Pass all test, this is a valid rtx. */ 194 return true; 195 } 196 197 /* Function to check whether the OP is a valid stack push/pop operation. 198 For a valid stack operation, it must satisfy following conditions: 199 1. Consecutive registers push/pop operations. 200 2. Valid $fp/$gp/$lp push/pop operations. 201 3. The last element must be stack adjustment rtx. 202 See the prologue/epilogue implementation for details. */ 203 bool 204 nds32_valid_stack_push_pop_p (rtx op, bool push_p) 205 { 206 int index; 207 int total_count; 208 int rest_count; 209 int first_regno; 210 int save_fp, save_gp, save_lp; 211 rtx elt; 212 rtx elt_reg; 213 rtx elt_mem; 214 rtx elt_plus; 215 216 /* Get the counts of elements in the parallel rtx. */ 217 total_count = XVECLEN (op, 0); 218 219 /* Perform some quick check for that every element should be 'set'. */ 220 for (index = 0; index < total_count; index++) 221 { 222 elt = XVECEXP (op, 0, index); 223 if (GET_CODE (elt) != SET) 224 return false; 225 } 226 227 /* For push operation, the parallel rtx looks like: 228 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32))) 229 (reg:SI Rb)) 230 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) 231 (reg:SI Rb+1)) 232 ... 233 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) 234 (reg:SI Re)) 235 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) 236 (reg:SI FP_REGNUM)) 237 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) 238 (reg:SI GP_REGNUM)) 239 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) 240 (reg:SI LP_REGNUM)) 241 (set (reg:SI SP_REGNUM) 242 (plus (reg:SI SP_REGNUM) (const_int -32)))]) 243 244 For pop operation, the parallel rtx looks like: 245 (parallel [(set (reg:SI Rb) 246 (mem (reg:SI SP_REGNUM))) 247 (set (reg:SI Rb+1) 248 (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) 249 ... 250 (set (reg:SI Re) 251 (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) 252 (set (reg:SI FP_REGNUM) 253 (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) 254 (set (reg:SI GP_REGNUM) 255 (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) 256 (set (reg:SI LP_REGNUM) 257 (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) 258 (set (reg:SI SP_REGNUM) 259 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */ 260 261 /* 1. Consecutive registers push/pop operations. 262 We need to calculate how many registers should be consecutive. 263 The $sp adjustment rtx, $fp push rtx, $gp push rtx, 264 and $lp push rtx are excluded. */ 265 266 /* Detect whether we have $fp, $gp, or $lp in the parallel rtx. */ 267 save_fp = reg_mentioned_p (gen_rtx_REG (SImode, FP_REGNUM), op); 268 save_gp = reg_mentioned_p (gen_rtx_REG (SImode, GP_REGNUM), op); 269 save_lp = reg_mentioned_p (gen_rtx_REG (SImode, LP_REGNUM), op); 270 /* Exclude last $sp adjustment rtx. */ 271 rest_count = total_count - 1; 272 /* Exclude $fp, $gp, and $lp if they are in the parallel rtx. */ 273 if (save_fp) 274 rest_count--; 275 if (save_gp) 276 rest_count--; 277 if (save_lp) 278 rest_count--; 279 280 if (rest_count > 0) 281 { 282 elt = XVECEXP (op, 0, 0); 283 /* Pick up register element. */ 284 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt); 285 first_regno = REGNO (elt_reg); 286 287 /* The 'push' operation is a kind of store operation. 288 The 'pop' operation is a kind of load operation. 289 Pass corresponding false/true as second argument (bool load_p). 290 The par_index is supposed to start with index 0. */ 291 if (!nds32_consecutive_registers_load_store_p (op, 292 !push_p ? true : false, 293 0, 294 first_regno, 295 rest_count)) 296 return false; 297 } 298 299 /* 2. Valid $fp/$gp/$lp push/pop operations. 300 Remember to set start index for checking them. */ 301 302 /* The rest_count is the start index for checking $fp/$gp/$lp. */ 303 index = rest_count; 304 /* If index < 0, this parallel rtx is definitely 305 not a valid stack push/pop operation. */ 306 if (index < 0) 307 return false; 308 309 /* Check $fp/$gp/$lp one by one. 310 We use 'push_p' to pick up reg rtx and mem rtx. */ 311 if (save_fp) 312 { 313 elt = XVECEXP (op, 0, index); 314 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt); 315 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt); 316 index++; 317 318 if (GET_CODE (elt_mem) != MEM 319 || GET_CODE (elt_reg) != REG 320 || REGNO (elt_reg) != FP_REGNUM) 321 return false; 322 } 323 if (save_gp) 324 { 325 elt = XVECEXP (op, 0, index); 326 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt); 327 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt); 328 index++; 329 330 if (GET_CODE (elt_mem) != MEM 331 || GET_CODE (elt_reg) != REG 332 || REGNO (elt_reg) != GP_REGNUM) 333 return false; 334 } 335 if (save_lp) 336 { 337 elt = XVECEXP (op, 0, index); 338 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt); 339 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt); 340 index++; 341 342 if (GET_CODE (elt_mem) != MEM 343 || GET_CODE (elt_reg) != REG 344 || REGNO (elt_reg) != LP_REGNUM) 345 return false; 346 } 347 348 /* 3. The last element must be stack adjustment rtx. 349 Its form of rtx should be: 350 (set (reg:SI SP_REGNUM) 351 (plus (reg:SI SP_REGNUM) (const_int X))) 352 The X could be positive or negative value. */ 353 354 /* Pick up the last element. */ 355 elt = XVECEXP (op, 0, total_count - 1); 356 357 /* Extract its destination and source rtx. */ 358 elt_reg = SET_DEST (elt); 359 elt_plus = SET_SRC (elt); 360 361 /* Check this is (set (stack_reg) (plus stack_reg const)) pattern. */ 362 if (GET_CODE (elt_reg) != REG 363 || GET_CODE (elt_plus) != PLUS 364 || REGNO (elt_reg) != SP_REGNUM) 365 return false; 366 367 /* Pass all test, this is a valid rtx. */ 368 return true; 369 } 370 371 /* Function to check if 'bclr' instruction can be used with IVAL. */ 372 int 373 nds32_can_use_bclr_p (int ival) 374 { 375 int one_bit_count; 376 377 /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit, 378 it means the original ival has only one 0-bit, 379 So it is ok to perform 'bclr' operation. */ 380 381 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival)); 382 383 /* 'bclr' is a performance extension instruction. */ 384 return (TARGET_PERF_EXT && (one_bit_count == 1)); 385 } 386 387 /* Function to check if 'bset' instruction can be used with IVAL. */ 388 int 389 nds32_can_use_bset_p (int ival) 390 { 391 int one_bit_count; 392 393 /* Caculate the number of 1-bit of ival, if there is only one 1-bit, 394 it is ok to perform 'bset' operation. */ 395 396 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); 397 398 /* 'bset' is a performance extension instruction. */ 399 return (TARGET_PERF_EXT && (one_bit_count == 1)); 400 } 401 402 /* Function to check if 'btgl' instruction can be used with IVAL. */ 403 int 404 nds32_can_use_btgl_p (int ival) 405 { 406 int one_bit_count; 407 408 /* Caculate the number of 1-bit of ival, if there is only one 1-bit, 409 it is ok to perform 'btgl' operation. */ 410 411 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); 412 413 /* 'btgl' is a performance extension instruction. */ 414 return (TARGET_PERF_EXT && (one_bit_count == 1)); 415 } 416 417 /* Function to check if 'bitci' instruction can be used with IVAL. */ 418 int 419 nds32_can_use_bitci_p (int ival) 420 { 421 /* If we are using V3 ISA, we have 'bitci' instruction. 422 Try to see if we can present 'andi' semantic with 423 such 'bit-clear-immediate' operation. 424 For example, 'andi $r0,$r0,0xfffffffc' can be 425 presented with 'bitci $r0,$r0,3'. */ 426 return (TARGET_ISA_V3 427 && (ival < 0) 428 && satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode))); 429 } 430 431 /* ------------------------------------------------------------------------ */ 432