1 /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2017 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 "backend.h" 27 #include "target.h" 28 #include "rtl.h" 29 #include "tree.h" 30 #include "memmodel.h" 31 #include "tm_p.h" 32 #include "optabs.h" /* For GEN_FCN. */ 33 #include "recog.h" 34 #include "tm-constrs.h" 35 36 /* ------------------------------------------------------------------------ */ 37 38 bool 39 nds32_rtx_costs_impl (rtx x, 40 machine_mode mode ATTRIBUTE_UNUSED, 41 int outer_code, 42 int opno ATTRIBUTE_UNUSED, 43 int *total, 44 bool speed) 45 { 46 int code = GET_CODE (x); 47 48 /* According to 'speed', goto suitable cost model section. */ 49 if (speed) 50 goto performance_cost; 51 else 52 goto size_cost; 53 54 55 performance_cost: 56 /* This is section for performance cost model. */ 57 58 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. 59 We treat it as 4-cycle cost for each instruction 60 under performance consideration. */ 61 switch (code) 62 { 63 case SET: 64 /* For 'SET' rtx, we need to return false 65 so that it can recursively calculate costs. */ 66 return false; 67 68 case USE: 69 /* Used in combine.c as a marker. */ 70 *total = 0; 71 break; 72 73 case MULT: 74 *total = COSTS_N_INSNS (1); 75 break; 76 77 case DIV: 78 case UDIV: 79 case MOD: 80 case UMOD: 81 *total = COSTS_N_INSNS (7); 82 break; 83 84 default: 85 *total = COSTS_N_INSNS (1); 86 break; 87 } 88 89 return true; 90 91 92 size_cost: 93 /* This is section for size cost model. */ 94 95 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. 96 We treat it as 4-byte cost for each instruction 97 under code size consideration. */ 98 switch (code) 99 { 100 case SET: 101 /* For 'SET' rtx, we need to return false 102 so that it can recursively calculate costs. */ 103 return false; 104 105 case USE: 106 /* Used in combine.c as a marker. */ 107 *total = 0; 108 break; 109 110 case CONST_INT: 111 /* All instructions involving constant operation 112 need to be considered for cost evaluation. */ 113 if (outer_code == SET) 114 { 115 /* (set X imm5s), use movi55, 2-byte cost. 116 (set X imm20s), use movi, 4-byte cost. 117 (set X BIG_INT), use sethi/ori, 8-byte cost. */ 118 if (satisfies_constraint_Is05 (x)) 119 *total = COSTS_N_INSNS (1) - 2; 120 else if (satisfies_constraint_Is20 (x)) 121 *total = COSTS_N_INSNS (1); 122 else 123 *total = COSTS_N_INSNS (2); 124 } 125 else if (outer_code == PLUS || outer_code == MINUS) 126 { 127 /* Possible addi333/subi333 or subi45/addi45, 2-byte cost. 128 General case, cost 1 instruction with 4-byte. */ 129 if (satisfies_constraint_Iu05 (x)) 130 *total = COSTS_N_INSNS (1) - 2; 131 else 132 *total = COSTS_N_INSNS (1); 133 } 134 else if (outer_code == ASHIFT) 135 { 136 /* Possible slli333, 2-byte cost. 137 General case, cost 1 instruction with 4-byte. */ 138 if (satisfies_constraint_Iu03 (x)) 139 *total = COSTS_N_INSNS (1) - 2; 140 else 141 *total = COSTS_N_INSNS (1); 142 } 143 else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT) 144 { 145 /* Possible srai45 or srli45, 2-byte cost. 146 General case, cost 1 instruction with 4-byte. */ 147 if (satisfies_constraint_Iu05 (x)) 148 *total = COSTS_N_INSNS (1) - 2; 149 else 150 *total = COSTS_N_INSNS (1); 151 } 152 else 153 { 154 /* For other cases, simply set it 4-byte cost. */ 155 *total = COSTS_N_INSNS (1); 156 } 157 break; 158 159 case CONST_DOUBLE: 160 /* It requires high part and low part processing, set it 8-byte cost. */ 161 *total = COSTS_N_INSNS (2); 162 break; 163 164 default: 165 /* For other cases, generally we set it 4-byte cost 166 and stop resurively traversing. */ 167 *total = COSTS_N_INSNS (1); 168 break; 169 } 170 171 return true; 172 } 173 174 int 175 nds32_address_cost_impl (rtx address, 176 machine_mode mode ATTRIBUTE_UNUSED, 177 addr_space_t as ATTRIBUTE_UNUSED, 178 bool speed) 179 { 180 rtx plus0, plus1; 181 enum rtx_code code; 182 183 code = GET_CODE (address); 184 185 /* According to 'speed', goto suitable cost model section. */ 186 if (speed) 187 goto performance_cost; 188 else 189 goto size_cost; 190 191 performance_cost: 192 /* This is section for performance cost model. */ 193 194 /* FALLTHRU, currently we use same cost model as size_cost. */ 195 196 size_cost: 197 /* This is section for size cost model. */ 198 199 switch (code) 200 { 201 case POST_MODIFY: 202 case POST_INC: 203 case POST_DEC: 204 /* We encourage that rtx contains 205 POST_MODIFY/POST_INC/POST_DEC behavior. */ 206 return 0; 207 208 case SYMBOL_REF: 209 /* We can have gp-relative load/store for symbol_ref. 210 Have it 4-byte cost. */ 211 return COSTS_N_INSNS (1); 212 213 case CONST: 214 /* It is supposed to be the pattern (const (plus symbol_ref const_int)). 215 Have it 4-byte cost. */ 216 return COSTS_N_INSNS (1); 217 218 case REG: 219 /* Simply return 4-byte costs. */ 220 return COSTS_N_INSNS (1); 221 222 case PLUS: 223 /* We do not need to check if the address is a legitimate address, 224 because this hook is never called with an invalid address. 225 But we better check the range of 226 const_int value for cost, if it exists. */ 227 plus0 = XEXP (address, 0); 228 plus1 = XEXP (address, 1); 229 230 if (REG_P (plus0) && CONST_INT_P (plus1)) 231 { 232 /* If it is possible to be lwi333/swi333 form, 233 make it 2-byte cost. */ 234 if (satisfies_constraint_Iu05 (plus1)) 235 return (COSTS_N_INSNS (1) - 2); 236 else 237 return COSTS_N_INSNS (1); 238 } 239 240 /* For other 'plus' situation, make it cost 4-byte. */ 241 return COSTS_N_INSNS (1); 242 243 default: 244 break; 245 } 246 247 return COSTS_N_INSNS (4); 248 } 249 250 /* ------------------------------------------------------------------------ */ 251