1 1.1 mrg /* Subroutines for loongarch-specific option handling. 2 1.1 mrg Copyright (C) 2021-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Loongson Ltd. 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify 8 1.1 mrg it under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg #define IN_TARGET_CODE 1 22 1.1 mrg 23 1.1 mrg #include "config.h" 24 1.1 mrg #include "system.h" 25 1.1 mrg #include "coretypes.h" 26 1.1 mrg #include "tm.h" 27 1.1 mrg #include "obstack.h" 28 1.1 mrg #include "diagnostic-core.h" 29 1.1 mrg #include "loongarch-cpu.h" 30 1.1 mrg #include "loongarch-opts.h" 31 1.1 mrg #include "loongarch-str.h" 32 1.1 mrg 33 1.1 mrg struct loongarch_target la_target; 34 1.1 mrg 35 1.1 mrg /* ABI-related configuration. */ 36 1.1 mrg #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi)) 37 1.1 mrg static const struct loongarch_abi 38 1.1 mrg abi_priority_list[] = { 39 1.1 mrg {ABI_BASE_LP64D, ABI_EXT_BASE}, 40 1.1 mrg {ABI_BASE_LP64F, ABI_EXT_BASE}, 41 1.1 mrg {ABI_BASE_LP64S, ABI_EXT_BASE}, 42 1.1 mrg }; 43 1.1 mrg 44 1.1 mrg /* Initialize enabled_abi_types from TM_MULTILIB_LIST. */ 45 1.1 mrg #ifdef LA_DISABLE_MULTILIB 46 1.1 mrg #define MULTILIB_LIST_LEN 1 47 1.1 mrg #else 48 1.1 mrg #define MULTILIB_LIST_LEN (sizeof (tm_multilib_list) / sizeof (int) / 2) 49 1.1 mrg static const int tm_multilib_list[] = { TM_MULTILIB_LIST }; 50 1.1 mrg #endif 51 1.1 mrg static int enabled_abi_types[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { 0 }; 52 1.1 mrg 53 1.1 mrg #define isa_required(ABI) (abi_minimal_isa[(ABI).base][(ABI).ext]) 54 1.1 mrg extern "C" const struct loongarch_isa 55 1.1 mrg abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES]; 56 1.1 mrg 57 1.1 mrg static inline int 58 1.1 mrg is_multilib_enabled (struct loongarch_abi abi) 59 1.1 mrg { 60 1.1 mrg return enabled_abi_types[abi.base][abi.ext]; 61 1.1 mrg } 62 1.1 mrg 63 1.1 mrg static void 64 1.1 mrg init_enabled_abi_types () 65 1.1 mrg { 66 1.1 mrg #ifdef LA_DISABLE_MULTILIB 67 1.1 mrg enabled_abi_types[DEFAULT_ABI_BASE][DEFAULT_ABI_EXT] = 1; 68 1.1 mrg #else 69 1.1 mrg int abi_base, abi_ext; 70 1.1 mrg for (unsigned int i = 0; i < MULTILIB_LIST_LEN; i++) 71 1.1 mrg { 72 1.1 mrg abi_base = tm_multilib_list[i << 1]; 73 1.1 mrg abi_ext = tm_multilib_list[(i << 1) + 1]; 74 1.1 mrg enabled_abi_types[abi_base][abi_ext] = 1; 75 1.1 mrg } 76 1.1 mrg #endif 77 1.1 mrg } 78 1.1 mrg 79 1.1 mrg /* Switch masks. */ 80 1.1 mrg #undef M 81 1.1 mrg #define M(NAME) OPTION_MASK_##NAME 82 1.1 mrg const int loongarch_switch_mask[N_SWITCH_TYPES] = { 83 1.1 mrg /* SW_SOFT_FLOAT */ M(FORCE_SOFTF), 84 1.1 mrg /* SW_SINGLE_FLOAT */ M(FORCE_F32), 85 1.1 mrg /* SW_DOUBLE_FLOAT */ M(FORCE_F64), 86 1.1 mrg }; 87 1.1 mrg #undef M 88 1.1 mrg 89 1.1 mrg /* String processing. */ 90 1.1 mrg static struct obstack msg_obstack; 91 1.1 mrg #define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR)); 92 1.1 mrg #define APPEND1(CH) obstack_1grow(&msg_obstack, CH); 93 1.1 mrg 94 1.1 mrg static const char* abi_str (struct loongarch_abi abi); 95 1.1 mrg static const char* isa_str (const struct loongarch_isa *isa, char separator); 96 1.1 mrg static const char* arch_str (const struct loongarch_target *target); 97 1.1 mrg static const char* multilib_enabled_abi_list (); 98 1.1 mrg 99 1.1 mrg /* Misc */ 100 1.1 mrg static struct loongarch_abi isa_default_abi (const struct loongarch_isa *isa); 101 1.1 mrg static int isa_base_compat_p (const struct loongarch_isa *set1, 102 1.1 mrg const struct loongarch_isa *set2); 103 1.1 mrg static int isa_fpu_compat_p (const struct loongarch_isa *set1, 104 1.1 mrg const struct loongarch_isa *set2); 105 1.1 mrg static int abi_compat_p (const struct loongarch_isa *isa, 106 1.1 mrg struct loongarch_abi abi); 107 1.1 mrg static int abi_default_cpu_arch (struct loongarch_abi abi); 108 1.1 mrg 109 1.1 mrg /* Checking configure-time defaults. */ 110 1.1 mrg #ifndef DEFAULT_ABI_BASE 111 1.1 mrg #error missing definition of DEFAULT_ABI_BASE in ${tm_defines}. 112 1.1 mrg #endif 113 1.1 mrg 114 1.1 mrg #ifndef DEFAULT_ABI_EXT 115 1.1 mrg #error missing definition of DEFAULT_ABI_EXT in ${tm_defines}. 116 1.1 mrg #endif 117 1.1 mrg 118 1.1 mrg #ifndef DEFAULT_CPU_ARCH 119 1.1 mrg #error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}. 120 1.1 mrg #endif 121 1.1 mrg 122 1.1 mrg #ifndef DEFAULT_ISA_EXT_FPU 123 1.1 mrg #error missing definition of DEFAULT_ISA_EXT_FPU in ${tm_defines}. 124 1.1 mrg #endif 125 1.1 mrg 126 1.1 mrg /* Handle combinations of -m machine option values 127 1.1 mrg (see loongarch.opt and loongarch-opts.h). */ 128 1.1 mrg void 129 1.1 mrg loongarch_config_target (struct loongarch_target *target, 130 1.1 mrg HOST_WIDE_INT opt_switches, 131 1.1 mrg int opt_arch, int opt_tune, int opt_fpu, 132 1.1 mrg int opt_abi_base, int opt_abi_ext, 133 1.1 mrg int opt_cmodel, int follow_multilib_list) 134 1.1 mrg { 135 1.1 mrg struct loongarch_target t; 136 1.1 mrg 137 1.1 mrg if (!target) 138 1.1 mrg return; 139 1.1 mrg 140 1.1 mrg /* Initialization */ 141 1.1 mrg init_enabled_abi_types (); 142 1.1 mrg obstack_init (&msg_obstack); 143 1.1 mrg 144 1.1 mrg struct { 145 1.1 mrg int arch, tune, fpu, abi_base, abi_ext, cmodel; 146 1.1 mrg } constrained = { 147 1.1 mrg M_OPT_ABSENT(opt_arch) ? 0 : 1, 148 1.1 mrg M_OPT_ABSENT(opt_tune) ? 0 : 1, 149 1.1 mrg M_OPT_ABSENT(opt_fpu) ? 0 : 1, 150 1.1 mrg M_OPT_ABSENT(opt_abi_base) ? 0 : 1, 151 1.1 mrg M_OPT_ABSENT(opt_abi_ext) ? 0 : 1, 152 1.1 mrg M_OPT_ABSENT(opt_cmodel) ? 0 : 1, 153 1.1 mrg }; 154 1.1 mrg 155 1.1 mrg #define on(NAME) ((loongarch_switch_mask[(SW_##NAME)] & opt_switches) \ 156 1.1 mrg && (on_switch = (SW_##NAME), 1)) 157 1.1 mrg int on_switch; 158 1.1 mrg 159 1.1 mrg /* 1. Target ABI */ 160 1.1 mrg t.abi.base = constrained.abi_base ? opt_abi_base : DEFAULT_ABI_BASE; 161 1.1 mrg 162 1.1 mrg t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT; 163 1.1 mrg 164 1.1 mrg /* Extra switch handling. */ 165 1.1 mrg if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT)) 166 1.1 mrg { 167 1.1 mrg switch (on_switch) 168 1.1 mrg { 169 1.1 mrg case SW_SOFT_FLOAT: 170 1.1 mrg opt_fpu = ISA_EXT_NOFPU; 171 1.1 mrg break; 172 1.1 mrg 173 1.1 mrg case SW_SINGLE_FLOAT: 174 1.1 mrg opt_fpu = ISA_EXT_FPU32; 175 1.1 mrg break; 176 1.1 mrg 177 1.1 mrg case SW_DOUBLE_FLOAT: 178 1.1 mrg opt_fpu = ISA_EXT_FPU64; 179 1.1 mrg break; 180 1.1 mrg 181 1.1 mrg default: 182 1.1 mrg gcc_unreachable(); 183 1.1 mrg } 184 1.1 mrg constrained.fpu = 1; 185 1.1 mrg 186 1.1 mrg /* The target ISA is not ready yet, but (isa_required (t.abi) 187 1.1 mrg + forced fpu) is enough for computing the forced base ABI. */ 188 1.1 mrg struct loongarch_isa default_isa = isa_required (t.abi); 189 1.1 mrg struct loongarch_isa force_isa = default_isa; 190 1.1 mrg struct loongarch_abi force_abi = t.abi; 191 1.1 mrg force_isa.fpu = opt_fpu; 192 1.1 mrg force_abi.base = isa_default_abi (&force_isa).base; 193 1.1 mrg 194 1.1 mrg if (constrained.abi_base && (t.abi.base != force_abi.base)) 195 1.1 mrg inform (UNKNOWN_LOCATION, 196 1.1 mrg "%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs", 197 1.1 mrg loongarch_switch_strings[on_switch], 198 1.1 mrg OPTSTR_ABI_BASE, loongarch_abi_base_strings[t.abi.base], 199 1.1 mrg abi_str (force_abi)); 200 1.1 mrg 201 1.1 mrg t.abi.base = force_abi.base; 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg #ifdef LA_DISABLE_MULTILIB 205 1.1 mrg if (follow_multilib_list) 206 1.1 mrg if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT) 207 1.1 mrg { 208 1.1 mrg static const struct loongarch_abi default_abi 209 1.1 mrg = {DEFAULT_ABI_BASE, DEFAULT_ABI_EXT}; 210 1.1 mrg 211 1.1 mrg warning (0, "ABI changed (%qs to %qs) while multilib is disabled", 212 1.1 mrg abi_str (default_abi), abi_str (t.abi)); 213 1.1 mrg } 214 1.1 mrg #endif 215 1.1 mrg 216 1.1 mrg /* 2. Target CPU */ 217 1.1 mrg t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH; 218 1.1 mrg 219 1.1 mrg t.cpu_tune = constrained.tune ? opt_tune 220 1.1 mrg : (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE); 221 1.1 mrg 222 1.1 mrg #ifdef __loongarch__ 223 1.1 mrg /* For native compilers, gather local CPU information 224 1.1 mrg and fill the "CPU_NATIVE" index of arrays defined in 225 1.1 mrg loongarch-cpu.c. */ 226 1.1 mrg 227 1.1 mrg t.cpu_native = fill_native_cpu_config (t.cpu_arch == CPU_NATIVE, 228 1.1 mrg t.cpu_tune == CPU_NATIVE); 229 1.1 mrg 230 1.1 mrg #else 231 1.1 mrg if (t.cpu_arch == CPU_NATIVE) 232 1.1 mrg fatal_error (UNKNOWN_LOCATION, 233 1.1 mrg "%qs does not work on a cross compiler", 234 1.1 mrg "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE); 235 1.1 mrg 236 1.1 mrg else if (t.cpu_tune == CPU_NATIVE) 237 1.1 mrg fatal_error (UNKNOWN_LOCATION, 238 1.1 mrg "%qs does not work on a cross compiler", 239 1.1 mrg "-m" OPTSTR_TUNE "=" STR_CPU_NATIVE); 240 1.1 mrg #endif 241 1.1 mrg 242 1.1 mrg /* 3. Target ISA */ 243 1.1 mrg config_target_isa: 244 1.1 mrg 245 1.1 mrg /* Get default ISA from "-march" or its default value. */ 246 1.1 mrg t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_ARCH]; 247 1.1 mrg 248 1.1 mrg /* Apply incremental changes. */ 249 1.1 mrg /* "-march=native" overrides the default FPU type. */ 250 1.1 mrg t.isa.fpu = constrained.fpu ? opt_fpu : 251 1.1 mrg ((t.cpu_arch == CPU_NATIVE && constrained.arch) ? 252 1.1 mrg t.isa.fpu : DEFAULT_ISA_EXT_FPU); 253 1.1 mrg 254 1.1 mrg 255 1.1 mrg /* 4. ABI-ISA compatibility */ 256 1.1 mrg /* Note: 257 1.1 mrg - There IS a unique default -march value for each ABI type 258 1.1 mrg (config.gcc: triplet -> abi -> default arch). 259 1.1 mrg 260 1.1 mrg - If the base ABI is incompatible with the default arch, 261 1.1 mrg try using the default -march it implies (and mark it 262 1.1 mrg as "constrained" this time), then re-apply step 3. */ 263 1.1 mrg 264 1.1 mrg struct loongarch_abi abi_tmp; 265 1.1 mrg const struct loongarch_isa* isa_min; 266 1.1 mrg 267 1.1 mrg abi_tmp = t.abi; 268 1.1 mrg isa_min = &isa_required (abi_tmp); 269 1.1 mrg 270 1.1 mrg if (isa_base_compat_p (&t.isa, isa_min)); /* OK. */ 271 1.1 mrg else if (!constrained.arch) 272 1.1 mrg { 273 1.1 mrg /* Base architecture can only be implied by -march, 274 1.1 mrg so we adjust that first if it is not constrained. */ 275 1.1 mrg int fallback_arch = abi_default_cpu_arch (t.abi); 276 1.1 mrg 277 1.1 mrg if (t.cpu_arch == CPU_NATIVE) 278 1.1 mrg warning (0, "your native CPU architecture (%qs) " 279 1.1 mrg "does not support %qs ABI, falling back to %<-m%s=%s%>", 280 1.1 mrg arch_str (&t), abi_str (t.abi), OPTSTR_ARCH, 281 1.1 mrg loongarch_cpu_strings[fallback_arch]); 282 1.1 mrg else 283 1.1 mrg warning (0, "default CPU architecture (%qs) " 284 1.1 mrg "does not support %qs ABI, falling back to %<-m%s=%s%>", 285 1.1 mrg arch_str (&t), abi_str (t.abi), OPTSTR_ARCH, 286 1.1 mrg loongarch_cpu_strings[fallback_arch]); 287 1.1 mrg 288 1.1 mrg t.cpu_arch = fallback_arch; 289 1.1 mrg constrained.arch = 1; 290 1.1 mrg goto config_target_isa; 291 1.1 mrg } 292 1.1 mrg else if (!constrained.abi_base) 293 1.1 mrg { 294 1.1 mrg /* If -march is given while -mabi is not, 295 1.1 mrg try selecting another base ABI type. */ 296 1.1 mrg abi_tmp.base = isa_default_abi (&t.isa).base; 297 1.1 mrg } 298 1.1 mrg else 299 1.1 mrg goto fatal; 300 1.1 mrg 301 1.1 mrg if (isa_fpu_compat_p (&t.isa, isa_min)); /* OK. */ 302 1.1 mrg else if (!constrained.fpu) 303 1.1 mrg t.isa.fpu = isa_min->fpu; 304 1.1 mrg else if (!constrained.abi_base) 305 1.1 mrg /* If -march is compatible with the default ABI 306 1.1 mrg while -mfpu is not. */ 307 1.1 mrg abi_tmp.base = isa_default_abi (&t.isa).base; 308 1.1 mrg else 309 1.1 mrg goto fatal; 310 1.1 mrg 311 1.1 mrg if (0) 312 1.1 mrg fatal: 313 1.1 mrg fatal_error (UNKNOWN_LOCATION, 314 1.1 mrg "unable to implement ABI %qs with instruction set %qs", 315 1.1 mrg abi_str (t.abi), isa_str (&t.isa, '/')); 316 1.1 mrg 317 1.1 mrg 318 1.1 mrg /* Using the fallback ABI. */ 319 1.1 mrg if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext) 320 1.1 mrg { 321 1.1 mrg /* This flag is only set in the GCC driver. */ 322 1.1 mrg if (follow_multilib_list) 323 1.1 mrg { 324 1.1 mrg 325 1.1 mrg /* Continue falling back until we find a feasible ABI type 326 1.1 mrg enabled by TM_MULTILIB_LIST. */ 327 1.1 mrg if (!is_multilib_enabled (abi_tmp)) 328 1.1 mrg { 329 1.1 mrg for (unsigned int i = 0; i < ABI_COUNT; i++) 330 1.1 mrg { 331 1.1 mrg if (is_multilib_enabled (abi_priority_list[i]) 332 1.1 mrg && abi_compat_p (&t.isa, abi_priority_list[i])) 333 1.1 mrg { 334 1.1 mrg abi_tmp = abi_priority_list[i]; 335 1.1 mrg 336 1.1 mrg warning (0, "ABI %qs cannot be implemented due to " 337 1.1 mrg "limited instruction set %qs, " 338 1.1 mrg "falling back to %qs", abi_str (t.abi), 339 1.1 mrg isa_str (&t.isa, '/'), abi_str (abi_tmp)); 340 1.1 mrg 341 1.1 mrg goto fallback; 342 1.1 mrg } 343 1.1 mrg } 344 1.1 mrg 345 1.1 mrg /* Otherwise, keep using abi_tmp with a warning. */ 346 1.1 mrg #ifdef LA_DISABLE_MULTILIB 347 1.1 mrg warning (0, "instruction set %qs cannot implement " 348 1.1 mrg "default ABI %qs, falling back to %qs", 349 1.1 mrg isa_str (&t.isa, '/'), abi_str (t.abi), 350 1.1 mrg abi_str (abi_tmp)); 351 1.1 mrg #else 352 1.1 mrg warning (0, "no multilib-enabled ABI (%qs) can be implemented " 353 1.1 mrg "with instruction set %qs, falling back to %qs", 354 1.1 mrg multilib_enabled_abi_list (), 355 1.1 mrg isa_str (&t.isa, '/'), abi_str (abi_tmp)); 356 1.1 mrg #endif 357 1.1 mrg } 358 1.1 mrg } 359 1.1 mrg 360 1.1 mrg fallback: 361 1.1 mrg t.abi = abi_tmp; 362 1.1 mrg } 363 1.1 mrg else if (follow_multilib_list) 364 1.1 mrg { 365 1.1 mrg if (!is_multilib_enabled (t.abi)) 366 1.1 mrg { 367 1.1 mrg inform (UNKNOWN_LOCATION, 368 1.1 mrg "ABI %qs is not enabled at configure-time, " 369 1.1 mrg "the linker might report an error", abi_str (t.abi)); 370 1.1 mrg 371 1.1 mrg inform (UNKNOWN_LOCATION, "ABI with startfiles: %s", 372 1.1 mrg multilib_enabled_abi_list ()); 373 1.1 mrg } 374 1.1 mrg } 375 1.1 mrg 376 1.1 mrg 377 1.1 mrg /* 5. Target code model */ 378 1.1 mrg t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL; 379 1.1 mrg 380 1.1 mrg /* Cleanup and return. */ 381 1.1 mrg obstack_free (&msg_obstack, NULL); 382 1.1 mrg *target = t; 383 1.1 mrg } 384 1.1 mrg 385 1.1 mrg /* Returns the default ABI for the given instruction set. */ 386 1.1 mrg static inline struct loongarch_abi 387 1.1 mrg isa_default_abi (const struct loongarch_isa *isa) 388 1.1 mrg { 389 1.1 mrg struct loongarch_abi abi; 390 1.1 mrg 391 1.1 mrg switch (isa->fpu) 392 1.1 mrg { 393 1.1 mrg case ISA_EXT_FPU64: 394 1.1 mrg if (isa->base == ISA_BASE_LA64V100) 395 1.1 mrg abi.base = ABI_BASE_LP64D; 396 1.1 mrg break; 397 1.1 mrg 398 1.1 mrg case ISA_EXT_FPU32: 399 1.1 mrg if (isa->base == ISA_BASE_LA64V100) 400 1.1 mrg abi.base = ABI_BASE_LP64F; 401 1.1 mrg break; 402 1.1 mrg 403 1.1 mrg case ISA_EXT_NOFPU: 404 1.1 mrg if (isa->base == ISA_BASE_LA64V100) 405 1.1 mrg abi.base = ABI_BASE_LP64S; 406 1.1 mrg break; 407 1.1 mrg 408 1.1 mrg default: 409 1.1 mrg gcc_unreachable (); 410 1.1 mrg } 411 1.1 mrg 412 1.1 mrg abi.ext = ABI_EXT_BASE; 413 1.1 mrg return abi; 414 1.1 mrg } 415 1.1 mrg 416 1.1 mrg /* Check if set2 is a subset of set1. */ 417 1.1 mrg static inline int 418 1.1 mrg isa_base_compat_p (const struct loongarch_isa *set1, 419 1.1 mrg const struct loongarch_isa *set2) 420 1.1 mrg { 421 1.1 mrg switch (set2->base) 422 1.1 mrg { 423 1.1 mrg case ISA_BASE_LA64V100: 424 1.1 mrg return (set1->base == ISA_BASE_LA64V100); 425 1.1 mrg 426 1.1 mrg default: 427 1.1 mrg gcc_unreachable (); 428 1.1 mrg } 429 1.1 mrg } 430 1.1 mrg 431 1.1 mrg static inline int 432 1.1 mrg isa_fpu_compat_p (const struct loongarch_isa *set1, 433 1.1 mrg const struct loongarch_isa *set2) 434 1.1 mrg { 435 1.1 mrg switch (set2->fpu) 436 1.1 mrg { 437 1.1 mrg case ISA_EXT_FPU64: 438 1.1 mrg return set1->fpu == ISA_EXT_FPU64; 439 1.1 mrg 440 1.1 mrg case ISA_EXT_FPU32: 441 1.1 mrg return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64; 442 1.1 mrg 443 1.1 mrg case ISA_EXT_NOFPU: 444 1.1 mrg return 1; 445 1.1 mrg 446 1.1 mrg default: 447 1.1 mrg gcc_unreachable (); 448 1.1 mrg } 449 1.1 mrg 450 1.1 mrg } 451 1.1 mrg 452 1.1 mrg static inline int 453 1.1 mrg abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi) 454 1.1 mrg { 455 1.1 mrg int compatible = 1; 456 1.1 mrg const struct loongarch_isa *isa2 = &isa_required (abi); 457 1.1 mrg 458 1.1 mrg /* Append conditionals for new ISA components below. */ 459 1.1 mrg compatible = compatible && isa_base_compat_p (isa, isa2); 460 1.1 mrg compatible = compatible && isa_fpu_compat_p (isa, isa2); 461 1.1 mrg return compatible; 462 1.1 mrg } 463 1.1 mrg 464 1.1 mrg /* The behavior of this function should be consistent 465 1.1 mrg with config.gcc. */ 466 1.1 mrg static inline int 467 1.1 mrg abi_default_cpu_arch (struct loongarch_abi abi) 468 1.1 mrg { 469 1.1 mrg switch (abi.base) 470 1.1 mrg { 471 1.1 mrg case ABI_BASE_LP64D: 472 1.1 mrg case ABI_BASE_LP64F: 473 1.1 mrg case ABI_BASE_LP64S: 474 1.1 mrg if (abi.ext == ABI_EXT_BASE) 475 1.1 mrg return CPU_LOONGARCH64; 476 1.1 mrg } 477 1.1 mrg gcc_unreachable (); 478 1.1 mrg } 479 1.1 mrg 480 1.1 mrg static const char* 481 1.1 mrg abi_str (struct loongarch_abi abi) 482 1.1 mrg { 483 1.1 mrg /* "/base" can be omitted. */ 484 1.1 mrg if (abi.ext == ABI_EXT_BASE) 485 1.1 mrg return (const char*) 486 1.1 mrg obstack_copy0 (&msg_obstack, loongarch_abi_base_strings[abi.base], 487 1.1 mrg strlen (loongarch_abi_base_strings[abi.base])); 488 1.1 mrg else 489 1.1 mrg { 490 1.1 mrg APPEND_STRING (loongarch_abi_base_strings[abi.base]) 491 1.1 mrg APPEND1 ('/') 492 1.1 mrg APPEND_STRING (loongarch_abi_ext_strings[abi.ext]) 493 1.1 mrg APPEND1 ('\0') 494 1.1 mrg 495 1.1 mrg return XOBFINISH (&msg_obstack, const char *); 496 1.1 mrg } 497 1.1 mrg } 498 1.1 mrg 499 1.1 mrg static const char* 500 1.1 mrg isa_str (const struct loongarch_isa *isa, char separator) 501 1.1 mrg { 502 1.1 mrg APPEND_STRING (loongarch_isa_base_strings[isa->base]) 503 1.1 mrg APPEND1 (separator) 504 1.1 mrg 505 1.1 mrg if (isa->fpu == ISA_EXT_NOFPU) 506 1.1 mrg { 507 1.1 mrg APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU) 508 1.1 mrg } 509 1.1 mrg else 510 1.1 mrg { 511 1.1 mrg APPEND_STRING (OPTSTR_ISA_EXT_FPU) 512 1.1 mrg APPEND_STRING (loongarch_isa_ext_strings[isa->fpu]) 513 1.1 mrg } 514 1.1 mrg APPEND1 ('\0') 515 1.1 mrg 516 1.1 mrg /* Add more here. */ 517 1.1 mrg 518 1.1 mrg return XOBFINISH (&msg_obstack, const char *); 519 1.1 mrg } 520 1.1 mrg 521 1.1 mrg static const char* 522 1.1 mrg arch_str (const struct loongarch_target *target) 523 1.1 mrg { 524 1.1 mrg if (target->cpu_arch == CPU_NATIVE) 525 1.1 mrg { 526 1.1 mrg if (target->cpu_native == CPU_NATIVE) 527 1.1 mrg { 528 1.1 mrg /* Describe a native CPU with unknown PRID. */ 529 1.1 mrg const char* isa_string = isa_str (&target->isa, ','); 530 1.1 mrg APPEND_STRING ("PRID: 0x") 531 1.1 mrg APPEND_STRING (get_native_prid_str ()) 532 1.1 mrg APPEND_STRING (", ISA features: ") 533 1.1 mrg APPEND_STRING (isa_string) 534 1.1 mrg APPEND1 ('\0') 535 1.1 mrg } 536 1.1 mrg else 537 1.1 mrg APPEND_STRING (loongarch_cpu_strings[target->cpu_native]); 538 1.1 mrg } 539 1.1 mrg else 540 1.1 mrg APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]); 541 1.1 mrg 542 1.1 mrg APPEND1 ('\0') 543 1.1 mrg return XOBFINISH (&msg_obstack, const char *); 544 1.1 mrg } 545 1.1 mrg 546 1.1 mrg static const char* 547 1.1 mrg multilib_enabled_abi_list () 548 1.1 mrg { 549 1.1 mrg int enabled_abi_idx[MULTILIB_LIST_LEN] = { 0 }; 550 1.1 mrg const char* enabled_abi_str[MULTILIB_LIST_LEN] = { NULL }; 551 1.1 mrg unsigned int j = 0; 552 1.1 mrg 553 1.1 mrg for (unsigned int i = 0; i < ABI_COUNT && j < MULTILIB_LIST_LEN; i++) 554 1.1 mrg { 555 1.1 mrg if (enabled_abi_types[abi_priority_list[i].base] 556 1.1 mrg [abi_priority_list[i].ext]) 557 1.1 mrg { 558 1.1 mrg enabled_abi_idx[j++] = i; 559 1.1 mrg } 560 1.1 mrg } 561 1.1 mrg 562 1.1 mrg for (unsigned int k = 0; k < j; k++) 563 1.1 mrg { 564 1.1 mrg enabled_abi_str[k] = abi_str (abi_priority_list[enabled_abi_idx[k]]); 565 1.1 mrg } 566 1.1 mrg 567 1.1 mrg for (unsigned int k = 0; k < j - 1; k++) 568 1.1 mrg { 569 1.1 mrg APPEND_STRING (enabled_abi_str[k]) 570 1.1 mrg APPEND1 (',') 571 1.1 mrg APPEND1 (' ') 572 1.1 mrg } 573 1.1 mrg APPEND_STRING (enabled_abi_str[j - 1]) 574 1.1 mrg APPEND1 ('\0') 575 1.1 mrg 576 1.1 mrg return XOBFINISH (&msg_obstack, const char *); 577 1.1 mrg } 578 1.1 mrg 579 1.1 mrg /* option status feedback for "gcc --help=target -Q" */ 580 1.1 mrg void 581 1.1 mrg loongarch_update_gcc_opt_status (struct loongarch_target *target, 582 1.1 mrg struct gcc_options *opts, 583 1.1 mrg struct gcc_options *opts_set) 584 1.1 mrg { 585 1.1 mrg (void) opts_set; 586 1.1 mrg 587 1.1 mrg /* status of -mabi */ 588 1.1 mrg opts->x_la_opt_abi_base = target->abi.base; 589 1.1 mrg 590 1.1 mrg /* status of -march and -mtune */ 591 1.1 mrg opts->x_la_opt_cpu_arch = target->cpu_arch; 592 1.1 mrg opts->x_la_opt_cpu_tune = target->cpu_tune; 593 1.1 mrg 594 1.1 mrg /* status of -mcmodel */ 595 1.1 mrg opts->x_la_opt_cmodel = target->cmodel; 596 1.1 mrg 597 1.1 mrg /* status of -mfpu */ 598 1.1 mrg opts->x_la_opt_fpu = target->isa.fpu; 599 1.1 mrg } 600