1 1.1 mrg /* Subroutines used for code generation on the DEC Alpha. 2 1.1 mrg Copyright (C) 1992-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Richard Kenner (kenner (at) vlsi1.ultra.nyu.edu) 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 22 1.1 mrg #define IN_TARGET_CODE 1 23 1.1 mrg 24 1.1 mrg #include "config.h" 25 1.1 mrg #include "system.h" 26 1.1 mrg #include "coretypes.h" 27 1.1 mrg #include "backend.h" 28 1.1 mrg #include "target.h" 29 1.1 mrg #include "rtl.h" 30 1.1 mrg #include "tree.h" 31 1.1 mrg #include "stringpool.h" 32 1.1 mrg #include "attribs.h" 33 1.1 mrg #include "memmodel.h" 34 1.1 mrg #include "gimple.h" 35 1.1 mrg #include "df.h" 36 1.1 mrg #include "predict.h" 37 1.1 mrg #include "tm_p.h" 38 1.1 mrg #include "ssa.h" 39 1.1 mrg #include "expmed.h" 40 1.1 mrg #include "optabs.h" 41 1.1 mrg #include "regs.h" 42 1.1 mrg #include "emit-rtl.h" 43 1.1 mrg #include "recog.h" 44 1.1 mrg #include "diagnostic-core.h" 45 1.1 mrg #include "alias.h" 46 1.1 mrg #include "fold-const.h" 47 1.1 mrg #include "stor-layout.h" 48 1.1 mrg #include "calls.h" 49 1.1 mrg #include "varasm.h" 50 1.1 mrg #include "output.h" 51 1.1 mrg #include "insn-attr.h" 52 1.1 mrg #include "explow.h" 53 1.1 mrg #include "expr.h" 54 1.1 mrg #include "reload.h" 55 1.1 mrg #include "except.h" 56 1.1 mrg #include "common/common-target.h" 57 1.1 mrg #include "debug.h" 58 1.1 mrg #include "langhooks.h" 59 1.1 mrg #include "cfgrtl.h" 60 1.1 mrg #include "tree-pass.h" 61 1.1 mrg #include "context.h" 62 1.1 mrg #include "gimple-iterator.h" 63 1.1 mrg #include "gimplify.h" 64 1.1 mrg #include "tree-stdarg.h" 65 1.1 mrg #include "tm-constrs.h" 66 1.1 mrg #include "libfuncs.h" 67 1.1 mrg #include "builtins.h" 68 1.1 mrg #include "rtl-iter.h" 69 1.1 mrg #include "flags.h" 70 1.1 mrg #include "opts.h" 71 1.1 mrg 72 1.1 mrg /* This file should be included last. */ 73 1.1 mrg #include "target-def.h" 74 1.1 mrg 75 1.1 mrg /* Specify which cpu to schedule for. */ 76 1.1 mrg enum processor_type alpha_tune; 77 1.1 mrg 78 1.1 mrg /* Which cpu we're generating code for. */ 79 1.1 mrg enum processor_type alpha_cpu; 80 1.1 mrg 81 1.1 mrg static const char * const alpha_cpu_name[] = 82 1.1 mrg { 83 1.1 mrg "ev4", "ev5", "ev6" 84 1.1 mrg }; 85 1.1 mrg 86 1.1 mrg /* Specify how accurate floating-point traps need to be. */ 87 1.1 mrg 88 1.1 mrg enum alpha_trap_precision alpha_tp; 89 1.1 mrg 90 1.1 mrg /* Specify the floating-point rounding mode. */ 91 1.1 mrg 92 1.1 mrg enum alpha_fp_rounding_mode alpha_fprm; 93 1.1 mrg 94 1.1 mrg /* Specify which things cause traps. */ 95 1.1 mrg 96 1.1 mrg enum alpha_fp_trap_mode alpha_fptm; 97 1.1 mrg 98 1.1 mrg /* Nonzero if inside of a function, because the Alpha asm can't 99 1.1 mrg handle .files inside of functions. */ 100 1.1 mrg 101 1.1 mrg static int inside_function = FALSE; 102 1.1 mrg 103 1.1 mrg /* The number of cycles of latency we should assume on memory reads. */ 104 1.1 mrg 105 1.1 mrg static int alpha_memory_latency = 3; 106 1.1 mrg 107 1.1 mrg /* Whether the function needs the GP. */ 108 1.1 mrg 109 1.1 mrg static int alpha_function_needs_gp; 110 1.1 mrg 111 1.1 mrg /* The assembler name of the current function. */ 112 1.1 mrg 113 1.1 mrg static const char *alpha_fnname; 114 1.1 mrg 115 1.1 mrg /* The next explicit relocation sequence number. */ 116 1.1 mrg extern GTY(()) int alpha_next_sequence_number; 117 1.1 mrg int alpha_next_sequence_number = 1; 118 1.1 mrg 119 1.1 mrg /* The literal and gpdisp sequence numbers for this insn, as printed 120 1.1 mrg by %# and %* respectively. */ 121 1.1 mrg extern GTY(()) int alpha_this_literal_sequence_number; 122 1.1 mrg extern GTY(()) int alpha_this_gpdisp_sequence_number; 123 1.1 mrg int alpha_this_literal_sequence_number; 124 1.1 mrg int alpha_this_gpdisp_sequence_number; 125 1.1 mrg 126 1.1 mrg /* Costs of various operations on the different architectures. */ 127 1.1 mrg 128 1.1 mrg struct alpha_rtx_cost_data 129 1.1 mrg { 130 1.1 mrg unsigned char fp_add; 131 1.1 mrg unsigned char fp_mult; 132 1.1 mrg unsigned char fp_div_sf; 133 1.1 mrg unsigned char fp_div_df; 134 1.1 mrg unsigned char int_mult_si; 135 1.1 mrg unsigned char int_mult_di; 136 1.1 mrg unsigned char int_shift; 137 1.1 mrg unsigned char int_cmov; 138 1.1 mrg unsigned short int_div; 139 1.1 mrg }; 140 1.1 mrg 141 1.1 mrg static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] = 142 1.1 mrg { 143 1.1 mrg { /* EV4 */ 144 1.1 mrg COSTS_N_INSNS (6), /* fp_add */ 145 1.1 mrg COSTS_N_INSNS (6), /* fp_mult */ 146 1.1 mrg COSTS_N_INSNS (34), /* fp_div_sf */ 147 1.1 mrg COSTS_N_INSNS (63), /* fp_div_df */ 148 1.1 mrg COSTS_N_INSNS (23), /* int_mult_si */ 149 1.1 mrg COSTS_N_INSNS (23), /* int_mult_di */ 150 1.1 mrg COSTS_N_INSNS (2), /* int_shift */ 151 1.1 mrg COSTS_N_INSNS (2), /* int_cmov */ 152 1.1 mrg COSTS_N_INSNS (97), /* int_div */ 153 1.1 mrg }, 154 1.1 mrg { /* EV5 */ 155 1.1 mrg COSTS_N_INSNS (4), /* fp_add */ 156 1.1 mrg COSTS_N_INSNS (4), /* fp_mult */ 157 1.1 mrg COSTS_N_INSNS (15), /* fp_div_sf */ 158 1.1 mrg COSTS_N_INSNS (22), /* fp_div_df */ 159 1.1 mrg COSTS_N_INSNS (8), /* int_mult_si */ 160 1.1 mrg COSTS_N_INSNS (12), /* int_mult_di */ 161 1.1 mrg COSTS_N_INSNS (1) + 1, /* int_shift */ 162 1.1 mrg COSTS_N_INSNS (1), /* int_cmov */ 163 1.1 mrg COSTS_N_INSNS (83), /* int_div */ 164 1.1 mrg }, 165 1.1 mrg { /* EV6 */ 166 1.1 mrg COSTS_N_INSNS (4), /* fp_add */ 167 1.1 mrg COSTS_N_INSNS (4), /* fp_mult */ 168 1.1 mrg COSTS_N_INSNS (12), /* fp_div_sf */ 169 1.1 mrg COSTS_N_INSNS (15), /* fp_div_df */ 170 1.1 mrg COSTS_N_INSNS (7), /* int_mult_si */ 171 1.1 mrg COSTS_N_INSNS (7), /* int_mult_di */ 172 1.1 mrg COSTS_N_INSNS (1), /* int_shift */ 173 1.1 mrg COSTS_N_INSNS (2), /* int_cmov */ 174 1.1 mrg COSTS_N_INSNS (86), /* int_div */ 175 1.1 mrg }, 176 1.1 mrg }; 177 1.1 mrg 178 1.1 mrg /* Similar but tuned for code size instead of execution latency. The 179 1.1 mrg extra +N is fractional cost tuning based on latency. It's used to 180 1.1 mrg encourage use of cheaper insns like shift, but only if there's just 181 1.1 mrg one of them. */ 182 1.1 mrg 183 1.1 mrg static struct alpha_rtx_cost_data const alpha_rtx_cost_size = 184 1.1 mrg { 185 1.1 mrg COSTS_N_INSNS (1), /* fp_add */ 186 1.1 mrg COSTS_N_INSNS (1), /* fp_mult */ 187 1.1 mrg COSTS_N_INSNS (1), /* fp_div_sf */ 188 1.1 mrg COSTS_N_INSNS (1) + 1, /* fp_div_df */ 189 1.1 mrg COSTS_N_INSNS (1) + 1, /* int_mult_si */ 190 1.1 mrg COSTS_N_INSNS (1) + 2, /* int_mult_di */ 191 1.1 mrg COSTS_N_INSNS (1), /* int_shift */ 192 1.1 mrg COSTS_N_INSNS (1), /* int_cmov */ 193 1.1 mrg COSTS_N_INSNS (6), /* int_div */ 194 1.1 mrg }; 195 1.1 mrg 196 1.1 mrg /* Get the number of args of a function in one of two ways. */ 197 1.1 mrg #if TARGET_ABI_OPEN_VMS 198 1.1 mrg #define NUM_ARGS crtl->args.info.num_args 199 1.1 mrg #else 200 1.1 mrg #define NUM_ARGS crtl->args.info 201 1.1 mrg #endif 202 1.1 mrg 203 1.1 mrg #define REG_PV 27 204 1.1 mrg #define REG_RA 26 205 1.1 mrg 206 1.1 mrg /* Declarations of static functions. */ 207 1.1 mrg static struct machine_function *alpha_init_machine_status (void); 208 1.1 mrg static rtx alpha_emit_xfloating_compare (enum rtx_code *, rtx, rtx); 209 1.1 mrg static void alpha_handle_trap_shadows (void); 210 1.1 mrg static void alpha_align_insns (void); 211 1.1 mrg static void alpha_override_options_after_change (void); 212 1.1 mrg 213 1.1 mrg #if TARGET_ABI_OPEN_VMS 214 1.1 mrg static void alpha_write_linkage (FILE *, const char *); 215 1.1 mrg static bool vms_valid_pointer_mode (scalar_int_mode); 216 1.1 mrg #else 217 1.1 mrg #define vms_patch_builtins() gcc_unreachable() 218 1.1 mrg #endif 219 1.1 mrg 220 1.1 mrg static unsigned int 222 1.1 mrg rest_of_handle_trap_shadows (void) 223 1.1 mrg { 224 1.1 mrg alpha_handle_trap_shadows (); 225 1.1 mrg return 0; 226 1.1 mrg } 227 1.1 mrg 228 1.1 mrg namespace { 229 1.1 mrg 230 1.1 mrg const pass_data pass_data_handle_trap_shadows = 231 1.1 mrg { 232 1.1 mrg RTL_PASS, 233 1.1 mrg "trap_shadows", /* name */ 234 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 235 1.1 mrg TV_NONE, /* tv_id */ 236 1.1 mrg 0, /* properties_required */ 237 1.1 mrg 0, /* properties_provided */ 238 1.1 mrg 0, /* properties_destroyed */ 239 1.1 mrg 0, /* todo_flags_start */ 240 1.1 mrg TODO_df_finish, /* todo_flags_finish */ 241 1.1 mrg }; 242 1.1 mrg 243 1.1 mrg class pass_handle_trap_shadows : public rtl_opt_pass 244 1.1 mrg { 245 1.1 mrg public: 246 1.1 mrg pass_handle_trap_shadows(gcc::context *ctxt) 247 1.1 mrg : rtl_opt_pass(pass_data_handle_trap_shadows, ctxt) 248 1.1 mrg {} 249 1.1 mrg 250 1.1 mrg /* opt_pass methods: */ 251 1.1 mrg virtual bool gate (function *) 252 1.1 mrg { 253 1.1 mrg return alpha_tp != ALPHA_TP_PROG || flag_exceptions; 254 1.1 mrg } 255 1.1 mrg 256 1.1 mrg virtual unsigned int execute (function *) 257 1.1 mrg { 258 1.1 mrg return rest_of_handle_trap_shadows (); 259 1.1 mrg } 260 1.1 mrg 261 1.1 mrg }; // class pass_handle_trap_shadows 262 1.1 mrg 263 1.1 mrg } // anon namespace 264 1.1 mrg 265 1.1 mrg rtl_opt_pass * 266 1.1 mrg make_pass_handle_trap_shadows (gcc::context *ctxt) 267 1.1 mrg { 268 1.1 mrg return new pass_handle_trap_shadows (ctxt); 269 1.1 mrg } 270 1.1 mrg 271 1.1 mrg static unsigned int 272 1.1 mrg rest_of_align_insns (void) 273 1.1 mrg { 274 1.1 mrg alpha_align_insns (); 275 1.1 mrg return 0; 276 1.1 mrg } 277 1.1 mrg 278 1.1 mrg namespace { 279 1.1 mrg 280 1.1 mrg const pass_data pass_data_align_insns = 281 1.1 mrg { 282 1.1 mrg RTL_PASS, 283 1.1 mrg "align_insns", /* name */ 284 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 285 1.1 mrg TV_NONE, /* tv_id */ 286 1.1 mrg 0, /* properties_required */ 287 1.1 mrg 0, /* properties_provided */ 288 1.1 mrg 0, /* properties_destroyed */ 289 1.1 mrg 0, /* todo_flags_start */ 290 1.1 mrg TODO_df_finish, /* todo_flags_finish */ 291 1.1 mrg }; 292 1.1 mrg 293 1.1 mrg class pass_align_insns : public rtl_opt_pass 294 1.1 mrg { 295 1.1 mrg public: 296 1.1 mrg pass_align_insns(gcc::context *ctxt) 297 1.1 mrg : rtl_opt_pass(pass_data_align_insns, ctxt) 298 1.1 mrg {} 299 1.1 mrg 300 1.1 mrg /* opt_pass methods: */ 301 1.1 mrg virtual bool gate (function *) 302 1.1 mrg { 303 1.1 mrg /* Due to the number of extra trapb insns, don't bother fixing up 304 1.1 mrg alignment when trap precision is instruction. Moreover, we can 305 1.1 mrg only do our job when sched2 is run. */ 306 1.1 mrg return ((alpha_tune == PROCESSOR_EV4 307 1.1 mrg || alpha_tune == PROCESSOR_EV5) 308 1.1 mrg && optimize && !optimize_size 309 1.1 mrg && alpha_tp != ALPHA_TP_INSN 310 1.1 mrg && flag_schedule_insns_after_reload); 311 1.1 mrg } 312 1.1 mrg 313 1.1 mrg virtual unsigned int execute (function *) 314 1.1 mrg { 315 1.1 mrg return rest_of_align_insns (); 316 1.1 mrg } 317 1.1 mrg 318 1.1 mrg }; // class pass_align_insns 319 1.1 mrg 320 1.1 mrg } // anon namespace 321 1.1 mrg 322 1.1 mrg rtl_opt_pass * 323 1.1 mrg make_pass_align_insns (gcc::context *ctxt) 324 1.1 mrg { 325 1.1 mrg return new pass_align_insns (ctxt); 326 1.1 mrg } 327 1.1 mrg 328 1.1 mrg #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING 329 1.1 mrg /* Implement TARGET_MANGLE_TYPE. */ 330 1.1 mrg 331 1.1 mrg static const char * 332 1.1 mrg alpha_mangle_type (const_tree type) 333 1.1 mrg { 334 1.1 mrg if (TYPE_MAIN_VARIANT (type) == long_double_type_node 335 1.1 mrg && TARGET_LONG_DOUBLE_128) 336 1.1 mrg return "g"; 337 1.1 mrg 338 1.1 mrg /* For all other types, use normal C++ mangling. */ 339 1.1 mrg return NULL; 340 1.1 mrg } 341 1.1 mrg #endif 342 1.1 mrg 343 1.1 mrg /* Parse target option strings. */ 344 1.1 mrg 345 1.1 mrg static void 346 1.1 mrg alpha_option_override (void) 347 1.1 mrg { 348 1.1 mrg static const struct cpu_table { 349 1.1 mrg const char *const name; 350 1.1 mrg const enum processor_type processor; 351 1.1 mrg const int flags; 352 1.1 mrg const unsigned short line_size; /* in bytes */ 353 1.1 mrg const unsigned short l1_size; /* in kb. */ 354 1.1 mrg const unsigned short l2_size; /* in kb. */ 355 1.1 mrg } cpu_table[] = { 356 1.1 mrg /* EV4/LCA45 had 8k L1 caches; EV45 had 16k L1 caches. 357 1.1 mrg EV4/EV45 had 128k to 16M 32-byte direct Bcache. LCA45 358 1.1 mrg had 64k to 8M 8-byte direct Bcache. */ 359 1.1 mrg { "ev4", PROCESSOR_EV4, 0, 32, 8, 8*1024 }, 360 1.1 mrg { "21064", PROCESSOR_EV4, 0, 32, 8, 8*1024 }, 361 1.1 mrg { "ev45", PROCESSOR_EV4, 0, 32, 16, 16*1024 }, 362 1.1 mrg 363 1.1 mrg /* EV5 or EV56 had 8k 32 byte L1, 96k 32 or 64 byte L2, 364 1.1 mrg and 1M to 16M 64 byte L3 (not modeled). 365 1.1 mrg PCA56 had 16k 64-byte cache; PCA57 had 32k Icache. 366 1.1 mrg PCA56 had 8k 64-byte cache; PCA57 had 16k Dcache. */ 367 1.1 mrg { "ev5", PROCESSOR_EV5, 0, 32, 8, 96 }, 368 1.1 mrg { "21164", PROCESSOR_EV5, 0, 32, 8, 96 }, 369 1.1 mrg { "ev56", PROCESSOR_EV5, MASK_BWX, 32, 8, 96 }, 370 1.1 mrg { "21164a", PROCESSOR_EV5, MASK_BWX, 32, 8, 96 }, 371 1.1 mrg { "pca56", PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 }, 372 1.1 mrg { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 }, 373 1.1 mrg { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 }, 374 1.1 mrg 375 1.1 mrg /* EV6 had 64k 64 byte L1, 1M to 16M Bcache. */ 376 1.1 mrg { "ev6", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 }, 377 1.1 mrg { "21264", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 }, 378 1.1 mrg { "ev67", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX, 379 1.1 mrg 64, 64, 16*1024 }, 380 1.1 mrg { "21264a", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX, 381 1.1 mrg 64, 64, 16*1024 } 382 1.1 mrg }; 383 1.1 mrg 384 1.1 mrg int const ct_size = ARRAY_SIZE (cpu_table); 385 1.1 mrg int line_size = 0, l1_size = 0, l2_size = 0; 386 1.1 mrg int i; 387 1.1 mrg 388 1.1 mrg #ifdef SUBTARGET_OVERRIDE_OPTIONS 389 1.1 mrg SUBTARGET_OVERRIDE_OPTIONS; 390 1.1 mrg #endif 391 1.1 mrg 392 1.1 mrg /* Default to full IEEE compliance mode for Go language. */ 393 1.1 mrg if (strcmp (lang_hooks.name, "GNU Go") == 0 394 1.1 mrg && !(target_flags_explicit & MASK_IEEE)) 395 1.1 mrg target_flags |= MASK_IEEE; 396 1.1 mrg 397 1.1 mrg alpha_fprm = ALPHA_FPRM_NORM; 398 1.1 mrg alpha_tp = ALPHA_TP_PROG; 399 1.1 mrg alpha_fptm = ALPHA_FPTM_N; 400 1.1 mrg 401 1.1 mrg if (TARGET_IEEE) 402 1.1 mrg { 403 1.1 mrg alpha_tp = ALPHA_TP_INSN; 404 1.1 mrg alpha_fptm = ALPHA_FPTM_SU; 405 1.1 mrg } 406 1.1 mrg if (TARGET_IEEE_WITH_INEXACT) 407 1.1 mrg { 408 1.1 mrg alpha_tp = ALPHA_TP_INSN; 409 1.1 mrg alpha_fptm = ALPHA_FPTM_SUI; 410 1.1 mrg } 411 1.1 mrg 412 1.1 mrg if (alpha_tp_string) 413 1.1 mrg { 414 1.1 mrg if (! strcmp (alpha_tp_string, "p")) 415 1.1 mrg alpha_tp = ALPHA_TP_PROG; 416 1.1 mrg else if (! strcmp (alpha_tp_string, "f")) 417 1.1 mrg alpha_tp = ALPHA_TP_FUNC; 418 1.1 mrg else if (! strcmp (alpha_tp_string, "i")) 419 1.1 mrg alpha_tp = ALPHA_TP_INSN; 420 1.1 mrg else 421 1.1 mrg error ("bad value %qs for %<-mtrap-precision%> switch", 422 1.1 mrg alpha_tp_string); 423 1.1 mrg } 424 1.1 mrg 425 1.1 mrg if (alpha_fprm_string) 426 1.1 mrg { 427 1.1 mrg if (! strcmp (alpha_fprm_string, "n")) 428 1.1 mrg alpha_fprm = ALPHA_FPRM_NORM; 429 1.1 mrg else if (! strcmp (alpha_fprm_string, "m")) 430 1.1 mrg alpha_fprm = ALPHA_FPRM_MINF; 431 1.1 mrg else if (! strcmp (alpha_fprm_string, "c")) 432 1.1 mrg alpha_fprm = ALPHA_FPRM_CHOP; 433 1.1 mrg else if (! strcmp (alpha_fprm_string,"d")) 434 1.1 mrg alpha_fprm = ALPHA_FPRM_DYN; 435 1.1 mrg else 436 1.1 mrg error ("bad value %qs for %<-mfp-rounding-mode%> switch", 437 1.1 mrg alpha_fprm_string); 438 1.1 mrg } 439 1.1 mrg 440 1.1 mrg if (alpha_fptm_string) 441 1.1 mrg { 442 1.1 mrg if (strcmp (alpha_fptm_string, "n") == 0) 443 1.1 mrg alpha_fptm = ALPHA_FPTM_N; 444 1.1 mrg else if (strcmp (alpha_fptm_string, "u") == 0) 445 1.1 mrg alpha_fptm = ALPHA_FPTM_U; 446 1.1 mrg else if (strcmp (alpha_fptm_string, "su") == 0) 447 1.1 mrg alpha_fptm = ALPHA_FPTM_SU; 448 1.1 mrg else if (strcmp (alpha_fptm_string, "sui") == 0) 449 1.1 mrg alpha_fptm = ALPHA_FPTM_SUI; 450 1.1 mrg else 451 1.1 mrg error ("bad value %qs for %<-mfp-trap-mode%> switch", 452 1.1 mrg alpha_fptm_string); 453 1.1 mrg } 454 1.1 mrg 455 1.1 mrg if (alpha_cpu_string) 456 1.1 mrg { 457 1.1 mrg for (i = 0; i < ct_size; i++) 458 1.1 mrg if (! strcmp (alpha_cpu_string, cpu_table [i].name)) 459 1.1 mrg { 460 1.1 mrg alpha_tune = alpha_cpu = cpu_table[i].processor; 461 1.1 mrg line_size = cpu_table[i].line_size; 462 1.1 mrg l1_size = cpu_table[i].l1_size; 463 1.1 mrg l2_size = cpu_table[i].l2_size; 464 1.1 mrg target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX); 465 1.1 mrg target_flags |= cpu_table[i].flags; 466 1.1 mrg break; 467 1.1 mrg } 468 1.1 mrg if (i == ct_size) 469 1.1 mrg error ("bad value %qs for %<-mcpu%> switch", alpha_cpu_string); 470 1.1 mrg } 471 1.1 mrg 472 1.1 mrg if (alpha_tune_string) 473 1.1 mrg { 474 1.1 mrg for (i = 0; i < ct_size; i++) 475 1.1 mrg if (! strcmp (alpha_tune_string, cpu_table [i].name)) 476 1.1 mrg { 477 1.1 mrg alpha_tune = cpu_table[i].processor; 478 1.1 mrg line_size = cpu_table[i].line_size; 479 1.1 mrg l1_size = cpu_table[i].l1_size; 480 1.1 mrg l2_size = cpu_table[i].l2_size; 481 1.1 mrg break; 482 1.1 mrg } 483 1.1 mrg if (i == ct_size) 484 1.1 mrg error ("bad value %qs for %<-mtune%> switch", alpha_tune_string); 485 1.1 mrg } 486 1.1 mrg 487 1.1 mrg if (line_size) 488 1.1 mrg SET_OPTION_IF_UNSET (&global_options, &global_options_set, 489 1.1 mrg param_l1_cache_line_size, line_size); 490 1.1 mrg if (l1_size) 491 1.1 mrg SET_OPTION_IF_UNSET (&global_options, &global_options_set, 492 1.1 mrg param_l1_cache_size, l1_size); 493 1.1 mrg if (l2_size) 494 1.1 mrg SET_OPTION_IF_UNSET (&global_options, &global_options_set, 495 1.1 mrg param_l2_cache_size, l2_size); 496 1.1 mrg 497 1.1 mrg /* Do some sanity checks on the above options. */ 498 1.1 mrg 499 1.1 mrg if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI) 500 1.1 mrg && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6) 501 1.1 mrg { 502 1.1 mrg warning (0, "fp software completion requires %<-mtrap-precision=i%>"); 503 1.1 mrg alpha_tp = ALPHA_TP_INSN; 504 1.1 mrg } 505 1.1 mrg 506 1.1 mrg if (alpha_cpu == PROCESSOR_EV6) 507 1.1 mrg { 508 1.1 mrg /* Except for EV6 pass 1 (not released), we always have precise 509 1.1 mrg arithmetic traps. Which means we can do software completion 510 1.1 mrg without minding trap shadows. */ 511 1.1 mrg alpha_tp = ALPHA_TP_PROG; 512 1.1 mrg } 513 1.1 mrg 514 1.1 mrg if (TARGET_FLOAT_VAX) 515 1.1 mrg { 516 1.1 mrg if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN) 517 1.1 mrg { 518 1.1 mrg warning (0, "rounding mode not supported for VAX floats"); 519 1.1 mrg alpha_fprm = ALPHA_FPRM_NORM; 520 1.1 mrg } 521 1.1 mrg if (alpha_fptm == ALPHA_FPTM_SUI) 522 1.1 mrg { 523 1.1 mrg warning (0, "trap mode not supported for VAX floats"); 524 1.1 mrg alpha_fptm = ALPHA_FPTM_SU; 525 1.1 mrg } 526 1.1 mrg if (target_flags_explicit & MASK_LONG_DOUBLE_128) 527 1.1 mrg warning (0, "128-bit %<long double%> not supported for VAX floats"); 528 1.1 mrg target_flags &= ~MASK_LONG_DOUBLE_128; 529 1.1 mrg } 530 1.1 mrg 531 1.1 mrg { 532 1.1 mrg char *end; 533 1.1 mrg int lat; 534 1.1 mrg 535 1.1 mrg if (!alpha_mlat_string) 536 1.1 mrg alpha_mlat_string = "L1"; 537 1.1 mrg 538 1.1 mrg if (ISDIGIT ((unsigned char)alpha_mlat_string[0]) 539 1.1 mrg && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0')) 540 1.1 mrg ; 541 1.1 mrg else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l') 542 1.1 mrg && ISDIGIT ((unsigned char)alpha_mlat_string[1]) 543 1.1 mrg && alpha_mlat_string[2] == '\0') 544 1.1 mrg { 545 1.1 mrg static int const cache_latency[][4] = 546 1.1 mrg { 547 1.1 mrg { 3, 30, -1 }, /* ev4 -- Bcache is a guess */ 548 1.1 mrg { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */ 549 1.1 mrg { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */ 550 1.1 mrg }; 551 1.1 mrg 552 1.1 mrg lat = alpha_mlat_string[1] - '0'; 553 1.1 mrg if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1) 554 1.1 mrg { 555 1.1 mrg warning (0, "L%d cache latency unknown for %s", 556 1.1 mrg lat, alpha_cpu_name[alpha_tune]); 557 1.1 mrg lat = 3; 558 1.1 mrg } 559 1.1 mrg else 560 1.1 mrg lat = cache_latency[alpha_tune][lat-1]; 561 1.1 mrg } 562 1.1 mrg else if (! strcmp (alpha_mlat_string, "main")) 563 1.1 mrg { 564 1.1 mrg /* Most current memories have about 370ns latency. This is 565 1.1 mrg a reasonable guess for a fast cpu. */ 566 1.1 mrg lat = 150; 567 1.1 mrg } 568 1.1 mrg else 569 1.1 mrg { 570 1.1 mrg warning (0, "bad value %qs for %<-mmemory-latency%>", 571 1.1 mrg alpha_mlat_string); 572 1.1 mrg lat = 3; 573 1.1 mrg } 574 1.1 mrg 575 1.1 mrg alpha_memory_latency = lat; 576 1.1 mrg } 577 1.1 mrg 578 1.1 mrg /* Default the definition of "small data" to 8 bytes. */ 579 1.1 mrg if (!OPTION_SET_P (g_switch_value)) 580 1.1 mrg g_switch_value = 8; 581 1.1 mrg 582 1.1 mrg /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */ 583 1.1 mrg if (flag_pic == 1) 584 1.1 mrg target_flags |= MASK_SMALL_DATA; 585 1.1 mrg else if (flag_pic == 2) 586 1.1 mrg target_flags &= ~MASK_SMALL_DATA; 587 1.1 mrg 588 1.1 mrg alpha_override_options_after_change (); 589 1.1 mrg 590 1.1 mrg /* Register variables and functions with the garbage collector. */ 591 1.1 mrg 592 1.1 mrg /* Set up function hooks. */ 593 1.1 mrg init_machine_status = alpha_init_machine_status; 594 1.1 mrg 595 1.1 mrg /* Tell the compiler when we're using VAX floating point. */ 596 1.1 mrg if (TARGET_FLOAT_VAX) 597 1.1 mrg { 598 1.1 mrg REAL_MODE_FORMAT (SFmode) = &vax_f_format; 599 1.1 mrg REAL_MODE_FORMAT (DFmode) = &vax_g_format; 600 1.1 mrg REAL_MODE_FORMAT (TFmode) = NULL; 601 1.1 mrg } 602 1.1 mrg 603 1.1 mrg #ifdef TARGET_DEFAULT_LONG_DOUBLE_128 604 1.1 mrg if (!(target_flags_explicit & MASK_LONG_DOUBLE_128)) 605 1.1 mrg target_flags |= MASK_LONG_DOUBLE_128; 606 1.1 mrg #endif 607 1.1 mrg 608 1.1 mrg } 609 1.1 mrg 610 1.1 mrg /* Implement targetm.override_options_after_change. */ 611 1.1 mrg 612 1.1 mrg static void 613 1.1 mrg alpha_override_options_after_change (void) 614 1.1 mrg { 615 1.1 mrg /* Align labels and loops for optimal branching. */ 616 1.1 mrg /* ??? Kludge these by not doing anything if we don't optimize. */ 617 1.1 mrg if (optimize > 0) 618 1.1 mrg { 619 1.1 mrg if (flag_align_loops && !str_align_loops) 620 1.1 mrg str_align_loops = "16"; 621 1.1 mrg if (flag_align_jumps && !str_align_jumps) 622 1.1 mrg str_align_jumps = "16"; 623 1.1 mrg } 624 1.1 mrg if (flag_align_functions && !str_align_functions) 625 1.1 mrg str_align_functions = "16"; 626 1.1 mrg } 627 1.1 mrg 628 1.1 mrg /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */ 630 1.1 mrg 631 1.1 mrg int 632 1.1 mrg zap_mask (HOST_WIDE_INT value) 633 1.1 mrg { 634 1.1 mrg int i; 635 1.1 mrg 636 1.1 mrg for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; 637 1.1 mrg i++, value >>= 8) 638 1.1 mrg if ((value & 0xff) != 0 && (value & 0xff) != 0xff) 639 1.1 mrg return 0; 640 1.1 mrg 641 1.1 mrg return 1; 642 1.1 mrg } 643 1.1 mrg 644 1.1 mrg /* Return true if OP is valid for a particular TLS relocation. 645 1.1 mrg We are already guaranteed that OP is a CONST. */ 646 1.1 mrg 647 1.1 mrg int 648 1.1 mrg tls_symbolic_operand_1 (rtx op, int size, int unspec) 649 1.1 mrg { 650 1.1 mrg op = XEXP (op, 0); 651 1.1 mrg 652 1.1 mrg if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec) 653 1.1 mrg return 0; 654 1.1 mrg op = XVECEXP (op, 0, 0); 655 1.1 mrg 656 1.1 mrg if (GET_CODE (op) != SYMBOL_REF) 657 1.1 mrg return 0; 658 1.1 mrg 659 1.1 mrg switch (SYMBOL_REF_TLS_MODEL (op)) 660 1.1 mrg { 661 1.1 mrg case TLS_MODEL_LOCAL_DYNAMIC: 662 1.1 mrg return unspec == UNSPEC_DTPREL && size == alpha_tls_size; 663 1.1 mrg case TLS_MODEL_INITIAL_EXEC: 664 1.1 mrg return unspec == UNSPEC_TPREL && size == 64; 665 1.1 mrg case TLS_MODEL_LOCAL_EXEC: 666 1.1 mrg return unspec == UNSPEC_TPREL && size == alpha_tls_size; 667 1.1 mrg default: 668 1.1 mrg gcc_unreachable (); 669 1.1 mrg } 670 1.1 mrg } 671 1.1 mrg 672 1.1 mrg /* Used by aligned_memory_operand and unaligned_memory_operand to 673 1.1 mrg resolve what reload is going to do with OP if it's a register. */ 674 1.1 mrg 675 1.1 mrg rtx 676 1.1 mrg resolve_reload_operand (rtx op) 677 1.1 mrg { 678 1.1 mrg if (reload_in_progress) 679 1.1 mrg { 680 1.1 mrg rtx tmp = op; 681 1.1 mrg if (SUBREG_P (tmp)) 682 1.1 mrg tmp = SUBREG_REG (tmp); 683 1.1 mrg if (REG_P (tmp) 684 1.1 mrg && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) 685 1.1 mrg { 686 1.1 mrg op = reg_equiv_memory_loc (REGNO (tmp)); 687 1.1 mrg if (op == 0) 688 1.1 mrg return 0; 689 1.1 mrg } 690 1.1 mrg } 691 1.1 mrg return op; 692 1.1 mrg } 693 1.1 mrg 694 1.1 mrg /* The scalar modes supported differs from the default check-what-c-supports 695 1.1 mrg version in that sometimes TFmode is available even when long double 696 1.1 mrg indicates only DFmode. */ 697 1.1 mrg 698 1.1 mrg static bool 699 1.1 mrg alpha_scalar_mode_supported_p (scalar_mode mode) 700 1.1 mrg { 701 1.1 mrg switch (mode) 702 1.1 mrg { 703 1.1 mrg case E_QImode: 704 1.1 mrg case E_HImode: 705 1.1 mrg case E_SImode: 706 1.1 mrg case E_DImode: 707 1.1 mrg case E_TImode: /* via optabs.cc */ 708 1.1 mrg return true; 709 1.1 mrg 710 1.1 mrg case E_SFmode: 711 1.1 mrg case E_DFmode: 712 1.1 mrg return true; 713 1.1 mrg 714 1.1 mrg case E_TFmode: 715 1.1 mrg return TARGET_HAS_XFLOATING_LIBS; 716 1.1 mrg 717 1.1 mrg default: 718 1.1 mrg return false; 719 1.1 mrg } 720 1.1 mrg } 721 1.1 mrg 722 1.1 mrg /* Alpha implements a couple of integer vector mode operations when 723 1.1 mrg TARGET_MAX is enabled. We do not check TARGET_MAX here, however, 724 1.1 mrg which allows the vectorizer to operate on e.g. move instructions, 725 1.1 mrg or when expand_vector_operations can do something useful. */ 726 1.1 mrg 727 1.1 mrg static bool 728 1.1 mrg alpha_vector_mode_supported_p (machine_mode mode) 729 1.1 mrg { 730 1.1 mrg return mode == V8QImode || mode == V4HImode || mode == V2SImode; 731 1.1 mrg } 732 1.1 mrg 733 1.1 mrg /* Return the TLS model to use for SYMBOL. */ 734 1.1 mrg 735 1.1 mrg static enum tls_model 736 1.1 mrg tls_symbolic_operand_type (rtx symbol) 737 1.1 mrg { 738 1.1 mrg enum tls_model model; 739 1.1 mrg 740 1.1 mrg if (GET_CODE (symbol) != SYMBOL_REF) 741 1.1 mrg return TLS_MODEL_NONE; 742 1.1 mrg model = SYMBOL_REF_TLS_MODEL (symbol); 743 1.1 mrg 744 1.1 mrg /* Local-exec with a 64-bit size is the same code as initial-exec. */ 745 1.1 mrg if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64) 746 1.1 mrg model = TLS_MODEL_INITIAL_EXEC; 747 1.1 mrg 748 1.1 mrg return model; 749 1.1 mrg } 750 1.1 mrg 751 1.1 mrg /* Return true if the function DECL will share the same GP as any 753 1.1 mrg function in the current unit of translation. */ 754 1.1 mrg 755 1.1 mrg static bool 756 1.1 mrg decl_has_samegp (const_tree decl) 757 1.1 mrg { 758 1.1 mrg /* Functions that are not local can be overridden, and thus may 759 1.1 mrg not share the same gp. */ 760 1.1 mrg if (!(*targetm.binds_local_p) (decl)) 761 1.1 mrg return false; 762 1.1 mrg 763 1.1 mrg /* If -msmall-data is in effect, assume that there is only one GP 764 1.1 mrg for the module, and so any local symbol has this property. We 765 1.1 mrg need explicit relocations to be able to enforce this for symbols 766 1.1 mrg not defined in this unit of translation, however. */ 767 1.1 mrg if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA) 768 1.1 mrg return true; 769 1.1 mrg 770 1.1 mrg /* Functions that are not external are defined in this UoT. */ 771 1.1 mrg /* ??? Irritatingly, static functions not yet emitted are still 772 1.1 mrg marked "external". Apply this to non-static functions only. */ 773 1.1 mrg return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl); 774 1.1 mrg } 775 1.1 mrg 776 1.1 mrg /* Return true if EXP should be placed in the small data section. */ 777 1.1 mrg 778 1.1 mrg static bool 779 1.1 mrg alpha_in_small_data_p (const_tree exp) 780 1.1 mrg { 781 1.1 mrg /* We want to merge strings, so we never consider them small data. */ 782 1.1 mrg if (TREE_CODE (exp) == STRING_CST) 783 1.1 mrg return false; 784 1.1 mrg 785 1.1 mrg /* Functions are never in the small data area. Duh. */ 786 1.1 mrg if (TREE_CODE (exp) == FUNCTION_DECL) 787 1.1 mrg return false; 788 1.1 mrg 789 1.1 mrg /* COMMON symbols are never small data. */ 790 1.1 mrg if (TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp)) 791 1.1 mrg return false; 792 1.1 mrg 793 1.1 mrg if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) 794 1.1 mrg { 795 1.1 mrg const char *section = DECL_SECTION_NAME (exp); 796 1.1 mrg if (strcmp (section, ".sdata") == 0 797 1.1 mrg || strcmp (section, ".sbss") == 0) 798 1.1 mrg return true; 799 1.1 mrg } 800 1.1 mrg else 801 1.1 mrg { 802 1.1 mrg HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); 803 1.1 mrg 804 1.1 mrg /* If this is an incomplete type with size 0, then we can't put it 805 1.1 mrg in sdata because it might be too big when completed. */ 806 1.1 mrg if (size > 0 && size <= g_switch_value) 807 1.1 mrg return true; 808 1.1 mrg } 809 1.1 mrg 810 1.1 mrg return false; 811 1.1 mrg } 812 1.1 mrg 813 1.1 mrg #if TARGET_ABI_OPEN_VMS 814 1.1 mrg static bool 815 1.1 mrg vms_valid_pointer_mode (scalar_int_mode mode) 816 1.1 mrg { 817 1.1 mrg return (mode == SImode || mode == DImode); 818 1.1 mrg } 819 1.1 mrg 820 1.1 mrg static bool 821 1.1 mrg alpha_linkage_symbol_p (const char *symname) 822 1.1 mrg { 823 1.1 mrg int symlen = strlen (symname); 824 1.1 mrg 825 1.1 mrg if (symlen > 4) 826 1.1 mrg return strcmp (&symname [symlen - 4], "..lk") == 0; 827 1.1 mrg 828 1.1 mrg return false; 829 1.1 mrg } 830 1.1 mrg 831 1.1 mrg #define LINKAGE_SYMBOL_REF_P(X) \ 832 1.1 mrg ((GET_CODE (X) == SYMBOL_REF \ 833 1.1 mrg && alpha_linkage_symbol_p (XSTR (X, 0))) \ 834 1.1 mrg || (GET_CODE (X) == CONST \ 835 1.1 mrg && GET_CODE (XEXP (X, 0)) == PLUS \ 836 1.1 mrg && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ 837 1.1 mrg && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0)))) 838 1.1 mrg #endif 839 1.1 mrg 840 1.1 mrg /* legitimate_address_p recognizes an RTL expression that is a valid 841 1.1 mrg memory address for an instruction. The MODE argument is the 842 1.1 mrg machine mode for the MEM expression that wants to use this address. 843 1.1 mrg 844 1.1 mrg For Alpha, we have either a constant address or the sum of a 845 1.1 mrg register and a constant address, or just a register. For DImode, 846 1.1 mrg any of those forms can be surrounded with an AND that clear the 847 1.1 mrg low-order three bits; this is an "unaligned" access. */ 848 1.1 mrg 849 1.1 mrg static bool 850 1.1 mrg alpha_legitimate_address_p (machine_mode mode, rtx x, bool strict) 851 1.1 mrg { 852 1.1 mrg /* If this is an ldq_u type address, discard the outer AND. */ 853 1.1 mrg if (mode == DImode 854 1.1 mrg && GET_CODE (x) == AND 855 1.1 mrg && CONST_INT_P (XEXP (x, 1)) 856 1.1 mrg && INTVAL (XEXP (x, 1)) == -8) 857 1.1 mrg x = XEXP (x, 0); 858 1.1 mrg 859 1.1 mrg /* Discard non-paradoxical subregs. */ 860 1.1 mrg if (SUBREG_P (x) 861 1.1 mrg && (GET_MODE_SIZE (GET_MODE (x)) 862 1.1 mrg < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) 863 1.1 mrg x = SUBREG_REG (x); 864 1.1 mrg 865 1.1 mrg /* Unadorned general registers are valid. */ 866 1.1 mrg if (REG_P (x) 867 1.1 mrg && (strict 868 1.1 mrg ? STRICT_REG_OK_FOR_BASE_P (x) 869 1.1 mrg : NONSTRICT_REG_OK_FOR_BASE_P (x))) 870 1.1 mrg return true; 871 1.1 mrg 872 1.1 mrg /* Constant addresses (i.e. +/- 32k) are valid. */ 873 1.1 mrg if (CONSTANT_ADDRESS_P (x)) 874 1.1 mrg return true; 875 1.1 mrg 876 1.1 mrg #if TARGET_ABI_OPEN_VMS 877 1.1 mrg if (LINKAGE_SYMBOL_REF_P (x)) 878 1.1 mrg return true; 879 1.1 mrg #endif 880 1.1 mrg 881 1.1 mrg /* Register plus a small constant offset is valid. */ 882 1.1 mrg if (GET_CODE (x) == PLUS) 883 1.1 mrg { 884 1.1 mrg rtx ofs = XEXP (x, 1); 885 1.1 mrg x = XEXP (x, 0); 886 1.1 mrg 887 1.1 mrg /* Discard non-paradoxical subregs. */ 888 1.1 mrg if (SUBREG_P (x) 889 1.1 mrg && (GET_MODE_SIZE (GET_MODE (x)) 890 1.1 mrg < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) 891 1.1 mrg x = SUBREG_REG (x); 892 1.1 mrg 893 1.1 mrg if (REG_P (x)) 894 1.1 mrg { 895 1.1 mrg if (! strict 896 1.1 mrg && NONSTRICT_REG_OK_FP_BASE_P (x) 897 1.1 mrg && CONST_INT_P (ofs)) 898 1.1 mrg return true; 899 1.1 mrg if ((strict 900 1.1 mrg ? STRICT_REG_OK_FOR_BASE_P (x) 901 1.1 mrg : NONSTRICT_REG_OK_FOR_BASE_P (x)) 902 1.1 mrg && CONSTANT_ADDRESS_P (ofs)) 903 1.1 mrg return true; 904 1.1 mrg } 905 1.1 mrg } 906 1.1 mrg 907 1.1 mrg /* If we're managing explicit relocations, LO_SUM is valid, as are small 908 1.1 mrg data symbols. Avoid explicit relocations of modes larger than word 909 1.1 mrg mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */ 910 1.1 mrg else if (TARGET_EXPLICIT_RELOCS 911 1.1 mrg && GET_MODE_SIZE (mode) <= UNITS_PER_WORD) 912 1.1 mrg { 913 1.1 mrg if (small_symbolic_operand (x, Pmode)) 914 1.1 mrg return true; 915 1.1 mrg 916 1.1 mrg if (GET_CODE (x) == LO_SUM) 917 1.1 mrg { 918 1.1 mrg rtx ofs = XEXP (x, 1); 919 1.1 mrg x = XEXP (x, 0); 920 1.1 mrg 921 1.1 mrg /* Discard non-paradoxical subregs. */ 922 1.1 mrg if (SUBREG_P (x) 923 1.1 mrg && (GET_MODE_SIZE (GET_MODE (x)) 924 1.1 mrg < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) 925 1.1 mrg x = SUBREG_REG (x); 926 1.1 mrg 927 1.1 mrg /* Must have a valid base register. */ 928 1.1 mrg if (! (REG_P (x) 929 1.1 mrg && (strict 930 1.1 mrg ? STRICT_REG_OK_FOR_BASE_P (x) 931 1.1 mrg : NONSTRICT_REG_OK_FOR_BASE_P (x)))) 932 1.1 mrg return false; 933 1.1 mrg 934 1.1 mrg /* The symbol must be local. */ 935 1.1 mrg if (local_symbolic_operand (ofs, Pmode) 936 1.1 mrg || dtp32_symbolic_operand (ofs, Pmode) 937 1.1 mrg || tp32_symbolic_operand (ofs, Pmode)) 938 1.1 mrg return true; 939 1.1 mrg } 940 1.1 mrg } 941 1.1 mrg 942 1.1 mrg return false; 943 1.1 mrg } 944 1.1 mrg 945 1.1 mrg /* Build the SYMBOL_REF for __tls_get_addr. */ 946 1.1 mrg 947 1.1 mrg static GTY(()) rtx tls_get_addr_libfunc; 948 1.1 mrg 949 1.1 mrg static rtx 950 1.1 mrg get_tls_get_addr (void) 951 1.1 mrg { 952 1.1 mrg if (!tls_get_addr_libfunc) 953 1.1 mrg tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr"); 954 1.1 mrg return tls_get_addr_libfunc; 955 1.1 mrg } 956 1.1 mrg 957 1.1 mrg /* Try machine-dependent ways of modifying an illegitimate address 958 1.1 mrg to be legitimate. If we find one, return the new, valid address. */ 959 1.1 mrg 960 1.1 mrg static rtx 961 1.1 mrg alpha_legitimize_address_1 (rtx x, rtx scratch, machine_mode mode) 962 1.1 mrg { 963 1.1 mrg HOST_WIDE_INT addend; 964 1.1 mrg 965 1.1 mrg /* If the address is (plus reg const_int) and the CONST_INT is not a 966 1.1 mrg valid offset, compute the high part of the constant and add it to 967 1.1 mrg the register. Then our address is (plus temp low-part-const). */ 968 1.1 mrg if (GET_CODE (x) == PLUS 969 1.1 mrg && REG_P (XEXP (x, 0)) 970 1.1 mrg && CONST_INT_P (XEXP (x, 1)) 971 1.1 mrg && ! CONSTANT_ADDRESS_P (XEXP (x, 1))) 972 1.1 mrg { 973 1.1 mrg addend = INTVAL (XEXP (x, 1)); 974 1.1 mrg x = XEXP (x, 0); 975 1.1 mrg goto split_addend; 976 1.1 mrg } 977 1.1 mrg 978 1.1 mrg /* If the address is (const (plus FOO const_int)), find the low-order 979 1.1 mrg part of the CONST_INT. Then load FOO plus any high-order part of the 980 1.1 mrg CONST_INT into a register. Our address is (plus reg low-part-const). 981 1.1 mrg This is done to reduce the number of GOT entries. */ 982 1.1 mrg if (can_create_pseudo_p () 983 1.1 mrg && GET_CODE (x) == CONST 984 1.1 mrg && GET_CODE (XEXP (x, 0)) == PLUS 985 1.1 mrg && CONST_INT_P (XEXP (XEXP (x, 0), 1))) 986 1.1 mrg { 987 1.1 mrg addend = INTVAL (XEXP (XEXP (x, 0), 1)); 988 1.1 mrg x = force_reg (Pmode, XEXP (XEXP (x, 0), 0)); 989 1.1 mrg goto split_addend; 990 1.1 mrg } 991 1.1 mrg 992 1.1 mrg /* If we have a (plus reg const), emit the load as in (2), then add 993 1.1 mrg the two registers, and finally generate (plus reg low-part-const) as 994 1.1 mrg our address. */ 995 1.1 mrg if (can_create_pseudo_p () 996 1.1 mrg && GET_CODE (x) == PLUS 997 1.1 mrg && REG_P (XEXP (x, 0)) 998 1.1 mrg && GET_CODE (XEXP (x, 1)) == CONST 999 1.1 mrg && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS 1000 1.1 mrg && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1))) 1001 1.1 mrg { 1002 1.1 mrg addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1)); 1003 1.1 mrg x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0), 1004 1.1 mrg XEXP (XEXP (XEXP (x, 1), 0), 0), 1005 1.1 mrg NULL_RTX, 1, OPTAB_LIB_WIDEN); 1006 1.1 mrg goto split_addend; 1007 1.1 mrg } 1008 1.1 mrg 1009 1.1 mrg /* If this is a local symbol, split the address into HIGH/LO_SUM parts. 1010 1.1 mrg Avoid modes larger than word mode since i.e. $LC0+8($1) can fold 1011 1.1 mrg around +/- 32k offset. */ 1012 1.1 mrg if (TARGET_EXPLICIT_RELOCS 1013 1.1 mrg && GET_MODE_SIZE (mode) <= UNITS_PER_WORD 1014 1.1 mrg && symbolic_operand (x, Pmode)) 1015 1.1 mrg { 1016 1.1 mrg rtx r0, r16, eqv, tga, tp, dest, seq; 1017 1.1 mrg rtx_insn *insn; 1018 1.1 mrg 1019 1.1 mrg switch (tls_symbolic_operand_type (x)) 1020 1.1 mrg { 1021 1.1 mrg case TLS_MODEL_NONE: 1022 1.1 mrg break; 1023 1.1 mrg 1024 1.1 mrg case TLS_MODEL_GLOBAL_DYNAMIC: 1025 1.1 mrg { 1026 1.1 mrg start_sequence (); 1027 1.1 mrg 1028 1.1 mrg r0 = gen_rtx_REG (Pmode, 0); 1029 1.1 mrg r16 = gen_rtx_REG (Pmode, 16); 1030 1.1 mrg tga = get_tls_get_addr (); 1031 1.1 mrg dest = gen_reg_rtx (Pmode); 1032 1.1 mrg seq = GEN_INT (alpha_next_sequence_number++); 1033 1.1 mrg 1034 1.1 mrg emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq)); 1035 1.1 mrg rtx val = gen_call_value_osf_tlsgd (r0, tga, seq); 1036 1.1 mrg insn = emit_call_insn (val); 1037 1.1 mrg RTL_CONST_CALL_P (insn) = 1; 1038 1.1 mrg use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16); 1039 1.1 mrg 1040 1.1 mrg insn = get_insns (); 1041 1.1 mrg end_sequence (); 1042 1.1 mrg 1043 1.1 mrg emit_libcall_block (insn, dest, r0, x); 1044 1.1 mrg return dest; 1045 1.1 mrg } 1046 1.1 mrg 1047 1.1 mrg case TLS_MODEL_LOCAL_DYNAMIC: 1048 1.1 mrg { 1049 1.1 mrg start_sequence (); 1050 1.1 mrg 1051 1.1 mrg r0 = gen_rtx_REG (Pmode, 0); 1052 1.1 mrg r16 = gen_rtx_REG (Pmode, 16); 1053 1.1 mrg tga = get_tls_get_addr (); 1054 1.1 mrg scratch = gen_reg_rtx (Pmode); 1055 1.1 mrg seq = GEN_INT (alpha_next_sequence_number++); 1056 1.1 mrg 1057 1.1 mrg emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq)); 1058 1.1 mrg rtx val = gen_call_value_osf_tlsldm (r0, tga, seq); 1059 1.1 mrg insn = emit_call_insn (val); 1060 1.1 mrg RTL_CONST_CALL_P (insn) = 1; 1061 1.1 mrg use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16); 1062 1.1 mrg 1063 1.1 mrg insn = get_insns (); 1064 1.1 mrg end_sequence (); 1065 1.1 mrg 1066 1.1 mrg eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), 1067 1.1 mrg UNSPEC_TLSLDM_CALL); 1068 1.1 mrg emit_libcall_block (insn, scratch, r0, eqv); 1069 1.1 mrg 1070 1.1 mrg eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL); 1071 1.1 mrg eqv = gen_rtx_CONST (Pmode, eqv); 1072 1.1 mrg 1073 1.1 mrg if (alpha_tls_size == 64) 1074 1.1 mrg { 1075 1.1 mrg dest = gen_reg_rtx (Pmode); 1076 1.1 mrg emit_insn (gen_rtx_SET (dest, eqv)); 1077 1.1 mrg emit_insn (gen_adddi3 (dest, dest, scratch)); 1078 1.1 mrg return dest; 1079 1.1 mrg } 1080 1.1 mrg if (alpha_tls_size == 32) 1081 1.1 mrg { 1082 1.1 mrg rtx temp = gen_rtx_HIGH (Pmode, eqv); 1083 1.1 mrg temp = gen_rtx_PLUS (Pmode, scratch, temp); 1084 1.1 mrg scratch = gen_reg_rtx (Pmode); 1085 1.1 mrg emit_insn (gen_rtx_SET (scratch, temp)); 1086 1.1 mrg } 1087 1.1 mrg return gen_rtx_LO_SUM (Pmode, scratch, eqv); 1088 1.1 mrg } 1089 1.1 mrg 1090 1.1 mrg case TLS_MODEL_INITIAL_EXEC: 1091 1.1 mrg eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL); 1092 1.1 mrg eqv = gen_rtx_CONST (Pmode, eqv); 1093 1.1 mrg tp = gen_reg_rtx (Pmode); 1094 1.1 mrg scratch = gen_reg_rtx (Pmode); 1095 1.1 mrg dest = gen_reg_rtx (Pmode); 1096 1.1 mrg 1097 1.1 mrg emit_insn (gen_get_thread_pointerdi (tp)); 1098 1.1 mrg emit_insn (gen_rtx_SET (scratch, eqv)); 1099 1.1 mrg emit_insn (gen_adddi3 (dest, tp, scratch)); 1100 1.1 mrg return dest; 1101 1.1 mrg 1102 1.1 mrg case TLS_MODEL_LOCAL_EXEC: 1103 1.1 mrg eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL); 1104 1.1 mrg eqv = gen_rtx_CONST (Pmode, eqv); 1105 1.1 mrg tp = gen_reg_rtx (Pmode); 1106 1.1 mrg 1107 1.1 mrg emit_insn (gen_get_thread_pointerdi (tp)); 1108 1.1 mrg if (alpha_tls_size == 32) 1109 1.1 mrg { 1110 1.1 mrg rtx temp = gen_rtx_HIGH (Pmode, eqv); 1111 1.1 mrg temp = gen_rtx_PLUS (Pmode, tp, temp); 1112 1.1 mrg tp = gen_reg_rtx (Pmode); 1113 1.1 mrg emit_insn (gen_rtx_SET (tp, temp)); 1114 1.1 mrg } 1115 1.1 mrg return gen_rtx_LO_SUM (Pmode, tp, eqv); 1116 1.1 mrg 1117 1.1 mrg default: 1118 1.1 mrg gcc_unreachable (); 1119 1.1 mrg } 1120 1.1 mrg 1121 1.1 mrg if (local_symbolic_operand (x, Pmode)) 1122 1.1 mrg { 1123 1.1 mrg if (small_symbolic_operand (x, Pmode)) 1124 1.1 mrg return x; 1125 1.1 mrg else 1126 1.1 mrg { 1127 1.1 mrg if (can_create_pseudo_p ()) 1128 1.1 mrg scratch = gen_reg_rtx (Pmode); 1129 1.1 mrg emit_insn (gen_rtx_SET (scratch, gen_rtx_HIGH (Pmode, x))); 1130 1.1 mrg return gen_rtx_LO_SUM (Pmode, scratch, x); 1131 1.1 mrg } 1132 1.1 mrg } 1133 1.1 mrg } 1134 1.1 mrg 1135 1.1 mrg return NULL; 1136 1.1 mrg 1137 1.1 mrg split_addend: 1138 1.1 mrg { 1139 1.1 mrg HOST_WIDE_INT low, high; 1140 1.1 mrg 1141 1.1 mrg low = ((addend & 0xffff) ^ 0x8000) - 0x8000; 1142 1.1 mrg addend -= low; 1143 1.1 mrg high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000; 1144 1.1 mrg addend -= high; 1145 1.1 mrg 1146 1.1 mrg if (addend) 1147 1.1 mrg x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend), 1148 1.1 mrg (!can_create_pseudo_p () ? scratch : NULL_RTX), 1149 1.1 mrg 1, OPTAB_LIB_WIDEN); 1150 1.1 mrg if (high) 1151 1.1 mrg x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high), 1152 1.1 mrg (!can_create_pseudo_p () ? scratch : NULL_RTX), 1153 1.1 mrg 1, OPTAB_LIB_WIDEN); 1154 1.1 mrg 1155 1.1 mrg return plus_constant (Pmode, x, low); 1156 1.1 mrg } 1157 1.1 mrg } 1158 1.1 mrg 1159 1.1 mrg 1160 1.1 mrg /* Try machine-dependent ways of modifying an illegitimate address 1161 1.1 mrg to be legitimate. Return X or the new, valid address. */ 1162 1.1 mrg 1163 1.1 mrg static rtx 1164 1.1 mrg alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, 1165 1.1 mrg machine_mode mode) 1166 1.1 mrg { 1167 1.1 mrg rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode); 1168 1.1 mrg return new_x ? new_x : x; 1169 1.1 mrg } 1170 1.1 mrg 1171 1.1 mrg /* Return true if ADDR has an effect that depends on the machine mode it 1172 1.1 mrg is used for. On the Alpha this is true only for the unaligned modes. 1173 1.1 mrg We can simplify the test since we know that the address must be valid. */ 1174 1.1 mrg 1175 1.1 mrg static bool 1176 1.1 mrg alpha_mode_dependent_address_p (const_rtx addr, 1177 1.1 mrg addr_space_t as ATTRIBUTE_UNUSED) 1178 1.1 mrg { 1179 1.1 mrg return GET_CODE (addr) == AND; 1180 1.1 mrg } 1181 1.1 mrg 1182 1.1 mrg /* Primarily this is required for TLS symbols, but given that our move 1183 1.1 mrg patterns *ought* to be able to handle any symbol at any time, we 1184 1.1 mrg should never be spilling symbolic operands to the constant pool, ever. */ 1185 1.1 mrg 1186 1.1 mrg static bool 1187 1.1 mrg alpha_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 1188 1.1 mrg { 1189 1.1 mrg enum rtx_code code = GET_CODE (x); 1190 1.1 mrg return code == SYMBOL_REF || code == LABEL_REF || code == CONST; 1191 1.1 mrg } 1192 1.1 mrg 1193 1.1 mrg /* We do not allow indirect calls to be optimized into sibling calls, nor 1194 1.1 mrg can we allow a call to a function with a different GP to be optimized 1195 1.1 mrg into a sibcall. */ 1196 1.1 mrg 1197 1.1 mrg static bool 1198 1.1 mrg alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) 1199 1.1 mrg { 1200 1.1 mrg /* Can't do indirect tail calls, since we don't know if the target 1201 1.1 mrg uses the same GP. */ 1202 1.1 mrg if (!decl) 1203 1.1 mrg return false; 1204 1.1 mrg 1205 1.1 mrg /* Otherwise, we can make a tail call if the target function shares 1206 1.1 mrg the same GP. */ 1207 1.1 mrg return decl_has_samegp (decl); 1208 1.1 mrg } 1209 1.1 mrg 1210 1.1 mrg bool 1211 1.1 mrg some_small_symbolic_operand_int (rtx x) 1212 1.1 mrg { 1213 1.1 mrg subrtx_var_iterator::array_type array; 1214 1.1 mrg FOR_EACH_SUBRTX_VAR (iter, array, x, ALL) 1215 1.1 mrg { 1216 1.1 mrg rtx x = *iter; 1217 1.1 mrg /* Don't re-split. */ 1218 1.1 mrg if (GET_CODE (x) == LO_SUM) 1219 1.1 mrg iter.skip_subrtxes (); 1220 1.1 mrg else if (small_symbolic_operand (x, Pmode)) 1221 1.1 mrg return true; 1222 1.1 mrg } 1223 1.1 mrg return false; 1224 1.1 mrg } 1225 1.1 mrg 1226 1.1 mrg rtx 1227 1.1 mrg split_small_symbolic_operand (rtx x) 1228 1.1 mrg { 1229 1.1 mrg x = copy_insn (x); 1230 1.1 mrg subrtx_ptr_iterator::array_type array; 1231 1.1 mrg FOR_EACH_SUBRTX_PTR (iter, array, &x, ALL) 1232 1.1 mrg { 1233 1.1 mrg rtx *ptr = *iter; 1234 1.1 mrg rtx x = *ptr; 1235 1.1 mrg /* Don't re-split. */ 1236 1.1 mrg if (GET_CODE (x) == LO_SUM) 1237 1.1 mrg iter.skip_subrtxes (); 1238 1.1 mrg else if (small_symbolic_operand (x, Pmode)) 1239 1.1 mrg { 1240 1.1 mrg *ptr = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x); 1241 1.1 mrg iter.skip_subrtxes (); 1242 1.1 mrg } 1243 1.1 mrg } 1244 1.1 mrg return x; 1245 1.1 mrg } 1246 1.1 mrg 1247 1.1 mrg /* Indicate that INSN cannot be duplicated. This is true for any insn 1248 1.1 mrg that we've marked with gpdisp relocs, since those have to stay in 1249 1.1 mrg 1-1 correspondence with one another. 1250 1.1 mrg 1251 1.1 mrg Technically we could copy them if we could set up a mapping from one 1252 1.1 mrg sequence number to another, across the set of insns to be duplicated. 1253 1.1 mrg This seems overly complicated and error-prone since interblock motion 1254 1.1 mrg from sched-ebb could move one of the pair of insns to a different block. 1255 1.1 mrg 1256 1.1 mrg Also cannot allow jsr insns to be duplicated. If they throw exceptions, 1257 1.1 mrg then they'll be in a different block from their ldgp. Which could lead 1258 1.1 mrg the bb reorder code to think that it would be ok to copy just the block 1259 1.1 mrg containing the call and branch to the block containing the ldgp. */ 1260 1.1 mrg 1261 1.1 mrg static bool 1262 1.1 mrg alpha_cannot_copy_insn_p (rtx_insn *insn) 1263 1.1 mrg { 1264 1.1 mrg if (!reload_completed || !TARGET_EXPLICIT_RELOCS) 1265 1.1 mrg return false; 1266 1.1 mrg if (recog_memoized (insn) >= 0) 1267 1.1 mrg return get_attr_cannot_copy (insn); 1268 1.1 mrg else 1269 1.1 mrg return false; 1270 1.1 mrg } 1271 1.1 mrg 1272 1.1 mrg 1273 1.1 mrg /* Try a machine-dependent way of reloading an illegitimate address 1274 1.1 mrg operand. If we find one, push the reload and return the new rtx. */ 1275 1.1 mrg 1276 1.1 mrg rtx 1277 1.1 mrg alpha_legitimize_reload_address (rtx x, 1278 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED, 1279 1.1 mrg int opnum, int type, 1280 1.1 mrg int ind_levels ATTRIBUTE_UNUSED) 1281 1.1 mrg { 1282 1.1 mrg /* We must recognize output that we have already generated ourselves. */ 1283 1.1 mrg if (GET_CODE (x) == PLUS 1284 1.1 mrg && GET_CODE (XEXP (x, 0)) == PLUS 1285 1.1 mrg && REG_P (XEXP (XEXP (x, 0), 0)) 1286 1.1 mrg && CONST_INT_P (XEXP (XEXP (x, 0), 1)) 1287 1.1 mrg && CONST_INT_P (XEXP (x, 1))) 1288 1.1 mrg { 1289 1.1 mrg push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 1290 1.1 mrg BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, 1291 1.1 mrg opnum, (enum reload_type) type); 1292 1.1 mrg return x; 1293 1.1 mrg } 1294 1.1 mrg 1295 1.1 mrg /* We wish to handle large displacements off a base register by 1296 1.1 mrg splitting the addend across an ldah and the mem insn. This 1297 1.1 mrg cuts number of extra insns needed from 3 to 1. */ 1298 1.1 mrg if (GET_CODE (x) == PLUS 1299 1.1 mrg && REG_P (XEXP (x, 0)) 1300 1.1 mrg && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER 1301 1.1 mrg && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0))) 1302 1.1 mrg && CONST_INT_P (XEXP (x, 1))) 1303 1.1 mrg { 1304 1.1 mrg HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); 1305 1.1 mrg HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1306 1.1 mrg HOST_WIDE_INT high 1307 1.1 mrg = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; 1308 1.1 mrg 1309 1.1 mrg /* Check for 32-bit overflow. */ 1310 1.1 mrg if (high + low != val) 1311 1.1 mrg return NULL_RTX; 1312 1.1 mrg 1313 1.1 mrg /* Reload the high part into a base reg; leave the low part 1314 1.1 mrg in the mem directly. */ 1315 1.1 mrg x = gen_rtx_PLUS (GET_MODE (x), 1316 1.1 mrg gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), 1317 1.1 mrg GEN_INT (high)), 1318 1.1 mrg GEN_INT (low)); 1319 1.1 mrg 1320 1.1 mrg push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 1321 1.1 mrg BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, 1322 1.1 mrg opnum, (enum reload_type) type); 1323 1.1 mrg return x; 1324 1.1 mrg } 1325 1.1 mrg 1326 1.1 mrg return NULL_RTX; 1327 1.1 mrg } 1328 1.1 mrg 1329 1.1 mrg /* Return the cost of moving between registers of various classes. Moving 1331 1.1 mrg between FLOAT_REGS and anything else except float regs is expensive. 1332 1.1 mrg In fact, we make it quite expensive because we really don't want to 1333 1.1 mrg do these moves unless it is clearly worth it. Optimizations may 1334 1.1 mrg reduce the impact of not being able to allocate a pseudo to a 1335 1.1 mrg hard register. */ 1336 1.1 mrg 1337 1.1 mrg static int 1338 1.1 mrg alpha_register_move_cost (machine_mode /*mode*/, 1339 1.1 mrg reg_class_t from, reg_class_t to) 1340 1.1 mrg { 1341 1.1 mrg if ((from == FLOAT_REGS) == (to == FLOAT_REGS)) 1342 1.1 mrg return 2; 1343 1.1 mrg 1344 1.1 mrg if (TARGET_FIX) 1345 1.1 mrg return (from == FLOAT_REGS) ? 6 : 8; 1346 1.1 mrg 1347 1.1 mrg return 4 + 2 * alpha_memory_latency; 1348 1.1 mrg } 1349 1.1 mrg 1350 1.1 mrg /* Return the cost of moving data of MODE from a register to 1351 1.1 mrg or from memory. On the Alpha, bump this up a bit. */ 1352 1.1 mrg 1353 1.1 mrg static int 1354 1.1 mrg alpha_memory_move_cost (machine_mode /*mode*/, reg_class_t /*regclass*/, 1355 1.1 mrg bool /*in*/) 1356 1.1 mrg { 1357 1.1 mrg return 2 * alpha_memory_latency; 1358 1.1 mrg } 1359 1.1 mrg 1360 1.1 mrg /* Compute a (partial) cost for rtx X. Return true if the complete 1361 1.1 mrg cost has been computed, and false if subexpressions should be 1362 1.1 mrg scanned. In either case, *TOTAL contains the cost result. */ 1363 1.1 mrg 1364 1.1 mrg static bool 1365 1.1 mrg alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, 1366 1.1 mrg bool speed) 1367 1.1 mrg { 1368 1.1 mrg int code = GET_CODE (x); 1369 1.1 mrg bool float_mode_p = FLOAT_MODE_P (mode); 1370 1.1 mrg const struct alpha_rtx_cost_data *cost_data; 1371 1.1 mrg 1372 1.1 mrg if (!speed) 1373 1.1 mrg cost_data = &alpha_rtx_cost_size; 1374 1.1 mrg else 1375 1.1 mrg cost_data = &alpha_rtx_cost_data[alpha_tune]; 1376 1.1 mrg 1377 1.1 mrg switch (code) 1378 1.1 mrg { 1379 1.1 mrg case CONST_INT: 1380 1.1 mrg /* If this is an 8-bit constant, return zero since it can be used 1381 1.1 mrg nearly anywhere with no cost. If it is a valid operand for an 1382 1.1 mrg ADD or AND, likewise return 0 if we know it will be used in that 1383 1.1 mrg context. Otherwise, return 2 since it might be used there later. 1384 1.1 mrg All other constants take at least two insns. */ 1385 1.1 mrg if (INTVAL (x) >= 0 && INTVAL (x) < 256) 1386 1.1 mrg { 1387 1.1 mrg *total = 0; 1388 1.1 mrg return true; 1389 1.1 mrg } 1390 1.1 mrg /* FALLTHRU */ 1391 1.1 mrg 1392 1.1 mrg case CONST_DOUBLE: 1393 1.1 mrg case CONST_WIDE_INT: 1394 1.1 mrg if (x == CONST0_RTX (mode)) 1395 1.1 mrg *total = 0; 1396 1.1 mrg else if ((outer_code == PLUS && add_operand (x, VOIDmode)) 1397 1.1 mrg || (outer_code == AND && and_operand (x, VOIDmode))) 1398 1.1 mrg *total = 0; 1399 1.1 mrg else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode)) 1400 1.1 mrg *total = 2; 1401 1.1 mrg else 1402 1.1 mrg *total = COSTS_N_INSNS (2); 1403 1.1 mrg return true; 1404 1.1 mrg 1405 1.1 mrg case CONST: 1406 1.1 mrg case SYMBOL_REF: 1407 1.1 mrg case LABEL_REF: 1408 1.1 mrg if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode)) 1409 1.1 mrg *total = COSTS_N_INSNS (outer_code != MEM); 1410 1.1 mrg else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode)) 1411 1.1 mrg *total = COSTS_N_INSNS (1 + (outer_code != MEM)); 1412 1.1 mrg else if (tls_symbolic_operand_type (x)) 1413 1.1 mrg /* Estimate of cost for call_pal rduniq. */ 1414 1.1 mrg /* ??? How many insns do we emit here? More than one... */ 1415 1.1 mrg *total = COSTS_N_INSNS (15); 1416 1.1 mrg else 1417 1.1 mrg /* Otherwise we do a load from the GOT. */ 1418 1.1 mrg *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency); 1419 1.1 mrg return true; 1420 1.1 mrg 1421 1.1 mrg case HIGH: 1422 1.1 mrg /* This is effectively an add_operand. */ 1423 1.1 mrg *total = 2; 1424 1.1 mrg return true; 1425 1.1 mrg 1426 1.1 mrg case PLUS: 1427 1.1 mrg case MINUS: 1428 1.1 mrg if (float_mode_p) 1429 1.1 mrg *total = cost_data->fp_add; 1430 1.1 mrg else if (GET_CODE (XEXP (x, 0)) == ASHIFT 1431 1.1 mrg && const23_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) 1432 1.1 mrg { 1433 1.1 mrg *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode, 1434 1.1 mrg (enum rtx_code) outer_code, opno, speed) 1435 1.1 mrg + rtx_cost (XEXP (x, 1), mode, 1436 1.1 mrg (enum rtx_code) outer_code, opno, speed) 1437 1.1 mrg + COSTS_N_INSNS (1)); 1438 1.1 mrg return true; 1439 1.1 mrg } 1440 1.1 mrg return false; 1441 1.1 mrg 1442 1.1 mrg case MULT: 1443 1.1 mrg if (float_mode_p) 1444 1.1 mrg *total = cost_data->fp_mult; 1445 1.1 mrg else if (mode == DImode) 1446 1.1 mrg *total = cost_data->int_mult_di; 1447 1.1 mrg else 1448 1.1 mrg *total = cost_data->int_mult_si; 1449 1.1 mrg return false; 1450 1.1 mrg 1451 1.1 mrg case ASHIFT: 1452 1.1 mrg if (CONST_INT_P (XEXP (x, 1)) 1453 1.1 mrg && INTVAL (XEXP (x, 1)) <= 3) 1454 1.1 mrg { 1455 1.1 mrg *total = COSTS_N_INSNS (1); 1456 1.1 mrg return false; 1457 1.1 mrg } 1458 1.1 mrg /* FALLTHRU */ 1459 1.1 mrg 1460 1.1 mrg case ASHIFTRT: 1461 1.1 mrg case LSHIFTRT: 1462 1.1 mrg *total = cost_data->int_shift; 1463 1.1 mrg return false; 1464 1.1 mrg 1465 1.1 mrg case IF_THEN_ELSE: 1466 1.1 mrg if (float_mode_p) 1467 1.1 mrg *total = cost_data->fp_add; 1468 1.1 mrg else 1469 1.1 mrg *total = cost_data->int_cmov; 1470 1.1 mrg return false; 1471 1.1 mrg 1472 1.1 mrg case DIV: 1473 1.1 mrg case UDIV: 1474 1.1 mrg case MOD: 1475 1.1 mrg case UMOD: 1476 1.1 mrg if (!float_mode_p) 1477 1.1 mrg *total = cost_data->int_div; 1478 1.1 mrg else if (mode == SFmode) 1479 1.1 mrg *total = cost_data->fp_div_sf; 1480 1.1 mrg else 1481 1.1 mrg *total = cost_data->fp_div_df; 1482 1.1 mrg return false; 1483 1.1 mrg 1484 1.1 mrg case MEM: 1485 1.1 mrg *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency); 1486 1.1 mrg return true; 1487 1.1 mrg 1488 1.1 mrg case NEG: 1489 1.1 mrg if (! float_mode_p) 1490 1.1 mrg { 1491 1.1 mrg *total = COSTS_N_INSNS (1); 1492 1.1 mrg return false; 1493 1.1 mrg } 1494 1.1 mrg /* FALLTHRU */ 1495 1.1 mrg 1496 1.1 mrg case ABS: 1497 1.1 mrg if (! float_mode_p) 1498 1.1 mrg { 1499 1.1 mrg *total = COSTS_N_INSNS (1) + cost_data->int_cmov; 1500 1.1 mrg return false; 1501 1.1 mrg } 1502 1.1 mrg /* FALLTHRU */ 1503 1.1 mrg 1504 1.1 mrg case FLOAT: 1505 1.1 mrg case UNSIGNED_FLOAT: 1506 1.1 mrg case FIX: 1507 1.1 mrg case UNSIGNED_FIX: 1508 1.1 mrg case FLOAT_TRUNCATE: 1509 1.1 mrg *total = cost_data->fp_add; 1510 1.1 mrg return false; 1511 1.1 mrg 1512 1.1 mrg case FLOAT_EXTEND: 1513 1.1 mrg if (MEM_P (XEXP (x, 0))) 1514 1.1 mrg *total = 0; 1515 1.1 mrg else 1516 1.1 mrg *total = cost_data->fp_add; 1517 1.1 mrg return false; 1518 1.1 mrg 1519 1.1 mrg default: 1520 1.1 mrg return false; 1521 1.1 mrg } 1522 1.1 mrg } 1523 1.1 mrg 1524 1.1 mrg /* REF is an alignable memory location. Place an aligned SImode 1526 1.1 mrg reference into *PALIGNED_MEM and the number of bits to shift into 1527 1.1 mrg *PBITNUM. SCRATCH is a free register for use in reloading out 1528 1.1 mrg of range stack slots. */ 1529 1.1 mrg 1530 1.1 mrg void 1531 1.1 mrg get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum) 1532 1.1 mrg { 1533 1.1 mrg rtx base; 1534 1.1 mrg HOST_WIDE_INT disp, offset; 1535 1.1 mrg 1536 1.1 mrg gcc_assert (MEM_P (ref)); 1537 1.1 mrg 1538 1.1 mrg if (reload_in_progress) 1539 1.1 mrg { 1540 1.1 mrg base = find_replacement (&XEXP (ref, 0)); 1541 1.1 mrg gcc_assert (memory_address_p (GET_MODE (ref), base)); 1542 1.1 mrg } 1543 1.1 mrg else 1544 1.1 mrg base = XEXP (ref, 0); 1545 1.1 mrg 1546 1.1 mrg if (GET_CODE (base) == PLUS) 1547 1.1 mrg disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0); 1548 1.1 mrg else 1549 1.1 mrg disp = 0; 1550 1.1 mrg 1551 1.1 mrg /* Find the byte offset within an aligned word. If the memory itself is 1552 1.1 mrg claimed to be aligned, believe it. Otherwise, aligned_memory_operand 1553 1.1 mrg will have examined the base register and determined it is aligned, and 1554 1.1 mrg thus displacements from it are naturally alignable. */ 1555 1.1 mrg if (MEM_ALIGN (ref) >= 32) 1556 1.1 mrg offset = 0; 1557 1.1 mrg else 1558 1.1 mrg offset = disp & 3; 1559 1.1 mrg 1560 1.1 mrg /* The location should not cross aligned word boundary. */ 1561 1.1 mrg gcc_assert (offset + GET_MODE_SIZE (GET_MODE (ref)) 1562 1.1 mrg <= GET_MODE_SIZE (SImode)); 1563 1.1 mrg 1564 1.1 mrg /* Access the entire aligned word. */ 1565 1.1 mrg *paligned_mem = widen_memory_access (ref, SImode, -offset); 1566 1.1 mrg 1567 1.1 mrg /* Convert the byte offset within the word to a bit offset. */ 1568 1.1 mrg offset *= BITS_PER_UNIT; 1569 1.1 mrg *pbitnum = GEN_INT (offset); 1570 1.1 mrg } 1571 1.1 mrg 1572 1.1 mrg /* Similar, but just get the address. Handle the two reload cases. 1573 1.1 mrg Add EXTRA_OFFSET to the address we return. */ 1574 1.1 mrg 1575 1.1 mrg rtx 1576 1.1 mrg get_unaligned_address (rtx ref) 1577 1.1 mrg { 1578 1.1 mrg rtx base; 1579 1.1 mrg HOST_WIDE_INT offset = 0; 1580 1.1 mrg 1581 1.1 mrg gcc_assert (MEM_P (ref)); 1582 1.1 mrg 1583 1.1 mrg if (reload_in_progress) 1584 1.1 mrg { 1585 1.1 mrg base = find_replacement (&XEXP (ref, 0)); 1586 1.1 mrg gcc_assert (memory_address_p (GET_MODE (ref), base)); 1587 1.1 mrg } 1588 1.1 mrg else 1589 1.1 mrg base = XEXP (ref, 0); 1590 1.1 mrg 1591 1.1 mrg if (GET_CODE (base) == PLUS) 1592 1.1 mrg offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); 1593 1.1 mrg 1594 1.1 mrg return plus_constant (Pmode, base, offset); 1595 1.1 mrg } 1596 1.1 mrg 1597 1.1 mrg /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7. 1598 1.1 mrg X is always returned in a register. */ 1599 1.1 mrg 1600 1.1 mrg rtx 1601 1.1 mrg get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs) 1602 1.1 mrg { 1603 1.1 mrg if (GET_CODE (addr) == PLUS) 1604 1.1 mrg { 1605 1.1 mrg ofs += INTVAL (XEXP (addr, 1)); 1606 1.1 mrg addr = XEXP (addr, 0); 1607 1.1 mrg } 1608 1.1 mrg 1609 1.1 mrg return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7), 1610 1.1 mrg NULL_RTX, 1, OPTAB_LIB_WIDEN); 1611 1.1 mrg } 1612 1.1 mrg 1613 1.1 mrg /* On the Alpha, all (non-symbolic) constants except zero go into 1614 1.1 mrg a floating-point register via memory. Note that we cannot 1615 1.1 mrg return anything that is not a subset of RCLASS, and that some 1616 1.1 mrg symbolic constants cannot be dropped to memory. */ 1617 1.1 mrg 1618 1.1 mrg enum reg_class 1619 1.1 mrg alpha_preferred_reload_class(rtx x, enum reg_class rclass) 1620 1.1 mrg { 1621 1.1 mrg /* Zero is present in any register class. */ 1622 1.1 mrg if (x == CONST0_RTX (GET_MODE (x))) 1623 1.1 mrg return rclass; 1624 1.1 mrg 1625 1.1 mrg /* These sorts of constants we can easily drop to memory. */ 1626 1.1 mrg if (CONST_SCALAR_INT_P (x) 1627 1.1 mrg || CONST_DOUBLE_P (x) 1628 1.1 mrg || GET_CODE (x) == CONST_VECTOR) 1629 1.1 mrg { 1630 1.1 mrg if (rclass == FLOAT_REGS) 1631 1.1 mrg return NO_REGS; 1632 1.1 mrg if (rclass == ALL_REGS) 1633 1.1 mrg return GENERAL_REGS; 1634 1.1 mrg return rclass; 1635 1.1 mrg } 1636 1.1 mrg 1637 1.1 mrg /* All other kinds of constants should not (and in the case of HIGH 1638 1.1 mrg cannot) be dropped to memory -- instead we use a GENERAL_REGS 1639 1.1 mrg secondary reload. */ 1640 1.1 mrg if (CONSTANT_P (x)) 1641 1.1 mrg return (rclass == ALL_REGS ? GENERAL_REGS : rclass); 1642 1.1 mrg 1643 1.1 mrg return rclass; 1644 1.1 mrg } 1645 1.1 mrg 1646 1.1 mrg /* Inform reload about cases where moving X with a mode MODE to a register in 1647 1.1 mrg RCLASS requires an extra scratch or immediate register. Return the class 1648 1.1 mrg needed for the immediate register. */ 1649 1.1 mrg 1650 1.1 mrg static reg_class_t 1651 1.1 mrg alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, 1652 1.1 mrg machine_mode mode, secondary_reload_info *sri) 1653 1.1 mrg { 1654 1.1 mrg enum reg_class rclass = (enum reg_class) rclass_i; 1655 1.1 mrg 1656 1.1 mrg /* Loading and storing HImode or QImode values to and from memory 1657 1.1 mrg usually requires a scratch register. */ 1658 1.1 mrg if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode)) 1659 1.1 mrg { 1660 1.1 mrg if (any_memory_operand (x, mode)) 1661 1.1 mrg { 1662 1.1 mrg if (in_p) 1663 1.1 mrg { 1664 1.1 mrg if (!aligned_memory_operand (x, mode)) 1665 1.1 mrg sri->icode = direct_optab_handler (reload_in_optab, mode); 1666 1.1 mrg } 1667 1.1 mrg else 1668 1.1 mrg sri->icode = direct_optab_handler (reload_out_optab, mode); 1669 1.1 mrg return NO_REGS; 1670 1.1 mrg } 1671 1.1 mrg } 1672 1.1 mrg 1673 1.1 mrg /* We also cannot do integral arithmetic into FP regs, as might result 1674 1.1 mrg from register elimination into a DImode fp register. */ 1675 1.1 mrg if (rclass == FLOAT_REGS) 1676 1.1 mrg { 1677 1.1 mrg if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND) 1678 1.1 mrg return GENERAL_REGS; 1679 1.1 mrg if (in_p && INTEGRAL_MODE_P (mode) 1680 1.1 mrg && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x)) 1681 1.1 mrg return GENERAL_REGS; 1682 1.1 mrg } 1683 1.1 mrg 1684 1.1 mrg return NO_REGS; 1685 1.1 mrg } 1686 1.1 mrg 1687 1.1 mrg /* Implement TARGET_SECONDARY_MEMORY_NEEDED. 1688 1.1 mrg 1689 1.1 mrg If we are copying between general and FP registers, we need a memory 1690 1.1 mrg location unless the FIX extension is available. */ 1691 1.1 mrg 1692 1.1 mrg static bool 1693 1.1 mrg alpha_secondary_memory_needed (machine_mode, reg_class_t class1, 1694 1.1 mrg reg_class_t class2) 1695 1.1 mrg { 1696 1.1 mrg return (!TARGET_FIX 1697 1.1 mrg && ((class1 == FLOAT_REGS && class2 != FLOAT_REGS) 1698 1.1 mrg || (class2 == FLOAT_REGS && class1 != FLOAT_REGS))); 1699 1.1 mrg } 1700 1.1 mrg 1701 1.1 mrg /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. If MODE is 1702 1.1 mrg floating-point, use it. Otherwise, widen to a word like the default. 1703 1.1 mrg This is needed because we always store integers in FP registers in 1704 1.1 mrg quadword format. This whole area is very tricky! */ 1705 1.1 mrg 1706 1.1 mrg static machine_mode 1707 1.1 mrg alpha_secondary_memory_needed_mode (machine_mode mode) 1708 1.1 mrg { 1709 1.1 mrg if (GET_MODE_CLASS (mode) == MODE_FLOAT) 1710 1.1 mrg return mode; 1711 1.1 mrg if (GET_MODE_SIZE (mode) >= 4) 1712 1.1 mrg return mode; 1713 1.1 mrg return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require (); 1714 1.1 mrg } 1715 1.1 mrg 1716 1.1 mrg /* Given SEQ, which is an INSN list, look for any MEMs in either 1718 1.1 mrg a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and 1719 1.1 mrg volatile flags from REF into each of the MEMs found. If REF is not 1720 1.1 mrg a MEM, don't do anything. */ 1721 1.1 mrg 1722 1.1 mrg void 1723 1.1 mrg alpha_set_memflags (rtx seq, rtx ref) 1724 1.1 mrg { 1725 1.1 mrg rtx_insn *insn; 1726 1.1 mrg 1727 1.1 mrg if (!MEM_P (ref)) 1728 1.1 mrg return; 1729 1.1 mrg 1730 1.1 mrg /* This is only called from alpha.md, after having had something 1731 1.1 mrg generated from one of the insn patterns. So if everything is 1732 1.1 mrg zero, the pattern is already up-to-date. */ 1733 1.1 mrg if (!MEM_VOLATILE_P (ref) 1734 1.1 mrg && !MEM_NOTRAP_P (ref) 1735 1.1 mrg && !MEM_READONLY_P (ref)) 1736 1.1 mrg return; 1737 1.1 mrg 1738 1.1 mrg subrtx_var_iterator::array_type array; 1739 1.1 mrg for (insn = as_a <rtx_insn *> (seq); insn; insn = NEXT_INSN (insn)) 1740 1.1 mrg if (INSN_P (insn)) 1741 1.1 mrg FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST) 1742 1.1 mrg { 1743 1.1 mrg rtx x = *iter; 1744 1.1 mrg if (MEM_P (x)) 1745 1.1 mrg { 1746 1.1 mrg MEM_VOLATILE_P (x) = MEM_VOLATILE_P (ref); 1747 1.1 mrg MEM_NOTRAP_P (x) = MEM_NOTRAP_P (ref); 1748 1.1 mrg MEM_READONLY_P (x) = MEM_READONLY_P (ref); 1749 1.1 mrg /* Sadly, we cannot use alias sets because the extra 1750 1.1 mrg aliasing produced by the AND interferes. Given that 1751 1.1 mrg two-byte quantities are the only thing we would be 1752 1.1 mrg able to differentiate anyway, there does not seem to 1753 1.1 mrg be any point in convoluting the early out of the 1754 1.1 mrg alias check. */ 1755 1.1 mrg iter.skip_subrtxes (); 1756 1.1 mrg } 1757 1.1 mrg } 1758 1.1 mrg else 1759 1.1 mrg gcc_unreachable (); 1760 1.1 mrg } 1761 1.1 mrg 1762 1.1 mrg static rtx alpha_emit_set_const (rtx, machine_mode, HOST_WIDE_INT, 1764 1.1 mrg int, bool); 1765 1.1 mrg 1766 1.1 mrg /* Internal routine for alpha_emit_set_const to check for N or below insns. 1767 1.1 mrg If NO_OUTPUT is true, then we only check to see if N insns are possible, 1768 1.1 mrg and return pc_rtx if successful. */ 1769 1.1 mrg 1770 1.1 mrg static rtx 1771 1.1 mrg alpha_emit_set_const_1 (rtx target, machine_mode mode, 1772 1.1 mrg HOST_WIDE_INT c, int n, bool no_output) 1773 1.1 mrg { 1774 1.1 mrg HOST_WIDE_INT new_const; 1775 1.1 mrg int i, bits; 1776 1.1 mrg /* Use a pseudo if highly optimizing and still generating RTL. */ 1777 1.1 mrg rtx subtarget 1778 1.1 mrg = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target); 1779 1.1 mrg rtx temp, insn; 1780 1.1 mrg 1781 1.1 mrg /* If this is a sign-extended 32-bit constant, we can do this in at most 1782 1.1 mrg three insns, so do it if we have enough insns left. */ 1783 1.1 mrg 1784 1.1 mrg if (c >> 31 == -1 || c >> 31 == 0) 1785 1.1 mrg { 1786 1.1 mrg HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000; 1787 1.1 mrg HOST_WIDE_INT tmp1 = c - low; 1788 1.1 mrg HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000; 1789 1.1 mrg HOST_WIDE_INT extra = 0; 1790 1.1 mrg 1791 1.1 mrg /* If HIGH will be interpreted as negative but the constant is 1792 1.1 mrg positive, we must adjust it to do two ldha insns. */ 1793 1.1 mrg 1794 1.1 mrg if ((high & 0x8000) != 0 && c >= 0) 1795 1.1 mrg { 1796 1.1 mrg extra = 0x4000; 1797 1.1 mrg tmp1 -= 0x40000000; 1798 1.1 mrg high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); 1799 1.1 mrg } 1800 1.1 mrg 1801 1.1 mrg if (c == low || (low == 0 && extra == 0)) 1802 1.1 mrg { 1803 1.1 mrg /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode) 1804 1.1 mrg but that meant that we can't handle INT_MIN on 32-bit machines 1805 1.1 mrg (like NT/Alpha), because we recurse indefinitely through 1806 1.1 mrg emit_move_insn to gen_movdi. So instead, since we know exactly 1807 1.1 mrg what we want, create it explicitly. */ 1808 1.1 mrg 1809 1.1 mrg if (no_output) 1810 1.1 mrg return pc_rtx; 1811 1.1 mrg if (target == NULL) 1812 1.1 mrg target = gen_reg_rtx (mode); 1813 1.1 mrg emit_insn (gen_rtx_SET (target, GEN_INT (c))); 1814 1.1 mrg return target; 1815 1.1 mrg } 1816 1.1 mrg else if (n >= 2 + (extra != 0)) 1817 1.1 mrg { 1818 1.1 mrg if (no_output) 1819 1.1 mrg return pc_rtx; 1820 1.1 mrg if (!can_create_pseudo_p ()) 1821 1.1 mrg { 1822 1.1 mrg emit_insn (gen_rtx_SET (target, GEN_INT (high << 16))); 1823 1.1 mrg temp = target; 1824 1.1 mrg } 1825 1.1 mrg else 1826 1.1 mrg temp = copy_to_suggested_reg (GEN_INT (high << 16), 1827 1.1 mrg subtarget, mode); 1828 1.1 mrg 1829 1.1 mrg /* As of 2002-02-23, addsi3 is only available when not optimizing. 1830 1.1 mrg This means that if we go through expand_binop, we'll try to 1831 1.1 mrg generate extensions, etc, which will require new pseudos, which 1832 1.1 mrg will fail during some split phases. The SImode add patterns 1833 1.1 mrg still exist, but are not named. So build the insns by hand. */ 1834 1.1 mrg 1835 1.1 mrg if (extra != 0) 1836 1.1 mrg { 1837 1.1 mrg if (! subtarget) 1838 1.1 mrg subtarget = gen_reg_rtx (mode); 1839 1.1 mrg insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16)); 1840 1.1 mrg insn = gen_rtx_SET (subtarget, insn); 1841 1.1 mrg emit_insn (insn); 1842 1.1 mrg temp = subtarget; 1843 1.1 mrg } 1844 1.1 mrg 1845 1.1 mrg if (target == NULL) 1846 1.1 mrg target = gen_reg_rtx (mode); 1847 1.1 mrg insn = gen_rtx_PLUS (mode, temp, GEN_INT (low)); 1848 1.1 mrg insn = gen_rtx_SET (target, insn); 1849 1.1 mrg emit_insn (insn); 1850 1.1 mrg return target; 1851 1.1 mrg } 1852 1.1 mrg } 1853 1.1 mrg 1854 1.1 mrg /* If we couldn't do it that way, try some other methods. But if we have 1855 1.1 mrg no instructions left, don't bother. Likewise, if this is SImode and 1856 1.1 mrg we can't make pseudos, we can't do anything since the expand_binop 1857 1.1 mrg and expand_unop calls will widen and try to make pseudos. */ 1858 1.1 mrg 1859 1.1 mrg if (n == 1 || (mode == SImode && !can_create_pseudo_p ())) 1860 1.1 mrg return 0; 1861 1.1 mrg 1862 1.1 mrg /* Next, see if we can load a related constant and then shift and possibly 1863 1.1 mrg negate it to get the constant we want. Try this once each increasing 1864 1.1 mrg numbers of insns. */ 1865 1.1 mrg 1866 1.1 mrg for (i = 1; i < n; i++) 1867 1.1 mrg { 1868 1.1 mrg /* First, see if minus some low bits, we've an easy load of 1869 1.1 mrg high bits. */ 1870 1.1 mrg 1871 1.1 mrg new_const = ((c & 0xffff) ^ 0x8000) - 0x8000; 1872 1.1 mrg if (new_const != 0) 1873 1.1 mrg { 1874 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output); 1875 1.1 mrg if (temp) 1876 1.1 mrg { 1877 1.1 mrg if (no_output) 1878 1.1 mrg return temp; 1879 1.1 mrg return expand_binop (mode, add_optab, temp, GEN_INT (new_const), 1880 1.1 mrg target, 0, OPTAB_WIDEN); 1881 1.1 mrg } 1882 1.1 mrg } 1883 1.1 mrg 1884 1.1 mrg /* Next try complementing. */ 1885 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output); 1886 1.1 mrg if (temp) 1887 1.1 mrg { 1888 1.1 mrg if (no_output) 1889 1.1 mrg return temp; 1890 1.1 mrg return expand_unop (mode, one_cmpl_optab, temp, target, 0); 1891 1.1 mrg } 1892 1.1 mrg 1893 1.1 mrg /* Next try to form a constant and do a left shift. We can do this 1894 1.1 mrg if some low-order bits are zero; the exact_log2 call below tells 1895 1.1 mrg us that information. The bits we are shifting out could be any 1896 1.1 mrg value, but here we'll just try the 0- and sign-extended forms of 1897 1.1 mrg the constant. To try to increase the chance of having the same 1898 1.1 mrg constant in more than one insn, start at the highest number of 1899 1.1 mrg bits to shift, but try all possibilities in case a ZAPNOT will 1900 1.1 mrg be useful. */ 1901 1.1 mrg 1902 1.1 mrg bits = exact_log2 (c & -c); 1903 1.1 mrg if (bits > 0) 1904 1.1 mrg for (; bits > 0; bits--) 1905 1.1 mrg { 1906 1.1 mrg new_const = c >> bits; 1907 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output); 1908 1.1 mrg if (!temp && c < 0) 1909 1.1 mrg { 1910 1.1 mrg new_const = (unsigned HOST_WIDE_INT)c >> bits; 1911 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, 1912 1.1 mrg i, no_output); 1913 1.1 mrg } 1914 1.1 mrg if (temp) 1915 1.1 mrg { 1916 1.1 mrg if (no_output) 1917 1.1 mrg return temp; 1918 1.1 mrg return expand_binop (mode, ashl_optab, temp, GEN_INT (bits), 1919 1.1 mrg target, 0, OPTAB_WIDEN); 1920 1.1 mrg } 1921 1.1 mrg } 1922 1.1 mrg 1923 1.1 mrg /* Now try high-order zero bits. Here we try the shifted-in bits as 1924 1.1 mrg all zero and all ones. Be careful to avoid shifting outside the 1925 1.1 mrg mode and to avoid shifting outside the host wide int size. */ 1926 1.1 mrg 1927 1.1 mrg bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) 1928 1.1 mrg - floor_log2 (c) - 1); 1929 1.1 mrg if (bits > 0) 1930 1.1 mrg for (; bits > 0; bits--) 1931 1.1 mrg { 1932 1.1 mrg new_const = c << bits; 1933 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output); 1934 1.1 mrg if (!temp) 1935 1.1 mrg { 1936 1.1 mrg new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1); 1937 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, 1938 1.1 mrg i, no_output); 1939 1.1 mrg } 1940 1.1 mrg if (temp) 1941 1.1 mrg { 1942 1.1 mrg if (no_output) 1943 1.1 mrg return temp; 1944 1.1 mrg return expand_binop (mode, lshr_optab, temp, GEN_INT (bits), 1945 1.1 mrg target, 1, OPTAB_WIDEN); 1946 1.1 mrg } 1947 1.1 mrg } 1948 1.1 mrg 1949 1.1 mrg /* Now try high-order 1 bits. We get that with a sign-extension. 1950 1.1 mrg But one bit isn't enough here. Be careful to avoid shifting outside 1951 1.1 mrg the mode and to avoid shifting outside the host wide int size. */ 1952 1.1 mrg 1953 1.1 mrg bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) 1954 1.1 mrg - floor_log2 (~ c) - 2); 1955 1.1 mrg if (bits > 0) 1956 1.1 mrg for (; bits > 0; bits--) 1957 1.1 mrg { 1958 1.1 mrg new_const = c << bits; 1959 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output); 1960 1.1 mrg if (!temp) 1961 1.1 mrg { 1962 1.1 mrg new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1); 1963 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, 1964 1.1 mrg i, no_output); 1965 1.1 mrg } 1966 1.1 mrg if (temp) 1967 1.1 mrg { 1968 1.1 mrg if (no_output) 1969 1.1 mrg return temp; 1970 1.1 mrg return expand_binop (mode, ashr_optab, temp, GEN_INT (bits), 1971 1.1 mrg target, 0, OPTAB_WIDEN); 1972 1.1 mrg } 1973 1.1 mrg } 1974 1.1 mrg } 1975 1.1 mrg 1976 1.1 mrg /* Finally, see if can load a value into the target that is the same as the 1977 1.1 mrg constant except that all bytes that are 0 are changed to be 0xff. If we 1978 1.1 mrg can, then we can do a ZAPNOT to obtain the desired constant. */ 1979 1.1 mrg 1980 1.1 mrg new_const = c; 1981 1.1 mrg for (i = 0; i < 64; i += 8) 1982 1.1 mrg if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0) 1983 1.1 mrg new_const |= (HOST_WIDE_INT) 0xff << i; 1984 1.1 mrg 1985 1.1 mrg /* We are only called for SImode and DImode. If this is SImode, ensure that 1986 1.1 mrg we are sign extended to a full word. */ 1987 1.1 mrg 1988 1.1 mrg if (mode == SImode) 1989 1.1 mrg new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000; 1990 1.1 mrg 1991 1.1 mrg if (new_const != c) 1992 1.1 mrg { 1993 1.1 mrg temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output); 1994 1.1 mrg if (temp) 1995 1.1 mrg { 1996 1.1 mrg if (no_output) 1997 1.1 mrg return temp; 1998 1.1 mrg return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const), 1999 1.1 mrg target, 0, OPTAB_WIDEN); 2000 1.1 mrg } 2001 1.1 mrg } 2002 1.1 mrg 2003 1.1 mrg return 0; 2004 1.1 mrg } 2005 1.1 mrg 2006 1.1 mrg /* Try to output insns to set TARGET equal to the constant C if it can be 2007 1.1 mrg done in less than N insns. Do all computations in MODE. Returns the place 2008 1.1 mrg where the output has been placed if it can be done and the insns have been 2009 1.1 mrg emitted. If it would take more than N insns, zero is returned and no 2010 1.1 mrg insns and emitted. */ 2011 1.1 mrg 2012 1.1 mrg static rtx 2013 1.1 mrg alpha_emit_set_const (rtx target, machine_mode mode, 2014 1.1 mrg HOST_WIDE_INT c, int n, bool no_output) 2015 1.1 mrg { 2016 1.1 mrg machine_mode orig_mode = mode; 2017 1.1 mrg rtx orig_target = target; 2018 1.1 mrg rtx result = 0; 2019 1.1 mrg int i; 2020 1.1 mrg 2021 1.1 mrg /* If we can't make any pseudos, TARGET is an SImode hard register, we 2022 1.1 mrg can't load this constant in one insn, do this in DImode. */ 2023 1.1 mrg if (!can_create_pseudo_p () && mode == SImode 2024 1.1 mrg && REG_P (target) && REGNO (target) < FIRST_PSEUDO_REGISTER) 2025 1.1 mrg { 2026 1.1 mrg result = alpha_emit_set_const_1 (target, mode, c, 1, no_output); 2027 1.1 mrg if (result) 2028 1.1 mrg return result; 2029 1.1 mrg 2030 1.1 mrg target = no_output ? NULL : gen_lowpart (DImode, target); 2031 1.1 mrg mode = DImode; 2032 1.1 mrg } 2033 1.1 mrg else if (mode == V8QImode || mode == V4HImode || mode == V2SImode) 2034 1.1 mrg { 2035 1.1 mrg target = no_output ? NULL : gen_lowpart (DImode, target); 2036 1.1 mrg mode = DImode; 2037 1.1 mrg } 2038 1.1 mrg 2039 1.1 mrg /* Try 1 insn, then 2, then up to N. */ 2040 1.1 mrg for (i = 1; i <= n; i++) 2041 1.1 mrg { 2042 1.1 mrg result = alpha_emit_set_const_1 (target, mode, c, i, no_output); 2043 1.1 mrg if (result) 2044 1.1 mrg { 2045 1.1 mrg rtx_insn *insn; 2046 1.1 mrg rtx set; 2047 1.1 mrg 2048 1.1 mrg if (no_output) 2049 1.1 mrg return result; 2050 1.1 mrg 2051 1.1 mrg insn = get_last_insn (); 2052 1.1 mrg set = single_set (insn); 2053 1.1 mrg if (! CONSTANT_P (SET_SRC (set))) 2054 1.1 mrg set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c)); 2055 1.1 mrg break; 2056 1.1 mrg } 2057 1.1 mrg } 2058 1.1 mrg 2059 1.1 mrg /* Allow for the case where we changed the mode of TARGET. */ 2060 1.1 mrg if (result) 2061 1.1 mrg { 2062 1.1 mrg if (result == target) 2063 1.1 mrg result = orig_target; 2064 1.1 mrg else if (mode != orig_mode) 2065 1.1 mrg result = gen_lowpart (orig_mode, result); 2066 1.1 mrg } 2067 1.1 mrg 2068 1.1 mrg return result; 2069 1.1 mrg } 2070 1.1 mrg 2071 1.1 mrg /* Having failed to find a 3 insn sequence in alpha_emit_set_const, 2072 1.1 mrg fall back to a straight forward decomposition. We do this to avoid 2073 1.1 mrg exponential run times encountered when looking for longer sequences 2074 1.1 mrg with alpha_emit_set_const. */ 2075 1.1 mrg 2076 1.1 mrg static rtx 2077 1.1 mrg alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1) 2078 1.1 mrg { 2079 1.1 mrg HOST_WIDE_INT d1, d2, d3, d4; 2080 1.1 mrg machine_mode mode = GET_MODE (target); 2081 1.1 mrg rtx orig_target = target; 2082 1.1 mrg 2083 1.1 mrg /* Decompose the entire word */ 2084 1.1 mrg 2085 1.1 mrg d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; 2086 1.1 mrg c1 -= d1; 2087 1.1 mrg d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; 2088 1.1 mrg c1 = (c1 - d2) >> 32; 2089 1.1 mrg d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; 2090 1.1 mrg c1 -= d3; 2091 1.1 mrg d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; 2092 1.1 mrg gcc_assert (c1 == d4); 2093 1.1 mrg 2094 1.1 mrg if (mode != DImode) 2095 1.1 mrg target = gen_lowpart (DImode, target); 2096 1.1 mrg 2097 1.1 mrg /* Construct the high word */ 2098 1.1 mrg if (d4) 2099 1.1 mrg { 2100 1.1 mrg emit_move_insn (target, GEN_INT (d4)); 2101 1.1 mrg if (d3) 2102 1.1 mrg emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3))); 2103 1.1 mrg } 2104 1.1 mrg else 2105 1.1 mrg emit_move_insn (target, GEN_INT (d3)); 2106 1.1 mrg 2107 1.1 mrg /* Shift it into place */ 2108 1.1 mrg emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32))); 2109 1.1 mrg 2110 1.1 mrg /* Add in the low bits. */ 2111 1.1 mrg if (d2) 2112 1.1 mrg emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2))); 2113 1.1 mrg if (d1) 2114 1.1 mrg emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1))); 2115 1.1 mrg 2116 1.1 mrg return orig_target; 2117 1.1 mrg } 2118 1.1 mrg 2119 1.1 mrg /* Given an integral CONST_INT or CONST_VECTOR, return the low 64 bits. */ 2120 1.1 mrg 2121 1.1 mrg static HOST_WIDE_INT 2122 1.1 mrg alpha_extract_integer (rtx x) 2123 1.1 mrg { 2124 1.1 mrg if (GET_CODE (x) == CONST_VECTOR) 2125 1.1 mrg x = simplify_subreg (DImode, x, GET_MODE (x), 0); 2126 1.1 mrg 2127 1.1 mrg gcc_assert (CONST_INT_P (x)); 2128 1.1 mrg 2129 1.1 mrg return INTVAL (x); 2130 1.1 mrg } 2131 1.1 mrg 2132 1.1 mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P. This is all constants for which 2133 1.1 mrg we are willing to load the value into a register via a move pattern. 2134 1.1 mrg Normally this is all symbolic constants, integral constants that 2135 1.1 mrg take three or fewer instructions, and floating-point zero. */ 2136 1.1 mrg 2137 1.1 mrg bool 2138 1.1 mrg alpha_legitimate_constant_p (machine_mode mode, rtx x) 2139 1.1 mrg { 2140 1.1 mrg HOST_WIDE_INT i0; 2141 1.1 mrg 2142 1.1 mrg switch (GET_CODE (x)) 2143 1.1 mrg { 2144 1.1 mrg case LABEL_REF: 2145 1.1 mrg case HIGH: 2146 1.1 mrg return true; 2147 1.1 mrg 2148 1.1 mrg case CONST: 2149 1.1 mrg if (GET_CODE (XEXP (x, 0)) == PLUS 2150 1.1 mrg && CONST_INT_P (XEXP (XEXP (x, 0), 1))) 2151 1.1 mrg x = XEXP (XEXP (x, 0), 0); 2152 1.1 mrg else 2153 1.1 mrg return true; 2154 1.1 mrg 2155 1.1 mrg if (GET_CODE (x) != SYMBOL_REF) 2156 1.1 mrg return true; 2157 1.1 mrg /* FALLTHRU */ 2158 1.1 mrg 2159 1.1 mrg case SYMBOL_REF: 2160 1.1 mrg /* TLS symbols are never valid. */ 2161 1.1 mrg return SYMBOL_REF_TLS_MODEL (x) == 0; 2162 1.1 mrg 2163 1.1 mrg case CONST_WIDE_INT: 2164 1.1 mrg if (TARGET_BUILD_CONSTANTS) 2165 1.1 mrg return true; 2166 1.1 mrg if (x == CONST0_RTX (mode)) 2167 1.1 mrg return true; 2168 1.1 mrg mode = DImode; 2169 1.1 mrg gcc_assert (CONST_WIDE_INT_NUNITS (x) == 2); 2170 1.1 mrg i0 = CONST_WIDE_INT_ELT (x, 1); 2171 1.1 mrg if (alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) == NULL) 2172 1.1 mrg return false; 2173 1.1 mrg i0 = CONST_WIDE_INT_ELT (x, 0); 2174 1.1 mrg goto do_integer; 2175 1.1 mrg 2176 1.1 mrg case CONST_DOUBLE: 2177 1.1 mrg if (x == CONST0_RTX (mode)) 2178 1.1 mrg return true; 2179 1.1 mrg return false; 2180 1.1 mrg 2181 1.1 mrg case CONST_VECTOR: 2182 1.1 mrg if (x == CONST0_RTX (mode)) 2183 1.1 mrg return true; 2184 1.1 mrg if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) 2185 1.1 mrg return false; 2186 1.1 mrg if (GET_MODE_SIZE (mode) != 8) 2187 1.1 mrg return false; 2188 1.1 mrg /* FALLTHRU */ 2189 1.1 mrg 2190 1.1 mrg case CONST_INT: 2191 1.1 mrg if (TARGET_BUILD_CONSTANTS) 2192 1.1 mrg return true; 2193 1.1 mrg i0 = alpha_extract_integer (x); 2194 1.1 mrg do_integer: 2195 1.1 mrg return alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) != NULL; 2196 1.1 mrg 2197 1.1 mrg default: 2198 1.1 mrg return false; 2199 1.1 mrg } 2200 1.1 mrg } 2201 1.1 mrg 2202 1.1 mrg /* Operand 1 is known to be a constant, and should require more than one 2203 1.1 mrg instruction to load. Emit that multi-part load. */ 2204 1.1 mrg 2205 1.1 mrg bool 2206 1.1 mrg alpha_split_const_mov (machine_mode mode, rtx *operands) 2207 1.1 mrg { 2208 1.1 mrg HOST_WIDE_INT i0; 2209 1.1 mrg rtx temp = NULL_RTX; 2210 1.1 mrg 2211 1.1 mrg i0 = alpha_extract_integer (operands[1]); 2212 1.1 mrg 2213 1.1 mrg temp = alpha_emit_set_const (operands[0], mode, i0, 3, false); 2214 1.1 mrg 2215 1.1 mrg if (!temp && TARGET_BUILD_CONSTANTS) 2216 1.1 mrg temp = alpha_emit_set_long_const (operands[0], i0); 2217 1.1 mrg 2218 1.1 mrg if (temp) 2219 1.1 mrg { 2220 1.1 mrg if (!rtx_equal_p (operands[0], temp)) 2221 1.1 mrg emit_move_insn (operands[0], temp); 2222 1.1 mrg return true; 2223 1.1 mrg } 2224 1.1 mrg 2225 1.1 mrg return false; 2226 1.1 mrg } 2227 1.1 mrg 2228 1.1 mrg /* Expand a move instruction; return true if all work is done. 2229 1.1 mrg We don't handle non-bwx subword loads here. */ 2230 1.1 mrg 2231 1.1 mrg bool 2232 1.1 mrg alpha_expand_mov (machine_mode mode, rtx *operands) 2233 1.1 mrg { 2234 1.1 mrg rtx tmp; 2235 1.1 mrg 2236 1.1 mrg /* If the output is not a register, the input must be. */ 2237 1.1 mrg if (MEM_P (operands[0]) 2238 1.1 mrg && ! reg_or_0_operand (operands[1], mode)) 2239 1.1 mrg operands[1] = force_reg (mode, operands[1]); 2240 1.1 mrg 2241 1.1 mrg /* Allow legitimize_address to perform some simplifications. */ 2242 1.1 mrg if (mode == Pmode && symbolic_operand (operands[1], mode)) 2243 1.1 mrg { 2244 1.1 mrg tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode); 2245 1.1 mrg if (tmp) 2246 1.1 mrg { 2247 1.1 mrg if (tmp == operands[0]) 2248 1.1 mrg return true; 2249 1.1 mrg operands[1] = tmp; 2250 1.1 mrg return false; 2251 1.1 mrg } 2252 1.1 mrg } 2253 1.1 mrg 2254 1.1 mrg /* Early out for non-constants and valid constants. */ 2255 1.1 mrg if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode)) 2256 1.1 mrg return false; 2257 1.1 mrg 2258 1.1 mrg /* Split large integers. */ 2259 1.1 mrg if (CONST_INT_P (operands[1]) 2260 1.1 mrg || GET_CODE (operands[1]) == CONST_VECTOR) 2261 1.1 mrg { 2262 1.1 mrg if (alpha_split_const_mov (mode, operands)) 2263 1.1 mrg return true; 2264 1.1 mrg } 2265 1.1 mrg 2266 1.1 mrg /* Otherwise we've nothing left but to drop the thing to memory. */ 2267 1.1 mrg tmp = force_const_mem (mode, operands[1]); 2268 1.1 mrg 2269 1.1 mrg if (tmp == NULL_RTX) 2270 1.1 mrg return false; 2271 1.1 mrg 2272 1.1 mrg if (reload_in_progress) 2273 1.1 mrg { 2274 1.1 mrg emit_move_insn (operands[0], XEXP (tmp, 0)); 2275 1.1 mrg operands[1] = replace_equiv_address (tmp, operands[0]); 2276 1.1 mrg } 2277 1.1 mrg else 2278 1.1 mrg operands[1] = validize_mem (tmp); 2279 1.1 mrg return false; 2280 1.1 mrg } 2281 1.1 mrg 2282 1.1 mrg /* Expand a non-bwx QImode or HImode move instruction; 2283 1.1 mrg return true if all work is done. */ 2284 1.1 mrg 2285 1.1 mrg bool 2286 1.1 mrg alpha_expand_mov_nobwx (machine_mode mode, rtx *operands) 2287 1.1 mrg { 2288 1.1 mrg rtx seq; 2289 1.1 mrg 2290 1.1 mrg /* If the output is not a register, the input must be. */ 2291 1.1 mrg if (MEM_P (operands[0])) 2292 1.1 mrg operands[1] = force_reg (mode, operands[1]); 2293 1.1 mrg 2294 1.1 mrg /* Handle four memory cases, unaligned and aligned for either the input 2295 1.1 mrg or the output. The only case where we can be called during reload is 2296 1.1 mrg for aligned loads; all other cases require temporaries. */ 2297 1.1 mrg 2298 1.1 mrg if (any_memory_operand (operands[1], mode)) 2299 1.1 mrg { 2300 1.1 mrg if (aligned_memory_operand (operands[1], mode)) 2301 1.1 mrg { 2302 1.1 mrg if (reload_in_progress) 2303 1.1 mrg { 2304 1.1 mrg seq = gen_reload_in_aligned (mode, operands[0], operands[1]); 2305 1.1 mrg emit_insn (seq); 2306 1.1 mrg } 2307 1.1 mrg else 2308 1.1 mrg { 2309 1.1 mrg rtx aligned_mem, bitnum; 2310 1.1 mrg rtx scratch = gen_reg_rtx (SImode); 2311 1.1 mrg rtx subtarget; 2312 1.1 mrg bool copyout; 2313 1.1 mrg 2314 1.1 mrg get_aligned_mem (operands[1], &aligned_mem, &bitnum); 2315 1.1 mrg 2316 1.1 mrg subtarget = operands[0]; 2317 1.1 mrg if (REG_P (subtarget)) 2318 1.1 mrg subtarget = gen_lowpart (DImode, subtarget), copyout = false; 2319 1.1 mrg else 2320 1.1 mrg subtarget = gen_reg_rtx (DImode), copyout = true; 2321 1.1 mrg 2322 1.1 mrg if (mode == QImode) 2323 1.1 mrg seq = gen_aligned_loadqi (subtarget, aligned_mem, 2324 1.1 mrg bitnum, scratch); 2325 1.1 mrg else 2326 1.1 mrg seq = gen_aligned_loadhi (subtarget, aligned_mem, 2327 1.1 mrg bitnum, scratch); 2328 1.1 mrg emit_insn (seq); 2329 1.1 mrg 2330 1.1 mrg if (copyout) 2331 1.1 mrg emit_move_insn (operands[0], gen_lowpart (mode, subtarget)); 2332 1.1 mrg } 2333 1.1 mrg } 2334 1.1 mrg else 2335 1.1 mrg { 2336 1.1 mrg /* Don't pass these as parameters since that makes the generated 2337 1.1 mrg code depend on parameter evaluation order which will cause 2338 1.1 mrg bootstrap failures. */ 2339 1.1 mrg 2340 1.1 mrg rtx temp1, temp2, subtarget, ua; 2341 1.1 mrg bool copyout; 2342 1.1 mrg 2343 1.1 mrg temp1 = gen_reg_rtx (DImode); 2344 1.1 mrg temp2 = gen_reg_rtx (DImode); 2345 1.1 mrg 2346 1.1 mrg subtarget = operands[0]; 2347 1.1 mrg if (REG_P (subtarget)) 2348 1.1 mrg subtarget = gen_lowpart (DImode, subtarget), copyout = false; 2349 1.1 mrg else 2350 1.1 mrg subtarget = gen_reg_rtx (DImode), copyout = true; 2351 1.1 mrg 2352 1.1 mrg ua = get_unaligned_address (operands[1]); 2353 1.1 mrg if (mode == QImode) 2354 1.1 mrg seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2); 2355 1.1 mrg else 2356 1.1 mrg seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2); 2357 1.1 mrg 2358 1.1 mrg alpha_set_memflags (seq, operands[1]); 2359 1.1 mrg emit_insn (seq); 2360 1.1 mrg 2361 1.1 mrg if (copyout) 2362 1.1 mrg emit_move_insn (operands[0], gen_lowpart (mode, subtarget)); 2363 1.1 mrg } 2364 1.1 mrg return true; 2365 1.1 mrg } 2366 1.1 mrg 2367 1.1 mrg if (any_memory_operand (operands[0], mode)) 2368 1.1 mrg { 2369 1.1 mrg if (aligned_memory_operand (operands[0], mode)) 2370 1.1 mrg { 2371 1.1 mrg rtx aligned_mem, bitnum; 2372 1.1 mrg rtx temp1 = gen_reg_rtx (SImode); 2373 1.1 mrg rtx temp2 = gen_reg_rtx (SImode); 2374 1.1 mrg 2375 1.1 mrg get_aligned_mem (operands[0], &aligned_mem, &bitnum); 2376 1.1 mrg 2377 1.1 mrg emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, 2378 1.1 mrg temp1, temp2)); 2379 1.1 mrg } 2380 1.1 mrg else 2381 1.1 mrg { 2382 1.1 mrg rtx temp1 = gen_reg_rtx (DImode); 2383 1.1 mrg rtx temp2 = gen_reg_rtx (DImode); 2384 1.1 mrg rtx temp3 = gen_reg_rtx (DImode); 2385 1.1 mrg rtx ua = get_unaligned_address (operands[0]); 2386 1.1 mrg 2387 1.1 mrg seq = gen_unaligned_store 2388 1.1 mrg (mode, ua, operands[1], temp1, temp2, temp3); 2389 1.1 mrg 2390 1.1 mrg alpha_set_memflags (seq, operands[0]); 2391 1.1 mrg emit_insn (seq); 2392 1.1 mrg } 2393 1.1 mrg return true; 2394 1.1 mrg } 2395 1.1 mrg 2396 1.1 mrg return false; 2397 1.1 mrg } 2398 1.1 mrg 2399 1.1 mrg /* Implement the movmisalign patterns. One of the operands is a memory 2400 1.1 mrg that is not naturally aligned. Emit instructions to load it. */ 2401 1.1 mrg 2402 1.1 mrg void 2403 1.1 mrg alpha_expand_movmisalign (machine_mode mode, rtx *operands) 2404 1.1 mrg { 2405 1.1 mrg /* Honor misaligned loads, for those we promised to do so. */ 2406 1.1 mrg if (MEM_P (operands[1])) 2407 1.1 mrg { 2408 1.1 mrg rtx tmp; 2409 1.1 mrg 2410 1.1 mrg if (register_operand (operands[0], mode)) 2411 1.1 mrg tmp = operands[0]; 2412 1.1 mrg else 2413 1.1 mrg tmp = gen_reg_rtx (mode); 2414 1.1 mrg 2415 1.1 mrg alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0); 2416 1.1 mrg if (tmp != operands[0]) 2417 1.1 mrg emit_move_insn (operands[0], tmp); 2418 1.1 mrg } 2419 1.1 mrg else if (MEM_P (operands[0])) 2420 1.1 mrg { 2421 1.1 mrg if (!reg_or_0_operand (operands[1], mode)) 2422 1.1 mrg operands[1] = force_reg (mode, operands[1]); 2423 1.1 mrg alpha_expand_unaligned_store (operands[0], operands[1], 8, 0); 2424 1.1 mrg } 2425 1.1 mrg else 2426 1.1 mrg gcc_unreachable (); 2427 1.1 mrg } 2428 1.1 mrg 2429 1.1 mrg /* Generate an unsigned DImode to FP conversion. This is the same code 2430 1.1 mrg optabs would emit if we didn't have TFmode patterns. 2431 1.1 mrg 2432 1.1 mrg For SFmode, this is the only construction I've found that can pass 2433 1.1 mrg gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode 2434 1.1 mrg intermediates will work, because you'll get intermediate rounding 2435 1.1 mrg that ruins the end result. Some of this could be fixed by turning 2436 1.1 mrg on round-to-positive-infinity, but that requires diddling the fpsr, 2437 1.1 mrg which kills performance. I tried turning this around and converting 2438 1.1 mrg to a negative number, so that I could turn on /m, but either I did 2439 1.1 mrg it wrong or there's something else cause I wound up with the exact 2440 1.1 mrg same single-bit error. There is a branch-less form of this same code: 2441 1.1 mrg 2442 1.1 mrg srl $16,1,$1 2443 1.1 mrg and $16,1,$2 2444 1.1 mrg cmplt $16,0,$3 2445 1.1 mrg or $1,$2,$2 2446 1.1 mrg cmovge $16,$16,$2 2447 1.1 mrg itoft $3,$f10 2448 1.1 mrg itoft $2,$f11 2449 1.1 mrg cvtqs $f11,$f11 2450 1.1 mrg adds $f11,$f11,$f0 2451 1.1 mrg fcmoveq $f10,$f11,$f0 2452 1.1 mrg 2453 1.1 mrg I'm not using it because it's the same number of instructions as 2454 1.1 mrg this branch-full form, and it has more serialized long latency 2455 1.1 mrg instructions on the critical path. 2456 1.1 mrg 2457 1.1 mrg For DFmode, we can avoid rounding errors by breaking up the word 2458 1.1 mrg into two pieces, converting them separately, and adding them back: 2459 1.1 mrg 2460 1.1 mrg LC0: .long 0,0x5f800000 2461 1.1 mrg 2462 1.1 mrg itoft $16,$f11 2463 1.1 mrg lda $2,LC0 2464 1.1 mrg cmplt $16,0,$1 2465 1.1 mrg cpyse $f11,$f31,$f10 2466 1.1 mrg cpyse $f31,$f11,$f11 2467 1.1 mrg s4addq $1,$2,$1 2468 1.1 mrg lds $f12,0($1) 2469 1.1 mrg cvtqt $f10,$f10 2470 1.1 mrg cvtqt $f11,$f11 2471 1.1 mrg addt $f12,$f10,$f0 2472 1.1 mrg addt $f0,$f11,$f0 2473 1.1 mrg 2474 1.1 mrg This doesn't seem to be a clear-cut win over the optabs form. 2475 1.1 mrg It probably all depends on the distribution of numbers being 2476 1.1 mrg converted -- in the optabs form, all but high-bit-set has a 2477 1.1 mrg much lower minimum execution time. */ 2478 1.1 mrg 2479 1.1 mrg void 2480 1.1 mrg alpha_emit_floatuns (rtx operands[2]) 2481 1.1 mrg { 2482 1.1 mrg rtx neglab, donelab, i0, i1, f0, in, out; 2483 1.1 mrg machine_mode mode; 2484 1.1 mrg 2485 1.1 mrg out = operands[0]; 2486 1.1 mrg in = force_reg (DImode, operands[1]); 2487 1.1 mrg mode = GET_MODE (out); 2488 1.1 mrg neglab = gen_label_rtx (); 2489 1.1 mrg donelab = gen_label_rtx (); 2490 1.1 mrg i0 = gen_reg_rtx (DImode); 2491 1.1 mrg i1 = gen_reg_rtx (DImode); 2492 1.1 mrg f0 = gen_reg_rtx (mode); 2493 1.1 mrg 2494 1.1 mrg emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab); 2495 1.1 mrg 2496 1.1 mrg emit_insn (gen_rtx_SET (out, gen_rtx_FLOAT (mode, in))); 2497 1.1 mrg emit_jump_insn (gen_jump (donelab)); 2498 1.1 mrg emit_barrier (); 2499 1.1 mrg 2500 1.1 mrg emit_label (neglab); 2501 1.1 mrg 2502 1.1 mrg emit_insn (gen_lshrdi3 (i0, in, const1_rtx)); 2503 1.1 mrg emit_insn (gen_anddi3 (i1, in, const1_rtx)); 2504 1.1 mrg emit_insn (gen_iordi3 (i0, i0, i1)); 2505 1.1 mrg emit_insn (gen_rtx_SET (f0, gen_rtx_FLOAT (mode, i0))); 2506 1.1 mrg emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0))); 2507 1.1 mrg 2508 1.1 mrg emit_label (donelab); 2509 1.1 mrg } 2510 1.1 mrg 2511 1.1 mrg /* Generate the comparison for a conditional branch. */ 2512 1.1 mrg 2513 1.1 mrg void 2514 1.1 mrg alpha_emit_conditional_branch (rtx operands[], machine_mode cmp_mode) 2515 1.1 mrg { 2516 1.1 mrg enum rtx_code cmp_code, branch_code; 2517 1.1 mrg machine_mode branch_mode = VOIDmode; 2518 1.1 mrg enum rtx_code code = GET_CODE (operands[0]); 2519 1.1 mrg rtx op0 = operands[1], op1 = operands[2]; 2520 1.1 mrg rtx tem; 2521 1.1 mrg 2522 1.1 mrg if (cmp_mode == TFmode) 2523 1.1 mrg { 2524 1.1 mrg op0 = alpha_emit_xfloating_compare (&code, op0, op1); 2525 1.1 mrg op1 = const0_rtx; 2526 1.1 mrg cmp_mode = DImode; 2527 1.1 mrg } 2528 1.1 mrg 2529 1.1 mrg /* The general case: fold the comparison code to the types of compares 2530 1.1 mrg that we have, choosing the branch as necessary. */ 2531 1.1 mrg switch (code) 2532 1.1 mrg { 2533 1.1 mrg case EQ: case LE: case LT: case LEU: case LTU: 2534 1.1 mrg case UNORDERED: 2535 1.1 mrg /* We have these compares. */ 2536 1.1 mrg cmp_code = code, branch_code = NE; 2537 1.1 mrg break; 2538 1.1 mrg 2539 1.1 mrg case NE: 2540 1.1 mrg case ORDERED: 2541 1.1 mrg /* These must be reversed. */ 2542 1.1 mrg cmp_code = reverse_condition (code), branch_code = EQ; 2543 1.1 mrg break; 2544 1.1 mrg 2545 1.1 mrg case GE: case GT: case GEU: case GTU: 2546 1.1 mrg /* For FP, we swap them, for INT, we reverse them. */ 2547 1.1 mrg if (cmp_mode == DFmode) 2548 1.1 mrg { 2549 1.1 mrg cmp_code = swap_condition (code); 2550 1.1 mrg branch_code = NE; 2551 1.1 mrg std::swap (op0, op1); 2552 1.1 mrg } 2553 1.1 mrg else 2554 1.1 mrg { 2555 1.1 mrg cmp_code = reverse_condition (code); 2556 1.1 mrg branch_code = EQ; 2557 1.1 mrg } 2558 1.1 mrg break; 2559 1.1 mrg 2560 1.1 mrg default: 2561 1.1 mrg gcc_unreachable (); 2562 1.1 mrg } 2563 1.1 mrg 2564 1.1 mrg if (cmp_mode == DFmode) 2565 1.1 mrg { 2566 1.1 mrg if (flag_unsafe_math_optimizations && cmp_code != UNORDERED) 2567 1.1 mrg { 2568 1.1 mrg /* When we are not as concerned about non-finite values, and we 2569 1.1 mrg are comparing against zero, we can branch directly. */ 2570 1.1 mrg if (op1 == CONST0_RTX (DFmode)) 2571 1.1 mrg cmp_code = UNKNOWN, branch_code = code; 2572 1.1 mrg else if (op0 == CONST0_RTX (DFmode)) 2573 1.1 mrg { 2574 1.1 mrg /* Undo the swap we probably did just above. */ 2575 1.1 mrg std::swap (op0, op1); 2576 1.1 mrg branch_code = swap_condition (cmp_code); 2577 1.1 mrg cmp_code = UNKNOWN; 2578 1.1 mrg } 2579 1.1 mrg } 2580 1.1 mrg else 2581 1.1 mrg { 2582 1.1 mrg /* ??? We mark the branch mode to be CCmode to prevent the 2583 1.1 mrg compare and branch from being combined, since the compare 2584 1.1 mrg insn follows IEEE rules that the branch does not. */ 2585 1.1 mrg branch_mode = CCmode; 2586 1.1 mrg } 2587 1.1 mrg } 2588 1.1 mrg else 2589 1.1 mrg { 2590 1.1 mrg /* The following optimizations are only for signed compares. */ 2591 1.1 mrg if (code != LEU && code != LTU && code != GEU && code != GTU) 2592 1.1 mrg { 2593 1.1 mrg /* Whee. Compare and branch against 0 directly. */ 2594 1.1 mrg if (op1 == const0_rtx) 2595 1.1 mrg cmp_code = UNKNOWN, branch_code = code; 2596 1.1 mrg 2597 1.1 mrg /* If the constants doesn't fit into an immediate, but can 2598 1.1 mrg be generated by lda/ldah, we adjust the argument and 2599 1.1 mrg compare against zero, so we can use beq/bne directly. */ 2600 1.1 mrg /* ??? Don't do this when comparing against symbols, otherwise 2601 1.1 mrg we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will 2602 1.1 mrg be declared false out of hand (at least for non-weak). */ 2603 1.1 mrg else if (CONST_INT_P (op1) 2604 1.1 mrg && (code == EQ || code == NE) 2605 1.1 mrg && !(symbolic_operand (op0, VOIDmode) 2606 1.1 mrg || (REG_P (op0) && REG_POINTER (op0)))) 2607 1.1 mrg { 2608 1.1 mrg rtx n_op1 = GEN_INT (-INTVAL (op1)); 2609 1.1 mrg 2610 1.1 mrg if (! satisfies_constraint_I (op1) 2611 1.1 mrg && (satisfies_constraint_K (n_op1) 2612 1.1 mrg || satisfies_constraint_L (n_op1))) 2613 1.1 mrg cmp_code = PLUS, branch_code = code, op1 = n_op1; 2614 1.1 mrg } 2615 1.1 mrg } 2616 1.1 mrg 2617 1.1 mrg if (!reg_or_0_operand (op0, DImode)) 2618 1.1 mrg op0 = force_reg (DImode, op0); 2619 1.1 mrg if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode)) 2620 1.1 mrg op1 = force_reg (DImode, op1); 2621 1.1 mrg } 2622 1.1 mrg 2623 1.1 mrg /* Emit an initial compare instruction, if necessary. */ 2624 1.1 mrg tem = op0; 2625 1.1 mrg if (cmp_code != UNKNOWN) 2626 1.1 mrg { 2627 1.1 mrg tem = gen_reg_rtx (cmp_mode); 2628 1.1 mrg emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)); 2629 1.1 mrg } 2630 1.1 mrg 2631 1.1 mrg /* Emit the branch instruction. */ 2632 1.1 mrg tem = gen_rtx_SET (pc_rtx, 2633 1.1 mrg gen_rtx_IF_THEN_ELSE (VOIDmode, 2634 1.1 mrg gen_rtx_fmt_ee (branch_code, 2635 1.1 mrg branch_mode, tem, 2636 1.1 mrg CONST0_RTX (cmp_mode)), 2637 1.1 mrg gen_rtx_LABEL_REF (VOIDmode, 2638 1.1 mrg operands[3]), 2639 1.1 mrg pc_rtx)); 2640 1.1 mrg emit_jump_insn (tem); 2641 1.1 mrg } 2642 1.1 mrg 2643 1.1 mrg /* Certain simplifications can be done to make invalid setcc operations 2644 1.1 mrg valid. Return the final comparison, or NULL if we can't work. */ 2645 1.1 mrg 2646 1.1 mrg bool 2647 1.1 mrg alpha_emit_setcc (rtx operands[], machine_mode cmp_mode) 2648 1.1 mrg { 2649 1.1 mrg enum rtx_code cmp_code; 2650 1.1 mrg enum rtx_code code = GET_CODE (operands[1]); 2651 1.1 mrg rtx op0 = operands[2], op1 = operands[3]; 2652 1.1 mrg rtx tmp; 2653 1.1 mrg 2654 1.1 mrg if (cmp_mode == TFmode) 2655 1.1 mrg { 2656 1.1 mrg op0 = alpha_emit_xfloating_compare (&code, op0, op1); 2657 1.1 mrg op1 = const0_rtx; 2658 1.1 mrg cmp_mode = DImode; 2659 1.1 mrg } 2660 1.1 mrg 2661 1.1 mrg if (cmp_mode == DFmode && !TARGET_FIX) 2662 1.1 mrg return 0; 2663 1.1 mrg 2664 1.1 mrg /* The general case: fold the comparison code to the types of compares 2665 1.1 mrg that we have, choosing the branch as necessary. */ 2666 1.1 mrg 2667 1.1 mrg cmp_code = UNKNOWN; 2668 1.1 mrg switch (code) 2669 1.1 mrg { 2670 1.1 mrg case EQ: case LE: case LT: case LEU: case LTU: 2671 1.1 mrg case UNORDERED: 2672 1.1 mrg /* We have these compares. */ 2673 1.1 mrg if (cmp_mode == DFmode) 2674 1.1 mrg cmp_code = code, code = NE; 2675 1.1 mrg break; 2676 1.1 mrg 2677 1.1 mrg case NE: 2678 1.1 mrg if (cmp_mode == DImode && op1 == const0_rtx) 2679 1.1 mrg break; 2680 1.1 mrg /* FALLTHRU */ 2681 1.1 mrg 2682 1.1 mrg case ORDERED: 2683 1.1 mrg cmp_code = reverse_condition (code); 2684 1.1 mrg code = EQ; 2685 1.1 mrg break; 2686 1.1 mrg 2687 1.1 mrg case GE: case GT: case GEU: case GTU: 2688 1.1 mrg /* These normally need swapping, but for integer zero we have 2689 1.1 mrg special patterns that recognize swapped operands. */ 2690 1.1 mrg if (cmp_mode == DImode && op1 == const0_rtx) 2691 1.1 mrg break; 2692 1.1 mrg code = swap_condition (code); 2693 1.1 mrg if (cmp_mode == DFmode) 2694 1.1 mrg cmp_code = code, code = NE; 2695 1.1 mrg std::swap (op0, op1); 2696 1.1 mrg break; 2697 1.1 mrg 2698 1.1 mrg default: 2699 1.1 mrg gcc_unreachable (); 2700 1.1 mrg } 2701 1.1 mrg 2702 1.1 mrg if (cmp_mode == DImode) 2703 1.1 mrg { 2704 1.1 mrg if (!register_operand (op0, DImode)) 2705 1.1 mrg op0 = force_reg (DImode, op0); 2706 1.1 mrg if (!reg_or_8bit_operand (op1, DImode)) 2707 1.1 mrg op1 = force_reg (DImode, op1); 2708 1.1 mrg } 2709 1.1 mrg 2710 1.1 mrg /* Emit an initial compare instruction, if necessary. */ 2711 1.1 mrg if (cmp_code != UNKNOWN) 2712 1.1 mrg { 2713 1.1 mrg tmp = gen_reg_rtx (cmp_mode); 2714 1.1 mrg emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (cmp_code, cmp_mode, 2715 1.1 mrg op0, op1))); 2716 1.1 mrg 2717 1.1 mrg op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp; 2718 1.1 mrg op1 = const0_rtx; 2719 1.1 mrg } 2720 1.1 mrg 2721 1.1 mrg /* Emit the setcc instruction. */ 2722 1.1 mrg emit_insn (gen_rtx_SET (operands[0], gen_rtx_fmt_ee (code, DImode, 2723 1.1 mrg op0, op1))); 2724 1.1 mrg return true; 2725 1.1 mrg } 2726 1.1 mrg 2727 1.1 mrg 2728 1.1 mrg /* Rewrite a comparison against zero CMP of the form 2729 1.1 mrg (CODE (cc0) (const_int 0)) so it can be written validly in 2730 1.1 mrg a conditional move (if_then_else CMP ...). 2731 1.1 mrg If both of the operands that set cc0 are nonzero we must emit 2732 1.1 mrg an insn to perform the compare (it can't be done within 2733 1.1 mrg the conditional move). */ 2734 1.1 mrg 2735 1.1 mrg rtx 2736 1.1 mrg alpha_emit_conditional_move (rtx cmp, machine_mode mode) 2737 1.1 mrg { 2738 1.1 mrg enum rtx_code code = GET_CODE (cmp); 2739 1.1 mrg enum rtx_code cmov_code = NE; 2740 1.1 mrg rtx op0 = XEXP (cmp, 0); 2741 1.1 mrg rtx op1 = XEXP (cmp, 1); 2742 1.1 mrg machine_mode cmp_mode 2743 1.1 mrg = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0)); 2744 1.1 mrg machine_mode cmov_mode = VOIDmode; 2745 1.1 mrg int local_fast_math = flag_unsafe_math_optimizations; 2746 1.1 mrg rtx tem; 2747 1.1 mrg 2748 1.1 mrg if (cmp_mode == TFmode) 2749 1.1 mrg { 2750 1.1 mrg op0 = alpha_emit_xfloating_compare (&code, op0, op1); 2751 1.1 mrg op1 = const0_rtx; 2752 1.1 mrg cmp_mode = DImode; 2753 1.1 mrg } 2754 1.1 mrg 2755 1.1 mrg gcc_assert (cmp_mode == DFmode || cmp_mode == DImode); 2756 1.1 mrg 2757 1.1 mrg if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode)) 2758 1.1 mrg { 2759 1.1 mrg enum rtx_code cmp_code; 2760 1.1 mrg 2761 1.1 mrg if (! TARGET_FIX) 2762 1.1 mrg return 0; 2763 1.1 mrg 2764 1.1 mrg /* If we have fp<->int register move instructions, do a cmov by 2765 1.1 mrg performing the comparison in fp registers, and move the 2766 1.1 mrg zero/nonzero value to integer registers, where we can then 2767 1.1 mrg use a normal cmov, or vice-versa. */ 2768 1.1 mrg 2769 1.1 mrg switch (code) 2770 1.1 mrg { 2771 1.1 mrg case EQ: case LE: case LT: case LEU: case LTU: 2772 1.1 mrg case UNORDERED: 2773 1.1 mrg /* We have these compares. */ 2774 1.1 mrg cmp_code = code, code = NE; 2775 1.1 mrg break; 2776 1.1 mrg 2777 1.1 mrg case NE: 2778 1.1 mrg case ORDERED: 2779 1.1 mrg /* These must be reversed. */ 2780 1.1 mrg cmp_code = reverse_condition (code), code = EQ; 2781 1.1 mrg break; 2782 1.1 mrg 2783 1.1 mrg case GE: case GT: case GEU: case GTU: 2784 1.1 mrg /* These normally need swapping, but for integer zero we have 2785 1.1 mrg special patterns that recognize swapped operands. */ 2786 1.1 mrg if (cmp_mode == DImode && op1 == const0_rtx) 2787 1.1 mrg cmp_code = code, code = NE; 2788 1.1 mrg else 2789 1.1 mrg { 2790 1.1 mrg cmp_code = swap_condition (code); 2791 1.1 mrg code = NE; 2792 1.1 mrg std::swap (op0, op1); 2793 1.1 mrg } 2794 1.1 mrg break; 2795 1.1 mrg 2796 1.1 mrg default: 2797 1.1 mrg gcc_unreachable (); 2798 1.1 mrg } 2799 1.1 mrg 2800 1.1 mrg if (cmp_mode == DImode) 2801 1.1 mrg { 2802 1.1 mrg if (!reg_or_0_operand (op0, DImode)) 2803 1.1 mrg op0 = force_reg (DImode, op0); 2804 1.1 mrg if (!reg_or_8bit_operand (op1, DImode)) 2805 1.1 mrg op1 = force_reg (DImode, op1); 2806 1.1 mrg } 2807 1.1 mrg 2808 1.1 mrg tem = gen_reg_rtx (cmp_mode); 2809 1.1 mrg emit_insn (gen_rtx_SET (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, 2810 1.1 mrg op0, op1))); 2811 1.1 mrg 2812 1.1 mrg cmp_mode = cmp_mode == DImode ? E_DFmode : E_DImode; 2813 1.1 mrg op0 = gen_lowpart (cmp_mode, tem); 2814 1.1 mrg op1 = CONST0_RTX (cmp_mode); 2815 1.1 mrg cmp = gen_rtx_fmt_ee (code, VOIDmode, op0, op1); 2816 1.1 mrg local_fast_math = 1; 2817 1.1 mrg } 2818 1.1 mrg 2819 1.1 mrg if (cmp_mode == DImode) 2820 1.1 mrg { 2821 1.1 mrg if (!reg_or_0_operand (op0, DImode)) 2822 1.1 mrg op0 = force_reg (DImode, op0); 2823 1.1 mrg if (!reg_or_8bit_operand (op1, DImode)) 2824 1.1 mrg op1 = force_reg (DImode, op1); 2825 1.1 mrg } 2826 1.1 mrg 2827 1.1 mrg /* We may be able to use a conditional move directly. 2828 1.1 mrg This avoids emitting spurious compares. */ 2829 1.1 mrg if (signed_comparison_operator (cmp, VOIDmode) 2830 1.1 mrg && (cmp_mode == DImode || local_fast_math) 2831 1.1 mrg && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode))) 2832 1.1 mrg return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); 2833 1.1 mrg 2834 1.1 mrg /* We can't put the comparison inside the conditional move; 2835 1.1 mrg emit a compare instruction and put that inside the 2836 1.1 mrg conditional move. Make sure we emit only comparisons we have; 2837 1.1 mrg swap or reverse as necessary. */ 2838 1.1 mrg 2839 1.1 mrg if (!can_create_pseudo_p ()) 2840 1.1 mrg return NULL_RTX; 2841 1.1 mrg 2842 1.1 mrg switch (code) 2843 1.1 mrg { 2844 1.1 mrg case EQ: case LE: case LT: case LEU: case LTU: 2845 1.1 mrg case UNORDERED: 2846 1.1 mrg /* We have these compares: */ 2847 1.1 mrg break; 2848 1.1 mrg 2849 1.1 mrg case NE: 2850 1.1 mrg case ORDERED: 2851 1.1 mrg /* These must be reversed. */ 2852 1.1 mrg code = reverse_condition (code); 2853 1.1 mrg cmov_code = EQ; 2854 1.1 mrg break; 2855 1.1 mrg 2856 1.1 mrg case GE: case GT: case GEU: case GTU: 2857 1.1 mrg /* These normally need swapping, but for integer zero we have 2858 1.1 mrg special patterns that recognize swapped operands. */ 2859 1.1 mrg if (cmp_mode == DImode && op1 == const0_rtx) 2860 1.1 mrg break; 2861 1.1 mrg code = swap_condition (code); 2862 1.1 mrg std::swap (op0, op1); 2863 1.1 mrg break; 2864 1.1 mrg 2865 1.1 mrg default: 2866 1.1 mrg gcc_unreachable (); 2867 1.1 mrg } 2868 1.1 mrg 2869 1.1 mrg if (cmp_mode == DImode) 2870 1.1 mrg { 2871 1.1 mrg if (!reg_or_0_operand (op0, DImode)) 2872 1.1 mrg op0 = force_reg (DImode, op0); 2873 1.1 mrg if (!reg_or_8bit_operand (op1, DImode)) 2874 1.1 mrg op1 = force_reg (DImode, op1); 2875 1.1 mrg } 2876 1.1 mrg 2877 1.1 mrg /* ??? We mark the branch mode to be CCmode to prevent the compare 2878 1.1 mrg and cmov from being combined, since the compare insn follows IEEE 2879 1.1 mrg rules that the cmov does not. */ 2880 1.1 mrg if (cmp_mode == DFmode && !local_fast_math) 2881 1.1 mrg cmov_mode = CCmode; 2882 1.1 mrg 2883 1.1 mrg tem = gen_reg_rtx (cmp_mode); 2884 1.1 mrg emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1)); 2885 1.1 mrg return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode)); 2886 1.1 mrg } 2887 1.1 mrg 2888 1.1 mrg /* Simplify a conditional move of two constants into a setcc with 2889 1.1 mrg arithmetic. This is done with a splitter since combine would 2890 1.1 mrg just undo the work if done during code generation. It also catches 2891 1.1 mrg cases we wouldn't have before cse. */ 2892 1.1 mrg 2893 1.1 mrg int 2894 1.1 mrg alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond, 2895 1.1 mrg rtx t_rtx, rtx f_rtx) 2896 1.1 mrg { 2897 1.1 mrg HOST_WIDE_INT t, f, diff; 2898 1.1 mrg machine_mode mode; 2899 1.1 mrg rtx target, subtarget, tmp; 2900 1.1 mrg 2901 1.1 mrg mode = GET_MODE (dest); 2902 1.1 mrg t = INTVAL (t_rtx); 2903 1.1 mrg f = INTVAL (f_rtx); 2904 1.1 mrg diff = t - f; 2905 1.1 mrg 2906 1.1 mrg if (((code == NE || code == EQ) && diff < 0) 2907 1.1 mrg || (code == GE || code == GT)) 2908 1.1 mrg { 2909 1.1 mrg code = reverse_condition (code); 2910 1.1 mrg std::swap (t, f); 2911 1.1 mrg diff = -diff; 2912 1.1 mrg } 2913 1.1 mrg 2914 1.1 mrg subtarget = target = dest; 2915 1.1 mrg if (mode != DImode) 2916 1.1 mrg { 2917 1.1 mrg target = gen_lowpart (DImode, dest); 2918 1.1 mrg if (can_create_pseudo_p ()) 2919 1.1 mrg subtarget = gen_reg_rtx (DImode); 2920 1.1 mrg else 2921 1.1 mrg subtarget = target; 2922 1.1 mrg } 2923 1.1 mrg /* Below, we must be careful to use copy_rtx on target and subtarget 2924 1.1 mrg in intermediate insns, as they may be a subreg rtx, which may not 2925 1.1 mrg be shared. */ 2926 1.1 mrg 2927 1.1 mrg if (f == 0 && exact_log2 (diff) > 0 2928 1.1 mrg /* On EV6, we've got enough shifters to make non-arithmetic shifts 2929 1.1 mrg viable over a longer latency cmove. On EV5, the E0 slot is a 2930 1.1 mrg scarce resource, and on EV4 shift has the same latency as a cmove. */ 2931 1.1 mrg && (diff <= 8 || alpha_tune == PROCESSOR_EV6)) 2932 1.1 mrg { 2933 1.1 mrg tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); 2934 1.1 mrg emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); 2935 1.1 mrg 2936 1.1 mrg tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget), 2937 1.1 mrg GEN_INT (exact_log2 (t))); 2938 1.1 mrg emit_insn (gen_rtx_SET (target, tmp)); 2939 1.1 mrg } 2940 1.1 mrg else if (f == 0 && t == -1) 2941 1.1 mrg { 2942 1.1 mrg tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); 2943 1.1 mrg emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); 2944 1.1 mrg 2945 1.1 mrg emit_insn (gen_negdi2 (target, copy_rtx (subtarget))); 2946 1.1 mrg } 2947 1.1 mrg else if (diff == 1 || diff == 4 || diff == 8) 2948 1.1 mrg { 2949 1.1 mrg rtx add_op; 2950 1.1 mrg 2951 1.1 mrg tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); 2952 1.1 mrg emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); 2953 1.1 mrg 2954 1.1 mrg if (diff == 1) 2955 1.1 mrg emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f))); 2956 1.1 mrg else 2957 1.1 mrg { 2958 1.1 mrg add_op = GEN_INT (f); 2959 1.1 mrg if (sext_add_operand (add_op, mode)) 2960 1.1 mrg { 2961 1.1 mrg tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget), 2962 1.1 mrg GEN_INT (exact_log2 (diff))); 2963 1.1 mrg tmp = gen_rtx_PLUS (DImode, tmp, add_op); 2964 1.1 mrg emit_insn (gen_rtx_SET (target, tmp)); 2965 1.1 mrg } 2966 1.1 mrg else 2967 1.1 mrg return 0; 2968 1.1 mrg } 2969 1.1 mrg } 2970 1.1 mrg else 2971 1.1 mrg return 0; 2972 1.1 mrg 2973 1.1 mrg return 1; 2974 1.1 mrg } 2975 1.1 mrg 2976 1.1 mrg /* Look up the function X_floating library function name for the 2978 1.1 mrg given operation. */ 2979 1.1 mrg 2980 1.1 mrg struct GTY(()) xfloating_op 2981 1.1 mrg { 2982 1.1 mrg const enum rtx_code code; 2983 1.1 mrg const char *const GTY((skip)) osf_func; 2984 1.1 mrg const char *const GTY((skip)) vms_func; 2985 1.1 mrg rtx libcall; 2986 1.1 mrg }; 2987 1.1 mrg 2988 1.1 mrg static GTY(()) struct xfloating_op xfloating_ops[] = 2989 1.1 mrg { 2990 1.1 mrg { PLUS, "_OtsAddX", "OTS$ADD_X", 0 }, 2991 1.1 mrg { MINUS, "_OtsSubX", "OTS$SUB_X", 0 }, 2992 1.1 mrg { MULT, "_OtsMulX", "OTS$MUL_X", 0 }, 2993 1.1 mrg { DIV, "_OtsDivX", "OTS$DIV_X", 0 }, 2994 1.1 mrg { EQ, "_OtsEqlX", "OTS$EQL_X", 0 }, 2995 1.1 mrg { NE, "_OtsNeqX", "OTS$NEQ_X", 0 }, 2996 1.1 mrg { LT, "_OtsLssX", "OTS$LSS_X", 0 }, 2997 1.1 mrg { LE, "_OtsLeqX", "OTS$LEQ_X", 0 }, 2998 1.1 mrg { GT, "_OtsGtrX", "OTS$GTR_X", 0 }, 2999 1.1 mrg { GE, "_OtsGeqX", "OTS$GEQ_X", 0 }, 3000 1.1 mrg { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 }, 3001 1.1 mrg { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 }, 3002 1.1 mrg { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 }, 3003 1.1 mrg { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 }, 3004 1.1 mrg { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 } 3005 1.1 mrg }; 3006 1.1 mrg 3007 1.1 mrg static GTY(()) struct xfloating_op vax_cvt_ops[] = 3008 1.1 mrg { 3009 1.1 mrg { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 }, 3010 1.1 mrg { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 } 3011 1.1 mrg }; 3012 1.1 mrg 3013 1.1 mrg static rtx 3014 1.1 mrg alpha_lookup_xfloating_lib_func (enum rtx_code code) 3015 1.1 mrg { 3016 1.1 mrg struct xfloating_op *ops = xfloating_ops; 3017 1.1 mrg long n = ARRAY_SIZE (xfloating_ops); 3018 1.1 mrg long i; 3019 1.1 mrg 3020 1.1 mrg gcc_assert (TARGET_HAS_XFLOATING_LIBS); 3021 1.1 mrg 3022 1.1 mrg /* How irritating. Nothing to key off for the main table. */ 3023 1.1 mrg if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE)) 3024 1.1 mrg { 3025 1.1 mrg ops = vax_cvt_ops; 3026 1.1 mrg n = ARRAY_SIZE (vax_cvt_ops); 3027 1.1 mrg } 3028 1.1 mrg 3029 1.1 mrg for (i = 0; i < n; ++i, ++ops) 3030 1.1 mrg if (ops->code == code) 3031 1.1 mrg { 3032 1.1 mrg rtx func = ops->libcall; 3033 1.1 mrg if (!func) 3034 1.1 mrg { 3035 1.1 mrg func = init_one_libfunc (TARGET_ABI_OPEN_VMS 3036 1.1 mrg ? ops->vms_func : ops->osf_func); 3037 1.1 mrg ops->libcall = func; 3038 1.1 mrg } 3039 1.1 mrg return func; 3040 1.1 mrg } 3041 1.1 mrg 3042 1.1 mrg gcc_unreachable (); 3043 1.1 mrg } 3044 1.1 mrg 3045 1.1 mrg /* Most X_floating operations take the rounding mode as an argument. 3046 1.1 mrg Compute that here. */ 3047 1.1 mrg 3048 1.1 mrg static int 3049 1.1 mrg alpha_compute_xfloating_mode_arg (enum rtx_code code, 3050 1.1 mrg enum alpha_fp_rounding_mode round) 3051 1.1 mrg { 3052 1.1 mrg int mode; 3053 1.1 mrg 3054 1.1 mrg switch (round) 3055 1.1 mrg { 3056 1.1 mrg case ALPHA_FPRM_NORM: 3057 1.1 mrg mode = 2; 3058 1.1 mrg break; 3059 1.1 mrg case ALPHA_FPRM_MINF: 3060 1.1 mrg mode = 1; 3061 1.1 mrg break; 3062 1.1 mrg case ALPHA_FPRM_CHOP: 3063 1.1 mrg mode = 0; 3064 1.1 mrg break; 3065 1.1 mrg case ALPHA_FPRM_DYN: 3066 1.1 mrg mode = 4; 3067 1.1 mrg break; 3068 1.1 mrg default: 3069 1.1 mrg gcc_unreachable (); 3070 1.1 mrg 3071 1.1 mrg /* XXX For reference, round to +inf is mode = 3. */ 3072 1.1 mrg } 3073 1.1 mrg 3074 1.1 mrg if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N) 3075 1.1 mrg mode |= 0x10000; 3076 1.1 mrg 3077 1.1 mrg return mode; 3078 1.1 mrg } 3079 1.1 mrg 3080 1.1 mrg /* Emit an X_floating library function call. 3081 1.1 mrg 3082 1.1 mrg Note that these functions do not follow normal calling conventions: 3083 1.1 mrg TFmode arguments are passed in two integer registers (as opposed to 3084 1.1 mrg indirect); TFmode return values appear in R16+R17. 3085 1.1 mrg 3086 1.1 mrg FUNC is the function to call. 3087 1.1 mrg TARGET is where the output belongs. 3088 1.1 mrg OPERANDS are the inputs. 3089 1.1 mrg NOPERANDS is the count of inputs. 3090 1.1 mrg EQUIV is the expression equivalent for the function. 3091 1.1 mrg */ 3092 1.1 mrg 3093 1.1 mrg static void 3094 1.1 mrg alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[], 3095 1.1 mrg int noperands, rtx equiv) 3096 1.1 mrg { 3097 1.1 mrg rtx usage = NULL_RTX, reg; 3098 1.1 mrg int regno = 16, i; 3099 1.1 mrg 3100 1.1 mrg start_sequence (); 3101 1.1 mrg 3102 1.1 mrg for (i = 0; i < noperands; ++i) 3103 1.1 mrg { 3104 1.1 mrg switch (GET_MODE (operands[i])) 3105 1.1 mrg { 3106 1.1 mrg case E_TFmode: 3107 1.1 mrg reg = gen_rtx_REG (TFmode, regno); 3108 1.1 mrg regno += 2; 3109 1.1 mrg break; 3110 1.1 mrg 3111 1.1 mrg case E_DFmode: 3112 1.1 mrg reg = gen_rtx_REG (DFmode, regno + 32); 3113 1.1 mrg regno += 1; 3114 1.1 mrg break; 3115 1.1 mrg 3116 1.1 mrg case E_VOIDmode: 3117 1.1 mrg gcc_assert (CONST_INT_P (operands[i])); 3118 1.1 mrg /* FALLTHRU */ 3119 1.1 mrg case E_DImode: 3120 1.1 mrg reg = gen_rtx_REG (DImode, regno); 3121 1.1 mrg regno += 1; 3122 1.1 mrg break; 3123 1.1 mrg 3124 1.1 mrg default: 3125 1.1 mrg gcc_unreachable (); 3126 1.1 mrg } 3127 1.1 mrg 3128 1.1 mrg emit_move_insn (reg, operands[i]); 3129 1.1 mrg use_reg (&usage, reg); 3130 1.1 mrg } 3131 1.1 mrg 3132 1.1 mrg switch (GET_MODE (target)) 3133 1.1 mrg { 3134 1.1 mrg case E_TFmode: 3135 1.1 mrg reg = gen_rtx_REG (TFmode, 16); 3136 1.1 mrg break; 3137 1.1 mrg case E_DFmode: 3138 1.1 mrg reg = gen_rtx_REG (DFmode, 32); 3139 1.1 mrg break; 3140 1.1 mrg case E_DImode: 3141 1.1 mrg reg = gen_rtx_REG (DImode, 0); 3142 1.1 mrg break; 3143 1.1 mrg default: 3144 1.1 mrg gcc_unreachable (); 3145 1.1 mrg } 3146 1.1 mrg 3147 1.1 mrg rtx mem = gen_rtx_MEM (QImode, func); 3148 1.1 mrg rtx_insn *tmp = emit_call_insn (gen_call_value (reg, mem, const0_rtx, 3149 1.1 mrg const0_rtx, const0_rtx)); 3150 1.1 mrg CALL_INSN_FUNCTION_USAGE (tmp) = usage; 3151 1.1 mrg RTL_CONST_CALL_P (tmp) = 1; 3152 1.1 mrg 3153 1.1 mrg tmp = get_insns (); 3154 1.1 mrg end_sequence (); 3155 1.1 mrg 3156 1.1 mrg emit_libcall_block (tmp, target, reg, equiv); 3157 1.1 mrg } 3158 1.1 mrg 3159 1.1 mrg /* Emit an X_floating library function call for arithmetic (+,-,*,/). */ 3160 1.1 mrg 3161 1.1 mrg void 3162 1.1 mrg alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[]) 3163 1.1 mrg { 3164 1.1 mrg rtx func; 3165 1.1 mrg int mode; 3166 1.1 mrg rtx out_operands[3]; 3167 1.1 mrg 3168 1.1 mrg func = alpha_lookup_xfloating_lib_func (code); 3169 1.1 mrg mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm); 3170 1.1 mrg 3171 1.1 mrg out_operands[0] = operands[1]; 3172 1.1 mrg out_operands[1] = operands[2]; 3173 1.1 mrg out_operands[2] = GEN_INT (mode); 3174 1.1 mrg alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3, 3175 1.1 mrg gen_rtx_fmt_ee (code, TFmode, operands[1], 3176 1.1 mrg operands[2])); 3177 1.1 mrg } 3178 1.1 mrg 3179 1.1 mrg /* Emit an X_floating library function call for a comparison. */ 3180 1.1 mrg 3181 1.1 mrg static rtx 3182 1.1 mrg alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1) 3183 1.1 mrg { 3184 1.1 mrg enum rtx_code cmp_code, res_code; 3185 1.1 mrg rtx func, out, operands[2], note; 3186 1.1 mrg 3187 1.1 mrg /* X_floating library comparison functions return 3188 1.1 mrg -1 unordered 3189 1.1 mrg 0 false 3190 1.1 mrg 1 true 3191 1.1 mrg Convert the compare against the raw return value. */ 3192 1.1 mrg 3193 1.1 mrg cmp_code = *pcode; 3194 1.1 mrg switch (cmp_code) 3195 1.1 mrg { 3196 1.1 mrg case UNORDERED: 3197 1.1 mrg cmp_code = EQ; 3198 1.1 mrg res_code = LT; 3199 1.1 mrg break; 3200 1.1 mrg case ORDERED: 3201 1.1 mrg cmp_code = EQ; 3202 1.1 mrg res_code = GE; 3203 1.1 mrg break; 3204 1.1 mrg case NE: 3205 1.1 mrg res_code = NE; 3206 1.1 mrg break; 3207 1.1 mrg case EQ: 3208 1.1 mrg case LT: 3209 1.1 mrg case GT: 3210 1.1 mrg case LE: 3211 1.1 mrg case GE: 3212 1.1 mrg res_code = GT; 3213 1.1 mrg break; 3214 1.1 mrg default: 3215 1.1 mrg gcc_unreachable (); 3216 1.1 mrg } 3217 1.1 mrg *pcode = res_code; 3218 1.1 mrg 3219 1.1 mrg func = alpha_lookup_xfloating_lib_func (cmp_code); 3220 1.1 mrg 3221 1.1 mrg operands[0] = op0; 3222 1.1 mrg operands[1] = op1; 3223 1.1 mrg out = gen_reg_rtx (DImode); 3224 1.1 mrg 3225 1.1 mrg /* What's actually returned is -1,0,1, not a proper boolean value. */ 3226 1.1 mrg note = gen_rtx_fmt_ee (cmp_code, VOIDmode, op0, op1); 3227 1.1 mrg note = gen_rtx_UNSPEC (DImode, gen_rtvec (1, note), UNSPEC_XFLT_COMPARE); 3228 1.1 mrg alpha_emit_xfloating_libcall (func, out, operands, 2, note); 3229 1.1 mrg 3230 1.1 mrg return out; 3231 1.1 mrg } 3232 1.1 mrg 3233 1.1 mrg /* Emit an X_floating library function call for a conversion. */ 3234 1.1 mrg 3235 1.1 mrg void 3236 1.1 mrg alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[]) 3237 1.1 mrg { 3238 1.1 mrg int noperands = 1, mode; 3239 1.1 mrg rtx out_operands[2]; 3240 1.1 mrg rtx func; 3241 1.1 mrg enum rtx_code code = orig_code; 3242 1.1 mrg 3243 1.1 mrg if (code == UNSIGNED_FIX) 3244 1.1 mrg code = FIX; 3245 1.1 mrg 3246 1.1 mrg func = alpha_lookup_xfloating_lib_func (code); 3247 1.1 mrg 3248 1.1 mrg out_operands[0] = operands[1]; 3249 1.1 mrg 3250 1.1 mrg switch (code) 3251 1.1 mrg { 3252 1.1 mrg case FIX: 3253 1.1 mrg mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP); 3254 1.1 mrg out_operands[1] = GEN_INT (mode); 3255 1.1 mrg noperands = 2; 3256 1.1 mrg break; 3257 1.1 mrg case FLOAT_TRUNCATE: 3258 1.1 mrg mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm); 3259 1.1 mrg out_operands[1] = GEN_INT (mode); 3260 1.1 mrg noperands = 2; 3261 1.1 mrg break; 3262 1.1 mrg default: 3263 1.1 mrg break; 3264 1.1 mrg } 3265 1.1 mrg 3266 1.1 mrg alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands, 3267 1.1 mrg gen_rtx_fmt_e (orig_code, 3268 1.1 mrg GET_MODE (operands[0]), 3269 1.1 mrg operands[1])); 3270 1.1 mrg } 3271 1.1 mrg 3272 1.1 mrg /* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of 3273 1.1 mrg DImode moves from OP[2,3] to OP[0,1]. If FIXUP_OVERLAP is true, 3274 1.1 mrg guarantee that the sequence 3275 1.1 mrg set (OP[0] OP[2]) 3276 1.1 mrg set (OP[1] OP[3]) 3277 1.1 mrg is valid. Naturally, output operand ordering is little-endian. 3278 1.1 mrg This is used by *movtf_internal and *movti_internal. */ 3279 1.1 mrg 3280 1.1 mrg void 3281 1.1 mrg alpha_split_tmode_pair (rtx operands[4], machine_mode mode, 3282 1.1 mrg bool fixup_overlap) 3283 1.1 mrg { 3284 1.1 mrg switch (GET_CODE (operands[1])) 3285 1.1 mrg { 3286 1.1 mrg case REG: 3287 1.1 mrg operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1); 3288 1.1 mrg operands[2] = gen_rtx_REG (DImode, REGNO (operands[1])); 3289 1.1 mrg break; 3290 1.1 mrg 3291 1.1 mrg case MEM: 3292 1.1 mrg operands[3] = adjust_address (operands[1], DImode, 8); 3293 1.1 mrg operands[2] = adjust_address (operands[1], DImode, 0); 3294 1.1 mrg break; 3295 1.1 mrg 3296 1.1 mrg CASE_CONST_SCALAR_INT: 3297 1.1 mrg case CONST_DOUBLE: 3298 1.1 mrg gcc_assert (operands[1] == CONST0_RTX (mode)); 3299 1.1 mrg operands[2] = operands[3] = const0_rtx; 3300 1.1 mrg break; 3301 1.1 mrg 3302 1.1 mrg default: 3303 1.1 mrg gcc_unreachable (); 3304 1.1 mrg } 3305 1.1 mrg 3306 1.1 mrg switch (GET_CODE (operands[0])) 3307 1.1 mrg { 3308 1.1 mrg case REG: 3309 1.1 mrg operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1); 3310 1.1 mrg operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 3311 1.1 mrg break; 3312 1.1 mrg 3313 1.1 mrg case MEM: 3314 1.1 mrg operands[1] = adjust_address (operands[0], DImode, 8); 3315 1.1 mrg operands[0] = adjust_address (operands[0], DImode, 0); 3316 1.1 mrg break; 3317 1.1 mrg 3318 1.1 mrg default: 3319 1.1 mrg gcc_unreachable (); 3320 1.1 mrg } 3321 1.1 mrg 3322 1.1 mrg if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3])) 3323 1.1 mrg { 3324 1.1 mrg std::swap (operands[0], operands[1]); 3325 1.1 mrg std::swap (operands[2], operands[3]); 3326 1.1 mrg } 3327 1.1 mrg } 3328 1.1 mrg 3329 1.1 mrg /* Implement negtf2 or abstf2. Op0 is destination, op1 is source, 3330 1.1 mrg op2 is a register containing the sign bit, operation is the 3331 1.1 mrg logical operation to be performed. */ 3332 1.1 mrg 3333 1.1 mrg void 3334 1.1 mrg alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx)) 3335 1.1 mrg { 3336 1.1 mrg rtx high_bit = operands[2]; 3337 1.1 mrg rtx scratch; 3338 1.1 mrg int move; 3339 1.1 mrg 3340 1.1 mrg alpha_split_tmode_pair (operands, TFmode, false); 3341 1.1 mrg 3342 1.1 mrg /* Detect three flavors of operand overlap. */ 3343 1.1 mrg move = 1; 3344 1.1 mrg if (rtx_equal_p (operands[0], operands[2])) 3345 1.1 mrg move = 0; 3346 1.1 mrg else if (rtx_equal_p (operands[1], operands[2])) 3347 1.1 mrg { 3348 1.1 mrg if (rtx_equal_p (operands[0], high_bit)) 3349 1.1 mrg move = 2; 3350 1.1 mrg else 3351 1.1 mrg move = -1; 3352 1.1 mrg } 3353 1.1 mrg 3354 1.1 mrg if (move < 0) 3355 1.1 mrg emit_move_insn (operands[0], operands[2]); 3356 1.1 mrg 3357 1.1 mrg /* ??? If the destination overlaps both source tf and high_bit, then 3358 1.1 mrg assume source tf is dead in its entirety and use the other half 3359 1.1 mrg for a scratch register. Otherwise "scratch" is just the proper 3360 1.1 mrg destination register. */ 3361 1.1 mrg scratch = operands[move < 2 ? 1 : 3]; 3362 1.1 mrg 3363 1.1 mrg emit_insn ((*operation) (scratch, high_bit, operands[3])); 3364 1.1 mrg 3365 1.1 mrg if (move > 0) 3366 1.1 mrg { 3367 1.1 mrg emit_move_insn (operands[0], operands[2]); 3368 1.1 mrg if (move > 1) 3369 1.1 mrg emit_move_insn (operands[1], scratch); 3370 1.1 mrg } 3371 1.1 mrg } 3372 1.1 mrg 3373 1.1 mrg /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting 3375 1.1 mrg unaligned data: 3376 1.1 mrg 3377 1.1 mrg unsigned: signed: 3378 1.1 mrg word: ldq_u r1,X(r11) ldq_u r1,X(r11) 3379 1.1 mrg ldq_u r2,X+1(r11) ldq_u r2,X+1(r11) 3380 1.1 mrg lda r3,X(r11) lda r3,X+2(r11) 3381 1.1 mrg extwl r1,r3,r1 extql r1,r3,r1 3382 1.1 mrg extwh r2,r3,r2 extqh r2,r3,r2 3383 1.1 mrg or r1.r2.r1 or r1,r2,r1 3384 1.1 mrg sra r1,48,r1 3385 1.1 mrg 3386 1.1 mrg long: ldq_u r1,X(r11) ldq_u r1,X(r11) 3387 1.1 mrg ldq_u r2,X+3(r11) ldq_u r2,X+3(r11) 3388 1.1 mrg lda r3,X(r11) lda r3,X(r11) 3389 1.1 mrg extll r1,r3,r1 extll r1,r3,r1 3390 1.1 mrg extlh r2,r3,r2 extlh r2,r3,r2 3391 1.1 mrg or r1.r2.r1 addl r1,r2,r1 3392 1.1 mrg 3393 1.1 mrg quad: ldq_u r1,X(r11) 3394 1.1 mrg ldq_u r2,X+7(r11) 3395 1.1 mrg lda r3,X(r11) 3396 1.1 mrg extql r1,r3,r1 3397 1.1 mrg extqh r2,r3,r2 3398 1.1 mrg or r1.r2.r1 3399 1.1 mrg */ 3400 1.1 mrg 3401 1.1 mrg void 3402 1.1 mrg alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size, 3403 1.1 mrg HOST_WIDE_INT ofs, int sign) 3404 1.1 mrg { 3405 1.1 mrg rtx meml, memh, addr, extl, exth, tmp, mema; 3406 1.1 mrg machine_mode mode; 3407 1.1 mrg 3408 1.1 mrg if (TARGET_BWX && size == 2) 3409 1.1 mrg { 3410 1.1 mrg meml = adjust_address (mem, QImode, ofs); 3411 1.1 mrg memh = adjust_address (mem, QImode, ofs+1); 3412 1.1 mrg extl = gen_reg_rtx (DImode); 3413 1.1 mrg exth = gen_reg_rtx (DImode); 3414 1.1 mrg emit_insn (gen_zero_extendqidi2 (extl, meml)); 3415 1.1 mrg emit_insn (gen_zero_extendqidi2 (exth, memh)); 3416 1.1 mrg exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8), 3417 1.1 mrg NULL, 1, OPTAB_LIB_WIDEN); 3418 1.1 mrg addr = expand_simple_binop (DImode, IOR, extl, exth, 3419 1.1 mrg NULL, 1, OPTAB_LIB_WIDEN); 3420 1.1 mrg 3421 1.1 mrg if (sign && GET_MODE (tgt) != HImode) 3422 1.1 mrg { 3423 1.1 mrg addr = gen_lowpart (HImode, addr); 3424 1.1 mrg emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0)); 3425 1.1 mrg } 3426 1.1 mrg else 3427 1.1 mrg { 3428 1.1 mrg if (GET_MODE (tgt) != DImode) 3429 1.1 mrg addr = gen_lowpart (GET_MODE (tgt), addr); 3430 1.1 mrg emit_move_insn (tgt, addr); 3431 1.1 mrg } 3432 1.1 mrg return; 3433 1.1 mrg } 3434 1.1 mrg 3435 1.1 mrg meml = gen_reg_rtx (DImode); 3436 1.1 mrg memh = gen_reg_rtx (DImode); 3437 1.1 mrg addr = gen_reg_rtx (DImode); 3438 1.1 mrg extl = gen_reg_rtx (DImode); 3439 1.1 mrg exth = gen_reg_rtx (DImode); 3440 1.1 mrg 3441 1.1 mrg mema = XEXP (mem, 0); 3442 1.1 mrg if (GET_CODE (mema) == LO_SUM) 3443 1.1 mrg mema = force_reg (Pmode, mema); 3444 1.1 mrg 3445 1.1 mrg /* AND addresses cannot be in any alias set, since they may implicitly 3446 1.1 mrg alias surrounding code. Ideally we'd have some alias set that 3447 1.1 mrg covered all types except those with alignment 8 or higher. */ 3448 1.1 mrg 3449 1.1 mrg tmp = change_address (mem, DImode, 3450 1.1 mrg gen_rtx_AND (DImode, 3451 1.1 mrg plus_constant (DImode, mema, ofs), 3452 1.1 mrg GEN_INT (-8))); 3453 1.1 mrg set_mem_alias_set (tmp, 0); 3454 1.1 mrg emit_move_insn (meml, tmp); 3455 1.1 mrg 3456 1.1 mrg tmp = change_address (mem, DImode, 3457 1.1 mrg gen_rtx_AND (DImode, 3458 1.1 mrg plus_constant (DImode, mema, 3459 1.1 mrg ofs + size - 1), 3460 1.1 mrg GEN_INT (-8))); 3461 1.1 mrg set_mem_alias_set (tmp, 0); 3462 1.1 mrg emit_move_insn (memh, tmp); 3463 1.1 mrg 3464 1.1 mrg if (sign && size == 2) 3465 1.1 mrg { 3466 1.1 mrg emit_move_insn (addr, plus_constant (Pmode, mema, ofs+2)); 3467 1.1 mrg 3468 1.1 mrg emit_insn (gen_extql (extl, meml, addr)); 3469 1.1 mrg emit_insn (gen_extqh (exth, memh, addr)); 3470 1.1 mrg 3471 1.1 mrg /* We must use tgt here for the target. Alpha-vms port fails if we use 3472 1.1 mrg addr for the target, because addr is marked as a pointer and combine 3473 1.1 mrg knows that pointers are always sign-extended 32-bit values. */ 3474 1.1 mrg addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN); 3475 1.1 mrg addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), 3476 1.1 mrg addr, 1, OPTAB_WIDEN); 3477 1.1 mrg } 3478 1.1 mrg else 3479 1.1 mrg { 3480 1.1 mrg emit_move_insn (addr, plus_constant (Pmode, mema, ofs)); 3481 1.1 mrg emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr)); 3482 1.1 mrg switch ((int) size) 3483 1.1 mrg { 3484 1.1 mrg case 2: 3485 1.1 mrg emit_insn (gen_extwh (exth, memh, addr)); 3486 1.1 mrg mode = HImode; 3487 1.1 mrg break; 3488 1.1 mrg case 4: 3489 1.1 mrg emit_insn (gen_extlh (exth, memh, addr)); 3490 1.1 mrg mode = SImode; 3491 1.1 mrg break; 3492 1.1 mrg case 8: 3493 1.1 mrg emit_insn (gen_extqh (exth, memh, addr)); 3494 1.1 mrg mode = DImode; 3495 1.1 mrg break; 3496 1.1 mrg default: 3497 1.1 mrg gcc_unreachable (); 3498 1.1 mrg } 3499 1.1 mrg 3500 1.1 mrg addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl), 3501 1.1 mrg gen_lowpart (mode, exth), gen_lowpart (mode, tgt), 3502 1.1 mrg sign, OPTAB_WIDEN); 3503 1.1 mrg } 3504 1.1 mrg 3505 1.1 mrg if (addr != tgt) 3506 1.1 mrg emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr)); 3507 1.1 mrg } 3508 1.1 mrg 3509 1.1 mrg /* Similarly, use ins and msk instructions to perform unaligned stores. */ 3510 1.1 mrg 3511 1.1 mrg void 3512 1.1 mrg alpha_expand_unaligned_store (rtx dst, rtx src, 3513 1.1 mrg HOST_WIDE_INT size, HOST_WIDE_INT ofs) 3514 1.1 mrg { 3515 1.1 mrg rtx dstl, dsth, addr, insl, insh, meml, memh, dsta; 3516 1.1 mrg 3517 1.1 mrg if (TARGET_BWX && size == 2) 3518 1.1 mrg { 3519 1.1 mrg if (src != const0_rtx) 3520 1.1 mrg { 3521 1.1 mrg dstl = gen_lowpart (QImode, src); 3522 1.1 mrg dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8), 3523 1.1 mrg NULL, 1, OPTAB_LIB_WIDEN); 3524 1.1 mrg dsth = gen_lowpart (QImode, dsth); 3525 1.1 mrg } 3526 1.1 mrg else 3527 1.1 mrg dstl = dsth = const0_rtx; 3528 1.1 mrg 3529 1.1 mrg meml = adjust_address (dst, QImode, ofs); 3530 1.1 mrg memh = adjust_address (dst, QImode, ofs+1); 3531 1.1 mrg 3532 1.1 mrg emit_move_insn (meml, dstl); 3533 1.1 mrg emit_move_insn (memh, dsth); 3534 1.1 mrg return; 3535 1.1 mrg } 3536 1.1 mrg 3537 1.1 mrg dstl = gen_reg_rtx (DImode); 3538 1.1 mrg dsth = gen_reg_rtx (DImode); 3539 1.1 mrg insl = gen_reg_rtx (DImode); 3540 1.1 mrg insh = gen_reg_rtx (DImode); 3541 1.1 mrg 3542 1.1 mrg dsta = XEXP (dst, 0); 3543 1.1 mrg if (GET_CODE (dsta) == LO_SUM) 3544 1.1 mrg dsta = force_reg (Pmode, dsta); 3545 1.1 mrg 3546 1.1 mrg /* AND addresses cannot be in any alias set, since they may implicitly 3547 1.1 mrg alias surrounding code. Ideally we'd have some alias set that 3548 1.1 mrg covered all types except those with alignment 8 or higher. */ 3549 1.1 mrg 3550 1.1 mrg meml = change_address (dst, DImode, 3551 1.1 mrg gen_rtx_AND (DImode, 3552 1.1 mrg plus_constant (DImode, dsta, ofs), 3553 1.1 mrg GEN_INT (-8))); 3554 1.1 mrg set_mem_alias_set (meml, 0); 3555 1.1 mrg 3556 1.1 mrg memh = change_address (dst, DImode, 3557 1.1 mrg gen_rtx_AND (DImode, 3558 1.1 mrg plus_constant (DImode, dsta, 3559 1.1 mrg ofs + size - 1), 3560 1.1 mrg GEN_INT (-8))); 3561 1.1 mrg set_mem_alias_set (memh, 0); 3562 1.1 mrg 3563 1.1 mrg emit_move_insn (dsth, memh); 3564 1.1 mrg emit_move_insn (dstl, meml); 3565 1.1 mrg 3566 1.1 mrg addr = copy_addr_to_reg (plus_constant (Pmode, dsta, ofs)); 3567 1.1 mrg 3568 1.1 mrg if (src != CONST0_RTX (GET_MODE (src))) 3569 1.1 mrg { 3570 1.1 mrg emit_insn (gen_insxh (insh, gen_lowpart (DImode, src), 3571 1.1 mrg GEN_INT (size*8), addr)); 3572 1.1 mrg 3573 1.1 mrg switch ((int) size) 3574 1.1 mrg { 3575 1.1 mrg case 2: 3576 1.1 mrg emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr)); 3577 1.1 mrg break; 3578 1.1 mrg case 4: 3579 1.1 mrg emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr)); 3580 1.1 mrg break; 3581 1.1 mrg case 8: 3582 1.1 mrg emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr)); 3583 1.1 mrg break; 3584 1.1 mrg default: 3585 1.1 mrg gcc_unreachable (); 3586 1.1 mrg } 3587 1.1 mrg } 3588 1.1 mrg 3589 1.1 mrg emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr)); 3590 1.1 mrg 3591 1.1 mrg switch ((int) size) 3592 1.1 mrg { 3593 1.1 mrg case 2: 3594 1.1 mrg emit_insn (gen_mskwl (dstl, dstl, addr)); 3595 1.1 mrg break; 3596 1.1 mrg case 4: 3597 1.1 mrg emit_insn (gen_mskll (dstl, dstl, addr)); 3598 1.1 mrg break; 3599 1.1 mrg case 8: 3600 1.1 mrg emit_insn (gen_mskql (dstl, dstl, addr)); 3601 1.1 mrg break; 3602 1.1 mrg default: 3603 1.1 mrg gcc_unreachable (); 3604 1.1 mrg } 3605 1.1 mrg 3606 1.1 mrg if (src != CONST0_RTX (GET_MODE (src))) 3607 1.1 mrg { 3608 1.1 mrg dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN); 3609 1.1 mrg dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN); 3610 1.1 mrg } 3611 1.1 mrg 3612 1.1 mrg /* Must store high before low for degenerate case of aligned. */ 3613 1.1 mrg emit_move_insn (memh, dsth); 3614 1.1 mrg emit_move_insn (meml, dstl); 3615 1.1 mrg } 3616 1.1 mrg 3617 1.1 mrg /* The block move code tries to maximize speed by separating loads and 3618 1.1 mrg stores at the expense of register pressure: we load all of the data 3619 1.1 mrg before we store it back out. There are two secondary effects worth 3620 1.1 mrg mentioning, that this speeds copying to/from aligned and unaligned 3621 1.1 mrg buffers, and that it makes the code significantly easier to write. */ 3622 1.1 mrg 3623 1.1 mrg #define MAX_MOVE_WORDS 8 3624 1.1 mrg 3625 1.1 mrg /* Load an integral number of consecutive unaligned quadwords. */ 3626 1.1 mrg 3627 1.1 mrg static void 3628 1.1 mrg alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem, 3629 1.1 mrg HOST_WIDE_INT words, HOST_WIDE_INT ofs) 3630 1.1 mrg { 3631 1.1 mrg rtx const im8 = GEN_INT (-8); 3632 1.1 mrg rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1]; 3633 1.1 mrg rtx sreg, areg, tmp, smema; 3634 1.1 mrg HOST_WIDE_INT i; 3635 1.1 mrg 3636 1.1 mrg smema = XEXP (smem, 0); 3637 1.1 mrg if (GET_CODE (smema) == LO_SUM) 3638 1.1 mrg smema = force_reg (Pmode, smema); 3639 1.1 mrg 3640 1.1 mrg /* Generate all the tmp registers we need. */ 3641 1.1 mrg for (i = 0; i < words; ++i) 3642 1.1 mrg { 3643 1.1 mrg data_regs[i] = out_regs[i]; 3644 1.1 mrg ext_tmps[i] = gen_reg_rtx (DImode); 3645 1.1 mrg } 3646 1.1 mrg data_regs[words] = gen_reg_rtx (DImode); 3647 1.1 mrg 3648 1.1 mrg if (ofs != 0) 3649 1.1 mrg smem = adjust_address (smem, GET_MODE (smem), ofs); 3650 1.1 mrg 3651 1.1 mrg /* Load up all of the source data. */ 3652 1.1 mrg for (i = 0; i < words; ++i) 3653 1.1 mrg { 3654 1.1 mrg tmp = change_address (smem, DImode, 3655 1.1 mrg gen_rtx_AND (DImode, 3656 1.1 mrg plus_constant (DImode, smema, 8*i), 3657 1.1 mrg im8)); 3658 1.1 mrg set_mem_alias_set (tmp, 0); 3659 1.1 mrg emit_move_insn (data_regs[i], tmp); 3660 1.1 mrg } 3661 1.1 mrg 3662 1.1 mrg tmp = change_address (smem, DImode, 3663 1.1 mrg gen_rtx_AND (DImode, 3664 1.1 mrg plus_constant (DImode, smema, 3665 1.1 mrg 8*words - 1), 3666 1.1 mrg im8)); 3667 1.1 mrg set_mem_alias_set (tmp, 0); 3668 1.1 mrg emit_move_insn (data_regs[words], tmp); 3669 1.1 mrg 3670 1.1 mrg /* Extract the half-word fragments. Unfortunately DEC decided to make 3671 1.1 mrg extxh with offset zero a noop instead of zeroing the register, so 3672 1.1 mrg we must take care of that edge condition ourselves with cmov. */ 3673 1.1 mrg 3674 1.1 mrg sreg = copy_addr_to_reg (smema); 3675 1.1 mrg areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, 3676 1.1 mrg 1, OPTAB_WIDEN); 3677 1.1 mrg for (i = 0; i < words; ++i) 3678 1.1 mrg { 3679 1.1 mrg emit_insn (gen_extql (data_regs[i], data_regs[i], sreg)); 3680 1.1 mrg emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg)); 3681 1.1 mrg emit_insn (gen_rtx_SET (ext_tmps[i], 3682 1.1 mrg gen_rtx_IF_THEN_ELSE (DImode, 3683 1.1 mrg gen_rtx_EQ (DImode, areg, 3684 1.1 mrg const0_rtx), 3685 1.1 mrg const0_rtx, ext_tmps[i]))); 3686 1.1 mrg } 3687 1.1 mrg 3688 1.1 mrg /* Merge the half-words into whole words. */ 3689 1.1 mrg for (i = 0; i < words; ++i) 3690 1.1 mrg { 3691 1.1 mrg out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i], 3692 1.1 mrg ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN); 3693 1.1 mrg } 3694 1.1 mrg } 3695 1.1 mrg 3696 1.1 mrg /* Store an integral number of consecutive unaligned quadwords. DATA_REGS 3697 1.1 mrg may be NULL to store zeros. */ 3698 1.1 mrg 3699 1.1 mrg static void 3700 1.1 mrg alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem, 3701 1.1 mrg HOST_WIDE_INT words, HOST_WIDE_INT ofs) 3702 1.1 mrg { 3703 1.1 mrg rtx const im8 = GEN_INT (-8); 3704 1.1 mrg rtx ins_tmps[MAX_MOVE_WORDS]; 3705 1.1 mrg rtx st_tmp_1, st_tmp_2, dreg; 3706 1.1 mrg rtx st_addr_1, st_addr_2, dmema; 3707 1.1 mrg HOST_WIDE_INT i; 3708 1.1 mrg 3709 1.1 mrg dmema = XEXP (dmem, 0); 3710 1.1 mrg if (GET_CODE (dmema) == LO_SUM) 3711 1.1 mrg dmema = force_reg (Pmode, dmema); 3712 1.1 mrg 3713 1.1 mrg /* Generate all the tmp registers we need. */ 3714 1.1 mrg if (data_regs != NULL) 3715 1.1 mrg for (i = 0; i < words; ++i) 3716 1.1 mrg ins_tmps[i] = gen_reg_rtx(DImode); 3717 1.1 mrg st_tmp_1 = gen_reg_rtx(DImode); 3718 1.1 mrg st_tmp_2 = gen_reg_rtx(DImode); 3719 1.1 mrg 3720 1.1 mrg if (ofs != 0) 3721 1.1 mrg dmem = adjust_address (dmem, GET_MODE (dmem), ofs); 3722 1.1 mrg 3723 1.1 mrg st_addr_2 = change_address (dmem, DImode, 3724 1.1 mrg gen_rtx_AND (DImode, 3725 1.1 mrg plus_constant (DImode, dmema, 3726 1.1 mrg words*8 - 1), 3727 1.1 mrg im8)); 3728 1.1 mrg set_mem_alias_set (st_addr_2, 0); 3729 1.1 mrg 3730 1.1 mrg st_addr_1 = change_address (dmem, DImode, 3731 1.1 mrg gen_rtx_AND (DImode, dmema, im8)); 3732 1.1 mrg set_mem_alias_set (st_addr_1, 0); 3733 1.1 mrg 3734 1.1 mrg /* Load up the destination end bits. */ 3735 1.1 mrg emit_move_insn (st_tmp_2, st_addr_2); 3736 1.1 mrg emit_move_insn (st_tmp_1, st_addr_1); 3737 1.1 mrg 3738 1.1 mrg /* Shift the input data into place. */ 3739 1.1 mrg dreg = copy_addr_to_reg (dmema); 3740 1.1 mrg if (data_regs != NULL) 3741 1.1 mrg { 3742 1.1 mrg for (i = words-1; i >= 0; --i) 3743 1.1 mrg { 3744 1.1 mrg emit_insn (gen_insqh (ins_tmps[i], data_regs[i], dreg)); 3745 1.1 mrg emit_insn (gen_insql (data_regs[i], data_regs[i], dreg)); 3746 1.1 mrg } 3747 1.1 mrg for (i = words-1; i > 0; --i) 3748 1.1 mrg { 3749 1.1 mrg ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i], 3750 1.1 mrg ins_tmps[i-1], ins_tmps[i-1], 1, 3751 1.1 mrg OPTAB_WIDEN); 3752 1.1 mrg } 3753 1.1 mrg } 3754 1.1 mrg 3755 1.1 mrg /* Split and merge the ends with the destination data. */ 3756 1.1 mrg emit_insn (gen_mskqh (st_tmp_2, st_tmp_2, dreg)); 3757 1.1 mrg emit_insn (gen_mskql (st_tmp_1, st_tmp_1, dreg)); 3758 1.1 mrg 3759 1.1 mrg if (data_regs != NULL) 3760 1.1 mrg { 3761 1.1 mrg st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1], 3762 1.1 mrg st_tmp_2, 1, OPTAB_WIDEN); 3763 1.1 mrg st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0], 3764 1.1 mrg st_tmp_1, 1, OPTAB_WIDEN); 3765 1.1 mrg } 3766 1.1 mrg 3767 1.1 mrg /* Store it all. */ 3768 1.1 mrg emit_move_insn (st_addr_2, st_tmp_2); 3769 1.1 mrg for (i = words-1; i > 0; --i) 3770 1.1 mrg { 3771 1.1 mrg rtx tmp = change_address (dmem, DImode, 3772 1.1 mrg gen_rtx_AND (DImode, 3773 1.1 mrg plus_constant (DImode, 3774 1.1 mrg dmema, i*8), 3775 1.1 mrg im8)); 3776 1.1 mrg set_mem_alias_set (tmp, 0); 3777 1.1 mrg emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx); 3778 1.1 mrg } 3779 1.1 mrg emit_move_insn (st_addr_1, st_tmp_1); 3780 1.1 mrg } 3781 1.1 mrg 3782 1.1 mrg 3783 1.1 mrg /* Expand string/block move operations. 3784 1.1 mrg 3785 1.1 mrg operands[0] is the pointer to the destination. 3786 1.1 mrg operands[1] is the pointer to the source. 3787 1.1 mrg operands[2] is the number of bytes to move. 3788 1.1 mrg operands[3] is the alignment. */ 3789 1.1 mrg 3790 1.1 mrg int 3791 1.1 mrg alpha_expand_block_move (rtx operands[]) 3792 1.1 mrg { 3793 1.1 mrg rtx bytes_rtx = operands[2]; 3794 1.1 mrg rtx align_rtx = operands[3]; 3795 1.1 mrg HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); 3796 1.1 mrg HOST_WIDE_INT bytes = orig_bytes; 3797 1.1 mrg HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT; 3798 1.1 mrg HOST_WIDE_INT dst_align = src_align; 3799 1.1 mrg rtx orig_src = operands[1]; 3800 1.1 mrg rtx orig_dst = operands[0]; 3801 1.1 mrg rtx data_regs[2 * MAX_MOVE_WORDS + 16]; 3802 1.1 mrg rtx tmp; 3803 1.1 mrg unsigned int i, words, ofs, nregs = 0; 3804 1.1 mrg 3805 1.1 mrg if (orig_bytes <= 0) 3806 1.1 mrg return 1; 3807 1.1 mrg else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD) 3808 1.1 mrg return 0; 3809 1.1 mrg 3810 1.1 mrg /* Look for additional alignment information from recorded register info. */ 3811 1.1 mrg 3812 1.1 mrg tmp = XEXP (orig_src, 0); 3813 1.1 mrg if (REG_P (tmp)) 3814 1.1 mrg src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp))); 3815 1.1 mrg else if (GET_CODE (tmp) == PLUS 3816 1.1 mrg && REG_P (XEXP (tmp, 0)) 3817 1.1 mrg && CONST_INT_P (XEXP (tmp, 1))) 3818 1.1 mrg { 3819 1.1 mrg unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); 3820 1.1 mrg unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); 3821 1.1 mrg 3822 1.1 mrg if (a > src_align) 3823 1.1 mrg { 3824 1.1 mrg if (a >= 64 && c % 8 == 0) 3825 1.1 mrg src_align = 64; 3826 1.1 mrg else if (a >= 32 && c % 4 == 0) 3827 1.1 mrg src_align = 32; 3828 1.1 mrg else if (a >= 16 && c % 2 == 0) 3829 1.1 mrg src_align = 16; 3830 1.1 mrg } 3831 1.1 mrg } 3832 1.1 mrg 3833 1.1 mrg tmp = XEXP (orig_dst, 0); 3834 1.1 mrg if (REG_P (tmp)) 3835 1.1 mrg dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp))); 3836 1.1 mrg else if (GET_CODE (tmp) == PLUS 3837 1.1 mrg && REG_P (XEXP (tmp, 0)) 3838 1.1 mrg && CONST_INT_P (XEXP (tmp, 1))) 3839 1.1 mrg { 3840 1.1 mrg unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); 3841 1.1 mrg unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); 3842 1.1 mrg 3843 1.1 mrg if (a > dst_align) 3844 1.1 mrg { 3845 1.1 mrg if (a >= 64 && c % 8 == 0) 3846 1.1 mrg dst_align = 64; 3847 1.1 mrg else if (a >= 32 && c % 4 == 0) 3848 1.1 mrg dst_align = 32; 3849 1.1 mrg else if (a >= 16 && c % 2 == 0) 3850 1.1 mrg dst_align = 16; 3851 1.1 mrg } 3852 1.1 mrg } 3853 1.1 mrg 3854 1.1 mrg ofs = 0; 3855 1.1 mrg if (src_align >= 64 && bytes >= 8) 3856 1.1 mrg { 3857 1.1 mrg words = bytes / 8; 3858 1.1 mrg 3859 1.1 mrg for (i = 0; i < words; ++i) 3860 1.1 mrg data_regs[nregs + i] = gen_reg_rtx (DImode); 3861 1.1 mrg 3862 1.1 mrg for (i = 0; i < words; ++i) 3863 1.1 mrg emit_move_insn (data_regs[nregs + i], 3864 1.1 mrg adjust_address (orig_src, DImode, ofs + i * 8)); 3865 1.1 mrg 3866 1.1 mrg nregs += words; 3867 1.1 mrg bytes -= words * 8; 3868 1.1 mrg ofs += words * 8; 3869 1.1 mrg } 3870 1.1 mrg 3871 1.1 mrg if (src_align >= 32 && bytes >= 4) 3872 1.1 mrg { 3873 1.1 mrg words = bytes / 4; 3874 1.1 mrg 3875 1.1 mrg for (i = 0; i < words; ++i) 3876 1.1 mrg data_regs[nregs + i] = gen_reg_rtx (SImode); 3877 1.1 mrg 3878 1.1 mrg for (i = 0; i < words; ++i) 3879 1.1 mrg emit_move_insn (data_regs[nregs + i], 3880 1.1 mrg adjust_address (orig_src, SImode, ofs + i * 4)); 3881 1.1 mrg 3882 1.1 mrg nregs += words; 3883 1.1 mrg bytes -= words * 4; 3884 1.1 mrg ofs += words * 4; 3885 1.1 mrg } 3886 1.1 mrg 3887 1.1 mrg if (bytes >= 8) 3888 1.1 mrg { 3889 1.1 mrg words = bytes / 8; 3890 1.1 mrg 3891 1.1 mrg for (i = 0; i < words+1; ++i) 3892 1.1 mrg data_regs[nregs + i] = gen_reg_rtx (DImode); 3893 1.1 mrg 3894 1.1 mrg alpha_expand_unaligned_load_words (data_regs + nregs, orig_src, 3895 1.1 mrg words, ofs); 3896 1.1 mrg 3897 1.1 mrg nregs += words; 3898 1.1 mrg bytes -= words * 8; 3899 1.1 mrg ofs += words * 8; 3900 1.1 mrg } 3901 1.1 mrg 3902 1.1 mrg if (! TARGET_BWX && bytes >= 4) 3903 1.1 mrg { 3904 1.1 mrg data_regs[nregs++] = tmp = gen_reg_rtx (SImode); 3905 1.1 mrg alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0); 3906 1.1 mrg bytes -= 4; 3907 1.1 mrg ofs += 4; 3908 1.1 mrg } 3909 1.1 mrg 3910 1.1 mrg if (bytes >= 2) 3911 1.1 mrg { 3912 1.1 mrg if (src_align >= 16) 3913 1.1 mrg { 3914 1.1 mrg do { 3915 1.1 mrg data_regs[nregs++] = tmp = gen_reg_rtx (HImode); 3916 1.1 mrg emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs)); 3917 1.1 mrg bytes -= 2; 3918 1.1 mrg ofs += 2; 3919 1.1 mrg } while (bytes >= 2); 3920 1.1 mrg } 3921 1.1 mrg else if (! TARGET_BWX) 3922 1.1 mrg { 3923 1.1 mrg data_regs[nregs++] = tmp = gen_reg_rtx (HImode); 3924 1.1 mrg alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0); 3925 1.1 mrg bytes -= 2; 3926 1.1 mrg ofs += 2; 3927 1.1 mrg } 3928 1.1 mrg } 3929 1.1 mrg 3930 1.1 mrg while (bytes > 0) 3931 1.1 mrg { 3932 1.1 mrg data_regs[nregs++] = tmp = gen_reg_rtx (QImode); 3933 1.1 mrg emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs)); 3934 1.1 mrg bytes -= 1; 3935 1.1 mrg ofs += 1; 3936 1.1 mrg } 3937 1.1 mrg 3938 1.1 mrg gcc_assert (nregs <= ARRAY_SIZE (data_regs)); 3939 1.1 mrg 3940 1.1 mrg /* Now save it back out again. */ 3941 1.1 mrg 3942 1.1 mrg i = 0, ofs = 0; 3943 1.1 mrg 3944 1.1 mrg /* Write out the data in whatever chunks reading the source allowed. */ 3945 1.1 mrg if (dst_align >= 64) 3946 1.1 mrg { 3947 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == DImode) 3948 1.1 mrg { 3949 1.1 mrg emit_move_insn (adjust_address (orig_dst, DImode, ofs), 3950 1.1 mrg data_regs[i]); 3951 1.1 mrg ofs += 8; 3952 1.1 mrg i++; 3953 1.1 mrg } 3954 1.1 mrg } 3955 1.1 mrg 3956 1.1 mrg if (dst_align >= 32) 3957 1.1 mrg { 3958 1.1 mrg /* If the source has remaining DImode regs, write them out in 3959 1.1 mrg two pieces. */ 3960 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == DImode) 3961 1.1 mrg { 3962 1.1 mrg tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32), 3963 1.1 mrg NULL_RTX, 1, OPTAB_WIDEN); 3964 1.1 mrg 3965 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs), 3966 1.1 mrg gen_lowpart (SImode, data_regs[i])); 3967 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4), 3968 1.1 mrg gen_lowpart (SImode, tmp)); 3969 1.1 mrg ofs += 8; 3970 1.1 mrg i++; 3971 1.1 mrg } 3972 1.1 mrg 3973 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == SImode) 3974 1.1 mrg { 3975 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs), 3976 1.1 mrg data_regs[i]); 3977 1.1 mrg ofs += 4; 3978 1.1 mrg i++; 3979 1.1 mrg } 3980 1.1 mrg } 3981 1.1 mrg 3982 1.1 mrg if (i < nregs && GET_MODE (data_regs[i]) == DImode) 3983 1.1 mrg { 3984 1.1 mrg /* Write out a remaining block of words using unaligned methods. */ 3985 1.1 mrg 3986 1.1 mrg for (words = 1; i + words < nregs; words++) 3987 1.1 mrg if (GET_MODE (data_regs[i + words]) != DImode) 3988 1.1 mrg break; 3989 1.1 mrg 3990 1.1 mrg if (words == 1) 3991 1.1 mrg alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs); 3992 1.1 mrg else 3993 1.1 mrg alpha_expand_unaligned_store_words (data_regs + i, orig_dst, 3994 1.1 mrg words, ofs); 3995 1.1 mrg 3996 1.1 mrg i += words; 3997 1.1 mrg ofs += words * 8; 3998 1.1 mrg } 3999 1.1 mrg 4000 1.1 mrg /* Due to the above, this won't be aligned. */ 4001 1.1 mrg /* ??? If we have more than one of these, consider constructing full 4002 1.1 mrg words in registers and using alpha_expand_unaligned_store_words. */ 4003 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == SImode) 4004 1.1 mrg { 4005 1.1 mrg alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs); 4006 1.1 mrg ofs += 4; 4007 1.1 mrg i++; 4008 1.1 mrg } 4009 1.1 mrg 4010 1.1 mrg if (dst_align >= 16) 4011 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == HImode) 4012 1.1 mrg { 4013 1.1 mrg emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]); 4014 1.1 mrg i++; 4015 1.1 mrg ofs += 2; 4016 1.1 mrg } 4017 1.1 mrg else 4018 1.1 mrg while (i < nregs && GET_MODE (data_regs[i]) == HImode) 4019 1.1 mrg { 4020 1.1 mrg alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs); 4021 1.1 mrg i++; 4022 1.1 mrg ofs += 2; 4023 1.1 mrg } 4024 1.1 mrg 4025 1.1 mrg /* The remainder must be byte copies. */ 4026 1.1 mrg while (i < nregs) 4027 1.1 mrg { 4028 1.1 mrg gcc_assert (GET_MODE (data_regs[i]) == QImode); 4029 1.1 mrg emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]); 4030 1.1 mrg i++; 4031 1.1 mrg ofs += 1; 4032 1.1 mrg } 4033 1.1 mrg 4034 1.1 mrg return 1; 4035 1.1 mrg } 4036 1.1 mrg 4037 1.1 mrg int 4038 1.1 mrg alpha_expand_block_clear (rtx operands[]) 4039 1.1 mrg { 4040 1.1 mrg rtx bytes_rtx = operands[1]; 4041 1.1 mrg rtx align_rtx = operands[3]; 4042 1.1 mrg HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); 4043 1.1 mrg HOST_WIDE_INT bytes = orig_bytes; 4044 1.1 mrg HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT; 4045 1.1 mrg HOST_WIDE_INT alignofs = 0; 4046 1.1 mrg rtx orig_dst = operands[0]; 4047 1.1 mrg rtx tmp; 4048 1.1 mrg int i, words, ofs = 0; 4049 1.1 mrg 4050 1.1 mrg if (orig_bytes <= 0) 4051 1.1 mrg return 1; 4052 1.1 mrg if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD) 4053 1.1 mrg return 0; 4054 1.1 mrg 4055 1.1 mrg /* Look for stricter alignment. */ 4056 1.1 mrg tmp = XEXP (orig_dst, 0); 4057 1.1 mrg if (REG_P (tmp)) 4058 1.1 mrg align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp))); 4059 1.1 mrg else if (GET_CODE (tmp) == PLUS 4060 1.1 mrg && REG_P (XEXP (tmp, 0)) 4061 1.1 mrg && CONST_INT_P (XEXP (tmp, 1))) 4062 1.1 mrg { 4063 1.1 mrg HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); 4064 1.1 mrg int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); 4065 1.1 mrg 4066 1.1 mrg if (a > align) 4067 1.1 mrg { 4068 1.1 mrg if (a >= 64) 4069 1.1 mrg align = a, alignofs = 8 - c % 8; 4070 1.1 mrg else if (a >= 32) 4071 1.1 mrg align = a, alignofs = 4 - c % 4; 4072 1.1 mrg else if (a >= 16) 4073 1.1 mrg align = a, alignofs = 2 - c % 2; 4074 1.1 mrg } 4075 1.1 mrg } 4076 1.1 mrg 4077 1.1 mrg /* Handle an unaligned prefix first. */ 4078 1.1 mrg 4079 1.1 mrg if (alignofs > 0) 4080 1.1 mrg { 4081 1.1 mrg /* Given that alignofs is bounded by align, the only time BWX could 4082 1.1 mrg generate three stores is for a 7 byte fill. Prefer two individual 4083 1.1 mrg stores over a load/mask/store sequence. */ 4084 1.1 mrg if ((!TARGET_BWX || alignofs == 7) 4085 1.1 mrg && align >= 32 4086 1.1 mrg && !(alignofs == 4 && bytes >= 4)) 4087 1.1 mrg { 4088 1.1 mrg machine_mode mode = (align >= 64 ? DImode : SImode); 4089 1.1 mrg int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs; 4090 1.1 mrg rtx mem, tmp; 4091 1.1 mrg HOST_WIDE_INT mask; 4092 1.1 mrg 4093 1.1 mrg mem = adjust_address (orig_dst, mode, ofs - inv_alignofs); 4094 1.1 mrg set_mem_alias_set (mem, 0); 4095 1.1 mrg 4096 1.1 mrg mask = ~(HOST_WIDE_INT_M1U << (inv_alignofs * 8)); 4097 1.1 mrg if (bytes < alignofs) 4098 1.1 mrg { 4099 1.1 mrg mask |= HOST_WIDE_INT_M1U << ((inv_alignofs + bytes) * 8); 4100 1.1 mrg ofs += bytes; 4101 1.1 mrg bytes = 0; 4102 1.1 mrg } 4103 1.1 mrg else 4104 1.1 mrg { 4105 1.1 mrg bytes -= alignofs; 4106 1.1 mrg ofs += alignofs; 4107 1.1 mrg } 4108 1.1 mrg alignofs = 0; 4109 1.1 mrg 4110 1.1 mrg tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask), 4111 1.1 mrg NULL_RTX, 1, OPTAB_WIDEN); 4112 1.1 mrg 4113 1.1 mrg emit_move_insn (mem, tmp); 4114 1.1 mrg } 4115 1.1 mrg 4116 1.1 mrg if (TARGET_BWX && (alignofs & 1) && bytes >= 1) 4117 1.1 mrg { 4118 1.1 mrg emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx); 4119 1.1 mrg bytes -= 1; 4120 1.1 mrg ofs += 1; 4121 1.1 mrg alignofs -= 1; 4122 1.1 mrg } 4123 1.1 mrg if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2) 4124 1.1 mrg { 4125 1.1 mrg emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx); 4126 1.1 mrg bytes -= 2; 4127 1.1 mrg ofs += 2; 4128 1.1 mrg alignofs -= 2; 4129 1.1 mrg } 4130 1.1 mrg if (alignofs == 4 && bytes >= 4) 4131 1.1 mrg { 4132 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx); 4133 1.1 mrg bytes -= 4; 4134 1.1 mrg ofs += 4; 4135 1.1 mrg alignofs = 0; 4136 1.1 mrg } 4137 1.1 mrg 4138 1.1 mrg /* If we've not used the extra lead alignment information by now, 4139 1.1 mrg we won't be able to. Downgrade align to match what's left over. */ 4140 1.1 mrg if (alignofs > 0) 4141 1.1 mrg { 4142 1.1 mrg alignofs = alignofs & -alignofs; 4143 1.1 mrg align = MIN (align, alignofs * BITS_PER_UNIT); 4144 1.1 mrg } 4145 1.1 mrg } 4146 1.1 mrg 4147 1.1 mrg /* Handle a block of contiguous long-words. */ 4148 1.1 mrg 4149 1.1 mrg if (align >= 64 && bytes >= 8) 4150 1.1 mrg { 4151 1.1 mrg words = bytes / 8; 4152 1.1 mrg 4153 1.1 mrg for (i = 0; i < words; ++i) 4154 1.1 mrg emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8), 4155 1.1 mrg const0_rtx); 4156 1.1 mrg 4157 1.1 mrg bytes -= words * 8; 4158 1.1 mrg ofs += words * 8; 4159 1.1 mrg } 4160 1.1 mrg 4161 1.1 mrg /* If the block is large and appropriately aligned, emit a single 4162 1.1 mrg store followed by a sequence of stq_u insns. */ 4163 1.1 mrg 4164 1.1 mrg if (align >= 32 && bytes > 16) 4165 1.1 mrg { 4166 1.1 mrg rtx orig_dsta; 4167 1.1 mrg 4168 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx); 4169 1.1 mrg bytes -= 4; 4170 1.1 mrg ofs += 4; 4171 1.1 mrg 4172 1.1 mrg orig_dsta = XEXP (orig_dst, 0); 4173 1.1 mrg if (GET_CODE (orig_dsta) == LO_SUM) 4174 1.1 mrg orig_dsta = force_reg (Pmode, orig_dsta); 4175 1.1 mrg 4176 1.1 mrg words = bytes / 8; 4177 1.1 mrg for (i = 0; i < words; ++i) 4178 1.1 mrg { 4179 1.1 mrg rtx mem 4180 1.1 mrg = change_address (orig_dst, DImode, 4181 1.1 mrg gen_rtx_AND (DImode, 4182 1.1 mrg plus_constant (DImode, orig_dsta, 4183 1.1 mrg ofs + i*8), 4184 1.1 mrg GEN_INT (-8))); 4185 1.1 mrg set_mem_alias_set (mem, 0); 4186 1.1 mrg emit_move_insn (mem, const0_rtx); 4187 1.1 mrg } 4188 1.1 mrg 4189 1.1 mrg /* Depending on the alignment, the first stq_u may have overlapped 4190 1.1 mrg with the initial stl, which means that the last stq_u didn't 4191 1.1 mrg write as much as it would appear. Leave those questionable bytes 4192 1.1 mrg unaccounted for. */ 4193 1.1 mrg bytes -= words * 8 - 4; 4194 1.1 mrg ofs += words * 8 - 4; 4195 1.1 mrg } 4196 1.1 mrg 4197 1.1 mrg /* Handle a smaller block of aligned words. */ 4198 1.1 mrg 4199 1.1 mrg if ((align >= 64 && bytes == 4) 4200 1.1 mrg || (align == 32 && bytes >= 4)) 4201 1.1 mrg { 4202 1.1 mrg words = bytes / 4; 4203 1.1 mrg 4204 1.1 mrg for (i = 0; i < words; ++i) 4205 1.1 mrg emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4), 4206 1.1 mrg const0_rtx); 4207 1.1 mrg 4208 1.1 mrg bytes -= words * 4; 4209 1.1 mrg ofs += words * 4; 4210 1.1 mrg } 4211 1.1 mrg 4212 1.1 mrg /* An unaligned block uses stq_u stores for as many as possible. */ 4213 1.1 mrg 4214 1.1 mrg if (bytes >= 8) 4215 1.1 mrg { 4216 1.1 mrg words = bytes / 8; 4217 1.1 mrg 4218 1.1 mrg alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs); 4219 1.1 mrg 4220 1.1 mrg bytes -= words * 8; 4221 1.1 mrg ofs += words * 8; 4222 1.1 mrg } 4223 1.1 mrg 4224 1.1 mrg /* Next clean up any trailing pieces. */ 4225 1.1 mrg 4226 1.1 mrg /* Count the number of bits in BYTES for which aligned stores could 4227 1.1 mrg be emitted. */ 4228 1.1 mrg words = 0; 4229 1.1 mrg for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1) 4230 1.1 mrg if (bytes & i) 4231 1.1 mrg words += 1; 4232 1.1 mrg 4233 1.1 mrg /* If we have appropriate alignment (and it wouldn't take too many 4234 1.1 mrg instructions otherwise), mask out the bytes we need. */ 4235 1.1 mrg if (TARGET_BWX ? words > 2 : bytes > 0) 4236 1.1 mrg { 4237 1.1 mrg if (align >= 64) 4238 1.1 mrg { 4239 1.1 mrg rtx mem, tmp; 4240 1.1 mrg HOST_WIDE_INT mask; 4241 1.1 mrg 4242 1.1 mrg mem = adjust_address (orig_dst, DImode, ofs); 4243 1.1 mrg set_mem_alias_set (mem, 0); 4244 1.1 mrg 4245 1.1 mrg mask = HOST_WIDE_INT_M1U << (bytes * 8); 4246 1.1 mrg 4247 1.1 mrg tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask), 4248 1.1 mrg NULL_RTX, 1, OPTAB_WIDEN); 4249 1.1 mrg 4250 1.1 mrg emit_move_insn (mem, tmp); 4251 1.1 mrg return 1; 4252 1.1 mrg } 4253 1.1 mrg else if (align >= 32 && bytes < 4) 4254 1.1 mrg { 4255 1.1 mrg rtx mem, tmp; 4256 1.1 mrg HOST_WIDE_INT mask; 4257 1.1 mrg 4258 1.1 mrg mem = adjust_address (orig_dst, SImode, ofs); 4259 1.1 mrg set_mem_alias_set (mem, 0); 4260 1.1 mrg 4261 1.1 mrg mask = HOST_WIDE_INT_M1U << (bytes * 8); 4262 1.1 mrg 4263 1.1 mrg tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask), 4264 1.1 mrg NULL_RTX, 1, OPTAB_WIDEN); 4265 1.1 mrg 4266 1.1 mrg emit_move_insn (mem, tmp); 4267 1.1 mrg return 1; 4268 1.1 mrg } 4269 1.1 mrg } 4270 1.1 mrg 4271 1.1 mrg if (!TARGET_BWX && bytes >= 4) 4272 1.1 mrg { 4273 1.1 mrg alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs); 4274 1.1 mrg bytes -= 4; 4275 1.1 mrg ofs += 4; 4276 1.1 mrg } 4277 1.1 mrg 4278 1.1 mrg if (bytes >= 2) 4279 1.1 mrg { 4280 1.1 mrg if (align >= 16) 4281 1.1 mrg { 4282 1.1 mrg do { 4283 1.1 mrg emit_move_insn (adjust_address (orig_dst, HImode, ofs), 4284 1.1 mrg const0_rtx); 4285 1.1 mrg bytes -= 2; 4286 1.1 mrg ofs += 2; 4287 1.1 mrg } while (bytes >= 2); 4288 1.1 mrg } 4289 1.1 mrg else if (! TARGET_BWX) 4290 1.1 mrg { 4291 1.1 mrg alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs); 4292 1.1 mrg bytes -= 2; 4293 1.1 mrg ofs += 2; 4294 1.1 mrg } 4295 1.1 mrg } 4296 1.1 mrg 4297 1.1 mrg while (bytes > 0) 4298 1.1 mrg { 4299 1.1 mrg emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx); 4300 1.1 mrg bytes -= 1; 4301 1.1 mrg ofs += 1; 4302 1.1 mrg } 4303 1.1 mrg 4304 1.1 mrg return 1; 4305 1.1 mrg } 4306 1.1 mrg 4307 1.1 mrg /* Returns a mask so that zap(x, value) == x & mask. */ 4308 1.1 mrg 4309 1.1 mrg rtx 4310 1.1 mrg alpha_expand_zap_mask (HOST_WIDE_INT value) 4311 1.1 mrg { 4312 1.1 mrg rtx result; 4313 1.1 mrg int i; 4314 1.1 mrg HOST_WIDE_INT mask = 0; 4315 1.1 mrg 4316 1.1 mrg for (i = 7; i >= 0; --i) 4317 1.1 mrg { 4318 1.1 mrg mask <<= 8; 4319 1.1 mrg if (!((value >> i) & 1)) 4320 1.1 mrg mask |= 0xff; 4321 1.1 mrg } 4322 1.1 mrg 4323 1.1 mrg result = gen_int_mode (mask, DImode); 4324 1.1 mrg return result; 4325 1.1 mrg } 4326 1.1 mrg 4327 1.1 mrg void 4328 1.1 mrg alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx), 4329 1.1 mrg machine_mode mode, 4330 1.1 mrg rtx op0, rtx op1, rtx op2) 4331 1.1 mrg { 4332 1.1 mrg op0 = gen_lowpart (mode, op0); 4333 1.1 mrg 4334 1.1 mrg if (op1 == const0_rtx) 4335 1.1 mrg op1 = CONST0_RTX (mode); 4336 1.1 mrg else 4337 1.1 mrg op1 = gen_lowpart (mode, op1); 4338 1.1 mrg 4339 1.1 mrg if (op2 == const0_rtx) 4340 1.1 mrg op2 = CONST0_RTX (mode); 4341 1.1 mrg else 4342 1.1 mrg op2 = gen_lowpart (mode, op2); 4343 1.1 mrg 4344 1.1 mrg emit_insn ((*gen) (op0, op1, op2)); 4345 1.1 mrg } 4346 1.1 mrg 4347 1.1 mrg /* A subroutine of the atomic operation splitters. Jump to LABEL if 4348 1.1 mrg COND is true. Mark the jump as unlikely to be taken. */ 4349 1.1 mrg 4350 1.1 mrg static void 4351 1.1 mrg emit_unlikely_jump (rtx cond, rtx label) 4352 1.1 mrg { 4353 1.1 mrg rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx); 4354 1.1 mrg rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x)); 4355 1.1 mrg add_reg_br_prob_note (insn, profile_probability::very_unlikely ()); 4356 1.1 mrg } 4357 1.1 mrg 4358 1.1 mrg /* Subroutines of the atomic operation splitters. Emit barriers 4359 1.1 mrg as needed for the memory MODEL. */ 4360 1.1 mrg 4361 1.1 mrg static void 4362 1.1 mrg alpha_pre_atomic_barrier (enum memmodel model) 4363 1.1 mrg { 4364 1.1 mrg if (need_atomic_barrier_p (model, true)) 4365 1.1 mrg emit_insn (gen_memory_barrier ()); 4366 1.1 mrg } 4367 1.1 mrg 4368 1.1 mrg static void 4369 1.1 mrg alpha_post_atomic_barrier (enum memmodel model) 4370 1.1 mrg { 4371 1.1 mrg if (need_atomic_barrier_p (model, false)) 4372 1.1 mrg emit_insn (gen_memory_barrier ()); 4373 1.1 mrg } 4374 1.1 mrg 4375 1.1 mrg /* A subroutine of the atomic operation splitters. Emit an insxl 4376 1.1 mrg instruction in MODE. */ 4377 1.1 mrg 4378 1.1 mrg static rtx 4379 1.1 mrg emit_insxl (machine_mode mode, rtx op1, rtx op2) 4380 1.1 mrg { 4381 1.1 mrg rtx ret = gen_reg_rtx (DImode); 4382 1.1 mrg rtx (*fn) (rtx, rtx, rtx); 4383 1.1 mrg 4384 1.1 mrg switch (mode) 4385 1.1 mrg { 4386 1.1 mrg case E_QImode: 4387 1.1 mrg fn = gen_insbl; 4388 1.1 mrg break; 4389 1.1 mrg case E_HImode: 4390 1.1 mrg fn = gen_inswl; 4391 1.1 mrg break; 4392 1.1 mrg case E_SImode: 4393 1.1 mrg fn = gen_insll; 4394 1.1 mrg break; 4395 1.1 mrg case E_DImode: 4396 1.1 mrg fn = gen_insql; 4397 1.1 mrg break; 4398 1.1 mrg default: 4399 1.1 mrg gcc_unreachable (); 4400 1.1 mrg } 4401 1.1 mrg 4402 1.1 mrg op1 = force_reg (mode, op1); 4403 1.1 mrg emit_insn (fn (ret, op1, op2)); 4404 1.1 mrg 4405 1.1 mrg return ret; 4406 1.1 mrg } 4407 1.1 mrg 4408 1.1 mrg /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation 4409 1.1 mrg to perform. MEM is the memory on which to operate. VAL is the second 4410 1.1 mrg operand of the binary operator. BEFORE and AFTER are optional locations to 4411 1.1 mrg return the value of MEM either before of after the operation. SCRATCH is 4412 1.1 mrg a scratch register. */ 4413 1.1 mrg 4414 1.1 mrg void 4415 1.1 mrg alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val, rtx before, 4416 1.1 mrg rtx after, rtx scratch, enum memmodel model) 4417 1.1 mrg { 4418 1.1 mrg machine_mode mode = GET_MODE (mem); 4419 1.1 mrg rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch)); 4420 1.1 mrg 4421 1.1 mrg alpha_pre_atomic_barrier (model); 4422 1.1 mrg 4423 1.1 mrg label = gen_label_rtx (); 4424 1.1 mrg emit_label (label); 4425 1.1 mrg label = gen_rtx_LABEL_REF (DImode, label); 4426 1.1 mrg 4427 1.1 mrg if (before == NULL) 4428 1.1 mrg before = scratch; 4429 1.1 mrg emit_insn (gen_load_locked (mode, before, mem)); 4430 1.1 mrg 4431 1.1 mrg if (code == NOT) 4432 1.1 mrg { 4433 1.1 mrg x = gen_rtx_AND (mode, before, val); 4434 1.1 mrg emit_insn (gen_rtx_SET (val, x)); 4435 1.1 mrg 4436 1.1 mrg x = gen_rtx_NOT (mode, val); 4437 1.1 mrg } 4438 1.1 mrg else 4439 1.1 mrg x = gen_rtx_fmt_ee (code, mode, before, val); 4440 1.1 mrg if (after) 4441 1.1 mrg emit_insn (gen_rtx_SET (after, copy_rtx (x))); 4442 1.1 mrg emit_insn (gen_rtx_SET (scratch, x)); 4443 1.1 mrg 4444 1.1 mrg emit_insn (gen_store_conditional (mode, cond, mem, scratch)); 4445 1.1 mrg 4446 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4447 1.1 mrg emit_unlikely_jump (x, label); 4448 1.1 mrg 4449 1.1 mrg alpha_post_atomic_barrier (model); 4450 1.1 mrg } 4451 1.1 mrg 4452 1.1 mrg /* Expand a compare and swap operation. */ 4453 1.1 mrg 4454 1.1 mrg void 4455 1.1 mrg alpha_split_compare_and_swap (rtx operands[]) 4456 1.1 mrg { 4457 1.1 mrg rtx cond, retval, mem, oldval, newval; 4458 1.1 mrg bool is_weak; 4459 1.1 mrg enum memmodel mod_s, mod_f; 4460 1.1 mrg machine_mode mode; 4461 1.1 mrg rtx label1, label2, x; 4462 1.1 mrg 4463 1.1 mrg cond = operands[0]; 4464 1.1 mrg retval = operands[1]; 4465 1.1 mrg mem = operands[2]; 4466 1.1 mrg oldval = operands[3]; 4467 1.1 mrg newval = operands[4]; 4468 1.1 mrg is_weak = (operands[5] != const0_rtx); 4469 1.1 mrg mod_s = memmodel_from_int (INTVAL (operands[6])); 4470 1.1 mrg mod_f = memmodel_from_int (INTVAL (operands[7])); 4471 1.1 mrg mode = GET_MODE (mem); 4472 1.1 mrg 4473 1.1 mrg alpha_pre_atomic_barrier (mod_s); 4474 1.1 mrg 4475 1.1 mrg label1 = NULL_RTX; 4476 1.1 mrg if (!is_weak) 4477 1.1 mrg { 4478 1.1 mrg label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4479 1.1 mrg emit_label (XEXP (label1, 0)); 4480 1.1 mrg } 4481 1.1 mrg label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4482 1.1 mrg 4483 1.1 mrg emit_insn (gen_load_locked (mode, retval, mem)); 4484 1.1 mrg 4485 1.1 mrg x = gen_lowpart (DImode, retval); 4486 1.1 mrg if (oldval == const0_rtx) 4487 1.1 mrg { 4488 1.1 mrg emit_move_insn (cond, const0_rtx); 4489 1.1 mrg x = gen_rtx_NE (DImode, x, const0_rtx); 4490 1.1 mrg } 4491 1.1 mrg else 4492 1.1 mrg { 4493 1.1 mrg x = gen_rtx_EQ (DImode, x, oldval); 4494 1.1 mrg emit_insn (gen_rtx_SET (cond, x)); 4495 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4496 1.1 mrg } 4497 1.1 mrg emit_unlikely_jump (x, label2); 4498 1.1 mrg 4499 1.1 mrg emit_move_insn (cond, newval); 4500 1.1 mrg emit_insn (gen_store_conditional 4501 1.1 mrg (mode, cond, mem, gen_lowpart (mode, cond))); 4502 1.1 mrg 4503 1.1 mrg if (!is_weak) 4504 1.1 mrg { 4505 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4506 1.1 mrg emit_unlikely_jump (x, label1); 4507 1.1 mrg } 4508 1.1 mrg 4509 1.1 mrg if (!is_mm_relaxed (mod_f)) 4510 1.1 mrg emit_label (XEXP (label2, 0)); 4511 1.1 mrg 4512 1.1 mrg alpha_post_atomic_barrier (mod_s); 4513 1.1 mrg 4514 1.1 mrg if (is_mm_relaxed (mod_f)) 4515 1.1 mrg emit_label (XEXP (label2, 0)); 4516 1.1 mrg } 4517 1.1 mrg 4518 1.1 mrg void 4519 1.1 mrg alpha_expand_compare_and_swap_12 (rtx operands[]) 4520 1.1 mrg { 4521 1.1 mrg rtx cond, dst, mem, oldval, newval, is_weak, mod_s, mod_f; 4522 1.1 mrg machine_mode mode; 4523 1.1 mrg rtx addr, align, wdst; 4524 1.1 mrg 4525 1.1 mrg cond = operands[0]; 4526 1.1 mrg dst = operands[1]; 4527 1.1 mrg mem = operands[2]; 4528 1.1 mrg oldval = operands[3]; 4529 1.1 mrg newval = operands[4]; 4530 1.1 mrg is_weak = operands[5]; 4531 1.1 mrg mod_s = operands[6]; 4532 1.1 mrg mod_f = operands[7]; 4533 1.1 mrg mode = GET_MODE (mem); 4534 1.1 mrg 4535 1.1 mrg /* We forced the address into a register via mem_noofs_operand. */ 4536 1.1 mrg addr = XEXP (mem, 0); 4537 1.1 mrg gcc_assert (register_operand (addr, DImode)); 4538 1.1 mrg 4539 1.1 mrg align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8), 4540 1.1 mrg NULL_RTX, 1, OPTAB_DIRECT); 4541 1.1 mrg 4542 1.1 mrg oldval = convert_modes (DImode, mode, oldval, 1); 4543 1.1 mrg 4544 1.1 mrg if (newval != const0_rtx) 4545 1.1 mrg newval = emit_insxl (mode, newval, addr); 4546 1.1 mrg 4547 1.1 mrg wdst = gen_reg_rtx (DImode); 4548 1.1 mrg emit_insn (gen_atomic_compare_and_swap_1 4549 1.1 mrg (mode, cond, wdst, mem, oldval, newval, align, 4550 1.1 mrg is_weak, mod_s, mod_f)); 4551 1.1 mrg 4552 1.1 mrg emit_move_insn (dst, gen_lowpart (mode, wdst)); 4553 1.1 mrg } 4554 1.1 mrg 4555 1.1 mrg void 4556 1.1 mrg alpha_split_compare_and_swap_12 (rtx operands[]) 4557 1.1 mrg { 4558 1.1 mrg rtx cond, dest, orig_mem, oldval, newval, align, scratch; 4559 1.1 mrg machine_mode mode; 4560 1.1 mrg bool is_weak; 4561 1.1 mrg enum memmodel mod_s, mod_f; 4562 1.1 mrg rtx label1, label2, mem, addr, width, mask, x; 4563 1.1 mrg 4564 1.1 mrg cond = operands[0]; 4565 1.1 mrg dest = operands[1]; 4566 1.1 mrg orig_mem = operands[2]; 4567 1.1 mrg oldval = operands[3]; 4568 1.1 mrg newval = operands[4]; 4569 1.1 mrg align = operands[5]; 4570 1.1 mrg is_weak = (operands[6] != const0_rtx); 4571 1.1 mrg mod_s = memmodel_from_int (INTVAL (operands[7])); 4572 1.1 mrg mod_f = memmodel_from_int (INTVAL (operands[8])); 4573 1.1 mrg scratch = operands[9]; 4574 1.1 mrg mode = GET_MODE (orig_mem); 4575 1.1 mrg addr = XEXP (orig_mem, 0); 4576 1.1 mrg 4577 1.1 mrg mem = gen_rtx_MEM (DImode, align); 4578 1.1 mrg MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); 4579 1.1 mrg if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) 4580 1.1 mrg set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 4581 1.1 mrg 4582 1.1 mrg alpha_pre_atomic_barrier (mod_s); 4583 1.1 mrg 4584 1.1 mrg label1 = NULL_RTX; 4585 1.1 mrg if (!is_weak) 4586 1.1 mrg { 4587 1.1 mrg label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4588 1.1 mrg emit_label (XEXP (label1, 0)); 4589 1.1 mrg } 4590 1.1 mrg label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4591 1.1 mrg 4592 1.1 mrg emit_insn (gen_load_locked (DImode, scratch, mem)); 4593 1.1 mrg 4594 1.1 mrg width = GEN_INT (GET_MODE_BITSIZE (mode)); 4595 1.1 mrg mask = GEN_INT (mode == QImode ? 0xff : 0xffff); 4596 1.1 mrg emit_insn (gen_extxl (dest, scratch, width, addr)); 4597 1.1 mrg 4598 1.1 mrg if (oldval == const0_rtx) 4599 1.1 mrg { 4600 1.1 mrg emit_move_insn (cond, const0_rtx); 4601 1.1 mrg x = gen_rtx_NE (DImode, dest, const0_rtx); 4602 1.1 mrg } 4603 1.1 mrg else 4604 1.1 mrg { 4605 1.1 mrg x = gen_rtx_EQ (DImode, dest, oldval); 4606 1.1 mrg emit_insn (gen_rtx_SET (cond, x)); 4607 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4608 1.1 mrg } 4609 1.1 mrg emit_unlikely_jump (x, label2); 4610 1.1 mrg 4611 1.1 mrg emit_insn (gen_mskxl (cond, scratch, mask, addr)); 4612 1.1 mrg 4613 1.1 mrg if (newval != const0_rtx) 4614 1.1 mrg emit_insn (gen_iordi3 (cond, cond, newval)); 4615 1.1 mrg 4616 1.1 mrg emit_insn (gen_store_conditional (DImode, cond, mem, cond)); 4617 1.1 mrg 4618 1.1 mrg if (!is_weak) 4619 1.1 mrg { 4620 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4621 1.1 mrg emit_unlikely_jump (x, label1); 4622 1.1 mrg } 4623 1.1 mrg 4624 1.1 mrg if (!is_mm_relaxed (mod_f)) 4625 1.1 mrg emit_label (XEXP (label2, 0)); 4626 1.1 mrg 4627 1.1 mrg alpha_post_atomic_barrier (mod_s); 4628 1.1 mrg 4629 1.1 mrg if (is_mm_relaxed (mod_f)) 4630 1.1 mrg emit_label (XEXP (label2, 0)); 4631 1.1 mrg } 4632 1.1 mrg 4633 1.1 mrg /* Expand an atomic exchange operation. */ 4634 1.1 mrg 4635 1.1 mrg void 4636 1.1 mrg alpha_split_atomic_exchange (rtx operands[]) 4637 1.1 mrg { 4638 1.1 mrg rtx retval, mem, val, scratch; 4639 1.1 mrg enum memmodel model; 4640 1.1 mrg machine_mode mode; 4641 1.1 mrg rtx label, x, cond; 4642 1.1 mrg 4643 1.1 mrg retval = operands[0]; 4644 1.1 mrg mem = operands[1]; 4645 1.1 mrg val = operands[2]; 4646 1.1 mrg model = (enum memmodel) INTVAL (operands[3]); 4647 1.1 mrg scratch = operands[4]; 4648 1.1 mrg mode = GET_MODE (mem); 4649 1.1 mrg cond = gen_lowpart (DImode, scratch); 4650 1.1 mrg 4651 1.1 mrg alpha_pre_atomic_barrier (model); 4652 1.1 mrg 4653 1.1 mrg label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4654 1.1 mrg emit_label (XEXP (label, 0)); 4655 1.1 mrg 4656 1.1 mrg emit_insn (gen_load_locked (mode, retval, mem)); 4657 1.1 mrg emit_move_insn (scratch, val); 4658 1.1 mrg emit_insn (gen_store_conditional (mode, cond, mem, scratch)); 4659 1.1 mrg 4660 1.1 mrg x = gen_rtx_EQ (DImode, cond, const0_rtx); 4661 1.1 mrg emit_unlikely_jump (x, label); 4662 1.1 mrg 4663 1.1 mrg alpha_post_atomic_barrier (model); 4664 1.1 mrg } 4665 1.1 mrg 4666 1.1 mrg void 4667 1.1 mrg alpha_expand_atomic_exchange_12 (rtx operands[]) 4668 1.1 mrg { 4669 1.1 mrg rtx dst, mem, val, model; 4670 1.1 mrg machine_mode mode; 4671 1.1 mrg rtx addr, align, wdst; 4672 1.1 mrg 4673 1.1 mrg dst = operands[0]; 4674 1.1 mrg mem = operands[1]; 4675 1.1 mrg val = operands[2]; 4676 1.1 mrg model = operands[3]; 4677 1.1 mrg mode = GET_MODE (mem); 4678 1.1 mrg 4679 1.1 mrg /* We forced the address into a register via mem_noofs_operand. */ 4680 1.1 mrg addr = XEXP (mem, 0); 4681 1.1 mrg gcc_assert (register_operand (addr, DImode)); 4682 1.1 mrg 4683 1.1 mrg align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8), 4684 1.1 mrg NULL_RTX, 1, OPTAB_DIRECT); 4685 1.1 mrg 4686 1.1 mrg /* Insert val into the correct byte location within the word. */ 4687 1.1 mrg if (val != const0_rtx) 4688 1.1 mrg val = emit_insxl (mode, val, addr); 4689 1.1 mrg 4690 1.1 mrg wdst = gen_reg_rtx (DImode); 4691 1.1 mrg emit_insn (gen_atomic_exchange_1 (mode, wdst, mem, val, align, model)); 4692 1.1 mrg 4693 1.1 mrg emit_move_insn (dst, gen_lowpart (mode, wdst)); 4694 1.1 mrg } 4695 1.1 mrg 4696 1.1 mrg void 4697 1.1 mrg alpha_split_atomic_exchange_12 (rtx operands[]) 4698 1.1 mrg { 4699 1.1 mrg rtx dest, orig_mem, addr, val, align, scratch; 4700 1.1 mrg rtx label, mem, width, mask, x; 4701 1.1 mrg machine_mode mode; 4702 1.1 mrg enum memmodel model; 4703 1.1 mrg 4704 1.1 mrg dest = operands[0]; 4705 1.1 mrg orig_mem = operands[1]; 4706 1.1 mrg val = operands[2]; 4707 1.1 mrg align = operands[3]; 4708 1.1 mrg model = (enum memmodel) INTVAL (operands[4]); 4709 1.1 mrg scratch = operands[5]; 4710 1.1 mrg mode = GET_MODE (orig_mem); 4711 1.1 mrg addr = XEXP (orig_mem, 0); 4712 1.1 mrg 4713 1.1 mrg mem = gen_rtx_MEM (DImode, align); 4714 1.1 mrg MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); 4715 1.1 mrg if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) 4716 1.1 mrg set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 4717 1.1 mrg 4718 1.1 mrg alpha_pre_atomic_barrier (model); 4719 1.1 mrg 4720 1.1 mrg label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); 4721 1.1 mrg emit_label (XEXP (label, 0)); 4722 1.1 mrg 4723 1.1 mrg emit_insn (gen_load_locked (DImode, scratch, mem)); 4724 1.1 mrg 4725 1.1 mrg width = GEN_INT (GET_MODE_BITSIZE (mode)); 4726 1.1 mrg mask = GEN_INT (mode == QImode ? 0xff : 0xffff); 4727 1.1 mrg emit_insn (gen_extxl (dest, scratch, width, addr)); 4728 1.1 mrg emit_insn (gen_mskxl (scratch, scratch, mask, addr)); 4729 1.1 mrg if (val != const0_rtx) 4730 1.1 mrg emit_insn (gen_iordi3 (scratch, scratch, val)); 4731 1.1 mrg 4732 1.1 mrg emit_insn (gen_store_conditional (DImode, scratch, mem, scratch)); 4733 1.1 mrg 4734 1.1 mrg x = gen_rtx_EQ (DImode, scratch, const0_rtx); 4735 1.1 mrg emit_unlikely_jump (x, label); 4736 1.1 mrg 4737 1.1 mrg alpha_post_atomic_barrier (model); 4738 1.1 mrg } 4739 1.1 mrg 4740 1.1 mrg /* Adjust the cost of a scheduling dependency. Return the new cost of 4742 1.1 mrg a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 4743 1.1 mrg 4744 1.1 mrg static int 4745 1.1 mrg alpha_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, 4746 1.1 mrg unsigned int) 4747 1.1 mrg { 4748 1.1 mrg enum attr_type dep_insn_type; 4749 1.1 mrg 4750 1.1 mrg /* If the dependence is an anti-dependence, there is no cost. For an 4751 1.1 mrg output dependence, there is sometimes a cost, but it doesn't seem 4752 1.1 mrg worth handling those few cases. */ 4753 1.1 mrg if (dep_type != 0) 4754 1.1 mrg return cost; 4755 1.1 mrg 4756 1.1 mrg /* If we can't recognize the insns, we can't really do anything. */ 4757 1.1 mrg if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) 4758 1.1 mrg return cost; 4759 1.1 mrg 4760 1.1 mrg dep_insn_type = get_attr_type (dep_insn); 4761 1.1 mrg 4762 1.1 mrg /* Bring in the user-defined memory latency. */ 4763 1.1 mrg if (dep_insn_type == TYPE_ILD 4764 1.1 mrg || dep_insn_type == TYPE_FLD 4765 1.1 mrg || dep_insn_type == TYPE_LDSYM) 4766 1.1 mrg cost += alpha_memory_latency-1; 4767 1.1 mrg 4768 1.1 mrg /* Everything else handled in DFA bypasses now. */ 4769 1.1 mrg 4770 1.1 mrg return cost; 4771 1.1 mrg } 4772 1.1 mrg 4773 1.1 mrg /* The number of instructions that can be issued per cycle. */ 4774 1.1 mrg 4775 1.1 mrg static int 4776 1.1 mrg alpha_issue_rate (void) 4777 1.1 mrg { 4778 1.1 mrg return (alpha_tune == PROCESSOR_EV4 ? 2 : 4); 4779 1.1 mrg } 4780 1.1 mrg 4781 1.1 mrg /* How many alternative schedules to try. This should be as wide as the 4782 1.1 mrg scheduling freedom in the DFA, but no wider. Making this value too 4783 1.1 mrg large results extra work for the scheduler. 4784 1.1 mrg 4785 1.1 mrg For EV4, loads can be issued to either IB0 or IB1, thus we have 2 4786 1.1 mrg alternative schedules. For EV5, we can choose between E0/E1 and 4787 1.1 mrg FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */ 4788 1.1 mrg 4789 1.1 mrg static int 4790 1.1 mrg alpha_multipass_dfa_lookahead (void) 4791 1.1 mrg { 4792 1.1 mrg return (alpha_tune == PROCESSOR_EV6 ? 4 : 2); 4793 1.1 mrg } 4794 1.1 mrg 4795 1.1 mrg /* Machine-specific function data. */ 4797 1.1 mrg 4798 1.1 mrg struct GTY(()) alpha_links; 4799 1.1 mrg 4800 1.1 mrg struct GTY(()) machine_function 4801 1.1 mrg { 4802 1.1 mrg unsigned HOST_WIDE_INT sa_mask; 4803 1.1 mrg HOST_WIDE_INT sa_size; 4804 1.1 mrg HOST_WIDE_INT frame_size; 4805 1.1 mrg 4806 1.1 mrg /* For flag_reorder_blocks_and_partition. */ 4807 1.1 mrg rtx gp_save_rtx; 4808 1.1 mrg 4809 1.1 mrg /* For VMS condition handlers. */ 4810 1.1 mrg bool uses_condition_handler; 4811 1.1 mrg 4812 1.1 mrg /* Linkage entries. */ 4813 1.1 mrg hash_map<nofree_string_hash, alpha_links *> *links; 4814 1.1 mrg }; 4815 1.1 mrg 4816 1.1 mrg /* How to allocate a 'struct machine_function'. */ 4817 1.1 mrg 4818 1.1 mrg static struct machine_function * 4819 1.1 mrg alpha_init_machine_status (void) 4820 1.1 mrg { 4821 1.1 mrg return ggc_cleared_alloc<machine_function> (); 4822 1.1 mrg } 4823 1.1 mrg 4824 1.1 mrg /* Support for frame based VMS condition handlers. */ 4825 1.1 mrg 4826 1.1 mrg /* A VMS condition handler may be established for a function with a call to 4827 1.1 mrg __builtin_establish_vms_condition_handler, and cancelled with a call to 4828 1.1 mrg __builtin_revert_vms_condition_handler. 4829 1.1 mrg 4830 1.1 mrg The VMS Condition Handling Facility knows about the existence of a handler 4831 1.1 mrg from the procedure descriptor .handler field. As the VMS native compilers, 4832 1.1 mrg we store the user specified handler's address at a fixed location in the 4833 1.1 mrg stack frame and point the procedure descriptor at a common wrapper which 4834 1.1 mrg fetches the real handler's address and issues an indirect call. 4835 1.1 mrg 4836 1.1 mrg The indirection wrapper is "__gcc_shell_handler", provided by libgcc. 4837 1.1 mrg 4838 1.1 mrg We force the procedure kind to PT_STACK, and the fixed frame location is 4839 1.1 mrg fp+8, just before the register save area. We use the handler_data field in 4840 1.1 mrg the procedure descriptor to state the fp offset at which the installed 4841 1.1 mrg handler address can be found. */ 4842 1.1 mrg 4843 1.1 mrg #define VMS_COND_HANDLER_FP_OFFSET 8 4844 1.1 mrg 4845 1.1 mrg /* Expand code to store the currently installed user VMS condition handler 4846 1.1 mrg into TARGET and install HANDLER as the new condition handler. */ 4847 1.1 mrg 4848 1.1 mrg void 4849 1.1 mrg alpha_expand_builtin_establish_vms_condition_handler (rtx target, rtx handler) 4850 1.1 mrg { 4851 1.1 mrg rtx handler_slot_address = plus_constant (Pmode, hard_frame_pointer_rtx, 4852 1.1 mrg VMS_COND_HANDLER_FP_OFFSET); 4853 1.1 mrg 4854 1.1 mrg rtx handler_slot 4855 1.1 mrg = gen_rtx_MEM (DImode, handler_slot_address); 4856 1.1 mrg 4857 1.1 mrg emit_move_insn (target, handler_slot); 4858 1.1 mrg emit_move_insn (handler_slot, handler); 4859 1.1 mrg 4860 1.1 mrg /* Notify the start/prologue/epilogue emitters that the condition handler 4861 1.1 mrg slot is needed. In addition to reserving the slot space, this will force 4862 1.1 mrg the procedure kind to PT_STACK so ensure that the hard_frame_pointer_rtx 4863 1.1 mrg use above is correct. */ 4864 1.1 mrg cfun->machine->uses_condition_handler = true; 4865 1.1 mrg } 4866 1.1 mrg 4867 1.1 mrg /* Expand code to store the current VMS condition handler into TARGET and 4868 1.1 mrg nullify it. */ 4869 1.1 mrg 4870 1.1 mrg void 4871 1.1 mrg alpha_expand_builtin_revert_vms_condition_handler (rtx target) 4872 1.1 mrg { 4873 1.1 mrg /* We implement this by establishing a null condition handler, with the tiny 4874 1.1 mrg side effect of setting uses_condition_handler. This is a little bit 4875 1.1 mrg pessimistic if no actual builtin_establish call is ever issued, which is 4876 1.1 mrg not a real problem and expected never to happen anyway. */ 4877 1.1 mrg 4878 1.1 mrg alpha_expand_builtin_establish_vms_condition_handler (target, const0_rtx); 4879 1.1 mrg } 4880 1.1 mrg 4881 1.1 mrg /* Functions to save and restore alpha_return_addr_rtx. */ 4882 1.1 mrg 4883 1.1 mrg /* Start the ball rolling with RETURN_ADDR_RTX. */ 4884 1.1 mrg 4885 1.1 mrg rtx 4886 1.1 mrg alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) 4887 1.1 mrg { 4888 1.1 mrg if (count != 0) 4889 1.1 mrg return const0_rtx; 4890 1.1 mrg 4891 1.1 mrg return get_hard_reg_initial_val (Pmode, REG_RA); 4892 1.1 mrg } 4893 1.1 mrg 4894 1.1 mrg /* Return or create a memory slot containing the gp value for the current 4895 1.1 mrg function. Needed only if TARGET_LD_BUGGY_LDGP. */ 4896 1.1 mrg 4897 1.1 mrg rtx 4898 1.1 mrg alpha_gp_save_rtx (void) 4899 1.1 mrg { 4900 1.1 mrg rtx_insn *seq; 4901 1.1 mrg rtx m = cfun->machine->gp_save_rtx; 4902 1.1 mrg 4903 1.1 mrg if (m == NULL) 4904 1.1 mrg { 4905 1.1 mrg start_sequence (); 4906 1.1 mrg 4907 1.1 mrg m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD); 4908 1.1 mrg m = validize_mem (m); 4909 1.1 mrg emit_move_insn (m, pic_offset_table_rtx); 4910 1.1 mrg 4911 1.1 mrg seq = get_insns (); 4912 1.1 mrg end_sequence (); 4913 1.1 mrg 4914 1.1 mrg /* We used to simply emit the sequence after entry_of_function. 4915 1.1 mrg However this breaks the CFG if the first instruction in the 4916 1.1 mrg first block is not the NOTE_INSN_BASIC_BLOCK, for example a 4917 1.1 mrg label. Emit the sequence properly on the edge. We are only 4918 1.1 mrg invoked from dw2_build_landing_pads and finish_eh_generation 4919 1.1 mrg will call commit_edge_insertions thanks to a kludge. */ 4920 1.1 mrg insert_insn_on_edge (seq, 4921 1.1 mrg single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); 4922 1.1 mrg 4923 1.1 mrg cfun->machine->gp_save_rtx = m; 4924 1.1 mrg } 4925 1.1 mrg 4926 1.1 mrg return m; 4927 1.1 mrg } 4928 1.1 mrg 4929 1.1 mrg static void 4930 1.1 mrg alpha_instantiate_decls (void) 4931 1.1 mrg { 4932 1.1 mrg if (cfun->machine->gp_save_rtx != NULL_RTX) 4933 1.1 mrg instantiate_decl_rtl (cfun->machine->gp_save_rtx); 4934 1.1 mrg } 4935 1.1 mrg 4936 1.1 mrg static int 4937 1.1 mrg alpha_ra_ever_killed (void) 4938 1.1 mrg { 4939 1.1 mrg rtx_insn *top; 4940 1.1 mrg 4941 1.1 mrg if (!has_hard_reg_initial_val (Pmode, REG_RA)) 4942 1.1 mrg return (int)df_regs_ever_live_p (REG_RA); 4943 1.1 mrg 4944 1.1 mrg push_topmost_sequence (); 4945 1.1 mrg top = get_insns (); 4946 1.1 mrg pop_topmost_sequence (); 4947 1.1 mrg 4948 1.1 mrg return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL); 4949 1.1 mrg } 4950 1.1 mrg 4951 1.1 mrg 4952 1.1 mrg /* Return the trap mode suffix applicable to the current 4954 1.1 mrg instruction, or NULL. */ 4955 1.1 mrg 4956 1.1 mrg static const char * 4957 1.1 mrg get_trap_mode_suffix (void) 4958 1.1 mrg { 4959 1.1 mrg enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn); 4960 1.1 mrg 4961 1.1 mrg switch (s) 4962 1.1 mrg { 4963 1.1 mrg case TRAP_SUFFIX_NONE: 4964 1.1 mrg return NULL; 4965 1.1 mrg 4966 1.1 mrg case TRAP_SUFFIX_SU: 4967 1.1 mrg if (alpha_fptm >= ALPHA_FPTM_SU) 4968 1.1 mrg return "su"; 4969 1.1 mrg return NULL; 4970 1.1 mrg 4971 1.1 mrg case TRAP_SUFFIX_SUI: 4972 1.1 mrg if (alpha_fptm >= ALPHA_FPTM_SUI) 4973 1.1 mrg return "sui"; 4974 1.1 mrg return NULL; 4975 1.1 mrg 4976 1.1 mrg case TRAP_SUFFIX_V_SV: 4977 1.1 mrg switch (alpha_fptm) 4978 1.1 mrg { 4979 1.1 mrg case ALPHA_FPTM_N: 4980 1.1 mrg return NULL; 4981 1.1 mrg case ALPHA_FPTM_U: 4982 1.1 mrg return "v"; 4983 1.1 mrg case ALPHA_FPTM_SU: 4984 1.1 mrg case ALPHA_FPTM_SUI: 4985 1.1 mrg return "sv"; 4986 1.1 mrg default: 4987 1.1 mrg gcc_unreachable (); 4988 1.1 mrg } 4989 1.1 mrg 4990 1.1 mrg case TRAP_SUFFIX_V_SV_SVI: 4991 1.1 mrg switch (alpha_fptm) 4992 1.1 mrg { 4993 1.1 mrg case ALPHA_FPTM_N: 4994 1.1 mrg return NULL; 4995 1.1 mrg case ALPHA_FPTM_U: 4996 1.1 mrg return "v"; 4997 1.1 mrg case ALPHA_FPTM_SU: 4998 1.1 mrg return "sv"; 4999 1.1 mrg case ALPHA_FPTM_SUI: 5000 1.1 mrg return "svi"; 5001 1.1 mrg default: 5002 1.1 mrg gcc_unreachable (); 5003 1.1 mrg } 5004 1.1 mrg break; 5005 1.1 mrg 5006 1.1 mrg case TRAP_SUFFIX_U_SU_SUI: 5007 1.1 mrg switch (alpha_fptm) 5008 1.1 mrg { 5009 1.1 mrg case ALPHA_FPTM_N: 5010 1.1 mrg return NULL; 5011 1.1 mrg case ALPHA_FPTM_U: 5012 1.1 mrg return "u"; 5013 1.1 mrg case ALPHA_FPTM_SU: 5014 1.1 mrg return "su"; 5015 1.1 mrg case ALPHA_FPTM_SUI: 5016 1.1 mrg return "sui"; 5017 1.1 mrg default: 5018 1.1 mrg gcc_unreachable (); 5019 1.1 mrg } 5020 1.1 mrg break; 5021 1.1 mrg 5022 1.1 mrg default: 5023 1.1 mrg gcc_unreachable (); 5024 1.1 mrg } 5025 1.1 mrg gcc_unreachable (); 5026 1.1 mrg } 5027 1.1 mrg 5028 1.1 mrg /* Return the rounding mode suffix applicable to the current 5029 1.1 mrg instruction, or NULL. */ 5030 1.1 mrg 5031 1.1 mrg static const char * 5032 1.1 mrg get_round_mode_suffix (void) 5033 1.1 mrg { 5034 1.1 mrg enum attr_round_suffix s = get_attr_round_suffix (current_output_insn); 5035 1.1 mrg 5036 1.1 mrg switch (s) 5037 1.1 mrg { 5038 1.1 mrg case ROUND_SUFFIX_NONE: 5039 1.1 mrg return NULL; 5040 1.1 mrg case ROUND_SUFFIX_NORMAL: 5041 1.1 mrg switch (alpha_fprm) 5042 1.1 mrg { 5043 1.1 mrg case ALPHA_FPRM_NORM: 5044 1.1 mrg return NULL; 5045 1.1 mrg case ALPHA_FPRM_MINF: 5046 1.1 mrg return "m"; 5047 1.1 mrg case ALPHA_FPRM_CHOP: 5048 1.1 mrg return "c"; 5049 1.1 mrg case ALPHA_FPRM_DYN: 5050 1.1 mrg return "d"; 5051 1.1 mrg default: 5052 1.1 mrg gcc_unreachable (); 5053 1.1 mrg } 5054 1.1 mrg break; 5055 1.1 mrg 5056 1.1 mrg case ROUND_SUFFIX_C: 5057 1.1 mrg return "c"; 5058 1.1 mrg 5059 1.1 mrg default: 5060 1.1 mrg gcc_unreachable (); 5061 1.1 mrg } 5062 1.1 mrg gcc_unreachable (); 5063 1.1 mrg } 5064 1.1 mrg 5065 1.1 mrg /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */ 5066 1.1 mrg 5067 1.1 mrg static bool 5068 1.1 mrg alpha_print_operand_punct_valid_p (unsigned char code) 5069 1.1 mrg { 5070 1.1 mrg return (code == '/' || code == ',' || code == '-' || code == '~' 5071 1.1 mrg || code == '#' || code == '*' || code == '&'); 5072 1.1 mrg } 5073 1.1 mrg 5074 1.1 mrg /* Implement TARGET_PRINT_OPERAND. The alpha-specific 5075 1.1 mrg operand codes are documented below. */ 5076 1.1 mrg 5077 1.1 mrg static void 5078 1.1 mrg alpha_print_operand (FILE *file, rtx x, int code) 5079 1.1 mrg { 5080 1.1 mrg int i; 5081 1.1 mrg 5082 1.1 mrg switch (code) 5083 1.1 mrg { 5084 1.1 mrg case '~': 5085 1.1 mrg /* Print the assembler name of the current function. */ 5086 1.1 mrg assemble_name (file, alpha_fnname); 5087 1.1 mrg break; 5088 1.1 mrg 5089 1.1 mrg case '&': 5090 1.1 mrg if (const char *name = get_some_local_dynamic_name ()) 5091 1.1 mrg assemble_name (file, name); 5092 1.1 mrg else 5093 1.1 mrg output_operand_lossage ("'%%&' used without any " 5094 1.1 mrg "local dynamic TLS references"); 5095 1.1 mrg break; 5096 1.1 mrg 5097 1.1 mrg case '/': 5098 1.1 mrg /* Generates the instruction suffix. The TRAP_SUFFIX and ROUND_SUFFIX 5099 1.1 mrg attributes are examined to determine what is appropriate. */ 5100 1.1 mrg { 5101 1.1 mrg const char *trap = get_trap_mode_suffix (); 5102 1.1 mrg const char *round = get_round_mode_suffix (); 5103 1.1 mrg 5104 1.1 mrg if (trap || round) 5105 1.1 mrg fprintf (file, "/%s%s", (trap ? trap : ""), (round ? round : "")); 5106 1.1 mrg break; 5107 1.1 mrg } 5108 1.1 mrg 5109 1.1 mrg case ',': 5110 1.1 mrg /* Generates single precision suffix for floating point 5111 1.1 mrg instructions (s for IEEE, f for VAX). */ 5112 1.1 mrg fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file); 5113 1.1 mrg break; 5114 1.1 mrg 5115 1.1 mrg case '-': 5116 1.1 mrg /* Generates double precision suffix for floating point 5117 1.1 mrg instructions (t for IEEE, g for VAX). */ 5118 1.1 mrg fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file); 5119 1.1 mrg break; 5120 1.1 mrg 5121 1.1 mrg case '#': 5122 1.1 mrg if (alpha_this_literal_sequence_number == 0) 5123 1.1 mrg alpha_this_literal_sequence_number = alpha_next_sequence_number++; 5124 1.1 mrg fprintf (file, "%d", alpha_this_literal_sequence_number); 5125 1.1 mrg break; 5126 1.1 mrg 5127 1.1 mrg case '*': 5128 1.1 mrg if (alpha_this_gpdisp_sequence_number == 0) 5129 1.1 mrg alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++; 5130 1.1 mrg fprintf (file, "%d", alpha_this_gpdisp_sequence_number); 5131 1.1 mrg break; 5132 1.1 mrg 5133 1.1 mrg case 'J': 5134 1.1 mrg { 5135 1.1 mrg const char *lituse; 5136 1.1 mrg 5137 1.1 mrg if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL) 5138 1.1 mrg { 5139 1.1 mrg x = XVECEXP (x, 0, 0); 5140 1.1 mrg lituse = "lituse_tlsgd"; 5141 1.1 mrg } 5142 1.1 mrg else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL) 5143 1.1 mrg { 5144 1.1 mrg x = XVECEXP (x, 0, 0); 5145 1.1 mrg lituse = "lituse_tlsldm"; 5146 1.1 mrg } 5147 1.1 mrg else if (CONST_INT_P (x)) 5148 1.1 mrg lituse = "lituse_jsr"; 5149 1.1 mrg else 5150 1.1 mrg { 5151 1.1 mrg output_operand_lossage ("invalid %%J value"); 5152 1.1 mrg break; 5153 1.1 mrg } 5154 1.1 mrg 5155 1.1 mrg if (x != const0_rtx) 5156 1.1 mrg fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x)); 5157 1.1 mrg } 5158 1.1 mrg break; 5159 1.1 mrg 5160 1.1 mrg case 'j': 5161 1.1 mrg { 5162 1.1 mrg const char *lituse; 5163 1.1 mrg 5164 1.1 mrg #ifdef HAVE_AS_JSRDIRECT_RELOCS 5165 1.1 mrg lituse = "lituse_jsrdirect"; 5166 1.1 mrg #else 5167 1.1 mrg lituse = "lituse_jsr"; 5168 1.1 mrg #endif 5169 1.1 mrg 5170 1.1 mrg gcc_assert (INTVAL (x) != 0); 5171 1.1 mrg fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x)); 5172 1.1 mrg } 5173 1.1 mrg break; 5174 1.1 mrg case 'r': 5175 1.1 mrg /* If this operand is the constant zero, write it as "$31". */ 5176 1.1 mrg if (REG_P (x)) 5177 1.1 mrg fprintf (file, "%s", reg_names[REGNO (x)]); 5178 1.1 mrg else if (x == CONST0_RTX (GET_MODE (x))) 5179 1.1 mrg fprintf (file, "$31"); 5180 1.1 mrg else 5181 1.1 mrg output_operand_lossage ("invalid %%r value"); 5182 1.1 mrg break; 5183 1.1 mrg 5184 1.1 mrg case 'R': 5185 1.1 mrg /* Similar, but for floating-point. */ 5186 1.1 mrg if (REG_P (x)) 5187 1.1 mrg fprintf (file, "%s", reg_names[REGNO (x)]); 5188 1.1 mrg else if (x == CONST0_RTX (GET_MODE (x))) 5189 1.1 mrg fprintf (file, "$f31"); 5190 1.1 mrg else 5191 1.1 mrg output_operand_lossage ("invalid %%R value"); 5192 1.1 mrg break; 5193 1.1 mrg 5194 1.1 mrg case 'N': 5195 1.1 mrg /* Write the 1's complement of a constant. */ 5196 1.1 mrg if (!CONST_INT_P (x)) 5197 1.1 mrg output_operand_lossage ("invalid %%N value"); 5198 1.1 mrg 5199 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x)); 5200 1.1 mrg break; 5201 1.1 mrg 5202 1.1 mrg case 'P': 5203 1.1 mrg /* Write 1 << C, for a constant C. */ 5204 1.1 mrg if (!CONST_INT_P (x)) 5205 1.1 mrg output_operand_lossage ("invalid %%P value"); 5206 1.1 mrg 5207 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_1 << INTVAL (x)); 5208 1.1 mrg break; 5209 1.1 mrg 5210 1.1 mrg case 'h': 5211 1.1 mrg /* Write the high-order 16 bits of a constant, sign-extended. */ 5212 1.1 mrg if (!CONST_INT_P (x)) 5213 1.1 mrg output_operand_lossage ("invalid %%h value"); 5214 1.1 mrg 5215 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16); 5216 1.1 mrg break; 5217 1.1 mrg 5218 1.1 mrg case 'L': 5219 1.1 mrg /* Write the low-order 16 bits of a constant, sign-extended. */ 5220 1.1 mrg if (!CONST_INT_P (x)) 5221 1.1 mrg output_operand_lossage ("invalid %%L value"); 5222 1.1 mrg 5223 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, 5224 1.1 mrg (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000)); 5225 1.1 mrg break; 5226 1.1 mrg 5227 1.1 mrg case 'm': 5228 1.1 mrg /* Write mask for ZAP insn. */ 5229 1.1 mrg if (CONST_INT_P (x)) 5230 1.1 mrg { 5231 1.1 mrg HOST_WIDE_INT mask = 0, value = INTVAL (x); 5232 1.1 mrg 5233 1.1 mrg for (i = 0; i < 8; i++, value >>= 8) 5234 1.1 mrg if (value & 0xff) 5235 1.1 mrg mask |= (1 << i); 5236 1.1 mrg 5237 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask); 5238 1.1 mrg } 5239 1.1 mrg else 5240 1.1 mrg output_operand_lossage ("invalid %%m value"); 5241 1.1 mrg break; 5242 1.1 mrg 5243 1.1 mrg case 'M': 5244 1.1 mrg /* 'b', 'w', 'l', or 'q' as the value of the constant. */ 5245 1.1 mrg if (!mode_width_operand (x, VOIDmode)) 5246 1.1 mrg output_operand_lossage ("invalid %%M value"); 5247 1.1 mrg 5248 1.1 mrg fprintf (file, "%s", 5249 1.1 mrg (INTVAL (x) == 8 ? "b" 5250 1.1 mrg : INTVAL (x) == 16 ? "w" 5251 1.1 mrg : INTVAL (x) == 32 ? "l" 5252 1.1 mrg : "q")); 5253 1.1 mrg break; 5254 1.1 mrg 5255 1.1 mrg case 'U': 5256 1.1 mrg /* Similar, except do it from the mask. */ 5257 1.1 mrg if (CONST_INT_P (x)) 5258 1.1 mrg { 5259 1.1 mrg HOST_WIDE_INT value = INTVAL (x); 5260 1.1 mrg 5261 1.1 mrg if (value == 0xff) 5262 1.1 mrg { 5263 1.1 mrg fputc ('b', file); 5264 1.1 mrg break; 5265 1.1 mrg } 5266 1.1 mrg if (value == 0xffff) 5267 1.1 mrg { 5268 1.1 mrg fputc ('w', file); 5269 1.1 mrg break; 5270 1.1 mrg } 5271 1.1 mrg if (value == 0xffffffff) 5272 1.1 mrg { 5273 1.1 mrg fputc ('l', file); 5274 1.1 mrg break; 5275 1.1 mrg } 5276 1.1 mrg if (value == -1) 5277 1.1 mrg { 5278 1.1 mrg fputc ('q', file); 5279 1.1 mrg break; 5280 1.1 mrg } 5281 1.1 mrg } 5282 1.1 mrg 5283 1.1 mrg output_operand_lossage ("invalid %%U value"); 5284 1.1 mrg break; 5285 1.1 mrg 5286 1.1 mrg case 's': 5287 1.1 mrg /* Write the constant value divided by 8. */ 5288 1.1 mrg if (!CONST_INT_P (x) 5289 1.1 mrg || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64 5290 1.1 mrg || (INTVAL (x) & 7) != 0) 5291 1.1 mrg output_operand_lossage ("invalid %%s value"); 5292 1.1 mrg 5293 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8); 5294 1.1 mrg break; 5295 1.1 mrg 5296 1.1 mrg case 'C': case 'D': case 'c': case 'd': 5297 1.1 mrg /* Write out comparison name. */ 5298 1.1 mrg { 5299 1.1 mrg enum rtx_code c = GET_CODE (x); 5300 1.1 mrg 5301 1.1 mrg if (!COMPARISON_P (x)) 5302 1.1 mrg output_operand_lossage ("invalid %%C value"); 5303 1.1 mrg 5304 1.1 mrg else if (code == 'D') 5305 1.1 mrg c = reverse_condition (c); 5306 1.1 mrg else if (code == 'c') 5307 1.1 mrg c = swap_condition (c); 5308 1.1 mrg else if (code == 'd') 5309 1.1 mrg c = swap_condition (reverse_condition (c)); 5310 1.1 mrg 5311 1.1 mrg if (c == LEU) 5312 1.1 mrg fprintf (file, "ule"); 5313 1.1 mrg else if (c == LTU) 5314 1.1 mrg fprintf (file, "ult"); 5315 1.1 mrg else if (c == UNORDERED) 5316 1.1 mrg fprintf (file, "un"); 5317 1.1 mrg else 5318 1.1 mrg fprintf (file, "%s", GET_RTX_NAME (c)); 5319 1.1 mrg } 5320 1.1 mrg break; 5321 1.1 mrg 5322 1.1 mrg case 'E': 5323 1.1 mrg /* Write the divide or modulus operator. */ 5324 1.1 mrg switch (GET_CODE (x)) 5325 1.1 mrg { 5326 1.1 mrg case DIV: 5327 1.1 mrg fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q"); 5328 1.1 mrg break; 5329 1.1 mrg case UDIV: 5330 1.1 mrg fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q"); 5331 1.1 mrg break; 5332 1.1 mrg case MOD: 5333 1.1 mrg fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q"); 5334 1.1 mrg break; 5335 1.1 mrg case UMOD: 5336 1.1 mrg fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q"); 5337 1.1 mrg break; 5338 1.1 mrg default: 5339 1.1 mrg output_operand_lossage ("invalid %%E value"); 5340 1.1 mrg break; 5341 1.1 mrg } 5342 1.1 mrg break; 5343 1.1 mrg 5344 1.1 mrg case 'A': 5345 1.1 mrg /* Write "_u" for unaligned access. */ 5346 1.1 mrg if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND) 5347 1.1 mrg fprintf (file, "_u"); 5348 1.1 mrg break; 5349 1.1 mrg 5350 1.1 mrg case 0: 5351 1.1 mrg if (REG_P (x)) 5352 1.1 mrg fprintf (file, "%s", reg_names[REGNO (x)]); 5353 1.1 mrg else if (MEM_P (x)) 5354 1.1 mrg output_address (GET_MODE (x), XEXP (x, 0)); 5355 1.1 mrg else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC) 5356 1.1 mrg { 5357 1.1 mrg switch (XINT (XEXP (x, 0), 1)) 5358 1.1 mrg { 5359 1.1 mrg case UNSPEC_DTPREL: 5360 1.1 mrg case UNSPEC_TPREL: 5361 1.1 mrg output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0)); 5362 1.1 mrg break; 5363 1.1 mrg default: 5364 1.1 mrg output_operand_lossage ("unknown relocation unspec"); 5365 1.1 mrg break; 5366 1.1 mrg } 5367 1.1 mrg } 5368 1.1 mrg else 5369 1.1 mrg output_addr_const (file, x); 5370 1.1 mrg break; 5371 1.1 mrg 5372 1.1 mrg default: 5373 1.1 mrg output_operand_lossage ("invalid %%xn code"); 5374 1.1 mrg } 5375 1.1 mrg } 5376 1.1 mrg 5377 1.1 mrg /* Implement TARGET_PRINT_OPERAND_ADDRESS. */ 5378 1.1 mrg 5379 1.1 mrg static void 5380 1.1 mrg alpha_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr) 5381 1.1 mrg { 5382 1.1 mrg int basereg = 31; 5383 1.1 mrg HOST_WIDE_INT offset = 0; 5384 1.1 mrg 5385 1.1 mrg if (GET_CODE (addr) == AND) 5386 1.1 mrg addr = XEXP (addr, 0); 5387 1.1 mrg 5388 1.1 mrg if (GET_CODE (addr) == PLUS 5389 1.1 mrg && CONST_INT_P (XEXP (addr, 1))) 5390 1.1 mrg { 5391 1.1 mrg offset = INTVAL (XEXP (addr, 1)); 5392 1.1 mrg addr = XEXP (addr, 0); 5393 1.1 mrg } 5394 1.1 mrg 5395 1.1 mrg if (GET_CODE (addr) == LO_SUM) 5396 1.1 mrg { 5397 1.1 mrg const char *reloc16, *reloclo; 5398 1.1 mrg rtx op1 = XEXP (addr, 1); 5399 1.1 mrg 5400 1.1 mrg if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC) 5401 1.1 mrg { 5402 1.1 mrg op1 = XEXP (op1, 0); 5403 1.1 mrg switch (XINT (op1, 1)) 5404 1.1 mrg { 5405 1.1 mrg case UNSPEC_DTPREL: 5406 1.1 mrg reloc16 = NULL; 5407 1.1 mrg reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello"); 5408 1.1 mrg break; 5409 1.1 mrg case UNSPEC_TPREL: 5410 1.1 mrg reloc16 = NULL; 5411 1.1 mrg reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello"); 5412 1.1 mrg break; 5413 1.1 mrg default: 5414 1.1 mrg output_operand_lossage ("unknown relocation unspec"); 5415 1.1 mrg return; 5416 1.1 mrg } 5417 1.1 mrg 5418 1.1 mrg output_addr_const (file, XVECEXP (op1, 0, 0)); 5419 1.1 mrg } 5420 1.1 mrg else 5421 1.1 mrg { 5422 1.1 mrg reloc16 = "gprel"; 5423 1.1 mrg reloclo = "gprellow"; 5424 1.1 mrg output_addr_const (file, op1); 5425 1.1 mrg } 5426 1.1 mrg 5427 1.1 mrg if (offset) 5428 1.1 mrg fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset); 5429 1.1 mrg 5430 1.1 mrg addr = XEXP (addr, 0); 5431 1.1 mrg switch (GET_CODE (addr)) 5432 1.1 mrg { 5433 1.1 mrg case REG: 5434 1.1 mrg basereg = REGNO (addr); 5435 1.1 mrg break; 5436 1.1 mrg 5437 1.1 mrg case SUBREG: 5438 1.1 mrg basereg = subreg_regno (addr); 5439 1.1 mrg break; 5440 1.1 mrg 5441 1.1 mrg default: 5442 1.1 mrg gcc_unreachable (); 5443 1.1 mrg } 5444 1.1 mrg 5445 1.1 mrg fprintf (file, "($%d)\t\t!%s", basereg, 5446 1.1 mrg (basereg == 29 ? reloc16 : reloclo)); 5447 1.1 mrg return; 5448 1.1 mrg } 5449 1.1 mrg 5450 1.1 mrg switch (GET_CODE (addr)) 5451 1.1 mrg { 5452 1.1 mrg case REG: 5453 1.1 mrg basereg = REGNO (addr); 5454 1.1 mrg break; 5455 1.1 mrg 5456 1.1 mrg case SUBREG: 5457 1.1 mrg basereg = subreg_regno (addr); 5458 1.1 mrg break; 5459 1.1 mrg 5460 1.1 mrg case CONST_INT: 5461 1.1 mrg offset = INTVAL (addr); 5462 1.1 mrg break; 5463 1.1 mrg 5464 1.1 mrg case SYMBOL_REF: 5465 1.1 mrg gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands); 5466 1.1 mrg fprintf (file, "%s", XSTR (addr, 0)); 5467 1.1 mrg return; 5468 1.1 mrg 5469 1.1 mrg case CONST: 5470 1.1 mrg gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands); 5471 1.1 mrg gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS 5472 1.1 mrg && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF); 5473 1.1 mrg fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC, 5474 1.1 mrg XSTR (XEXP (XEXP (addr, 0), 0), 0), 5475 1.1 mrg INTVAL (XEXP (XEXP (addr, 0), 1))); 5476 1.1 mrg return; 5477 1.1 mrg 5478 1.1 mrg default: 5479 1.1 mrg output_operand_lossage ("invalid operand address"); 5480 1.1 mrg return; 5481 1.1 mrg } 5482 1.1 mrg 5483 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg); 5484 1.1 mrg } 5485 1.1 mrg 5486 1.1 mrg /* Emit RTL insns to initialize the variable parts of a trampoline at 5488 1.1 mrg M_TRAMP. FNDECL is target function's decl. CHAIN_VALUE is an rtx 5489 1.1 mrg for the static chain value for the function. */ 5490 1.1 mrg 5491 1.1 mrg static void 5492 1.1 mrg alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) 5493 1.1 mrg { 5494 1.1 mrg rtx fnaddr, mem, word1, word2; 5495 1.1 mrg 5496 1.1 mrg fnaddr = XEXP (DECL_RTL (fndecl), 0); 5497 1.1 mrg 5498 1.1 mrg #ifdef POINTERS_EXTEND_UNSIGNED 5499 1.1 mrg fnaddr = convert_memory_address (Pmode, fnaddr); 5500 1.1 mrg chain_value = convert_memory_address (Pmode, chain_value); 5501 1.1 mrg #endif 5502 1.1 mrg 5503 1.1 mrg if (TARGET_ABI_OPEN_VMS) 5504 1.1 mrg { 5505 1.1 mrg const char *fnname; 5506 1.1 mrg char *trname; 5507 1.1 mrg 5508 1.1 mrg /* Construct the name of the trampoline entry point. */ 5509 1.1 mrg fnname = XSTR (fnaddr, 0); 5510 1.1 mrg trname = (char *) alloca (strlen (fnname) + 5); 5511 1.1 mrg strcpy (trname, fnname); 5512 1.1 mrg strcat (trname, "..tr"); 5513 1.1 mrg fnname = ggc_alloc_string (trname, strlen (trname) + 1); 5514 1.1 mrg word2 = gen_rtx_SYMBOL_REF (Pmode, fnname); 5515 1.1 mrg 5516 1.1 mrg /* Trampoline (or "bounded") procedure descriptor is constructed from 5517 1.1 mrg the function's procedure descriptor with certain fields zeroed IAW 5518 1.1 mrg the VMS calling standard. This is stored in the first quadword. */ 5519 1.1 mrg word1 = force_reg (DImode, gen_const_mem (DImode, fnaddr)); 5520 1.1 mrg word1 = expand_and (DImode, word1, 5521 1.1 mrg GEN_INT (HOST_WIDE_INT_C (0xffff0fff0000fff0)), 5522 1.1 mrg NULL); 5523 1.1 mrg } 5524 1.1 mrg else 5525 1.1 mrg { 5526 1.1 mrg /* These 4 instructions are: 5527 1.1 mrg ldq $1,24($27) 5528 1.1 mrg ldq $27,16($27) 5529 1.1 mrg jmp $31,($27),0 5530 1.1 mrg nop 5531 1.1 mrg We don't bother setting the HINT field of the jump; the nop 5532 1.1 mrg is merely there for padding. */ 5533 1.1 mrg word1 = GEN_INT (HOST_WIDE_INT_C (0xa77b0010a43b0018)); 5534 1.1 mrg word2 = GEN_INT (HOST_WIDE_INT_C (0x47ff041f6bfb0000)); 5535 1.1 mrg } 5536 1.1 mrg 5537 1.1 mrg /* Store the first two words, as computed above. */ 5538 1.1 mrg mem = adjust_address (m_tramp, DImode, 0); 5539 1.1 mrg emit_move_insn (mem, word1); 5540 1.1 mrg mem = adjust_address (m_tramp, DImode, 8); 5541 1.1 mrg emit_move_insn (mem, word2); 5542 1.1 mrg 5543 1.1 mrg /* Store function address and static chain value. */ 5544 1.1 mrg mem = adjust_address (m_tramp, Pmode, 16); 5545 1.1 mrg emit_move_insn (mem, fnaddr); 5546 1.1 mrg mem = adjust_address (m_tramp, Pmode, 24); 5547 1.1 mrg emit_move_insn (mem, chain_value); 5548 1.1 mrg 5549 1.1 mrg if (TARGET_ABI_OSF) 5550 1.1 mrg { 5551 1.1 mrg emit_insn (gen_imb ()); 5552 1.1 mrg #ifdef HAVE_ENABLE_EXECUTE_STACK 5553 1.1 mrg emit_library_call (init_one_libfunc ("__enable_execute_stack"), 5554 1.1 mrg LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode); 5555 1.1 mrg #endif 5556 1.1 mrg } 5557 1.1 mrg } 5558 1.1 mrg 5559 1.1 mrg /* Determine where to put an argument to a function. 5561 1.1 mrg Value is zero to push the argument on the stack, 5562 1.1 mrg or a hard register in which to store the argument. 5563 1.1 mrg 5564 1.1 mrg CUM is a variable of type CUMULATIVE_ARGS which gives info about 5565 1.1 mrg the preceding args and about the function being called. 5566 1.1 mrg ARG is a description of the argument. 5567 1.1 mrg 5568 1.1 mrg On Alpha the first 6 words of args are normally in registers 5569 1.1 mrg and the rest are pushed. */ 5570 1.1 mrg 5571 1.1 mrg static rtx 5572 1.1 mrg alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) 5573 1.1 mrg { 5574 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 5575 1.1 mrg int basereg; 5576 1.1 mrg int num_args; 5577 1.1 mrg 5578 1.1 mrg /* Don't get confused and pass small structures in FP registers. */ 5579 1.1 mrg if (arg.aggregate_type_p ()) 5580 1.1 mrg basereg = 16; 5581 1.1 mrg else 5582 1.1 mrg { 5583 1.1 mrg /* With alpha_split_complex_arg, we shouldn't see any raw complex 5584 1.1 mrg values here. */ 5585 1.1 mrg gcc_checking_assert (!COMPLEX_MODE_P (arg.mode)); 5586 1.1 mrg 5587 1.1 mrg /* Set up defaults for FP operands passed in FP registers, and 5588 1.1 mrg integral operands passed in integer registers. */ 5589 1.1 mrg if (TARGET_FPREGS && GET_MODE_CLASS (arg.mode) == MODE_FLOAT) 5590 1.1 mrg basereg = 32 + 16; 5591 1.1 mrg else 5592 1.1 mrg basereg = 16; 5593 1.1 mrg } 5594 1.1 mrg 5595 1.1 mrg /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for 5596 1.1 mrg the two platforms, so we can't avoid conditional compilation. */ 5597 1.1 mrg #if TARGET_ABI_OPEN_VMS 5598 1.1 mrg { 5599 1.1 mrg if (arg.end_marker_p ()) 5600 1.1 mrg return alpha_arg_info_reg_val (*cum); 5601 1.1 mrg 5602 1.1 mrg num_args = cum->num_args; 5603 1.1 mrg if (num_args >= 6 5604 1.1 mrg || targetm.calls.must_pass_in_stack (arg)) 5605 1.1 mrg return NULL_RTX; 5606 1.1 mrg } 5607 1.1 mrg #elif TARGET_ABI_OSF 5608 1.1 mrg { 5609 1.1 mrg if (*cum >= 6) 5610 1.1 mrg return NULL_RTX; 5611 1.1 mrg num_args = *cum; 5612 1.1 mrg 5613 1.1 mrg if (arg.end_marker_p ()) 5614 1.1 mrg basereg = 16; 5615 1.1 mrg else if (targetm.calls.must_pass_in_stack (arg)) 5616 1.1 mrg return NULL_RTX; 5617 1.1 mrg } 5618 1.1 mrg #else 5619 1.1 mrg #error Unhandled ABI 5620 1.1 mrg #endif 5621 1.1 mrg 5622 1.1 mrg return gen_rtx_REG (arg.mode, num_args + basereg); 5623 1.1 mrg } 5624 1.1 mrg 5625 1.1 mrg /* Update the data in CUM to advance over argument ARG. */ 5626 1.1 mrg 5627 1.1 mrg static void 5628 1.1 mrg alpha_function_arg_advance (cumulative_args_t cum_v, 5629 1.1 mrg const function_arg_info &arg) 5630 1.1 mrg { 5631 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 5632 1.1 mrg bool onstack = targetm.calls.must_pass_in_stack (arg); 5633 1.1 mrg int increment = onstack ? 6 : ALPHA_ARG_SIZE (arg.mode, arg.type); 5634 1.1 mrg 5635 1.1 mrg #if TARGET_ABI_OSF 5636 1.1 mrg *cum += increment; 5637 1.1 mrg #else 5638 1.1 mrg if (!onstack && cum->num_args < 6) 5639 1.1 mrg cum->atypes[cum->num_args] = alpha_arg_type (arg.mode); 5640 1.1 mrg cum->num_args += increment; 5641 1.1 mrg #endif 5642 1.1 mrg } 5643 1.1 mrg 5644 1.1 mrg static int 5645 1.1 mrg alpha_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) 5646 1.1 mrg { 5647 1.1 mrg int words = 0; 5648 1.1 mrg CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v); 5649 1.1 mrg 5650 1.1 mrg #if TARGET_ABI_OPEN_VMS 5651 1.1 mrg if (cum->num_args < 6 5652 1.1 mrg && 6 < cum->num_args + ALPHA_ARG_SIZE (arg.mode, arg.type)) 5653 1.1 mrg words = 6 - cum->num_args; 5654 1.1 mrg #elif TARGET_ABI_OSF 5655 1.1 mrg if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (arg.mode, arg.type)) 5656 1.1 mrg words = 6 - *cum; 5657 1.1 mrg #else 5658 1.1 mrg #error Unhandled ABI 5659 1.1 mrg #endif 5660 1.1 mrg 5661 1.1 mrg return words * UNITS_PER_WORD; 5662 1.1 mrg } 5663 1.1 mrg 5664 1.1 mrg 5665 1.1 mrg /* Return true if TYPE must be returned in memory, instead of in registers. */ 5666 1.1 mrg 5667 1.1 mrg static bool 5668 1.1 mrg alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) 5669 1.1 mrg { 5670 1.1 mrg machine_mode mode = VOIDmode; 5671 1.1 mrg int size; 5672 1.1 mrg 5673 1.1 mrg if (type) 5674 1.1 mrg { 5675 1.1 mrg mode = TYPE_MODE (type); 5676 1.1 mrg 5677 1.1 mrg /* All aggregates are returned in memory, except on OpenVMS where 5678 1.1 mrg records that fit 64 bits should be returned by immediate value 5679 1.1 mrg as required by section 3.8.7.1 of the OpenVMS Calling Standard. */ 5680 1.1 mrg if (TARGET_ABI_OPEN_VMS 5681 1.1 mrg && TREE_CODE (type) != ARRAY_TYPE 5682 1.1 mrg && (unsigned HOST_WIDE_INT) int_size_in_bytes(type) <= 8) 5683 1.1 mrg return false; 5684 1.1 mrg 5685 1.1 mrg if (AGGREGATE_TYPE_P (type)) 5686 1.1 mrg return true; 5687 1.1 mrg } 5688 1.1 mrg 5689 1.1 mrg size = GET_MODE_SIZE (mode); 5690 1.1 mrg switch (GET_MODE_CLASS (mode)) 5691 1.1 mrg { 5692 1.1 mrg case MODE_VECTOR_FLOAT: 5693 1.1 mrg /* Pass all float vectors in memory, like an aggregate. */ 5694 1.1 mrg return true; 5695 1.1 mrg 5696 1.1 mrg case MODE_COMPLEX_FLOAT: 5697 1.1 mrg /* We judge complex floats on the size of their element, 5698 1.1 mrg not the size of the whole type. */ 5699 1.1 mrg size = GET_MODE_UNIT_SIZE (mode); 5700 1.1 mrg break; 5701 1.1 mrg 5702 1.1 mrg case MODE_INT: 5703 1.1 mrg case MODE_FLOAT: 5704 1.1 mrg case MODE_COMPLEX_INT: 5705 1.1 mrg case MODE_VECTOR_INT: 5706 1.1 mrg break; 5707 1.1 mrg 5708 1.1 mrg default: 5709 1.1 mrg /* ??? We get called on all sorts of random stuff from 5710 1.1 mrg aggregate_value_p. We must return something, but it's not 5711 1.1 mrg clear what's safe to return. Pretend it's a struct I 5712 1.1 mrg guess. */ 5713 1.1 mrg return true; 5714 1.1 mrg } 5715 1.1 mrg 5716 1.1 mrg /* Otherwise types must fit in one register. */ 5717 1.1 mrg return size > UNITS_PER_WORD; 5718 1.1 mrg } 5719 1.1 mrg 5720 1.1 mrg /* Return true if ARG should be passed by invisible reference. */ 5721 1.1 mrg 5722 1.1 mrg static bool 5723 1.1 mrg alpha_pass_by_reference (cumulative_args_t, const function_arg_info &arg) 5724 1.1 mrg { 5725 1.1 mrg /* Pass float and _Complex float variable arguments by reference. 5726 1.1 mrg This avoids 64-bit store from a FP register to a pretend args save area 5727 1.1 mrg and subsequent 32-bit load from the saved location to a FP register. 5728 1.1 mrg 5729 1.1 mrg Note that 32-bit loads and stores to/from a FP register on alpha reorder 5730 1.1 mrg bits to form a canonical 64-bit value in the FP register. This fact 5731 1.1 mrg invalidates compiler assumption that 32-bit FP value lives in the lower 5732 1.1 mrg 32-bits of the passed 64-bit FP value, so loading the 32-bit value from 5733 1.1 mrg the stored 64-bit location using 32-bit FP load is invalid on alpha. 5734 1.1 mrg 5735 1.1 mrg This introduces sort of ABI incompatibility, but until _Float32 was 5736 1.1 mrg introduced, C-family languages promoted 32-bit float variable arg to 5737 1.1 mrg a 64-bit double, and it was not allowed to pass float as a varible 5738 1.1 mrg argument. Passing _Complex float as a variable argument never 5739 1.1 mrg worked on alpha. Thus, we have no backward compatibility issues 5740 1.1 mrg to worry about, and passing unpromoted _Float32 and _Complex float 5741 1.1 mrg as a variable argument will actually work in the future. */ 5742 1.1 mrg 5743 1.1 mrg if (arg.mode == SFmode || arg.mode == SCmode) 5744 1.1 mrg return !arg.named; 5745 1.1 mrg 5746 1.1 mrg return arg.mode == TFmode || arg.mode == TCmode; 5747 1.1 mrg } 5748 1.1 mrg 5749 1.1 mrg /* Define how to find the value returned by a function. VALTYPE is the 5750 1.1 mrg data type of the value (as a tree). If the precise function being 5751 1.1 mrg called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. 5752 1.1 mrg MODE is set instead of VALTYPE for libcalls. 5753 1.1 mrg 5754 1.1 mrg On Alpha the value is found in $0 for integer functions and 5755 1.1 mrg $f0 for floating-point functions. */ 5756 1.1 mrg 5757 1.1 mrg static rtx 5758 1.1 mrg alpha_function_value_1 (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, 5759 1.1 mrg machine_mode mode) 5760 1.1 mrg { 5761 1.1 mrg unsigned int regnum, dummy ATTRIBUTE_UNUSED; 5762 1.1 mrg enum mode_class mclass; 5763 1.1 mrg 5764 1.1 mrg gcc_assert (!valtype || !alpha_return_in_memory (valtype, func)); 5765 1.1 mrg 5766 1.1 mrg if (valtype) 5767 1.1 mrg mode = TYPE_MODE (valtype); 5768 1.1 mrg 5769 1.1 mrg mclass = GET_MODE_CLASS (mode); 5770 1.1 mrg switch (mclass) 5771 1.1 mrg { 5772 1.1 mrg case MODE_INT: 5773 1.1 mrg /* Do the same thing as PROMOTE_MODE except for libcalls on VMS, 5774 1.1 mrg where we have them returning both SImode and DImode. */ 5775 1.1 mrg if (!(TARGET_ABI_OPEN_VMS && valtype && AGGREGATE_TYPE_P (valtype))) 5776 1.1 mrg PROMOTE_MODE (mode, dummy, valtype); 5777 1.1 mrg /* FALLTHRU */ 5778 1.1 mrg 5779 1.1 mrg case MODE_COMPLEX_INT: 5780 1.1 mrg case MODE_VECTOR_INT: 5781 1.1 mrg regnum = 0; 5782 1.1 mrg break; 5783 1.1 mrg 5784 1.1 mrg case MODE_FLOAT: 5785 1.1 mrg regnum = 32; 5786 1.1 mrg break; 5787 1.1 mrg 5788 1.1 mrg case MODE_COMPLEX_FLOAT: 5789 1.1 mrg { 5790 1.1 mrg machine_mode cmode = GET_MODE_INNER (mode); 5791 1.1 mrg 5792 1.1 mrg return gen_rtx_PARALLEL 5793 1.1 mrg (VOIDmode, 5794 1.1 mrg gen_rtvec (2, 5795 1.1 mrg gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32), 5796 1.1 mrg const0_rtx), 5797 1.1 mrg gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33), 5798 1.1 mrg GEN_INT (GET_MODE_SIZE (cmode))))); 5799 1.1 mrg } 5800 1.1 mrg 5801 1.1 mrg case MODE_RANDOM: 5802 1.1 mrg /* We should only reach here for BLKmode on VMS. */ 5803 1.1 mrg gcc_assert (TARGET_ABI_OPEN_VMS && mode == BLKmode); 5804 1.1 mrg regnum = 0; 5805 1.1 mrg break; 5806 1.1 mrg 5807 1.1 mrg default: 5808 1.1 mrg gcc_unreachable (); 5809 1.1 mrg } 5810 1.1 mrg 5811 1.1 mrg return gen_rtx_REG (mode, regnum); 5812 1.1 mrg } 5813 1.1 mrg 5814 1.1 mrg /* Implement TARGET_FUNCTION_VALUE. */ 5815 1.1 mrg 5816 1.1 mrg static rtx 5817 1.1 mrg alpha_function_value (const_tree valtype, const_tree fn_decl_or_type, 5818 1.1 mrg bool /*outgoing*/) 5819 1.1 mrg { 5820 1.1 mrg return alpha_function_value_1 (valtype, fn_decl_or_type, VOIDmode); 5821 1.1 mrg } 5822 1.1 mrg 5823 1.1 mrg /* Implement TARGET_LIBCALL_VALUE. */ 5824 1.1 mrg 5825 1.1 mrg static rtx 5826 1.1 mrg alpha_libcall_value (machine_mode mode, const_rtx /*fun*/) 5827 1.1 mrg { 5828 1.1 mrg return alpha_function_value_1 (NULL_TREE, NULL_TREE, mode); 5829 1.1 mrg } 5830 1.1 mrg 5831 1.1 mrg /* Implement TARGET_FUNCTION_VALUE_REGNO_P. 5832 1.1 mrg 5833 1.1 mrg On the Alpha, $0 $1 and $f0 $f1 are the only register thus used. */ 5834 1.1 mrg 5835 1.1 mrg static bool 5836 1.1 mrg alpha_function_value_regno_p (const unsigned int regno) 5837 1.1 mrg { 5838 1.1 mrg return (regno == 0 || regno == 1 || regno == 32 || regno == 33); 5839 1.1 mrg } 5840 1.1 mrg 5841 1.1 mrg /* TCmode complex values are passed by invisible reference. We 5842 1.1 mrg should not split these values. */ 5843 1.1 mrg 5844 1.1 mrg static bool 5845 1.1 mrg alpha_split_complex_arg (const_tree type) 5846 1.1 mrg { 5847 1.1 mrg return TYPE_MODE (type) != TCmode; 5848 1.1 mrg } 5849 1.1 mrg 5850 1.1 mrg static tree 5851 1.1 mrg alpha_build_builtin_va_list (void) 5852 1.1 mrg { 5853 1.1 mrg tree base, ofs, space, record, type_decl; 5854 1.1 mrg 5855 1.1 mrg if (TARGET_ABI_OPEN_VMS) 5856 1.1 mrg return ptr_type_node; 5857 1.1 mrg 5858 1.1 mrg record = (*lang_hooks.types.make_type) (RECORD_TYPE); 5859 1.1 mrg type_decl = build_decl (BUILTINS_LOCATION, 5860 1.1 mrg TYPE_DECL, get_identifier ("__va_list_tag"), record); 5861 1.1 mrg TYPE_STUB_DECL (record) = type_decl; 5862 1.1 mrg TYPE_NAME (record) = type_decl; 5863 1.1 mrg 5864 1.1 mrg /* C++? SET_IS_AGGR_TYPE (record, 1); */ 5865 1.1 mrg 5866 1.1 mrg /* Dummy field to prevent alignment warnings. */ 5867 1.1 mrg space = build_decl (BUILTINS_LOCATION, 5868 1.1 mrg FIELD_DECL, NULL_TREE, integer_type_node); 5869 1.1 mrg DECL_FIELD_CONTEXT (space) = record; 5870 1.1 mrg DECL_ARTIFICIAL (space) = 1; 5871 1.1 mrg DECL_IGNORED_P (space) = 1; 5872 1.1 mrg 5873 1.1 mrg ofs = build_decl (BUILTINS_LOCATION, 5874 1.1 mrg FIELD_DECL, get_identifier ("__offset"), 5875 1.1 mrg integer_type_node); 5876 1.1 mrg DECL_FIELD_CONTEXT (ofs) = record; 5877 1.1 mrg DECL_CHAIN (ofs) = space; 5878 1.1 mrg 5879 1.1 mrg base = build_decl (BUILTINS_LOCATION, 5880 1.1 mrg FIELD_DECL, get_identifier ("__base"), 5881 1.1 mrg ptr_type_node); 5882 1.1 mrg DECL_FIELD_CONTEXT (base) = record; 5883 1.1 mrg DECL_CHAIN (base) = ofs; 5884 1.1 mrg 5885 1.1 mrg TYPE_FIELDS (record) = base; 5886 1.1 mrg layout_type (record); 5887 1.1 mrg 5888 1.1 mrg va_list_gpr_counter_field = ofs; 5889 1.1 mrg return record; 5890 1.1 mrg } 5891 1.1 mrg 5892 1.1 mrg #if TARGET_ABI_OSF 5893 1.1 mrg /* Helper function for alpha_stdarg_optimize_hook. Skip over casts 5894 1.1 mrg and constant additions. */ 5895 1.1 mrg 5896 1.1 mrg static gimple * 5897 1.1 mrg va_list_skip_additions (tree lhs) 5898 1.1 mrg { 5899 1.1 mrg gimple *stmt; 5900 1.1 mrg 5901 1.1 mrg for (;;) 5902 1.1 mrg { 5903 1.1 mrg enum tree_code code; 5904 1.1 mrg 5905 1.1 mrg stmt = SSA_NAME_DEF_STMT (lhs); 5906 1.1 mrg 5907 1.1 mrg if (gimple_code (stmt) == GIMPLE_PHI) 5908 1.1 mrg return stmt; 5909 1.1 mrg 5910 1.1 mrg if (!is_gimple_assign (stmt) 5911 1.1 mrg || gimple_assign_lhs (stmt) != lhs) 5912 1.1 mrg return NULL; 5913 1.1 mrg 5914 1.1 mrg if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME) 5915 1.1 mrg return stmt; 5916 1.1 mrg code = gimple_assign_rhs_code (stmt); 5917 1.1 mrg if (!CONVERT_EXPR_CODE_P (code) 5918 1.1 mrg && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR) 5919 1.1 mrg || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST 5920 1.1 mrg || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt)))) 5921 1.1 mrg return stmt; 5922 1.1 mrg 5923 1.1 mrg lhs = gimple_assign_rhs1 (stmt); 5924 1.1 mrg } 5925 1.1 mrg } 5926 1.1 mrg 5927 1.1 mrg /* Check if LHS = RHS statement is 5928 1.1 mrg LHS = *(ap.__base + ap.__offset + cst) 5929 1.1 mrg or 5930 1.1 mrg LHS = *(ap.__base 5931 1.1 mrg + ((ap.__offset + cst <= 47) 5932 1.1 mrg ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2). 5933 1.1 mrg If the former, indicate that GPR registers are needed, 5934 1.1 mrg if the latter, indicate that FPR registers are needed. 5935 1.1 mrg 5936 1.1 mrg Also look for LHS = (*ptr).field, where ptr is one of the forms 5937 1.1 mrg listed above. 5938 1.1 mrg 5939 1.1 mrg On alpha, cfun->va_list_gpr_size is used as size of the needed 5940 1.1 mrg regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR 5941 1.1 mrg registers are needed and bit 1 set if FPR registers are needed. 5942 1.1 mrg Return true if va_list references should not be scanned for the 5943 1.1 mrg current statement. */ 5944 1.1 mrg 5945 1.1 mrg static bool 5946 1.1 mrg alpha_stdarg_optimize_hook (struct stdarg_info *si, const gimple *stmt) 5947 1.1 mrg { 5948 1.1 mrg tree base, offset, rhs; 5949 1.1 mrg int offset_arg = 1; 5950 1.1 mrg gimple *base_stmt; 5951 1.1 mrg 5952 1.1 mrg if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) 5953 1.1 mrg != GIMPLE_SINGLE_RHS) 5954 1.1 mrg return false; 5955 1.1 mrg 5956 1.1 mrg rhs = gimple_assign_rhs1 (stmt); 5957 1.1 mrg while (handled_component_p (rhs)) 5958 1.1 mrg rhs = TREE_OPERAND (rhs, 0); 5959 1.1 mrg if (TREE_CODE (rhs) != MEM_REF 5960 1.1 mrg || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME) 5961 1.1 mrg return false; 5962 1.1 mrg 5963 1.1 mrg stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0)); 5964 1.1 mrg if (stmt == NULL 5965 1.1 mrg || !is_gimple_assign (stmt) 5966 1.1 mrg || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR) 5967 1.1 mrg return false; 5968 1.1 mrg 5969 1.1 mrg base = gimple_assign_rhs1 (stmt); 5970 1.1 mrg if (TREE_CODE (base) == SSA_NAME) 5971 1.1 mrg { 5972 1.1 mrg base_stmt = va_list_skip_additions (base); 5973 1.1 mrg if (base_stmt 5974 1.1 mrg && is_gimple_assign (base_stmt) 5975 1.1 mrg && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF) 5976 1.1 mrg base = gimple_assign_rhs1 (base_stmt); 5977 1.1 mrg } 5978 1.1 mrg 5979 1.1 mrg if (TREE_CODE (base) != COMPONENT_REF 5980 1.1 mrg || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) 5981 1.1 mrg { 5982 1.1 mrg base = gimple_assign_rhs2 (stmt); 5983 1.1 mrg if (TREE_CODE (base) == SSA_NAME) 5984 1.1 mrg { 5985 1.1 mrg base_stmt = va_list_skip_additions (base); 5986 1.1 mrg if (base_stmt 5987 1.1 mrg && is_gimple_assign (base_stmt) 5988 1.1 mrg && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF) 5989 1.1 mrg base = gimple_assign_rhs1 (base_stmt); 5990 1.1 mrg } 5991 1.1 mrg 5992 1.1 mrg if (TREE_CODE (base) != COMPONENT_REF 5993 1.1 mrg || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) 5994 1.1 mrg return false; 5995 1.1 mrg 5996 1.1 mrg offset_arg = 0; 5997 1.1 mrg } 5998 1.1 mrg 5999 1.1 mrg base = get_base_address (base); 6000 1.1 mrg if (TREE_CODE (base) != VAR_DECL 6001 1.1 mrg || !bitmap_bit_p (si->va_list_vars, DECL_UID (base) + num_ssa_names)) 6002 1.1 mrg return false; 6003 1.1 mrg 6004 1.1 mrg offset = gimple_op (stmt, 1 + offset_arg); 6005 1.1 mrg if (TREE_CODE (offset) == SSA_NAME) 6006 1.1 mrg { 6007 1.1 mrg gimple *offset_stmt = va_list_skip_additions (offset); 6008 1.1 mrg 6009 1.1 mrg if (offset_stmt 6010 1.1 mrg && gimple_code (offset_stmt) == GIMPLE_PHI) 6011 1.1 mrg { 6012 1.1 mrg HOST_WIDE_INT sub; 6013 1.1 mrg gimple *arg1_stmt, *arg2_stmt; 6014 1.1 mrg tree arg1, arg2; 6015 1.1 mrg enum tree_code code1, code2; 6016 1.1 mrg 6017 1.1 mrg if (gimple_phi_num_args (offset_stmt) != 2) 6018 1.1 mrg goto escapes; 6019 1.1 mrg 6020 1.1 mrg arg1_stmt 6021 1.1 mrg = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0)); 6022 1.1 mrg arg2_stmt 6023 1.1 mrg = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1)); 6024 1.1 mrg if (arg1_stmt == NULL 6025 1.1 mrg || !is_gimple_assign (arg1_stmt) 6026 1.1 mrg || arg2_stmt == NULL 6027 1.1 mrg || !is_gimple_assign (arg2_stmt)) 6028 1.1 mrg goto escapes; 6029 1.1 mrg 6030 1.1 mrg code1 = gimple_assign_rhs_code (arg1_stmt); 6031 1.1 mrg code2 = gimple_assign_rhs_code (arg2_stmt); 6032 1.1 mrg if (code1 == COMPONENT_REF 6033 1.1 mrg && (code2 == MINUS_EXPR || code2 == PLUS_EXPR)) 6034 1.1 mrg /* Do nothing. */; 6035 1.1 mrg else if (code2 == COMPONENT_REF 6036 1.1 mrg && (code1 == MINUS_EXPR || code1 == PLUS_EXPR)) 6037 1.1 mrg { 6038 1.1 mrg std::swap (arg1_stmt, arg2_stmt); 6039 1.1 mrg code2 = code1; 6040 1.1 mrg } 6041 1.1 mrg else 6042 1.1 mrg goto escapes; 6043 1.1 mrg 6044 1.1 mrg if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt))) 6045 1.1 mrg goto escapes; 6046 1.1 mrg 6047 1.1 mrg sub = tree_to_shwi (gimple_assign_rhs2 (arg2_stmt)); 6048 1.1 mrg if (code2 == MINUS_EXPR) 6049 1.1 mrg sub = -sub; 6050 1.1 mrg if (sub < -48 || sub > -32) 6051 1.1 mrg goto escapes; 6052 1.1 mrg 6053 1.1 mrg arg1 = gimple_assign_rhs1 (arg1_stmt); 6054 1.1 mrg arg2 = gimple_assign_rhs1 (arg2_stmt); 6055 1.1 mrg if (TREE_CODE (arg2) == SSA_NAME) 6056 1.1 mrg { 6057 1.1 mrg arg2_stmt = va_list_skip_additions (arg2); 6058 1.1 mrg if (arg2_stmt == NULL 6059 1.1 mrg || !is_gimple_assign (arg2_stmt) 6060 1.1 mrg || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF) 6061 1.1 mrg goto escapes; 6062 1.1 mrg arg2 = gimple_assign_rhs1 (arg2_stmt); 6063 1.1 mrg } 6064 1.1 mrg if (arg1 != arg2) 6065 1.1 mrg goto escapes; 6066 1.1 mrg 6067 1.1 mrg if (TREE_CODE (arg1) != COMPONENT_REF 6068 1.1 mrg || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field 6069 1.1 mrg || get_base_address (arg1) != base) 6070 1.1 mrg goto escapes; 6071 1.1 mrg 6072 1.1 mrg /* Need floating point regs. */ 6073 1.1 mrg cfun->va_list_fpr_size |= 2; 6074 1.1 mrg return false; 6075 1.1 mrg } 6076 1.1 mrg if (offset_stmt 6077 1.1 mrg && is_gimple_assign (offset_stmt) 6078 1.1 mrg && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF) 6079 1.1 mrg offset = gimple_assign_rhs1 (offset_stmt); 6080 1.1 mrg } 6081 1.1 mrg if (TREE_CODE (offset) != COMPONENT_REF 6082 1.1 mrg || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field 6083 1.1 mrg || get_base_address (offset) != base) 6084 1.1 mrg goto escapes; 6085 1.1 mrg else 6086 1.1 mrg /* Need general regs. */ 6087 1.1 mrg cfun->va_list_fpr_size |= 1; 6088 1.1 mrg return false; 6089 1.1 mrg 6090 1.1 mrg escapes: 6091 1.1 mrg si->va_list_escapes = true; 6092 1.1 mrg return false; 6093 1.1 mrg } 6094 1.1 mrg #endif 6095 1.1 mrg 6096 1.1 mrg /* Perform any needed actions needed for a function that is receiving a 6097 1.1 mrg variable number of arguments. */ 6098 1.1 mrg 6099 1.1 mrg static void 6100 1.1 mrg alpha_setup_incoming_varargs (cumulative_args_t pcum, 6101 1.1 mrg const function_arg_info &arg, 6102 1.1 mrg int *pretend_size, int no_rtl) 6103 1.1 mrg { 6104 1.1 mrg CUMULATIVE_ARGS cum = *get_cumulative_args (pcum); 6105 1.1 mrg 6106 1.1 mrg /* Skip the current argument. */ 6107 1.1 mrg targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg); 6108 1.1 mrg 6109 1.1 mrg #if TARGET_ABI_OPEN_VMS 6110 1.1 mrg /* For VMS, we allocate space for all 6 arg registers plus a count. 6111 1.1 mrg 6112 1.1 mrg However, if NO registers need to be saved, don't allocate any space. 6113 1.1 mrg This is not only because we won't need the space, but because AP 6114 1.1 mrg includes the current_pretend_args_size and we don't want to mess up 6115 1.1 mrg any ap-relative addresses already made. */ 6116 1.1 mrg if (cum.num_args < 6) 6117 1.1 mrg { 6118 1.1 mrg if (!no_rtl) 6119 1.1 mrg { 6120 1.1 mrg emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx); 6121 1.1 mrg emit_insn (gen_arg_home ()); 6122 1.1 mrg } 6123 1.1 mrg *pretend_size = 7 * UNITS_PER_WORD; 6124 1.1 mrg } 6125 1.1 mrg #else 6126 1.1 mrg /* On OSF/1 and friends, we allocate space for all 12 arg registers, but 6127 1.1 mrg only push those that are remaining. However, if NO registers need to 6128 1.1 mrg be saved, don't allocate any space. This is not only because we won't 6129 1.1 mrg need the space, but because AP includes the current_pretend_args_size 6130 1.1 mrg and we don't want to mess up any ap-relative addresses already made. 6131 1.1 mrg 6132 1.1 mrg If we are not to use the floating-point registers, save the integer 6133 1.1 mrg registers where we would put the floating-point registers. This is 6134 1.1 mrg not the most efficient way to implement varargs with just one register 6135 1.1 mrg class, but it isn't worth doing anything more efficient in this rare 6136 1.1 mrg case. */ 6137 1.1 mrg if (cum >= 6) 6138 1.1 mrg return; 6139 1.1 mrg 6140 1.1 mrg if (!no_rtl) 6141 1.1 mrg { 6142 1.1 mrg int count; 6143 1.1 mrg alias_set_type set = get_varargs_alias_set (); 6144 1.1 mrg rtx tmp; 6145 1.1 mrg 6146 1.1 mrg count = cfun->va_list_gpr_size / UNITS_PER_WORD; 6147 1.1 mrg if (count > 6 - cum) 6148 1.1 mrg count = 6 - cum; 6149 1.1 mrg 6150 1.1 mrg /* Detect whether integer registers or floating-point registers 6151 1.1 mrg are needed by the detected va_arg statements. See above for 6152 1.1 mrg how these values are computed. Note that the "escape" value 6153 1.1 mrg is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of 6154 1.1 mrg these bits set. */ 6155 1.1 mrg gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3); 6156 1.1 mrg 6157 1.1 mrg if (cfun->va_list_fpr_size & 1) 6158 1.1 mrg { 6159 1.1 mrg tmp = gen_rtx_MEM (BLKmode, 6160 1.1 mrg plus_constant (Pmode, virtual_incoming_args_rtx, 6161 1.1 mrg (cum + 6) * UNITS_PER_WORD)); 6162 1.1 mrg MEM_NOTRAP_P (tmp) = 1; 6163 1.1 mrg set_mem_alias_set (tmp, set); 6164 1.1 mrg move_block_from_reg (16 + cum, tmp, count); 6165 1.1 mrg } 6166 1.1 mrg 6167 1.1 mrg if (cfun->va_list_fpr_size & 2) 6168 1.1 mrg { 6169 1.1 mrg tmp = gen_rtx_MEM (BLKmode, 6170 1.1 mrg plus_constant (Pmode, virtual_incoming_args_rtx, 6171 1.1 mrg cum * UNITS_PER_WORD)); 6172 1.1 mrg MEM_NOTRAP_P (tmp) = 1; 6173 1.1 mrg set_mem_alias_set (tmp, set); 6174 1.1 mrg move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count); 6175 1.1 mrg } 6176 1.1 mrg } 6177 1.1 mrg *pretend_size = 12 * UNITS_PER_WORD; 6178 1.1 mrg #endif 6179 1.1 mrg } 6180 1.1 mrg 6181 1.1 mrg static void 6182 1.1 mrg alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) 6183 1.1 mrg { 6184 1.1 mrg HOST_WIDE_INT offset; 6185 1.1 mrg tree t, offset_field, base_field; 6186 1.1 mrg 6187 1.1 mrg if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK) 6188 1.1 mrg return; 6189 1.1 mrg 6190 1.1 mrg /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base 6191 1.1 mrg up by 48, storing fp arg registers in the first 48 bytes, and the 6192 1.1 mrg integer arg registers in the next 48 bytes. This is only done, 6193 1.1 mrg however, if any integer registers need to be stored. 6194 1.1 mrg 6195 1.1 mrg If no integer registers need be stored, then we must subtract 48 6196 1.1 mrg in order to account for the integer arg registers which are counted 6197 1.1 mrg in argsize above, but which are not actually stored on the stack. 6198 1.1 mrg Must further be careful here about structures straddling the last 6199 1.1 mrg integer argument register; that futzes with pretend_args_size, 6200 1.1 mrg which changes the meaning of AP. */ 6201 1.1 mrg 6202 1.1 mrg if (NUM_ARGS < 6) 6203 1.1 mrg offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD; 6204 1.1 mrg else 6205 1.1 mrg offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size; 6206 1.1 mrg 6207 1.1 mrg if (TARGET_ABI_OPEN_VMS) 6208 1.1 mrg { 6209 1.1 mrg t = make_tree (ptr_type_node, virtual_incoming_args_rtx); 6210 1.1 mrg t = fold_build_pointer_plus_hwi (t, offset + NUM_ARGS * UNITS_PER_WORD); 6211 1.1 mrg t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); 6212 1.1 mrg TREE_SIDE_EFFECTS (t) = 1; 6213 1.1 mrg expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 6214 1.1 mrg } 6215 1.1 mrg else 6216 1.1 mrg { 6217 1.1 mrg base_field = TYPE_FIELDS (TREE_TYPE (valist)); 6218 1.1 mrg offset_field = DECL_CHAIN (base_field); 6219 1.1 mrg 6220 1.1 mrg base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field), 6221 1.1 mrg valist, base_field, NULL_TREE); 6222 1.1 mrg offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field), 6223 1.1 mrg valist, offset_field, NULL_TREE); 6224 1.1 mrg 6225 1.1 mrg t = make_tree (ptr_type_node, virtual_incoming_args_rtx); 6226 1.1 mrg t = fold_build_pointer_plus_hwi (t, offset); 6227 1.1 mrg t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t); 6228 1.1 mrg TREE_SIDE_EFFECTS (t) = 1; 6229 1.1 mrg expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 6230 1.1 mrg 6231 1.1 mrg t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD); 6232 1.1 mrg t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t); 6233 1.1 mrg TREE_SIDE_EFFECTS (t) = 1; 6234 1.1 mrg expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 6235 1.1 mrg } 6236 1.1 mrg } 6237 1.1 mrg 6238 1.1 mrg static tree 6239 1.1 mrg alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, 6240 1.1 mrg gimple_seq *pre_p) 6241 1.1 mrg { 6242 1.1 mrg tree type_size, ptr_type, addend, t, addr; 6243 1.1 mrg gimple_seq internal_post; 6244 1.1 mrg 6245 1.1 mrg /* If the type could not be passed in registers, skip the block 6246 1.1 mrg reserved for the registers. */ 6247 1.1 mrg if (must_pass_va_arg_in_stack (type)) 6248 1.1 mrg { 6249 1.1 mrg t = build_int_cst (TREE_TYPE (offset), 6*8); 6250 1.1 mrg gimplify_assign (offset, 6251 1.1 mrg build2 (MAX_EXPR, TREE_TYPE (offset), offset, t), 6252 1.1 mrg pre_p); 6253 1.1 mrg } 6254 1.1 mrg 6255 1.1 mrg addend = offset; 6256 1.1 mrg ptr_type = build_pointer_type_for_mode (type, ptr_mode, true); 6257 1.1 mrg 6258 1.1 mrg if (TREE_CODE (type) == COMPLEX_TYPE) 6259 1.1 mrg { 6260 1.1 mrg tree real_part, imag_part, real_temp; 6261 1.1 mrg 6262 1.1 mrg real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base, 6263 1.1 mrg offset, pre_p); 6264 1.1 mrg 6265 1.1 mrg /* Copy the value into a new temporary, lest the formal temporary 6266 1.1 mrg be reused out from under us. */ 6267 1.1 mrg real_temp = get_initialized_tmp_var (real_part, pre_p, NULL); 6268 1.1 mrg 6269 1.1 mrg imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base, 6270 1.1 mrg offset, pre_p); 6271 1.1 mrg 6272 1.1 mrg return build2 (COMPLEX_EXPR, type, real_temp, imag_part); 6273 1.1 mrg } 6274 1.1 mrg else if (TREE_CODE (type) == REAL_TYPE) 6275 1.1 mrg { 6276 1.1 mrg tree fpaddend, cond, fourtyeight; 6277 1.1 mrg 6278 1.1 mrg fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8); 6279 1.1 mrg fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend), 6280 1.1 mrg addend, fourtyeight); 6281 1.1 mrg cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight); 6282 1.1 mrg addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond, 6283 1.1 mrg fpaddend, addend); 6284 1.1 mrg } 6285 1.1 mrg 6286 1.1 mrg /* Build the final address and force that value into a temporary. */ 6287 1.1 mrg addr = fold_build_pointer_plus (fold_convert (ptr_type, base), addend); 6288 1.1 mrg internal_post = NULL; 6289 1.1 mrg gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue); 6290 1.1 mrg gimple_seq_add_seq (pre_p, internal_post); 6291 1.1 mrg 6292 1.1 mrg /* Update the offset field. */ 6293 1.1 mrg type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)); 6294 1.1 mrg if (type_size == NULL || TREE_OVERFLOW (type_size)) 6295 1.1 mrg t = size_zero_node; 6296 1.1 mrg else 6297 1.1 mrg { 6298 1.1 mrg t = size_binop (PLUS_EXPR, type_size, size_int (7)); 6299 1.1 mrg t = size_binop (TRUNC_DIV_EXPR, t, size_int (8)); 6300 1.1 mrg t = size_binop (MULT_EXPR, t, size_int (8)); 6301 1.1 mrg } 6302 1.1 mrg t = fold_convert (TREE_TYPE (offset), t); 6303 1.1 mrg gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t), 6304 1.1 mrg pre_p); 6305 1.1 mrg 6306 1.1 mrg return build_va_arg_indirect_ref (addr); 6307 1.1 mrg } 6308 1.1 mrg 6309 1.1 mrg static tree 6310 1.1 mrg alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, 6311 1.1 mrg gimple_seq *post_p) 6312 1.1 mrg { 6313 1.1 mrg tree offset_field, base_field, offset, base, t, r; 6314 1.1 mrg bool indirect; 6315 1.1 mrg 6316 1.1 mrg if (TARGET_ABI_OPEN_VMS) 6317 1.1 mrg return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); 6318 1.1 mrg 6319 1.1 mrg base_field = TYPE_FIELDS (va_list_type_node); 6320 1.1 mrg offset_field = DECL_CHAIN (base_field); 6321 1.1 mrg base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field), 6322 1.1 mrg valist, base_field, NULL_TREE); 6323 1.1 mrg offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field), 6324 1.1 mrg valist, offset_field, NULL_TREE); 6325 1.1 mrg 6326 1.1 mrg /* Pull the fields of the structure out into temporaries. Since we never 6327 1.1 mrg modify the base field, we can use a formal temporary. Sign-extend the 6328 1.1 mrg offset field so that it's the proper width for pointer arithmetic. */ 6329 1.1 mrg base = get_formal_tmp_var (base_field, pre_p); 6330 1.1 mrg 6331 1.1 mrg t = fold_convert (build_nonstandard_integer_type (64, 0), offset_field); 6332 1.1 mrg offset = get_initialized_tmp_var (t, pre_p, NULL); 6333 1.1 mrg 6334 1.1 mrg indirect = pass_va_arg_by_reference (type); 6335 1.1 mrg 6336 1.1 mrg if (indirect) 6337 1.1 mrg { 6338 1.1 mrg if (TREE_CODE (type) == COMPLEX_TYPE 6339 1.1 mrg && targetm.calls.split_complex_arg (type)) 6340 1.1 mrg { 6341 1.1 mrg tree real_part, imag_part, real_temp; 6342 1.1 mrg 6343 1.1 mrg tree ptr_type = build_pointer_type_for_mode (TREE_TYPE (type), 6344 1.1 mrg ptr_mode, true); 6345 1.1 mrg 6346 1.1 mrg real_part = alpha_gimplify_va_arg_1 (ptr_type, base, 6347 1.1 mrg offset, pre_p); 6348 1.1 mrg real_part = build_va_arg_indirect_ref (real_part); 6349 1.1 mrg 6350 1.1 mrg /* Copy the value into a new temporary, lest the formal temporary 6351 1.1 mrg be reused out from under us. */ 6352 1.1 mrg real_temp = get_initialized_tmp_var (real_part, pre_p, NULL); 6353 1.1 mrg 6354 1.1 mrg imag_part = alpha_gimplify_va_arg_1 (ptr_type, base, 6355 1.1 mrg offset, pre_p); 6356 1.1 mrg imag_part = build_va_arg_indirect_ref (imag_part); 6357 1.1 mrg 6358 1.1 mrg r = build2 (COMPLEX_EXPR, type, real_temp, imag_part); 6359 1.1 mrg 6360 1.1 mrg /* Stuff the offset temporary back into its field. */ 6361 1.1 mrg gimplify_assign (unshare_expr (offset_field), 6362 1.1 mrg fold_convert (TREE_TYPE (offset_field), offset), 6363 1.1 mrg pre_p); 6364 1.1 mrg return r; 6365 1.1 mrg } 6366 1.1 mrg else 6367 1.1 mrg type = build_pointer_type_for_mode (type, ptr_mode, true); 6368 1.1 mrg } 6369 1.1 mrg 6370 1.1 mrg /* Find the value. Note that this will be a stable indirection, or 6371 1.1 mrg a composite of stable indirections in the case of complex. */ 6372 1.1 mrg r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p); 6373 1.1 mrg 6374 1.1 mrg /* Stuff the offset temporary back into its field. */ 6375 1.1 mrg gimplify_assign (unshare_expr (offset_field), 6376 1.1 mrg fold_convert (TREE_TYPE (offset_field), offset), pre_p); 6377 1.1 mrg 6378 1.1 mrg if (indirect) 6379 1.1 mrg r = build_va_arg_indirect_ref (r); 6380 1.1 mrg 6381 1.1 mrg return r; 6382 1.1 mrg } 6383 1.1 mrg 6384 1.1 mrg /* Builtins. */ 6386 1.1 mrg 6387 1.1 mrg enum alpha_builtin 6388 1.1 mrg { 6389 1.1 mrg ALPHA_BUILTIN_CMPBGE, 6390 1.1 mrg ALPHA_BUILTIN_EXTBL, 6391 1.1 mrg ALPHA_BUILTIN_EXTWL, 6392 1.1 mrg ALPHA_BUILTIN_EXTLL, 6393 1.1 mrg ALPHA_BUILTIN_EXTQL, 6394 1.1 mrg ALPHA_BUILTIN_EXTWH, 6395 1.1 mrg ALPHA_BUILTIN_EXTLH, 6396 1.1 mrg ALPHA_BUILTIN_EXTQH, 6397 1.1 mrg ALPHA_BUILTIN_INSBL, 6398 1.1 mrg ALPHA_BUILTIN_INSWL, 6399 1.1 mrg ALPHA_BUILTIN_INSLL, 6400 1.1 mrg ALPHA_BUILTIN_INSQL, 6401 1.1 mrg ALPHA_BUILTIN_INSWH, 6402 1.1 mrg ALPHA_BUILTIN_INSLH, 6403 1.1 mrg ALPHA_BUILTIN_INSQH, 6404 1.1 mrg ALPHA_BUILTIN_MSKBL, 6405 1.1 mrg ALPHA_BUILTIN_MSKWL, 6406 1.1 mrg ALPHA_BUILTIN_MSKLL, 6407 1.1 mrg ALPHA_BUILTIN_MSKQL, 6408 1.1 mrg ALPHA_BUILTIN_MSKWH, 6409 1.1 mrg ALPHA_BUILTIN_MSKLH, 6410 1.1 mrg ALPHA_BUILTIN_MSKQH, 6411 1.1 mrg ALPHA_BUILTIN_UMULH, 6412 1.1 mrg ALPHA_BUILTIN_ZAP, 6413 1.1 mrg ALPHA_BUILTIN_ZAPNOT, 6414 1.1 mrg ALPHA_BUILTIN_AMASK, 6415 1.1 mrg ALPHA_BUILTIN_IMPLVER, 6416 1.1 mrg ALPHA_BUILTIN_RPCC, 6417 1.1 mrg ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER, 6418 1.1 mrg ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 6419 1.1 mrg 6420 1.1 mrg /* TARGET_MAX */ 6421 1.1 mrg ALPHA_BUILTIN_MINUB8, 6422 1.1 mrg ALPHA_BUILTIN_MINSB8, 6423 1.1 mrg ALPHA_BUILTIN_MINUW4, 6424 1.1 mrg ALPHA_BUILTIN_MINSW4, 6425 1.1 mrg ALPHA_BUILTIN_MAXUB8, 6426 1.1 mrg ALPHA_BUILTIN_MAXSB8, 6427 1.1 mrg ALPHA_BUILTIN_MAXUW4, 6428 1.1 mrg ALPHA_BUILTIN_MAXSW4, 6429 1.1 mrg ALPHA_BUILTIN_PERR, 6430 1.1 mrg ALPHA_BUILTIN_PKLB, 6431 1.1 mrg ALPHA_BUILTIN_PKWB, 6432 1.1 mrg ALPHA_BUILTIN_UNPKBL, 6433 1.1 mrg ALPHA_BUILTIN_UNPKBW, 6434 1.1 mrg 6435 1.1 mrg /* TARGET_CIX */ 6436 1.1 mrg ALPHA_BUILTIN_CTTZ, 6437 1.1 mrg ALPHA_BUILTIN_CTLZ, 6438 1.1 mrg ALPHA_BUILTIN_CTPOP, 6439 1.1 mrg 6440 1.1 mrg ALPHA_BUILTIN_max 6441 1.1 mrg }; 6442 1.1 mrg 6443 1.1 mrg static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = { 6444 1.1 mrg CODE_FOR_builtin_cmpbge, 6445 1.1 mrg CODE_FOR_extbl, 6446 1.1 mrg CODE_FOR_extwl, 6447 1.1 mrg CODE_FOR_extll, 6448 1.1 mrg CODE_FOR_extql, 6449 1.1 mrg CODE_FOR_extwh, 6450 1.1 mrg CODE_FOR_extlh, 6451 1.1 mrg CODE_FOR_extqh, 6452 1.1 mrg CODE_FOR_builtin_insbl, 6453 1.1 mrg CODE_FOR_builtin_inswl, 6454 1.1 mrg CODE_FOR_builtin_insll, 6455 1.1 mrg CODE_FOR_insql, 6456 1.1 mrg CODE_FOR_inswh, 6457 1.1 mrg CODE_FOR_inslh, 6458 1.1 mrg CODE_FOR_insqh, 6459 1.1 mrg CODE_FOR_mskbl, 6460 1.1 mrg CODE_FOR_mskwl, 6461 1.1 mrg CODE_FOR_mskll, 6462 1.1 mrg CODE_FOR_mskql, 6463 1.1 mrg CODE_FOR_mskwh, 6464 1.1 mrg CODE_FOR_msklh, 6465 1.1 mrg CODE_FOR_mskqh, 6466 1.1 mrg CODE_FOR_umuldi3_highpart, 6467 1.1 mrg CODE_FOR_builtin_zap, 6468 1.1 mrg CODE_FOR_builtin_zapnot, 6469 1.1 mrg CODE_FOR_builtin_amask, 6470 1.1 mrg CODE_FOR_builtin_implver, 6471 1.1 mrg CODE_FOR_builtin_rpcc, 6472 1.1 mrg CODE_FOR_builtin_establish_vms_condition_handler, 6473 1.1 mrg CODE_FOR_builtin_revert_vms_condition_handler, 6474 1.1 mrg 6475 1.1 mrg /* TARGET_MAX */ 6476 1.1 mrg CODE_FOR_builtin_minub8, 6477 1.1 mrg CODE_FOR_builtin_minsb8, 6478 1.1 mrg CODE_FOR_builtin_minuw4, 6479 1.1 mrg CODE_FOR_builtin_minsw4, 6480 1.1 mrg CODE_FOR_builtin_maxub8, 6481 1.1 mrg CODE_FOR_builtin_maxsb8, 6482 1.1 mrg CODE_FOR_builtin_maxuw4, 6483 1.1 mrg CODE_FOR_builtin_maxsw4, 6484 1.1 mrg CODE_FOR_builtin_perr, 6485 1.1 mrg CODE_FOR_builtin_pklb, 6486 1.1 mrg CODE_FOR_builtin_pkwb, 6487 1.1 mrg CODE_FOR_builtin_unpkbl, 6488 1.1 mrg CODE_FOR_builtin_unpkbw, 6489 1.1 mrg 6490 1.1 mrg /* TARGET_CIX */ 6491 1.1 mrg CODE_FOR_ctzdi2, 6492 1.1 mrg CODE_FOR_clzdi2, 6493 1.1 mrg CODE_FOR_popcountdi2 6494 1.1 mrg }; 6495 1.1 mrg 6496 1.1 mrg struct alpha_builtin_def 6497 1.1 mrg { 6498 1.1 mrg const char *name; 6499 1.1 mrg enum alpha_builtin code; 6500 1.1 mrg unsigned int target_mask; 6501 1.1 mrg bool is_const; 6502 1.1 mrg }; 6503 1.1 mrg 6504 1.1 mrg static struct alpha_builtin_def const zero_arg_builtins[] = { 6505 1.1 mrg { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0, true }, 6506 1.1 mrg { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0, false } 6507 1.1 mrg }; 6508 1.1 mrg 6509 1.1 mrg static struct alpha_builtin_def const one_arg_builtins[] = { 6510 1.1 mrg { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0, true }, 6511 1.1 mrg { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX, true }, 6512 1.1 mrg { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX, true }, 6513 1.1 mrg { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX, true }, 6514 1.1 mrg { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX, true }, 6515 1.1 mrg { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX, true }, 6516 1.1 mrg { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX, true }, 6517 1.1 mrg { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX, true } 6518 1.1 mrg }; 6519 1.1 mrg 6520 1.1 mrg static struct alpha_builtin_def const two_arg_builtins[] = { 6521 1.1 mrg { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0, true }, 6522 1.1 mrg { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0, true }, 6523 1.1 mrg { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0, true }, 6524 1.1 mrg { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0, true }, 6525 1.1 mrg { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0, true }, 6526 1.1 mrg { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0, true }, 6527 1.1 mrg { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0, true }, 6528 1.1 mrg { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0, true }, 6529 1.1 mrg { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0, true }, 6530 1.1 mrg { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0, true }, 6531 1.1 mrg { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0, true }, 6532 1.1 mrg { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0, true }, 6533 1.1 mrg { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0, true }, 6534 1.1 mrg { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0, true }, 6535 1.1 mrg { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0, true }, 6536 1.1 mrg { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0, true }, 6537 1.1 mrg { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0, true }, 6538 1.1 mrg { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0, true }, 6539 1.1 mrg { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0, true }, 6540 1.1 mrg { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0, true }, 6541 1.1 mrg { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0, true }, 6542 1.1 mrg { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0, true }, 6543 1.1 mrg { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0, true }, 6544 1.1 mrg { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0, true }, 6545 1.1 mrg { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0, true }, 6546 1.1 mrg { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX, true }, 6547 1.1 mrg { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX, true }, 6548 1.1 mrg { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX, true }, 6549 1.1 mrg { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX, true }, 6550 1.1 mrg { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX, true }, 6551 1.1 mrg { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX, true }, 6552 1.1 mrg { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX, true }, 6553 1.1 mrg { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX, true }, 6554 1.1 mrg { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX, true } 6555 1.1 mrg }; 6556 1.1 mrg 6557 1.1 mrg static GTY(()) tree alpha_dimode_u; 6558 1.1 mrg static GTY(()) tree alpha_v8qi_u; 6559 1.1 mrg static GTY(()) tree alpha_v8qi_s; 6560 1.1 mrg static GTY(()) tree alpha_v4hi_u; 6561 1.1 mrg static GTY(()) tree alpha_v4hi_s; 6562 1.1 mrg 6563 1.1 mrg static GTY(()) tree alpha_builtins[(int) ALPHA_BUILTIN_max]; 6564 1.1 mrg 6565 1.1 mrg /* Return the alpha builtin for CODE. */ 6566 1.1 mrg 6567 1.1 mrg static tree 6568 1.1 mrg alpha_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 6569 1.1 mrg { 6570 1.1 mrg if (code >= ALPHA_BUILTIN_max) 6571 1.1 mrg return error_mark_node; 6572 1.1 mrg return alpha_builtins[code]; 6573 1.1 mrg } 6574 1.1 mrg 6575 1.1 mrg /* Helper function of alpha_init_builtins. Add the built-in specified 6576 1.1 mrg by NAME, TYPE, CODE, and ECF. */ 6577 1.1 mrg 6578 1.1 mrg static void 6579 1.1 mrg alpha_builtin_function (const char *name, tree ftype, 6580 1.1 mrg enum alpha_builtin code, unsigned ecf) 6581 1.1 mrg { 6582 1.1 mrg tree decl = add_builtin_function (name, ftype, (int) code, 6583 1.1 mrg BUILT_IN_MD, NULL, NULL_TREE); 6584 1.1 mrg 6585 1.1 mrg if (ecf & ECF_CONST) 6586 1.1 mrg TREE_READONLY (decl) = 1; 6587 1.1 mrg if (ecf & ECF_NOTHROW) 6588 1.1 mrg TREE_NOTHROW (decl) = 1; 6589 1.1 mrg 6590 1.1 mrg alpha_builtins [(int) code] = decl; 6591 1.1 mrg } 6592 1.1 mrg 6593 1.1 mrg /* Helper function of alpha_init_builtins. Add the COUNT built-in 6594 1.1 mrg functions pointed to by P, with function type FTYPE. */ 6595 1.1 mrg 6596 1.1 mrg static void 6597 1.1 mrg alpha_add_builtins (const struct alpha_builtin_def *p, size_t count, 6598 1.1 mrg tree ftype) 6599 1.1 mrg { 6600 1.1 mrg size_t i; 6601 1.1 mrg 6602 1.1 mrg for (i = 0; i < count; ++i, ++p) 6603 1.1 mrg if ((target_flags & p->target_mask) == p->target_mask) 6604 1.1 mrg alpha_builtin_function (p->name, ftype, p->code, 6605 1.1 mrg (p->is_const ? ECF_CONST : 0) | ECF_NOTHROW); 6606 1.1 mrg } 6607 1.1 mrg 6608 1.1 mrg static void 6609 1.1 mrg alpha_init_builtins (void) 6610 1.1 mrg { 6611 1.1 mrg tree ftype; 6612 1.1 mrg 6613 1.1 mrg alpha_dimode_u = lang_hooks.types.type_for_mode (DImode, 1); 6614 1.1 mrg alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8); 6615 1.1 mrg alpha_v8qi_s = build_vector_type (intQI_type_node, 8); 6616 1.1 mrg alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4); 6617 1.1 mrg alpha_v4hi_s = build_vector_type (intHI_type_node, 4); 6618 1.1 mrg 6619 1.1 mrg ftype = build_function_type_list (alpha_dimode_u, NULL_TREE); 6620 1.1 mrg alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins), ftype); 6621 1.1 mrg 6622 1.1 mrg ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u, NULL_TREE); 6623 1.1 mrg alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins), ftype); 6624 1.1 mrg 6625 1.1 mrg ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u, 6626 1.1 mrg alpha_dimode_u, NULL_TREE); 6627 1.1 mrg alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype); 6628 1.1 mrg 6629 1.1 mrg if (TARGET_ABI_OPEN_VMS) 6630 1.2 mrg { 6631 1.2 mrg ftype = build_function_type_list (ptr_type_node, ptr_type_node, 6632 1.2 mrg NULL_TREE); 6633 1.2 mrg alpha_builtin_function ("__builtin_establish_vms_condition_handler", 6634 1.1 mrg ftype, 6635 1.1 mrg ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER, 6636 1.1 mrg 0); 6637 1.1 mrg 6638 1.1 mrg ftype = build_function_type_list (ptr_type_node, void_type_node, 6639 1.1 mrg NULL_TREE); 6640 1.1 mrg alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype, 6641 1.1 mrg ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 0); 6642 1.1 mrg 6643 1.1 mrg vms_patch_builtins (); 6644 1.1 mrg } 6645 1.1 mrg 6646 1.1 mrg #ifdef SUBTARGET_INIT_BUILTINS 6647 1.1 mrg SUBTARGET_INIT_BUILTINS; 6648 1.1 mrg #endif 6649 1.1 mrg } 6650 1.1 mrg 6651 1.1 mrg /* Expand an expression EXP that calls a built-in function, 6652 1.1 mrg with result going to TARGET if that's convenient 6653 1.1 mrg (and in mode MODE if that's convenient). 6654 1.1 mrg SUBTARGET may be used as the target for computing one of EXP's operands. 6655 1.1 mrg IGNORE is nonzero if the value is to be ignored. */ 6656 1.1 mrg 6657 1.1 mrg static rtx 6658 1.1 mrg alpha_expand_builtin (tree exp, rtx target, 6659 1.1 mrg rtx subtarget ATTRIBUTE_UNUSED, 6660 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED, 6661 1.1 mrg int ignore ATTRIBUTE_UNUSED) 6662 1.1 mrg { 6663 1.1 mrg #define MAX_ARGS 2 6664 1.1 mrg 6665 1.1 mrg tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 6666 1.1 mrg unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 6667 1.1 mrg tree arg; 6668 1.1 mrg call_expr_arg_iterator iter; 6669 1.1 mrg enum insn_code icode; 6670 1.1 mrg rtx op[MAX_ARGS], pat; 6671 1.1 mrg int arity; 6672 1.1 mrg bool nonvoid; 6673 1.1 mrg 6674 1.1 mrg if (fcode >= ALPHA_BUILTIN_max) 6675 1.1 mrg internal_error ("bad builtin fcode"); 6676 1.1 mrg icode = code_for_builtin[fcode]; 6677 1.1 mrg if (icode == 0) 6678 1.1 mrg internal_error ("bad builtin fcode"); 6679 1.1 mrg 6680 1.1 mrg nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node; 6681 1.1 mrg 6682 1.1 mrg arity = 0; 6683 1.1 mrg FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 6684 1.1 mrg { 6685 1.1 mrg const struct insn_operand_data *insn_op; 6686 1.1 mrg 6687 1.1 mrg if (arg == error_mark_node) 6688 1.1 mrg return NULL_RTX; 6689 1.1 mrg if (arity > MAX_ARGS) 6690 1.1 mrg return NULL_RTX; 6691 1.1 mrg 6692 1.1 mrg insn_op = &insn_data[icode].operand[arity + nonvoid]; 6693 1.1 mrg 6694 1.1 mrg op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL); 6695 1.1 mrg 6696 1.1 mrg if (!(*insn_op->predicate) (op[arity], insn_op->mode)) 6697 1.1 mrg op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]); 6698 1.1 mrg arity++; 6699 1.1 mrg } 6700 1.1 mrg 6701 1.1 mrg if (nonvoid) 6702 1.1 mrg { 6703 1.1 mrg machine_mode tmode = insn_data[icode].operand[0].mode; 6704 1.1 mrg if (!target 6705 1.1 mrg || GET_MODE (target) != tmode 6706 1.1 mrg || !(*insn_data[icode].operand[0].predicate) (target, tmode)) 6707 1.1 mrg target = gen_reg_rtx (tmode); 6708 1.1 mrg } 6709 1.1 mrg 6710 1.1 mrg switch (arity) 6711 1.1 mrg { 6712 1.1 mrg case 0: 6713 1.1 mrg pat = GEN_FCN (icode) (target); 6714 1.1 mrg break; 6715 1.1 mrg case 1: 6716 1.1 mrg if (nonvoid) 6717 1.1 mrg pat = GEN_FCN (icode) (target, op[0]); 6718 1.1 mrg else 6719 1.1 mrg pat = GEN_FCN (icode) (op[0]); 6720 1.1 mrg break; 6721 1.1 mrg case 2: 6722 1.1 mrg pat = GEN_FCN (icode) (target, op[0], op[1]); 6723 1.1 mrg break; 6724 1.1 mrg default: 6725 1.1 mrg gcc_unreachable (); 6726 1.1 mrg } 6727 1.1 mrg if (!pat) 6728 1.1 mrg return NULL_RTX; 6729 1.1 mrg emit_insn (pat); 6730 1.1 mrg 6731 1.1 mrg if (nonvoid) 6732 1.1 mrg return target; 6733 1.1 mrg else 6734 1.1 mrg return const0_rtx; 6735 1.1 mrg } 6736 1.1 mrg 6737 1.1 mrg /* Fold the builtin for the CMPBGE instruction. This is a vector comparison 6738 1.1 mrg with an 8-bit output vector. OPINT contains the integer operands; bit N 6739 1.1 mrg of OP_CONST is set if OPINT[N] is valid. */ 6740 1.1 mrg 6741 1.1 mrg static tree 6742 1.1 mrg alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const) 6743 1.1 mrg { 6744 1.1 mrg if (op_const == 3) 6745 1.1 mrg { 6746 1.1 mrg int i, val; 6747 1.1 mrg for (i = 0, val = 0; i < 8; ++i) 6748 1.1 mrg { 6749 1.1 mrg unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff; 6750 1.1 mrg unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff; 6751 1.1 mrg if (c0 >= c1) 6752 1.1 mrg val |= 1 << i; 6753 1.1 mrg } 6754 1.1 mrg return build_int_cst (alpha_dimode_u, val); 6755 1.1 mrg } 6756 1.1 mrg else if (op_const == 2 && opint[1] == 0) 6757 1.1 mrg return build_int_cst (alpha_dimode_u, 0xff); 6758 1.1 mrg return NULL; 6759 1.1 mrg } 6760 1.1 mrg 6761 1.1 mrg /* Fold the builtin for the ZAPNOT instruction. This is essentially a 6762 1.1 mrg specialized form of an AND operation. Other byte manipulation instructions 6763 1.1 mrg are defined in terms of this instruction, so this is also used as a 6764 1.1 mrg subroutine for other builtins. 6765 1.1 mrg 6766 1.1 mrg OP contains the tree operands; OPINT contains the extracted integer values. 6767 1.1 mrg Bit N of OP_CONST it set if OPINT[N] is valid. OP may be null if only 6768 1.1 mrg OPINT may be considered. */ 6769 1.1 mrg 6770 1.1 mrg static tree 6771 1.1 mrg alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[], 6772 1.1 mrg long op_const) 6773 1.1 mrg { 6774 1.1 mrg if (op_const & 2) 6775 1.1 mrg { 6776 1.1 mrg unsigned HOST_WIDE_INT mask = 0; 6777 1.1 mrg int i; 6778 1.1 mrg 6779 1.1 mrg for (i = 0; i < 8; ++i) 6780 1.1 mrg if ((opint[1] >> i) & 1) 6781 1.1 mrg mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8); 6782 1.1 mrg 6783 1.1 mrg if (op_const & 1) 6784 1.1 mrg return build_int_cst (alpha_dimode_u, opint[0] & mask); 6785 1.1 mrg 6786 1.1 mrg if (op) 6787 1.1 mrg return fold_build2 (BIT_AND_EXPR, alpha_dimode_u, op[0], 6788 1.1 mrg build_int_cst (alpha_dimode_u, mask)); 6789 1.1 mrg } 6790 1.1 mrg else if ((op_const & 1) && opint[0] == 0) 6791 1.1 mrg return build_int_cst (alpha_dimode_u, 0); 6792 1.1 mrg return NULL; 6793 1.1 mrg } 6794 1.1 mrg 6795 1.1 mrg /* Fold the builtins for the EXT family of instructions. */ 6796 1.1 mrg 6797 1.1 mrg static tree 6798 1.1 mrg alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[], 6799 1.1 mrg long op_const, unsigned HOST_WIDE_INT bytemask, 6800 1.1 mrg bool is_high) 6801 1.1 mrg { 6802 1.1 mrg long zap_const = 2; 6803 1.1 mrg tree *zap_op = NULL; 6804 1.1 mrg 6805 1.1 mrg if (op_const & 2) 6806 1.1 mrg { 6807 1.1 mrg unsigned HOST_WIDE_INT loc; 6808 1.1 mrg 6809 1.1 mrg loc = opint[1] & 7; 6810 1.1 mrg loc *= BITS_PER_UNIT; 6811 1.1 mrg 6812 1.1 mrg if (loc != 0) 6813 1.1 mrg { 6814 1.1 mrg if (op_const & 1) 6815 1.1 mrg { 6816 1.1 mrg unsigned HOST_WIDE_INT temp = opint[0]; 6817 1.1 mrg if (is_high) 6818 1.1 mrg temp <<= loc; 6819 1.1 mrg else 6820 1.1 mrg temp >>= loc; 6821 1.1 mrg opint[0] = temp; 6822 1.1 mrg zap_const = 3; 6823 1.1 mrg } 6824 1.1 mrg } 6825 1.1 mrg else 6826 1.1 mrg zap_op = op; 6827 1.1 mrg } 6828 1.1 mrg 6829 1.1 mrg opint[1] = bytemask; 6830 1.1 mrg return alpha_fold_builtin_zapnot (zap_op, opint, zap_const); 6831 1.1 mrg } 6832 1.1 mrg 6833 1.1 mrg /* Fold the builtins for the INS family of instructions. */ 6834 1.1 mrg 6835 1.1 mrg static tree 6836 1.1 mrg alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[], 6837 1.1 mrg long op_const, unsigned HOST_WIDE_INT bytemask, 6838 1.1 mrg bool is_high) 6839 1.1 mrg { 6840 1.1 mrg if ((op_const & 1) && opint[0] == 0) 6841 1.1 mrg return build_int_cst (alpha_dimode_u, 0); 6842 1.1 mrg 6843 1.1 mrg if (op_const & 2) 6844 1.1 mrg { 6845 1.1 mrg unsigned HOST_WIDE_INT temp, loc, byteloc; 6846 1.1 mrg tree *zap_op = NULL; 6847 1.1 mrg 6848 1.1 mrg loc = opint[1] & 7; 6849 1.1 mrg bytemask <<= loc; 6850 1.1 mrg 6851 1.1 mrg temp = opint[0]; 6852 1.1 mrg if (is_high) 6853 1.1 mrg { 6854 1.1 mrg byteloc = (64 - (loc * 8)) & 0x3f; 6855 1.1 mrg if (byteloc == 0) 6856 1.1 mrg zap_op = op; 6857 1.1 mrg else 6858 1.1 mrg temp >>= byteloc; 6859 1.1 mrg bytemask >>= 8; 6860 1.1 mrg } 6861 1.1 mrg else 6862 1.1 mrg { 6863 1.1 mrg byteloc = loc * 8; 6864 1.1 mrg if (byteloc == 0) 6865 1.1 mrg zap_op = op; 6866 1.1 mrg else 6867 1.1 mrg temp <<= byteloc; 6868 1.1 mrg } 6869 1.1 mrg 6870 1.1 mrg opint[0] = temp; 6871 1.1 mrg opint[1] = bytemask; 6872 1.1 mrg return alpha_fold_builtin_zapnot (zap_op, opint, op_const); 6873 1.1 mrg } 6874 1.1 mrg 6875 1.1 mrg return NULL; 6876 1.1 mrg } 6877 1.1 mrg 6878 1.1 mrg static tree 6879 1.1 mrg alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[], 6880 1.1 mrg long op_const, unsigned HOST_WIDE_INT bytemask, 6881 1.1 mrg bool is_high) 6882 1.1 mrg { 6883 1.1 mrg if (op_const & 2) 6884 1.1 mrg { 6885 1.1 mrg unsigned HOST_WIDE_INT loc; 6886 1.1 mrg 6887 1.1 mrg loc = opint[1] & 7; 6888 1.1 mrg bytemask <<= loc; 6889 1.1 mrg 6890 1.1 mrg if (is_high) 6891 1.1 mrg bytemask >>= 8; 6892 1.1 mrg 6893 1.1 mrg opint[1] = bytemask ^ 0xff; 6894 1.1 mrg } 6895 1.1 mrg 6896 1.1 mrg return alpha_fold_builtin_zapnot (op, opint, op_const); 6897 1.1 mrg } 6898 1.1 mrg 6899 1.1 mrg static tree 6900 1.1 mrg alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype) 6901 1.1 mrg { 6902 1.1 mrg tree op0 = fold_convert (vtype, op[0]); 6903 1.1 mrg tree op1 = fold_convert (vtype, op[1]); 6904 1.1 mrg tree val = fold_build2 (code, vtype, op0, op1); 6905 1.1 mrg return fold_build1 (VIEW_CONVERT_EXPR, alpha_dimode_u, val); 6906 1.1 mrg } 6907 1.1 mrg 6908 1.1 mrg static tree 6909 1.1 mrg alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const) 6910 1.1 mrg { 6911 1.1 mrg unsigned HOST_WIDE_INT temp = 0; 6912 1.1 mrg int i; 6913 1.1 mrg 6914 1.1 mrg if (op_const != 3) 6915 1.1 mrg return NULL; 6916 1.1 mrg 6917 1.1 mrg for (i = 0; i < 8; ++i) 6918 1.1 mrg { 6919 1.1 mrg unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff; 6920 1.1 mrg unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff; 6921 1.1 mrg if (a >= b) 6922 1.1 mrg temp += a - b; 6923 1.1 mrg else 6924 1.1 mrg temp += b - a; 6925 1.1 mrg } 6926 1.1 mrg 6927 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 6928 1.1 mrg } 6929 1.1 mrg 6930 1.1 mrg static tree 6931 1.1 mrg alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const) 6932 1.1 mrg { 6933 1.1 mrg unsigned HOST_WIDE_INT temp; 6934 1.1 mrg 6935 1.1 mrg if (op_const == 0) 6936 1.1 mrg return NULL; 6937 1.1 mrg 6938 1.1 mrg temp = opint[0] & 0xff; 6939 1.1 mrg temp |= (opint[0] >> 24) & 0xff00; 6940 1.1 mrg 6941 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 6942 1.1 mrg } 6943 1.1 mrg 6944 1.1 mrg static tree 6945 1.1 mrg alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const) 6946 1.1 mrg { 6947 1.1 mrg unsigned HOST_WIDE_INT temp; 6948 1.1 mrg 6949 1.1 mrg if (op_const == 0) 6950 1.1 mrg return NULL; 6951 1.1 mrg 6952 1.1 mrg temp = opint[0] & 0xff; 6953 1.1 mrg temp |= (opint[0] >> 8) & 0xff00; 6954 1.1 mrg temp |= (opint[0] >> 16) & 0xff0000; 6955 1.1 mrg temp |= (opint[0] >> 24) & 0xff000000; 6956 1.1 mrg 6957 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 6958 1.1 mrg } 6959 1.1 mrg 6960 1.1 mrg static tree 6961 1.1 mrg alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const) 6962 1.1 mrg { 6963 1.1 mrg unsigned HOST_WIDE_INT temp; 6964 1.1 mrg 6965 1.1 mrg if (op_const == 0) 6966 1.1 mrg return NULL; 6967 1.1 mrg 6968 1.1 mrg temp = opint[0] & 0xff; 6969 1.1 mrg temp |= (opint[0] & 0xff00) << 24; 6970 1.1 mrg 6971 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 6972 1.1 mrg } 6973 1.1 mrg 6974 1.1 mrg static tree 6975 1.1 mrg alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const) 6976 1.1 mrg { 6977 1.1 mrg unsigned HOST_WIDE_INT temp; 6978 1.1 mrg 6979 1.1 mrg if (op_const == 0) 6980 1.1 mrg return NULL; 6981 1.1 mrg 6982 1.1 mrg temp = opint[0] & 0xff; 6983 1.1 mrg temp |= (opint[0] & 0x0000ff00) << 8; 6984 1.1 mrg temp |= (opint[0] & 0x00ff0000) << 16; 6985 1.1 mrg temp |= (opint[0] & 0xff000000) << 24; 6986 1.1 mrg 6987 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 6988 1.1 mrg } 6989 1.1 mrg 6990 1.1 mrg static tree 6991 1.1 mrg alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const) 6992 1.1 mrg { 6993 1.1 mrg unsigned HOST_WIDE_INT temp; 6994 1.1 mrg 6995 1.1 mrg if (op_const == 0) 6996 1.1 mrg return NULL; 6997 1.1 mrg 6998 1.1 mrg if (opint[0] == 0) 6999 1.1 mrg temp = 64; 7000 1.1 mrg else 7001 1.1 mrg temp = exact_log2 (opint[0] & -opint[0]); 7002 1.1 mrg 7003 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 7004 1.1 mrg } 7005 1.1 mrg 7006 1.1 mrg static tree 7007 1.1 mrg alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const) 7008 1.1 mrg { 7009 1.1 mrg unsigned HOST_WIDE_INT temp; 7010 1.1 mrg 7011 1.1 mrg if (op_const == 0) 7012 1.1 mrg return NULL; 7013 1.1 mrg 7014 1.1 mrg if (opint[0] == 0) 7015 1.1 mrg temp = 64; 7016 1.1 mrg else 7017 1.1 mrg temp = 64 - floor_log2 (opint[0]) - 1; 7018 1.1 mrg 7019 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 7020 1.1 mrg } 7021 1.1 mrg 7022 1.1 mrg static tree 7023 1.1 mrg alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const) 7024 1.1 mrg { 7025 1.1 mrg unsigned HOST_WIDE_INT temp, op; 7026 1.1 mrg 7027 1.1 mrg if (op_const == 0) 7028 1.1 mrg return NULL; 7029 1.1 mrg 7030 1.1 mrg op = opint[0]; 7031 1.1 mrg temp = 0; 7032 1.1 mrg while (op) 7033 1.1 mrg temp++, op &= op - 1; 7034 1.1 mrg 7035 1.1 mrg return build_int_cst (alpha_dimode_u, temp); 7036 1.1 mrg } 7037 1.1 mrg 7038 1.1 mrg /* Fold one of our builtin functions. */ 7039 1.1 mrg 7040 1.1 mrg static tree 7041 1.1 mrg alpha_fold_builtin (tree fndecl, int n_args, tree *op, 7042 1.1 mrg bool ignore ATTRIBUTE_UNUSED) 7043 1.1 mrg { 7044 1.1 mrg unsigned HOST_WIDE_INT opint[MAX_ARGS]; 7045 1.1 mrg long op_const = 0; 7046 1.1 mrg int i; 7047 1.1 mrg 7048 1.1 mrg if (n_args > MAX_ARGS) 7049 1.1 mrg return NULL; 7050 1.1 mrg 7051 1.1 mrg for (i = 0; i < n_args; i++) 7052 1.1 mrg { 7053 1.1 mrg tree arg = op[i]; 7054 1.1 mrg if (arg == error_mark_node) 7055 1.1 mrg return NULL; 7056 1.1 mrg 7057 1.1 mrg opint[i] = 0; 7058 1.1 mrg if (TREE_CODE (arg) == INTEGER_CST) 7059 1.1 mrg { 7060 1.1 mrg op_const |= 1L << i; 7061 1.1 mrg opint[i] = int_cst_value (arg); 7062 1.1 mrg } 7063 1.1 mrg } 7064 1.1 mrg 7065 1.1 mrg switch (DECL_MD_FUNCTION_CODE (fndecl)) 7066 1.1 mrg { 7067 1.1 mrg case ALPHA_BUILTIN_CMPBGE: 7068 1.1 mrg return alpha_fold_builtin_cmpbge (opint, op_const); 7069 1.1 mrg 7070 1.1 mrg case ALPHA_BUILTIN_EXTBL: 7071 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false); 7072 1.1 mrg case ALPHA_BUILTIN_EXTWL: 7073 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false); 7074 1.1 mrg case ALPHA_BUILTIN_EXTLL: 7075 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false); 7076 1.1 mrg case ALPHA_BUILTIN_EXTQL: 7077 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false); 7078 1.1 mrg case ALPHA_BUILTIN_EXTWH: 7079 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true); 7080 1.1 mrg case ALPHA_BUILTIN_EXTLH: 7081 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true); 7082 1.1 mrg case ALPHA_BUILTIN_EXTQH: 7083 1.1 mrg return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true); 7084 1.1 mrg 7085 1.1 mrg case ALPHA_BUILTIN_INSBL: 7086 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false); 7087 1.1 mrg case ALPHA_BUILTIN_INSWL: 7088 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false); 7089 1.1 mrg case ALPHA_BUILTIN_INSLL: 7090 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false); 7091 1.1 mrg case ALPHA_BUILTIN_INSQL: 7092 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false); 7093 1.1 mrg case ALPHA_BUILTIN_INSWH: 7094 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true); 7095 1.1 mrg case ALPHA_BUILTIN_INSLH: 7096 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true); 7097 1.1 mrg case ALPHA_BUILTIN_INSQH: 7098 1.1 mrg return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true); 7099 1.1 mrg 7100 1.1 mrg case ALPHA_BUILTIN_MSKBL: 7101 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false); 7102 1.1 mrg case ALPHA_BUILTIN_MSKWL: 7103 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false); 7104 1.1 mrg case ALPHA_BUILTIN_MSKLL: 7105 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false); 7106 1.1 mrg case ALPHA_BUILTIN_MSKQL: 7107 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false); 7108 1.1 mrg case ALPHA_BUILTIN_MSKWH: 7109 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true); 7110 1.1 mrg case ALPHA_BUILTIN_MSKLH: 7111 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true); 7112 1.1 mrg case ALPHA_BUILTIN_MSKQH: 7113 1.1 mrg return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true); 7114 1.1 mrg 7115 1.1 mrg case ALPHA_BUILTIN_ZAP: 7116 1.1 mrg opint[1] ^= 0xff; 7117 1.1 mrg /* FALLTHRU */ 7118 1.1 mrg case ALPHA_BUILTIN_ZAPNOT: 7119 1.1 mrg return alpha_fold_builtin_zapnot (op, opint, op_const); 7120 1.1 mrg 7121 1.1 mrg case ALPHA_BUILTIN_MINUB8: 7122 1.1 mrg return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u); 7123 1.1 mrg case ALPHA_BUILTIN_MINSB8: 7124 1.1 mrg return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s); 7125 1.1 mrg case ALPHA_BUILTIN_MINUW4: 7126 1.1 mrg return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u); 7127 1.1 mrg case ALPHA_BUILTIN_MINSW4: 7128 1.1 mrg return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s); 7129 1.1 mrg case ALPHA_BUILTIN_MAXUB8: 7130 1.1 mrg return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u); 7131 1.1 mrg case ALPHA_BUILTIN_MAXSB8: 7132 1.1 mrg return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s); 7133 1.1 mrg case ALPHA_BUILTIN_MAXUW4: 7134 1.1 mrg return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u); 7135 1.1 mrg case ALPHA_BUILTIN_MAXSW4: 7136 1.1 mrg return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s); 7137 1.1 mrg 7138 1.1 mrg case ALPHA_BUILTIN_PERR: 7139 1.1 mrg return alpha_fold_builtin_perr (opint, op_const); 7140 1.1 mrg case ALPHA_BUILTIN_PKLB: 7141 1.1 mrg return alpha_fold_builtin_pklb (opint, op_const); 7142 1.1 mrg case ALPHA_BUILTIN_PKWB: 7143 1.1 mrg return alpha_fold_builtin_pkwb (opint, op_const); 7144 1.1 mrg case ALPHA_BUILTIN_UNPKBL: 7145 1.1 mrg return alpha_fold_builtin_unpkbl (opint, op_const); 7146 1.1 mrg case ALPHA_BUILTIN_UNPKBW: 7147 1.1 mrg return alpha_fold_builtin_unpkbw (opint, op_const); 7148 1.1 mrg 7149 1.1 mrg case ALPHA_BUILTIN_CTTZ: 7150 1.1 mrg return alpha_fold_builtin_cttz (opint, op_const); 7151 1.1 mrg case ALPHA_BUILTIN_CTLZ: 7152 1.1 mrg return alpha_fold_builtin_ctlz (opint, op_const); 7153 1.1 mrg case ALPHA_BUILTIN_CTPOP: 7154 1.1 mrg return alpha_fold_builtin_ctpop (opint, op_const); 7155 1.1 mrg 7156 1.1 mrg case ALPHA_BUILTIN_AMASK: 7157 1.1 mrg case ALPHA_BUILTIN_IMPLVER: 7158 1.1 mrg case ALPHA_BUILTIN_RPCC: 7159 1.1 mrg /* None of these are foldable at compile-time. */ 7160 1.1 mrg default: 7161 1.1 mrg return NULL; 7162 1.1 mrg } 7163 1.1 mrg } 7164 1.1 mrg 7165 1.1 mrg bool 7166 1.1 mrg alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi) 7167 1.1 mrg { 7168 1.1 mrg bool changed = false; 7169 1.1 mrg gimple *stmt = gsi_stmt (*gsi); 7170 1.1 mrg tree call = gimple_call_fn (stmt); 7171 1.1 mrg gimple *new_stmt = NULL; 7172 1.1 mrg 7173 1.1 mrg if (call) 7174 1.1 mrg { 7175 1.1 mrg tree fndecl = gimple_call_fndecl (stmt); 7176 1.1 mrg 7177 1.1 mrg if (fndecl) 7178 1.1 mrg { 7179 1.1 mrg tree arg0, arg1; 7180 1.1 mrg 7181 1.1 mrg switch (DECL_MD_FUNCTION_CODE (fndecl)) 7182 1.1 mrg { 7183 1.1 mrg case ALPHA_BUILTIN_UMULH: 7184 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 7185 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 7186 1.1 mrg 7187 1.1 mrg new_stmt = gimple_build_assign (gimple_call_lhs (stmt), 7188 1.1 mrg MULT_HIGHPART_EXPR, arg0, arg1); 7189 1.1 mrg break; 7190 1.1 mrg default: 7191 1.1 mrg break; 7192 1.1 mrg } 7193 1.1 mrg } 7194 1.1 mrg } 7195 1.1 mrg 7196 1.1 mrg if (new_stmt) 7197 1.1 mrg { 7198 1.1 mrg gsi_replace (gsi, new_stmt, true); 7199 1.1 mrg changed = true; 7200 1.1 mrg } 7201 1.1 mrg 7202 1.1 mrg return changed; 7203 1.1 mrg } 7204 1.1 mrg 7205 1.1 mrg /* This page contains routines that are used to determine what the function 7207 1.1 mrg prologue and epilogue code will do and write them out. */ 7208 1.1 mrg 7209 1.1 mrg /* Compute the size of the save area in the stack. */ 7210 1.1 mrg 7211 1.1 mrg /* These variables are used for communication between the following functions. 7212 1.1 mrg They indicate various things about the current function being compiled 7213 1.1 mrg that are used to tell what kind of prologue, epilogue and procedure 7214 1.1 mrg descriptor to generate. */ 7215 1.1 mrg 7216 1.1 mrg /* Nonzero if we need a stack procedure. */ 7217 1.1 mrg enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2}; 7218 1.1 mrg static enum alpha_procedure_types alpha_procedure_type; 7219 1.1 mrg 7220 1.1 mrg /* Register number (either FP or SP) that is used to unwind the frame. */ 7221 1.1 mrg static int vms_unwind_regno; 7222 1.1 mrg 7223 1.1 mrg /* Register number used to save FP. We need not have one for RA since 7224 1.1 mrg we don't modify it for register procedures. This is only defined 7225 1.1 mrg for register frame procedures. */ 7226 1.1 mrg static int vms_save_fp_regno; 7227 1.1 mrg 7228 1.1 mrg /* Register number used to reference objects off our PV. */ 7229 1.1 mrg static int vms_base_regno; 7230 1.1 mrg 7231 1.1 mrg /* Compute register masks for saved registers, register save area size, 7232 1.1 mrg and total frame size. */ 7233 1.1 mrg static void 7234 1.1 mrg alpha_compute_frame_layout (void) 7235 1.1 mrg { 7236 1.1 mrg unsigned HOST_WIDE_INT sa_mask = 0; 7237 1.1 mrg HOST_WIDE_INT frame_size; 7238 1.1 mrg int sa_size; 7239 1.1 mrg 7240 1.1 mrg /* When outputting a thunk, we don't have valid register life info, 7241 1.1 mrg but assemble_start_function wants to output .frame and .mask 7242 1.1 mrg directives. */ 7243 1.1 mrg if (!cfun->is_thunk) 7244 1.1 mrg { 7245 1.1 mrg if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK) 7246 1.1 mrg sa_mask |= HOST_WIDE_INT_1U << HARD_FRAME_POINTER_REGNUM; 7247 1.1 mrg 7248 1.1 mrg /* One for every register we have to save. */ 7249 1.1 mrg for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++) 7250 1.1 mrg if (! call_used_or_fixed_reg_p (i) 7251 1.1 mrg && df_regs_ever_live_p (i) && i != REG_RA) 7252 1.1 mrg sa_mask |= HOST_WIDE_INT_1U << i; 7253 1.1 mrg 7254 1.1 mrg /* We need to restore these for the handler. */ 7255 1.1 mrg if (crtl->calls_eh_return) 7256 1.1 mrg { 7257 1.1 mrg for (unsigned i = 0; ; ++i) 7258 1.1 mrg { 7259 1.1 mrg unsigned regno = EH_RETURN_DATA_REGNO (i); 7260 1.1 mrg if (regno == INVALID_REGNUM) 7261 1.1 mrg break; 7262 1.1 mrg sa_mask |= HOST_WIDE_INT_1U << regno; 7263 1.1 mrg } 7264 1.1 mrg } 7265 1.1 mrg 7266 1.1 mrg /* If any register spilled, then spill the return address also. */ 7267 1.1 mrg /* ??? This is required by the Digital stack unwind specification 7268 1.1 mrg and isn't needed if we're doing Dwarf2 unwinding. */ 7269 1.1 mrg if (sa_mask || alpha_ra_ever_killed ()) 7270 1.1 mrg sa_mask |= HOST_WIDE_INT_1U << REG_RA; 7271 1.1 mrg } 7272 1.1 mrg 7273 1.1 mrg sa_size = popcount_hwi(sa_mask); 7274 1.1 mrg frame_size = get_frame_size (); 7275 1.1 mrg 7276 1.1 mrg if (TARGET_ABI_OPEN_VMS) 7277 1.1 mrg { 7278 1.1 mrg /* Start with a stack procedure if we make any calls (REG_RA used), or 7279 1.1 mrg need a frame pointer, with a register procedure if we otherwise need 7280 1.1 mrg at least a slot, and with a null procedure in other cases. */ 7281 1.1 mrg if ((sa_mask >> REG_RA) & 1 || frame_pointer_needed) 7282 1.1 mrg alpha_procedure_type = PT_STACK; 7283 1.1 mrg else if (frame_size != 0) 7284 1.1 mrg alpha_procedure_type = PT_REGISTER; 7285 1.1 mrg else 7286 1.1 mrg alpha_procedure_type = PT_NULL; 7287 1.1 mrg 7288 1.1 mrg /* Don't reserve space for saving FP & RA yet. Do that later after we've 7289 1.1 mrg made the final decision on stack procedure vs register procedure. */ 7290 1.1 mrg if (alpha_procedure_type == PT_STACK) 7291 1.1 mrg sa_size -= 2; 7292 1.1 mrg 7293 1.1 mrg /* Decide whether to refer to objects off our PV via FP or PV. 7294 1.1 mrg If we need FP for something else or if we receive a nonlocal 7295 1.1 mrg goto (which expects PV to contain the value), we must use PV. 7296 1.1 mrg Otherwise, start by assuming we can use FP. */ 7297 1.1 mrg 7298 1.1 mrg vms_base_regno 7299 1.1 mrg = (frame_pointer_needed 7300 1.1 mrg || cfun->has_nonlocal_label 7301 1.1 mrg || alpha_procedure_type == PT_STACK 7302 1.1 mrg || crtl->outgoing_args_size) 7303 1.1 mrg ? REG_PV : HARD_FRAME_POINTER_REGNUM; 7304 1.1 mrg 7305 1.1 mrg /* If we want to copy PV into FP, we need to find some register 7306 1.1 mrg in which to save FP. */ 7307 1.1 mrg vms_save_fp_regno = -1; 7308 1.1 mrg if (vms_base_regno == HARD_FRAME_POINTER_REGNUM) 7309 1.1 mrg for (unsigned i = 0; i < 32; i++) 7310 1.1 mrg if (! fixed_regs[i] && call_used_or_fixed_reg_p (i) 7311 1.1 mrg && ! df_regs_ever_live_p (i)) 7312 1.1 mrg { 7313 1.1 mrg vms_save_fp_regno = i; 7314 1.1 mrg break; 7315 1.1 mrg } 7316 1.1 mrg 7317 1.1 mrg /* A VMS condition handler requires a stack procedure in our 7318 1.1 mrg implementation. (not required by the calling standard). */ 7319 1.1 mrg if ((vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER) 7320 1.1 mrg || cfun->machine->uses_condition_handler) 7321 1.1 mrg vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK; 7322 1.1 mrg else if (alpha_procedure_type == PT_NULL) 7323 1.1 mrg vms_base_regno = REG_PV; 7324 1.1 mrg 7325 1.1 mrg /* Stack unwinding should be done via FP unless we use it for PV. */ 7326 1.1 mrg vms_unwind_regno = (vms_base_regno == REG_PV 7327 1.1 mrg ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM); 7328 1.1 mrg 7329 1.1 mrg /* If this is a stack procedure, allow space for saving FP, RA and 7330 1.1 mrg a condition handler slot if needed. */ 7331 1.1 mrg if (alpha_procedure_type == PT_STACK) 7332 1.1 mrg sa_size += 2 + cfun->machine->uses_condition_handler; 7333 1.1 mrg } 7334 1.1 mrg else 7335 1.1 mrg { 7336 1.1 mrg /* Our size must be even (multiple of 16 bytes). */ 7337 1.1 mrg if (sa_size & 1) 7338 1.1 mrg sa_size++; 7339 1.1 mrg } 7340 1.1 mrg sa_size *= 8; 7341 1.1 mrg 7342 1.1 mrg if (TARGET_ABI_OPEN_VMS) 7343 1.1 mrg frame_size = ALPHA_ROUND (sa_size 7344 1.1 mrg + (alpha_procedure_type == PT_STACK ? 8 : 0) 7345 1.1 mrg + frame_size 7346 1.1 mrg + crtl->args.pretend_args_size); 7347 1.1 mrg else 7348 1.1 mrg frame_size = (ALPHA_ROUND (crtl->outgoing_args_size) 7349 1.1 mrg + sa_size 7350 1.1 mrg + ALPHA_ROUND (frame_size + crtl->args.pretend_args_size)); 7351 1.1 mrg 7352 1.1 mrg cfun->machine->sa_mask = sa_mask; 7353 1.1 mrg cfun->machine->sa_size = sa_size; 7354 1.1 mrg cfun->machine->frame_size = frame_size; 7355 1.1 mrg } 7356 1.1 mrg 7357 1.1 mrg #undef TARGET_COMPUTE_FRAME_LAYOUT 7358 1.1 mrg #define TARGET_COMPUTE_FRAME_LAYOUT alpha_compute_frame_layout 7359 1.1 mrg 7360 1.1 mrg /* Return 1 if this function can directly return via $26. */ 7361 1.1 mrg 7362 1.1 mrg bool 7363 1.1 mrg direct_return (void) 7364 1.1 mrg { 7365 1.1 mrg return (TARGET_ABI_OSF 7366 1.1 mrg && reload_completed 7367 1.1 mrg && cfun->machine->frame_size == 0); 7368 1.1 mrg } 7369 1.1 mrg 7370 1.1 mrg /* Define the offset between two registers, one to be eliminated, 7371 1.1 mrg and the other its replacement, at the start of a routine. */ 7372 1.1 mrg 7373 1.1 mrg HOST_WIDE_INT 7374 1.1 mrg alpha_initial_elimination_offset (unsigned int from, 7375 1.1 mrg unsigned int to ATTRIBUTE_UNUSED) 7376 1.1 mrg { 7377 1.1 mrg HOST_WIDE_INT ret; 7378 1.1 mrg 7379 1.1 mrg ret = cfun->machine->sa_size; 7380 1.1 mrg ret += ALPHA_ROUND (crtl->outgoing_args_size); 7381 1.1 mrg 7382 1.1 mrg switch (from) 7383 1.1 mrg { 7384 1.1 mrg case FRAME_POINTER_REGNUM: 7385 1.1 mrg break; 7386 1.1 mrg 7387 1.1 mrg case ARG_POINTER_REGNUM: 7388 1.1 mrg ret += (ALPHA_ROUND (get_frame_size () 7389 1.1 mrg + crtl->args.pretend_args_size) 7390 1.1 mrg - crtl->args.pretend_args_size); 7391 1.1 mrg break; 7392 1.1 mrg 7393 1.1 mrg default: 7394 1.1 mrg gcc_unreachable (); 7395 1.1 mrg } 7396 1.1 mrg 7397 1.1 mrg return ret; 7398 1.1 mrg } 7399 1.1 mrg 7400 1.1 mrg #if TARGET_ABI_OPEN_VMS 7401 1.1 mrg 7402 1.1 mrg /* Worker function for TARGET_CAN_ELIMINATE. */ 7403 1.1 mrg 7404 1.1 mrg static bool 7405 1.1 mrg alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 7406 1.1 mrg { 7407 1.1 mrg switch (alpha_procedure_type) 7408 1.1 mrg { 7409 1.1 mrg case PT_NULL: 7410 1.1 mrg /* NULL procedures have no frame of their own and we only 7411 1.1 mrg know how to resolve from the current stack pointer. */ 7412 1.1 mrg return to == STACK_POINTER_REGNUM; 7413 1.1 mrg 7414 1.1 mrg case PT_REGISTER: 7415 1.1 mrg case PT_STACK: 7416 1.1 mrg /* We always eliminate except to the stack pointer if there is no 7417 1.1 mrg usable frame pointer at hand. */ 7418 1.1 mrg return (to != STACK_POINTER_REGNUM 7419 1.1 mrg || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM); 7420 1.1 mrg } 7421 1.1 mrg 7422 1.1 mrg gcc_unreachable (); 7423 1.1 mrg } 7424 1.1 mrg 7425 1.1 mrg /* FROM is to be eliminated for TO. Return the offset so that TO+offset 7426 1.1 mrg designates the same location as FROM. */ 7427 1.1 mrg 7428 1.1 mrg HOST_WIDE_INT 7429 1.1 mrg alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to) 7430 1.1 mrg { 7431 1.1 mrg /* The only possible attempts we ever expect are ARG or FRAME_PTR to 7432 1.1 mrg HARD_FRAME or STACK_PTR. We need the alpha_procedure_type to decide 7433 1.1 mrg on the proper computations and will need the register save area size 7434 1.1 mrg in most cases. */ 7435 1.1 mrg 7436 1.1 mrg HOST_WIDE_INT sa_size = cfun->machine->sa_size; 7437 1.1 mrg 7438 1.1 mrg /* PT_NULL procedures have no frame of their own and we only allow 7439 1.1 mrg elimination to the stack pointer. This is the argument pointer and we 7440 1.1 mrg resolve the soft frame pointer to that as well. */ 7441 1.1 mrg 7442 1.1 mrg if (alpha_procedure_type == PT_NULL) 7443 1.1 mrg return 0; 7444 1.1 mrg 7445 1.1 mrg /* For a PT_STACK procedure the frame layout looks as follows 7446 1.1 mrg 7447 1.1 mrg -----> decreasing addresses 7448 1.1 mrg 7449 1.1 mrg < size rounded up to 16 | likewise > 7450 1.1 mrg --------------#------------------------------+++--------------+++-------# 7451 1.1 mrg incoming args # pretended args | "frame" | regs sa | PV | outgoing args # 7452 1.1 mrg --------------#---------------------------------------------------------# 7453 1.1 mrg ^ ^ ^ ^ 7454 1.1 mrg ARG_PTR FRAME_PTR HARD_FRAME_PTR STACK_PTR 7455 1.1 mrg 7456 1.1 mrg 7457 1.1 mrg PT_REGISTER procedures are similar in that they may have a frame of their 7458 1.1 mrg own. They have no regs-sa/pv/outgoing-args area. 7459 1.1 mrg 7460 1.1 mrg We first compute offset to HARD_FRAME_PTR, then add what we need to get 7461 1.1 mrg to STACK_PTR if need be. */ 7462 1.1 mrg 7463 1.1 mrg { 7464 1.1 mrg HOST_WIDE_INT offset; 7465 1.1 mrg HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0; 7466 1.1 mrg 7467 1.1 mrg switch (from) 7468 1.1 mrg { 7469 1.1 mrg case FRAME_POINTER_REGNUM: 7470 1.1 mrg offset = ALPHA_ROUND (sa_size + pv_save_size); 7471 1.1 mrg break; 7472 1.1 mrg case ARG_POINTER_REGNUM: 7473 1.1 mrg offset = (ALPHA_ROUND (sa_size + pv_save_size 7474 1.1 mrg + get_frame_size () 7475 1.1 mrg + crtl->args.pretend_args_size) 7476 1.1 mrg - crtl->args.pretend_args_size); 7477 1.1 mrg break; 7478 1.1 mrg default: 7479 1.1 mrg gcc_unreachable (); 7480 1.1 mrg } 7481 1.1 mrg 7482 1.1 mrg if (to == STACK_POINTER_REGNUM) 7483 1.1 mrg offset += ALPHA_ROUND (crtl->outgoing_args_size); 7484 1.1 mrg 7485 1.1 mrg return offset; 7486 1.1 mrg } 7487 1.1 mrg } 7488 1.1 mrg 7489 1.1 mrg #define COMMON_OBJECT "common_object" 7490 1.1 mrg 7491 1.1 mrg static tree 7492 1.1 mrg common_object_handler (tree *node, tree name ATTRIBUTE_UNUSED, 7493 1.1 mrg tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, 7494 1.1 mrg bool *no_add_attrs ATTRIBUTE_UNUSED) 7495 1.1 mrg { 7496 1.1 mrg tree decl = *node; 7497 1.1 mrg gcc_assert (DECL_P (decl)); 7498 1.1 mrg 7499 1.1 mrg DECL_COMMON (decl) = 1; 7500 1.1 mrg return NULL_TREE; 7501 1.1 mrg } 7502 1.1 mrg 7503 1.1 mrg static const struct attribute_spec vms_attribute_table[] = 7504 1.1 mrg { 7505 1.1 mrg /* { name, min_len, max_len, decl_req, type_req, fn_type_req, 7506 1.1 mrg affects_type_identity, handler, exclude } */ 7507 1.1 mrg { COMMON_OBJECT, 0, 1, true, false, false, false, common_object_handler, 7508 1.1 mrg NULL }, 7509 1.1 mrg { NULL, 0, 0, false, false, false, false, NULL, NULL } 7510 1.1 mrg }; 7511 1.1 mrg 7512 1.1 mrg void 7513 1.1 mrg vms_output_aligned_decl_common(FILE *file, tree decl, const char *name, 7514 1.1 mrg unsigned HOST_WIDE_INT size, 7515 1.1 mrg unsigned int align) 7516 1.1 mrg { 7517 1.1 mrg tree attr = DECL_ATTRIBUTES (decl); 7518 1.1 mrg fprintf (file, "%s", COMMON_ASM_OP); 7519 1.1 mrg assemble_name (file, name); 7520 1.1 mrg fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED, size); 7521 1.1 mrg /* ??? Unlike on OSF/1, the alignment factor is not in log units. */ 7522 1.1 mrg fprintf (file, ",%u", align / BITS_PER_UNIT); 7523 1.1 mrg if (attr) 7524 1.1 mrg { 7525 1.1 mrg attr = lookup_attribute (COMMON_OBJECT, attr); 7526 1.1 mrg if (attr) 7527 1.1 mrg fprintf (file, ",%s", 7528 1.1 mrg IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr)))); 7529 1.1 mrg } 7530 1.1 mrg fputc ('\n', file); 7531 1.1 mrg } 7532 1.1 mrg 7533 1.1 mrg #undef COMMON_OBJECT 7534 1.1 mrg 7535 1.1 mrg #endif 7536 1.1 mrg 7537 1.1 mrg bool 7538 1.1 mrg alpha_find_lo_sum_using_gp (rtx insn) 7539 1.1 mrg { 7540 1.1 mrg subrtx_iterator::array_type array; 7541 1.1 mrg FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST) 7542 1.1 mrg { 7543 1.1 mrg const_rtx x = *iter; 7544 1.1 mrg if (GET_CODE (x) == LO_SUM && XEXP (x, 0) == pic_offset_table_rtx) 7545 1.1 mrg return true; 7546 1.1 mrg } 7547 1.1 mrg return false; 7548 1.1 mrg } 7549 1.1 mrg 7550 1.1 mrg static int 7551 1.1 mrg alpha_does_function_need_gp (void) 7552 1.1 mrg { 7553 1.1 mrg rtx_insn *insn; 7554 1.1 mrg 7555 1.1 mrg /* The GP being variable is an OSF abi thing. */ 7556 1.1 mrg if (! TARGET_ABI_OSF) 7557 1.1 mrg return 0; 7558 1.1 mrg 7559 1.1 mrg /* We need the gp to load the address of __mcount. */ 7560 1.1 mrg if (TARGET_PROFILING_NEEDS_GP && crtl->profile) 7561 1.1 mrg return 1; 7562 1.1 mrg 7563 1.1 mrg /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */ 7564 1.1 mrg if (cfun->is_thunk) 7565 1.1 mrg return 1; 7566 1.1 mrg 7567 1.1 mrg /* The nonlocal receiver pattern assumes that the gp is valid for 7568 1.1 mrg the nested function. Reasonable because it's almost always set 7569 1.1 mrg correctly already. For the cases where that's wrong, make sure 7570 1.1 mrg the nested function loads its gp on entry. */ 7571 1.1 mrg if (crtl->has_nonlocal_goto) 7572 1.1 mrg return 1; 7573 1.1 mrg 7574 1.1 mrg /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 7575 1.1 mrg Even if we are a static function, we still need to do this in case 7576 1.1 mrg our address is taken and passed to something like qsort. */ 7577 1.1 mrg 7578 1.1 mrg push_topmost_sequence (); 7579 1.1 mrg insn = get_insns (); 7580 1.1 mrg pop_topmost_sequence (); 7581 1.1 mrg 7582 1.1 mrg for (; insn; insn = NEXT_INSN (insn)) 7583 1.1 mrg if (NONDEBUG_INSN_P (insn) 7584 1.1 mrg && GET_CODE (PATTERN (insn)) != USE 7585 1.1 mrg && GET_CODE (PATTERN (insn)) != CLOBBER 7586 1.1 mrg && get_attr_usegp (insn)) 7587 1.1 mrg return 1; 7588 1.1 mrg 7589 1.1 mrg return 0; 7590 1.1 mrg } 7591 1.1 mrg 7592 1.1 mrg /* Helper function for alpha_store_data_bypass_p, handle just a single SET 7593 1.1 mrg IN_SET. */ 7594 1.1 mrg 7595 1.1 mrg static bool 7596 1.1 mrg alpha_store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set) 7597 1.1 mrg { 7598 1.1 mrg if (!MEM_P (SET_DEST (in_set))) 7599 1.1 mrg return false; 7600 1.1 mrg 7601 1.1 mrg rtx out_set = single_set (out_insn); 7602 1.1 mrg if (out_set) 7603 1.1 mrg return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set)); 7604 1.1 mrg 7605 1.1 mrg rtx out_pat = PATTERN (out_insn); 7606 1.1 mrg if (GET_CODE (out_pat) != PARALLEL) 7607 1.1 mrg return false; 7608 1.1 mrg 7609 1.1 mrg for (int i = 0; i < XVECLEN (out_pat, 0); i++) 7610 1.1 mrg { 7611 1.1 mrg rtx out_exp = XVECEXP (out_pat, 0, i); 7612 1.1 mrg 7613 1.1 mrg if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE 7614 1.1 mrg || GET_CODE (out_exp) == TRAP_IF) 7615 1.1 mrg continue; 7616 1.1 mrg 7617 1.1 mrg gcc_assert (GET_CODE (out_exp) == SET); 7618 1.1 mrg 7619 1.1 mrg if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) 7620 1.1 mrg return false; 7621 1.1 mrg } 7622 1.1 mrg 7623 1.1 mrg return true; 7624 1.1 mrg } 7625 1.1 mrg 7626 1.1 mrg /* True if the dependency between OUT_INSN and IN_INSN is on the store 7627 1.1 mrg data not the address operand(s) of the store. IN_INSN and OUT_INSN 7628 1.1 mrg must be either a single_set or a PARALLEL with SETs inside. 7629 1.1 mrg 7630 1.1 mrg This alpha-specific version of store_data_bypass_p ignores TRAP_IF 7631 1.1 mrg that would result in assertion failure (and internal compiler error) 7632 1.1 mrg in the generic store_data_bypass_p function. */ 7633 1.1 mrg 7634 1.1 mrg int 7635 1.1 mrg alpha_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) 7636 1.1 mrg { 7637 1.1 mrg rtx in_set = single_set (in_insn); 7638 1.1 mrg if (in_set) 7639 1.1 mrg return alpha_store_data_bypass_p_1 (out_insn, in_set); 7640 1.1 mrg 7641 1.1 mrg rtx in_pat = PATTERN (in_insn); 7642 1.1 mrg if (GET_CODE (in_pat) != PARALLEL) 7643 1.1 mrg return false; 7644 1.1 mrg 7645 1.1 mrg for (int i = 0; i < XVECLEN (in_pat, 0); i++) 7646 1.1 mrg { 7647 1.1 mrg rtx in_exp = XVECEXP (in_pat, 0, i); 7648 1.1 mrg 7649 1.1 mrg if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE 7650 1.1 mrg || GET_CODE (in_exp) == TRAP_IF) 7651 1.1 mrg continue; 7652 1.1 mrg 7653 1.1 mrg gcc_assert (GET_CODE (in_exp) == SET); 7654 1.1 mrg 7655 1.1 mrg if (!alpha_store_data_bypass_p_1 (out_insn, in_exp)) 7656 1.1 mrg return false; 7657 1.1 mrg } 7658 1.1 mrg 7659 1.1 mrg return true; 7660 1.1 mrg } 7661 1.1 mrg 7662 1.1 mrg /* Helper function to set RTX_FRAME_RELATED_P on instructions, including 7664 1.1 mrg sequences. */ 7665 1.1 mrg 7666 1.1 mrg static rtx_insn * 7667 1.1 mrg set_frame_related_p (void) 7668 1.1 mrg { 7669 1.1 mrg rtx_insn *seq = get_insns (); 7670 1.1 mrg rtx_insn *insn; 7671 1.1 mrg 7672 1.1 mrg end_sequence (); 7673 1.1 mrg 7674 1.1 mrg if (!seq) 7675 1.1 mrg return NULL; 7676 1.1 mrg 7677 1.1 mrg if (INSN_P (seq)) 7678 1.1 mrg { 7679 1.1 mrg insn = seq; 7680 1.1 mrg while (insn != NULL_RTX) 7681 1.1 mrg { 7682 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 7683 1.1 mrg insn = NEXT_INSN (insn); 7684 1.1 mrg } 7685 1.1 mrg seq = emit_insn (seq); 7686 1.1 mrg } 7687 1.1 mrg else 7688 1.1 mrg { 7689 1.1 mrg seq = emit_insn (seq); 7690 1.1 mrg RTX_FRAME_RELATED_P (seq) = 1; 7691 1.1 mrg } 7692 1.1 mrg return seq; 7693 1.1 mrg } 7694 1.1 mrg 7695 1.1 mrg #define FRP(exp) (start_sequence (), exp, set_frame_related_p ()) 7696 1.1 mrg 7697 1.1 mrg /* Generates a store with the proper unwind info attached. VALUE is 7698 1.1 mrg stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG 7699 1.1 mrg contains SP+FRAME_BIAS, and that is the unwind info that should be 7700 1.1 mrg generated. If FRAME_REG != VALUE, then VALUE is being stored on 7701 1.1 mrg behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */ 7702 1.1 mrg 7703 1.1 mrg static void 7704 1.1 mrg emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias, 7705 1.1 mrg HOST_WIDE_INT base_ofs, rtx frame_reg) 7706 1.1 mrg { 7707 1.1 mrg rtx addr, mem; 7708 1.1 mrg rtx_insn *insn; 7709 1.1 mrg 7710 1.1 mrg addr = plus_constant (Pmode, base_reg, base_ofs); 7711 1.1 mrg mem = gen_frame_mem (DImode, addr); 7712 1.1 mrg 7713 1.1 mrg insn = emit_move_insn (mem, value); 7714 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 7715 1.1 mrg 7716 1.1 mrg if (frame_bias || value != frame_reg) 7717 1.1 mrg { 7718 1.1 mrg if (frame_bias) 7719 1.1 mrg { 7720 1.1 mrg addr = plus_constant (Pmode, stack_pointer_rtx, 7721 1.1 mrg frame_bias + base_ofs); 7722 1.1 mrg mem = gen_rtx_MEM (DImode, addr); 7723 1.1 mrg } 7724 1.1 mrg 7725 1.1 mrg add_reg_note (insn, REG_FRAME_RELATED_EXPR, 7726 1.1 mrg gen_rtx_SET (mem, frame_reg)); 7727 1.1 mrg } 7728 1.1 mrg } 7729 1.1 mrg 7730 1.1 mrg static void 7731 1.1 mrg emit_frame_store (unsigned int regno, rtx base_reg, 7732 1.1 mrg HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs) 7733 1.1 mrg { 7734 1.1 mrg rtx reg = gen_rtx_REG (DImode, regno); 7735 1.1 mrg emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg); 7736 1.1 mrg } 7737 1.1 mrg 7738 1.1 mrg /* Write function prologue. */ 7739 1.1 mrg 7740 1.1 mrg /* On vms we have two kinds of functions: 7741 1.1 mrg 7742 1.1 mrg - stack frame (PROC_STACK) 7743 1.1 mrg these are 'normal' functions with local vars and which are 7744 1.1 mrg calling other functions 7745 1.1 mrg - register frame (PROC_REGISTER) 7746 1.1 mrg keeps all data in registers, needs no stack 7747 1.1 mrg 7748 1.1 mrg We must pass this to the assembler so it can generate the 7749 1.1 mrg proper pdsc (procedure descriptor) 7750 1.1 mrg This is done with the '.pdesc' command. 7751 1.1 mrg 7752 1.1 mrg On not-vms, we don't really differentiate between the two, as we can 7753 1.1 mrg simply allocate stack without saving registers. */ 7754 1.1 mrg 7755 1.1 mrg void 7756 1.1 mrg alpha_expand_prologue (void) 7757 1.1 mrg { 7758 1.1 mrg /* Registers to save. */ 7759 1.1 mrg unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask; 7760 1.1 mrg /* Stack space needed for pushing registers clobbered by us. */ 7761 1.1 mrg HOST_WIDE_INT sa_size = cfun->machine->sa_size; 7762 1.1 mrg /* Complete stack size needed. */ 7763 1.1 mrg HOST_WIDE_INT frame_size = cfun->machine->frame_size; 7764 1.1 mrg /* Probed stack size; it additionally includes the size of 7765 1.1 mrg the "reserve region" if any. */ 7766 1.1 mrg HOST_WIDE_INT probed_size, sa_bias; 7767 1.1 mrg /* Offset from base reg to register save area. */ 7768 1.1 mrg HOST_WIDE_INT reg_offset; 7769 1.1 mrg rtx sa_reg; 7770 1.1 mrg 7771 1.1 mrg if (flag_stack_usage_info) 7772 1.1 mrg current_function_static_stack_size = frame_size; 7773 1.1 mrg 7774 1.1 mrg if (TARGET_ABI_OPEN_VMS) 7775 1.1 mrg reg_offset = 8 + 8 * cfun->machine->uses_condition_handler; 7776 1.1 mrg else 7777 1.1 mrg reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); 7778 1.1 mrg 7779 1.1 mrg /* Emit an insn to reload GP, if needed. */ 7780 1.1 mrg if (TARGET_ABI_OSF) 7781 1.1 mrg { 7782 1.1 mrg alpha_function_needs_gp = alpha_does_function_need_gp (); 7783 1.1 mrg if (alpha_function_needs_gp) 7784 1.1 mrg emit_insn (gen_prologue_ldgp ()); 7785 1.1 mrg } 7786 1.1 mrg 7787 1.1 mrg /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert 7788 1.1 mrg the call to mcount ourselves, rather than having the linker do it 7789 1.1 mrg magically in response to -pg. Since _mcount has special linkage, 7790 1.1 mrg don't represent the call as a call. */ 7791 1.1 mrg if (TARGET_PROFILING_NEEDS_GP && crtl->profile) 7792 1.1 mrg emit_insn (gen_prologue_mcount ()); 7793 1.1 mrg 7794 1.1 mrg /* Adjust the stack by the frame size. If the frame size is > 4096 7795 1.1 mrg bytes, we need to be sure we probe somewhere in the first and last 7796 1.1 mrg 4096 bytes (we can probably get away without the latter test) and 7797 1.1 mrg every 8192 bytes in between. If the frame size is > 32768, we 7798 1.1 mrg do this in a loop. Otherwise, we generate the explicit probe 7799 1.1 mrg instructions. 7800 1.1 mrg 7801 1.1 mrg Note that we are only allowed to adjust sp once in the prologue. */ 7802 1.1 mrg 7803 1.1 mrg probed_size = frame_size; 7804 1.1 mrg if (flag_stack_check || flag_stack_clash_protection) 7805 1.1 mrg probed_size += get_stack_check_protect (); 7806 1.1 mrg 7807 1.1 mrg if (probed_size <= 32768) 7808 1.1 mrg { 7809 1.1 mrg if (probed_size > 4096) 7810 1.1 mrg { 7811 1.1 mrg int probed; 7812 1.1 mrg 7813 1.1 mrg for (probed = 4096; probed < probed_size; probed += 8192) 7814 1.1 mrg emit_insn (gen_stack_probe_internal (GEN_INT (-probed))); 7815 1.1 mrg 7816 1.1 mrg /* We only have to do this probe if we aren't saving registers or 7817 1.1 mrg if we are probing beyond the frame because of -fstack-check. */ 7818 1.1 mrg if ((sa_size == 0 && probed_size > probed - 4096) 7819 1.1 mrg || flag_stack_check || flag_stack_clash_protection) 7820 1.1 mrg emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size))); 7821 1.1 mrg } 7822 1.1 mrg 7823 1.1 mrg if (frame_size != 0) 7824 1.1 mrg FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, 7825 1.1 mrg GEN_INT (-frame_size)))); 7826 1.1 mrg } 7827 1.1 mrg else 7828 1.1 mrg { 7829 1.1 mrg /* Here we generate code to set R22 to SP + 4096 and set R23 to the 7830 1.1 mrg number of 8192 byte blocks to probe. We then probe each block 7831 1.1 mrg in the loop and then set SP to the proper location. If the 7832 1.1 mrg amount remaining is > 4096, we have to do one more probe if we 7833 1.1 mrg are not saving any registers or if we are probing beyond the 7834 1.1 mrg frame because of -fstack-check. */ 7835 1.1 mrg 7836 1.1 mrg HOST_WIDE_INT blocks = (probed_size + 4096) / 8192; 7837 1.1 mrg HOST_WIDE_INT leftover = probed_size + 4096 - blocks * 8192; 7838 1.1 mrg rtx ptr = gen_rtx_REG (DImode, 22); 7839 1.1 mrg rtx count = gen_rtx_REG (DImode, 23); 7840 1.1 mrg rtx seq; 7841 1.1 mrg 7842 1.1 mrg emit_move_insn (count, GEN_INT (blocks)); 7843 1.1 mrg emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096))); 7844 1.1 mrg 7845 1.1 mrg /* Because of the difficulty in emitting a new basic block this 7846 1.1 mrg late in the compilation, generate the loop as a single insn. */ 7847 1.1 mrg emit_insn (gen_prologue_stack_probe_loop (count, ptr)); 7848 1.1 mrg 7849 1.1 mrg if ((leftover > 4096 && sa_size == 0) 7850 1.1 mrg || flag_stack_check || flag_stack_clash_protection) 7851 1.1 mrg { 7852 1.1 mrg rtx last = gen_rtx_MEM (DImode, 7853 1.1 mrg plus_constant (Pmode, ptr, -leftover)); 7854 1.1 mrg MEM_VOLATILE_P (last) = 1; 7855 1.1 mrg emit_move_insn (last, const0_rtx); 7856 1.1 mrg } 7857 1.1 mrg 7858 1.1 mrg if (flag_stack_check || flag_stack_clash_protection) 7859 1.1 mrg { 7860 1.1 mrg /* If -fstack-check is specified we have to load the entire 7861 1.1 mrg constant into a register and subtract from the sp in one go, 7862 1.1 mrg because the probed stack size is not equal to the frame size. */ 7863 1.1 mrg HOST_WIDE_INT lo, hi; 7864 1.1 mrg lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; 7865 1.1 mrg hi = frame_size - lo; 7866 1.1 mrg 7867 1.1 mrg emit_move_insn (ptr, GEN_INT (hi)); 7868 1.1 mrg emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo))); 7869 1.1 mrg seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, 7870 1.1 mrg ptr)); 7871 1.1 mrg } 7872 1.1 mrg else 7873 1.1 mrg { 7874 1.1 mrg seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, 7875 1.1 mrg GEN_INT (-leftover))); 7876 1.1 mrg } 7877 1.1 mrg 7878 1.1 mrg /* This alternative is special, because the DWARF code cannot 7879 1.1 mrg possibly intuit through the loop above. So we invent this 7880 1.1 mrg note it looks at instead. */ 7881 1.1 mrg RTX_FRAME_RELATED_P (seq) = 1; 7882 1.1 mrg add_reg_note (seq, REG_FRAME_RELATED_EXPR, 7883 1.1 mrg gen_rtx_SET (stack_pointer_rtx, 7884 1.1 mrg plus_constant (Pmode, stack_pointer_rtx, 7885 1.1 mrg -frame_size))); 7886 1.1 mrg } 7887 1.1 mrg 7888 1.1 mrg /* Cope with very large offsets to the register save area. */ 7889 1.1 mrg sa_bias = 0; 7890 1.1 mrg sa_reg = stack_pointer_rtx; 7891 1.1 mrg if (reg_offset + sa_size > 0x8000) 7892 1.1 mrg { 7893 1.1 mrg int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; 7894 1.1 mrg rtx sa_bias_rtx; 7895 1.1 mrg 7896 1.1 mrg if (low + sa_size <= 0x8000) 7897 1.1 mrg sa_bias = reg_offset - low, reg_offset = low; 7898 1.1 mrg else 7899 1.1 mrg sa_bias = reg_offset, reg_offset = 0; 7900 1.1 mrg 7901 1.1 mrg sa_reg = gen_rtx_REG (DImode, 24); 7902 1.1 mrg sa_bias_rtx = GEN_INT (sa_bias); 7903 1.1 mrg 7904 1.1 mrg if (add_operand (sa_bias_rtx, DImode)) 7905 1.1 mrg emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx)); 7906 1.1 mrg else 7907 1.1 mrg { 7908 1.1 mrg emit_move_insn (sa_reg, sa_bias_rtx); 7909 1.1 mrg emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg)); 7910 1.1 mrg } 7911 1.1 mrg } 7912 1.1 mrg 7913 1.1 mrg /* Save regs in stack order. Beginning with VMS PV. */ 7914 1.1 mrg if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK) 7915 1.1 mrg emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0); 7916 1.1 mrg 7917 1.1 mrg /* Save register RA next, followed by any other registers 7918 1.1 mrg that need to be saved. */ 7919 1.1 mrg for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask)) 7920 1.1 mrg { 7921 1.1 mrg emit_frame_store (i, sa_reg, sa_bias, reg_offset); 7922 1.1 mrg reg_offset += 8; 7923 1.1 mrg sa_mask &= ~(HOST_WIDE_INT_1U << i); 7924 1.1 mrg } 7925 1.1 mrg 7926 1.1 mrg if (TARGET_ABI_OPEN_VMS) 7927 1.1 mrg { 7928 1.1 mrg /* Register frame procedures save the fp. */ 7929 1.1 mrg if (alpha_procedure_type == PT_REGISTER) 7930 1.1 mrg { 7931 1.1 mrg rtx_insn *insn = 7932 1.1 mrg emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), 7933 1.1 mrg hard_frame_pointer_rtx); 7934 1.1 mrg add_reg_note (insn, REG_CFA_REGISTER, NULL); 7935 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 7936 1.1 mrg } 7937 1.1 mrg 7938 1.1 mrg if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV) 7939 1.1 mrg emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno), 7940 1.1 mrg gen_rtx_REG (DImode, REG_PV))); 7941 1.1 mrg 7942 1.1 mrg if (alpha_procedure_type != PT_NULL 7943 1.1 mrg && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) 7944 1.1 mrg FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); 7945 1.1 mrg 7946 1.1 mrg /* If we have to allocate space for outgoing args, do it now. */ 7947 1.1 mrg if (crtl->outgoing_args_size != 0) 7948 1.1 mrg { 7949 1.1 mrg rtx_insn *seq 7950 1.1 mrg = emit_move_insn (stack_pointer_rtx, 7951 1.1 mrg plus_constant 7952 1.1 mrg (Pmode, hard_frame_pointer_rtx, 7953 1.1 mrg - (ALPHA_ROUND 7954 1.1 mrg (crtl->outgoing_args_size)))); 7955 1.1 mrg 7956 1.1 mrg /* Only set FRAME_RELATED_P on the stack adjustment we just emitted 7957 1.1 mrg if ! frame_pointer_needed. Setting the bit will change the CFA 7958 1.1 mrg computation rule to use sp again, which would be wrong if we had 7959 1.1 mrg frame_pointer_needed, as this means sp might move unpredictably 7960 1.1 mrg later on. 7961 1.1 mrg 7962 1.1 mrg Also, note that 7963 1.1 mrg frame_pointer_needed 7964 1.1 mrg => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM 7965 1.1 mrg and 7966 1.1 mrg crtl->outgoing_args_size != 0 7967 1.1 mrg => alpha_procedure_type != PT_NULL, 7968 1.1 mrg 7969 1.1 mrg so when we are not setting the bit here, we are guaranteed to 7970 1.1 mrg have emitted an FRP frame pointer update just before. */ 7971 1.1 mrg RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed; 7972 1.1 mrg } 7973 1.1 mrg } 7974 1.1 mrg else 7975 1.1 mrg { 7976 1.1 mrg /* If we need a frame pointer, set it from the stack pointer. */ 7977 1.1 mrg if (frame_pointer_needed) 7978 1.1 mrg { 7979 1.1 mrg if (TARGET_CAN_FAULT_IN_PROLOGUE) 7980 1.1 mrg FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); 7981 1.1 mrg else 7982 1.1 mrg /* This must always be the last instruction in the 7983 1.1 mrg prologue, thus we emit a special move + clobber. */ 7984 1.1 mrg FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx, 7985 1.1 mrg stack_pointer_rtx, sa_reg))); 7986 1.1 mrg } 7987 1.1 mrg } 7988 1.1 mrg 7989 1.1 mrg /* The ABIs for VMS and OSF/1 say that while we can schedule insns into 7990 1.1 mrg the prologue, for exception handling reasons, we cannot do this for 7991 1.1 mrg any insn that might fault. We could prevent this for mems with a 7992 1.1 mrg (clobber:BLK (scratch)), but this doesn't work for fp insns. So we 7993 1.1 mrg have to prevent all such scheduling with a blockage. 7994 1.1 mrg 7995 1.1 mrg Linux, on the other hand, never bothered to implement OSF/1's 7996 1.1 mrg exception handling, and so doesn't care about such things. Anyone 7997 1.1 mrg planning to use dwarf2 frame-unwind info can also omit the blockage. */ 7998 1.1 mrg 7999 1.1 mrg if (! TARGET_CAN_FAULT_IN_PROLOGUE) 8000 1.1 mrg emit_insn (gen_blockage ()); 8001 1.1 mrg } 8002 1.1 mrg 8003 1.1 mrg /* Count the number of .file directives, so that .loc is up to date. */ 8004 1.1 mrg int num_source_filenames = 0; 8005 1.1 mrg 8006 1.1 mrg /* Output the textual info surrounding the prologue. */ 8007 1.1 mrg 8008 1.1 mrg void 8009 1.1 mrg alpha_start_function (FILE *file, const char *fnname, 8010 1.1 mrg tree decl ATTRIBUTE_UNUSED) 8011 1.1 mrg { 8012 1.1 mrg unsigned long imask, fmask; 8013 1.1 mrg /* Complete stack size needed. */ 8014 1.1 mrg HOST_WIDE_INT frame_size = cfun->machine->frame_size; 8015 1.1 mrg /* The maximum debuggable frame size. */ 8016 1.1 mrg const HOST_WIDE_INT max_frame_size = HOST_WIDE_INT_1 << 31; 8017 1.1 mrg /* Offset from base reg to register save area. */ 8018 1.1 mrg HOST_WIDE_INT reg_offset; 8019 1.1 mrg char *entry_label = (char *) alloca (strlen (fnname) + 6); 8020 1.1 mrg char *tramp_label = (char *) alloca (strlen (fnname) + 6); 8021 1.1 mrg int i; 8022 1.1 mrg 8023 1.1 mrg #if TARGET_ABI_OPEN_VMS 8024 1.1 mrg vms_start_function (fnname); 8025 1.1 mrg #endif 8026 1.1 mrg 8027 1.1 mrg alpha_fnname = fnname; 8028 1.1 mrg 8029 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8030 1.1 mrg reg_offset = 8 + 8 * cfun->machine->uses_condition_handler; 8031 1.1 mrg else 8032 1.1 mrg reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); 8033 1.1 mrg 8034 1.1 mrg imask = cfun->machine->sa_mask & 0xffffffffu; 8035 1.1 mrg fmask = cfun->machine->sa_mask >> 32; 8036 1.1 mrg 8037 1.1 mrg /* Issue function start and label. */ 8038 1.1 mrg if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive) 8039 1.1 mrg { 8040 1.1 mrg fputs ("\t.ent ", file); 8041 1.1 mrg assemble_name (file, fnname); 8042 1.1 mrg putc ('\n', file); 8043 1.1 mrg 8044 1.1 mrg /* If the function needs GP, we'll write the "..ng" label there. 8045 1.1 mrg Otherwise, do it here. */ 8046 1.1 mrg if (TARGET_ABI_OSF 8047 1.1 mrg && ! alpha_function_needs_gp 8048 1.1 mrg && ! cfun->is_thunk) 8049 1.1 mrg { 8050 1.1 mrg putc ('$', file); 8051 1.1 mrg assemble_name (file, fnname); 8052 1.1 mrg fputs ("..ng:\n", file); 8053 1.1 mrg } 8054 1.1 mrg } 8055 1.1 mrg /* Nested functions on VMS that are potentially called via trampoline 8056 1.1 mrg get a special transfer entry point that loads the called functions 8057 1.1 mrg procedure descriptor and static chain. */ 8058 1.1 mrg if (TARGET_ABI_OPEN_VMS 8059 1.1 mrg && !TREE_PUBLIC (decl) 8060 1.1 mrg && DECL_CONTEXT (decl) 8061 1.1 mrg && !TYPE_P (DECL_CONTEXT (decl)) 8062 1.1 mrg && TREE_CODE (DECL_CONTEXT (decl)) != TRANSLATION_UNIT_DECL) 8063 1.1 mrg { 8064 1.1 mrg strcpy (tramp_label, fnname); 8065 1.1 mrg strcat (tramp_label, "..tr"); 8066 1.1 mrg ASM_OUTPUT_LABEL (file, tramp_label); 8067 1.1 mrg fprintf (file, "\tldq $1,24($27)\n"); 8068 1.1 mrg fprintf (file, "\tldq $27,16($27)\n"); 8069 1.1 mrg } 8070 1.1 mrg 8071 1.1 mrg strcpy (entry_label, fnname); 8072 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8073 1.1 mrg strcat (entry_label, "..en"); 8074 1.1 mrg 8075 1.1 mrg ASM_OUTPUT_LABEL (file, entry_label); 8076 1.1 mrg inside_function = TRUE; 8077 1.1 mrg 8078 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8079 1.1 mrg fprintf (file, "\t.base $%d\n", vms_base_regno); 8080 1.1 mrg 8081 1.1 mrg if (TARGET_ABI_OSF 8082 1.1 mrg && TARGET_IEEE_CONFORMANT 8083 1.1 mrg && !flag_inhibit_size_directive) 8084 1.1 mrg { 8085 1.1 mrg /* Set flags in procedure descriptor to request IEEE-conformant 8086 1.1 mrg math-library routines. The value we set it to is PDSC_EXC_IEEE 8087 1.1 mrg (/usr/include/pdsc.h). */ 8088 1.1 mrg fputs ("\t.eflag 48\n", file); 8089 1.1 mrg } 8090 1.1 mrg 8091 1.1 mrg /* Set up offsets to alpha virtual arg/local debugging pointer. */ 8092 1.1 mrg alpha_auto_offset = -frame_size + crtl->args.pretend_args_size; 8093 1.1 mrg alpha_arg_offset = -frame_size + 48; 8094 1.1 mrg 8095 1.1 mrg /* Describe our frame. If the frame size is larger than an integer, 8096 1.1 mrg print it as zero to avoid an assembler error. We won't be 8097 1.1 mrg properly describing such a frame, but that's the best we can do. */ 8098 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8099 1.1 mrg fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26," 8100 1.1 mrg HOST_WIDE_INT_PRINT_DEC "\n", 8101 1.1 mrg vms_unwind_regno, 8102 1.1 mrg frame_size >= max_frame_size ? 0 : frame_size, 8103 1.1 mrg reg_offset); 8104 1.1 mrg else if (!flag_inhibit_size_directive) 8105 1.1 mrg fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n", 8106 1.1 mrg (frame_pointer_needed 8107 1.1 mrg ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM), 8108 1.1 mrg frame_size >= max_frame_size ? 0 : frame_size, 8109 1.1 mrg crtl->args.pretend_args_size); 8110 1.1 mrg 8111 1.1 mrg /* Describe which registers were spilled. */ 8112 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8113 1.1 mrg { 8114 1.1 mrg if (imask) 8115 1.1 mrg /* ??? Does VMS care if mask contains ra? The old code didn't 8116 1.1 mrg set it, so I don't here. */ 8117 1.1 mrg fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA)); 8118 1.1 mrg if (fmask) 8119 1.1 mrg fprintf (file, "\t.fmask 0x%lx,0\n", fmask); 8120 1.1 mrg if (alpha_procedure_type == PT_REGISTER) 8121 1.1 mrg fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno); 8122 1.1 mrg } 8123 1.1 mrg else if (!flag_inhibit_size_directive) 8124 1.1 mrg { 8125 1.1 mrg if (imask) 8126 1.1 mrg { 8127 1.1 mrg fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask, 8128 1.1 mrg frame_size >= max_frame_size ? 0 : reg_offset - frame_size); 8129 1.1 mrg 8130 1.1 mrg for (i = 0; i < 32; ++i) 8131 1.1 mrg if (imask & (1UL << i)) 8132 1.1 mrg reg_offset += 8; 8133 1.1 mrg } 8134 1.1 mrg 8135 1.1 mrg if (fmask) 8136 1.1 mrg fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask, 8137 1.1 mrg frame_size >= max_frame_size ? 0 : reg_offset - frame_size); 8138 1.1 mrg } 8139 1.1 mrg 8140 1.1 mrg #if TARGET_ABI_OPEN_VMS 8141 1.1 mrg /* If a user condition handler has been installed at some point, emit 8142 1.1 mrg the procedure descriptor bits to point the Condition Handling Facility 8143 1.1 mrg at the indirection wrapper, and state the fp offset at which the user 8144 1.1 mrg handler may be found. */ 8145 1.1 mrg if (cfun->machine->uses_condition_handler) 8146 1.1 mrg { 8147 1.1 mrg fprintf (file, "\t.handler __gcc_shell_handler\n"); 8148 1.1 mrg fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET); 8149 1.1 mrg } 8150 1.1 mrg 8151 1.1 mrg #ifdef TARGET_VMS_CRASH_DEBUG 8152 1.1 mrg /* Support of minimal traceback info. */ 8153 1.1 mrg switch_to_section (readonly_data_section); 8154 1.1 mrg fprintf (file, "\t.align 3\n"); 8155 1.1 mrg assemble_name (file, fnname); fputs ("..na:\n", file); 8156 1.1 mrg fputs ("\t.ascii \"", file); 8157 1.1 mrg assemble_name (file, fnname); 8158 1.1 mrg fputs ("\\0\"\n", file); 8159 1.1 mrg switch_to_section (text_section); 8160 1.1 mrg #endif 8161 1.1 mrg #endif /* TARGET_ABI_OPEN_VMS */ 8162 1.1 mrg } 8163 1.1 mrg 8164 1.1 mrg /* Emit the .prologue note at the scheduled end of the prologue. */ 8165 1.1 mrg 8166 1.1 mrg static void 8167 1.1 mrg alpha_output_function_end_prologue (FILE *file) 8168 1.1 mrg { 8169 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8170 1.1 mrg fputs ("\t.prologue\n", file); 8171 1.1 mrg else if (!flag_inhibit_size_directive) 8172 1.1 mrg fprintf (file, "\t.prologue %d\n", 8173 1.1 mrg alpha_function_needs_gp || cfun->is_thunk); 8174 1.1 mrg } 8175 1.1 mrg 8176 1.1 mrg /* Write function epilogue. */ 8177 1.1 mrg 8178 1.1 mrg void 8179 1.1 mrg alpha_expand_epilogue (void) 8180 1.1 mrg { 8181 1.1 mrg /* Registers to save. */ 8182 1.1 mrg unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask; 8183 1.1 mrg /* Stack space needed for pushing registers clobbered by us. */ 8184 1.1 mrg HOST_WIDE_INT sa_size = cfun->machine->sa_size; 8185 1.1 mrg /* Complete stack size needed. */ 8186 1.1 mrg HOST_WIDE_INT frame_size = cfun->machine->frame_size; 8187 1.1 mrg /* Offset from base reg to register save area. */ 8188 1.1 mrg HOST_WIDE_INT reg_offset; 8189 1.1 mrg int fp_is_frame_pointer, fp_offset; 8190 1.1 mrg rtx sa_reg, sa_reg_exp = NULL; 8191 1.1 mrg rtx sp_adj1, sp_adj2, mem, reg, insn; 8192 1.1 mrg rtx eh_ofs; 8193 1.1 mrg rtx cfa_restores = NULL_RTX; 8194 1.1 mrg 8195 1.1 mrg if (TARGET_ABI_OPEN_VMS) 8196 1.1 mrg { 8197 1.1 mrg if (alpha_procedure_type == PT_STACK) 8198 1.1 mrg reg_offset = 8 + 8 * cfun->machine->uses_condition_handler; 8199 1.1 mrg else 8200 1.1 mrg reg_offset = 0; 8201 1.1 mrg } 8202 1.1 mrg else 8203 1.1 mrg reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); 8204 1.1 mrg 8205 1.1 mrg fp_is_frame_pointer 8206 1.1 mrg = (TARGET_ABI_OPEN_VMS 8207 1.1 mrg ? alpha_procedure_type == PT_STACK 8208 1.1 mrg : frame_pointer_needed); 8209 1.1 mrg fp_offset = 0; 8210 1.1 mrg sa_reg = stack_pointer_rtx; 8211 1.1 mrg 8212 1.1 mrg if (crtl->calls_eh_return) 8213 1.1 mrg eh_ofs = EH_RETURN_STACKADJ_RTX; 8214 1.1 mrg else 8215 1.1 mrg eh_ofs = NULL_RTX; 8216 1.1 mrg 8217 1.1 mrg if (sa_size) 8218 1.1 mrg { 8219 1.1 mrg /* If we have a frame pointer, restore SP from it. */ 8220 1.1 mrg if (TARGET_ABI_OPEN_VMS 8221 1.1 mrg ? vms_unwind_regno == HARD_FRAME_POINTER_REGNUM 8222 1.1 mrg : frame_pointer_needed) 8223 1.1 mrg emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); 8224 1.1 mrg 8225 1.1 mrg /* Cope with very large offsets to the register save area. */ 8226 1.1 mrg if (reg_offset + sa_size > 0x8000) 8227 1.1 mrg { 8228 1.1 mrg int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; 8229 1.1 mrg HOST_WIDE_INT bias; 8230 1.1 mrg 8231 1.1 mrg if (low + sa_size <= 0x8000) 8232 1.1 mrg bias = reg_offset - low, reg_offset = low; 8233 1.1 mrg else 8234 1.1 mrg bias = reg_offset, reg_offset = 0; 8235 1.1 mrg 8236 1.1 mrg sa_reg = gen_rtx_REG (DImode, 22); 8237 1.1 mrg sa_reg_exp = plus_constant (Pmode, stack_pointer_rtx, bias); 8238 1.1 mrg 8239 1.1 mrg emit_move_insn (sa_reg, sa_reg_exp); 8240 1.1 mrg } 8241 1.1 mrg 8242 1.1 mrg /* Restore registers in order, excepting a true frame pointer. */ 8243 1.1 mrg for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask)) 8244 1.1 mrg { 8245 1.1 mrg if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer) 8246 1.1 mrg fp_offset = reg_offset; 8247 1.1 mrg else 8248 1.1 mrg { 8249 1.1 mrg mem = gen_frame_mem (DImode, 8250 1.1 mrg plus_constant (Pmode, sa_reg, 8251 1.1 mrg reg_offset)); 8252 1.1 mrg reg = gen_rtx_REG (DImode, i); 8253 1.1 mrg emit_move_insn (reg, mem); 8254 1.1 mrg cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 8255 1.1 mrg cfa_restores); 8256 1.1 mrg } 8257 1.1 mrg reg_offset += 8; 8258 1.1 mrg sa_mask &= ~(HOST_WIDE_INT_1U << i); 8259 1.1 mrg } 8260 1.1 mrg } 8261 1.1 mrg 8262 1.1 mrg if (frame_size || eh_ofs) 8263 1.1 mrg { 8264 1.1 mrg sp_adj1 = stack_pointer_rtx; 8265 1.1 mrg 8266 1.1 mrg if (eh_ofs) 8267 1.1 mrg { 8268 1.1 mrg sp_adj1 = gen_rtx_REG (DImode, 23); 8269 1.1 mrg emit_move_insn (sp_adj1, 8270 1.1 mrg gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs)); 8271 1.1 mrg } 8272 1.1 mrg 8273 1.1 mrg /* If the stack size is large, begin computation into a temporary 8274 1.1 mrg register so as not to interfere with a potential fp restore, 8275 1.1 mrg which must be consecutive with an SP restore. */ 8276 1.1 mrg if (frame_size < 32768 && !cfun->calls_alloca) 8277 1.1 mrg sp_adj2 = GEN_INT (frame_size); 8278 1.1 mrg else if (frame_size < 0x40007fffL) 8279 1.1 mrg { 8280 1.1 mrg int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; 8281 1.1 mrg 8282 1.1 mrg sp_adj2 = plus_constant (Pmode, sp_adj1, frame_size - low); 8283 1.1 mrg if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2)) 8284 1.1 mrg sp_adj1 = sa_reg; 8285 1.1 mrg else 8286 1.1 mrg { 8287 1.1 mrg sp_adj1 = gen_rtx_REG (DImode, 23); 8288 1.1 mrg emit_move_insn (sp_adj1, sp_adj2); 8289 1.1 mrg } 8290 1.1 mrg sp_adj2 = GEN_INT (low); 8291 1.1 mrg } 8292 1.1 mrg else 8293 1.1 mrg { 8294 1.1 mrg rtx tmp = gen_rtx_REG (DImode, 23); 8295 1.1 mrg sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false); 8296 1.1 mrg if (!sp_adj2) 8297 1.1 mrg { 8298 1.1 mrg /* We can't drop new things to memory this late, afaik, 8299 1.1 mrg so build it up by pieces. */ 8300 1.1 mrg sp_adj2 = alpha_emit_set_long_const (tmp, frame_size); 8301 1.1 mrg gcc_assert (sp_adj2); 8302 1.1 mrg } 8303 1.1 mrg } 8304 1.1 mrg 8305 1.1 mrg /* From now on, things must be in order. So emit blockages. */ 8306 1.1 mrg 8307 1.1 mrg /* Restore the frame pointer. */ 8308 1.1 mrg if (fp_is_frame_pointer) 8309 1.1 mrg { 8310 1.1 mrg emit_insn (gen_blockage ()); 8311 1.1 mrg mem = gen_frame_mem (DImode, plus_constant (Pmode, sa_reg, 8312 1.1 mrg fp_offset)); 8313 1.1 mrg emit_move_insn (hard_frame_pointer_rtx, mem); 8314 1.1 mrg cfa_restores = alloc_reg_note (REG_CFA_RESTORE, 8315 1.1 mrg hard_frame_pointer_rtx, cfa_restores); 8316 1.1 mrg } 8317 1.1 mrg else if (TARGET_ABI_OPEN_VMS) 8318 1.1 mrg { 8319 1.1 mrg emit_insn (gen_blockage ()); 8320 1.1 mrg emit_move_insn (hard_frame_pointer_rtx, 8321 1.1 mrg gen_rtx_REG (DImode, vms_save_fp_regno)); 8322 1.1 mrg cfa_restores = alloc_reg_note (REG_CFA_RESTORE, 8323 1.1 mrg hard_frame_pointer_rtx, cfa_restores); 8324 1.1 mrg } 8325 1.1 mrg 8326 1.1 mrg /* Restore the stack pointer. */ 8327 1.1 mrg emit_insn (gen_blockage ()); 8328 1.1 mrg if (sp_adj2 == const0_rtx) 8329 1.1 mrg insn = emit_move_insn (stack_pointer_rtx, sp_adj1); 8330 1.1 mrg else 8331 1.1 mrg insn = emit_move_insn (stack_pointer_rtx, 8332 1.1 mrg gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)); 8333 1.1 mrg REG_NOTES (insn) = cfa_restores; 8334 1.1 mrg add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx); 8335 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 8336 1.1 mrg } 8337 1.1 mrg else 8338 1.1 mrg { 8339 1.1 mrg gcc_assert (cfa_restores == NULL); 8340 1.1 mrg 8341 1.1 mrg if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER) 8342 1.1 mrg { 8343 1.1 mrg emit_insn (gen_blockage ()); 8344 1.1 mrg insn = emit_move_insn (hard_frame_pointer_rtx, 8345 1.1 mrg gen_rtx_REG (DImode, vms_save_fp_regno)); 8346 1.1 mrg add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx); 8347 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 8348 1.1 mrg } 8349 1.1 mrg } 8350 1.1 mrg } 8351 1.1 mrg 8352 1.1 mrg /* Output the rest of the textual info surrounding the epilogue. */ 8354 1.1 mrg 8355 1.1 mrg void 8356 1.1 mrg alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED) 8357 1.1 mrg { 8358 1.1 mrg rtx_insn *insn; 8359 1.1 mrg 8360 1.1 mrg /* We output a nop after noreturn calls at the very end of the function to 8361 1.1 mrg ensure that the return address always remains in the caller's code range, 8362 1.1 mrg as not doing so might confuse unwinding engines. */ 8363 1.1 mrg insn = get_last_insn (); 8364 1.1 mrg if (!INSN_P (insn)) 8365 1.1 mrg insn = prev_active_insn (insn); 8366 1.1 mrg if (insn && CALL_P (insn)) 8367 1.1 mrg output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL); 8368 1.1 mrg 8369 1.1 mrg #if TARGET_ABI_OPEN_VMS 8370 1.1 mrg /* Write the linkage entries. */ 8371 1.1 mrg alpha_write_linkage (file, fnname); 8372 1.1 mrg #endif 8373 1.1 mrg 8374 1.1 mrg /* End the function. */ 8375 1.1 mrg if (TARGET_ABI_OPEN_VMS 8376 1.1 mrg || !flag_inhibit_size_directive) 8377 1.1 mrg { 8378 1.1 mrg fputs ("\t.end ", file); 8379 1.1 mrg assemble_name (file, fnname); 8380 1.1 mrg putc ('\n', file); 8381 1.1 mrg } 8382 1.1 mrg inside_function = FALSE; 8383 1.1 mrg } 8384 1.1 mrg 8385 1.1 mrg #if TARGET_ABI_OSF 8386 1.1 mrg /* Emit a tail call to FUNCTION after adjusting THIS by DELTA. 8387 1.1 mrg 8388 1.1 mrg In order to avoid the hordes of differences between generated code 8389 1.1 mrg with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating 8390 1.1 mrg lots of code loading up large constants, generate rtl and emit it 8391 1.1 mrg instead of going straight to text. 8392 1.1 mrg 8393 1.1 mrg Not sure why this idea hasn't been explored before... */ 8394 1.1 mrg 8395 1.1 mrg static void 8396 1.1 mrg alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, 8397 1.1 mrg HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, 8398 1.1 mrg tree function) 8399 1.1 mrg { 8400 1.1 mrg const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); 8401 1.1 mrg HOST_WIDE_INT hi, lo; 8402 1.1 mrg rtx this_rtx, funexp; 8403 1.1 mrg rtx_insn *insn; 8404 1.1 mrg 8405 1.1 mrg /* We always require a valid GP. */ 8406 1.1 mrg emit_insn (gen_prologue_ldgp ()); 8407 1.1 mrg emit_note (NOTE_INSN_PROLOGUE_END); 8408 1.1 mrg 8409 1.1 mrg /* Find the "this" pointer. If the function returns a structure, 8410 1.1 mrg the structure return pointer is in $16. */ 8411 1.1 mrg if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) 8412 1.1 mrg this_rtx = gen_rtx_REG (Pmode, 17); 8413 1.1 mrg else 8414 1.1 mrg this_rtx = gen_rtx_REG (Pmode, 16); 8415 1.1 mrg 8416 1.1 mrg /* Add DELTA. When possible we use ldah+lda. Otherwise load the 8417 1.1 mrg entire constant for the add. */ 8418 1.1 mrg lo = ((delta & 0xffff) ^ 0x8000) - 0x8000; 8419 1.1 mrg hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000; 8420 1.1 mrg if (hi + lo == delta) 8421 1.1 mrg { 8422 1.1 mrg if (hi) 8423 1.1 mrg emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi))); 8424 1.1 mrg if (lo) 8425 1.1 mrg emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo))); 8426 1.1 mrg } 8427 1.1 mrg else 8428 1.1 mrg { 8429 1.1 mrg rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0), delta); 8430 1.1 mrg emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp)); 8431 1.1 mrg } 8432 1.1 mrg 8433 1.1 mrg /* Add a delta stored in the vtable at VCALL_OFFSET. */ 8434 1.1 mrg if (vcall_offset) 8435 1.1 mrg { 8436 1.1 mrg rtx tmp, tmp2; 8437 1.1 mrg 8438 1.1 mrg tmp = gen_rtx_REG (Pmode, 0); 8439 1.1 mrg emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); 8440 1.1 mrg 8441 1.1 mrg lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000; 8442 1.1 mrg hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000; 8443 1.1 mrg if (hi + lo == vcall_offset) 8444 1.1 mrg { 8445 1.1 mrg if (hi) 8446 1.1 mrg emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi))); 8447 1.1 mrg } 8448 1.1 mrg else 8449 1.1 mrg { 8450 1.1 mrg tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1), 8451 1.1 mrg vcall_offset); 8452 1.1 mrg emit_insn (gen_adddi3 (tmp, tmp, tmp2)); 8453 1.1 mrg lo = 0; 8454 1.1 mrg } 8455 1.1 mrg if (lo) 8456 1.1 mrg tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo)); 8457 1.1 mrg else 8458 1.1 mrg tmp2 = tmp; 8459 1.1 mrg emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2)); 8460 1.1 mrg 8461 1.1 mrg emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp)); 8462 1.1 mrg } 8463 1.1 mrg 8464 1.1 mrg /* Generate a tail call to the target function. */ 8465 1.1 mrg if (! TREE_USED (function)) 8466 1.1 mrg { 8467 1.1 mrg assemble_external (function); 8468 1.1 mrg TREE_USED (function) = 1; 8469 1.1 mrg } 8470 1.1 mrg funexp = XEXP (DECL_RTL (function), 0); 8471 1.1 mrg funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); 8472 1.1 mrg insn = emit_call_insn (gen_sibcall (funexp, const0_rtx)); 8473 1.1 mrg SIBLING_CALL_P (insn) = 1; 8474 1.1 mrg 8475 1.1 mrg /* Run just enough of rest_of_compilation to get the insns emitted. 8476 1.1 mrg There's not really enough bulk here to make other passes such as 8477 1.1 mrg instruction scheduling worth while. */ 8478 1.1 mrg insn = get_insns (); 8479 1.1 mrg shorten_branches (insn); 8480 1.1 mrg assemble_start_function (thunk_fndecl, fnname); 8481 1.1 mrg final_start_function (insn, file, 1); 8482 1.1 mrg final (insn, file, 1); 8483 1.1 mrg final_end_function (); 8484 1.1 mrg assemble_end_function (thunk_fndecl, fnname); 8485 1.1 mrg } 8486 1.1 mrg #endif /* TARGET_ABI_OSF */ 8487 1.1 mrg 8488 1.1 mrg /* Debugging support. */ 8490 1.1 mrg 8491 1.1 mrg #include "gstab.h" 8492 1.1 mrg 8493 1.1 mrg /* Name of the file containing the current function. */ 8494 1.1 mrg 8495 1.1 mrg static const char *current_function_file = ""; 8496 1.1 mrg 8497 1.1 mrg /* Offsets to alpha virtual arg/local debugging pointers. */ 8498 1.1 mrg 8499 1.1 mrg long alpha_arg_offset; 8500 1.1 mrg long alpha_auto_offset; 8501 1.1 mrg 8502 1.1 mrg /* Emit a new filename to a stream. */ 8504 1.1 mrg 8505 1.1 mrg void 8506 1.1 mrg alpha_output_filename (FILE *stream, const char *name) 8507 1.1 mrg { 8508 1.1 mrg static int first_time = TRUE; 8509 1.1 mrg 8510 1.1 mrg if (first_time) 8511 1.1 mrg { 8512 1.1 mrg first_time = FALSE; 8513 1.1 mrg ++num_source_filenames; 8514 1.1 mrg current_function_file = name; 8515 1.1 mrg fprintf (stream, "\t.file\t%d ", num_source_filenames); 8516 1.1 mrg output_quoted_string (stream, name); 8517 1.1 mrg fprintf (stream, "\n"); 8518 1.1 mrg } 8519 1.1 mrg 8520 1.1 mrg else if (name != current_function_file 8521 1.1 mrg && strcmp (name, current_function_file) != 0) 8522 1.1 mrg { 8523 1.1 mrg ++num_source_filenames; 8524 1.1 mrg current_function_file = name; 8525 1.1 mrg fprintf (stream, "\t.file\t%d ", num_source_filenames); 8526 1.1 mrg 8527 1.1 mrg output_quoted_string (stream, name); 8528 1.1 mrg fprintf (stream, "\n"); 8529 1.1 mrg } 8530 1.1 mrg } 8531 1.1 mrg 8532 1.1 mrg /* Structure to show the current status of registers and memory. */ 8534 1.1 mrg 8535 1.1 mrg struct shadow_summary 8536 1.1 mrg { 8537 1.1 mrg struct { 8538 1.1 mrg unsigned int i : 31; /* Mask of int regs */ 8539 1.1 mrg unsigned int fp : 31; /* Mask of fp regs */ 8540 1.1 mrg unsigned int mem : 1; /* mem == imem | fpmem */ 8541 1.1 mrg } used, defd; 8542 1.1 mrg }; 8543 1.1 mrg 8544 1.1 mrg /* Summary the effects of expression X on the machine. Update SUM, a pointer 8545 1.1 mrg to the summary structure. SET is nonzero if the insn is setting the 8546 1.1 mrg object, otherwise zero. */ 8547 1.1 mrg 8548 1.1 mrg static void 8549 1.1 mrg summarize_insn (rtx x, struct shadow_summary *sum, int set) 8550 1.1 mrg { 8551 1.1 mrg const char *format_ptr; 8552 1.1 mrg int i, j; 8553 1.1 mrg 8554 1.1 mrg if (x == 0) 8555 1.1 mrg return; 8556 1.1 mrg 8557 1.1 mrg switch (GET_CODE (x)) 8558 1.1 mrg { 8559 1.1 mrg /* ??? Note that this case would be incorrect if the Alpha had a 8560 1.1 mrg ZERO_EXTRACT in SET_DEST. */ 8561 1.1 mrg case SET: 8562 1.1 mrg summarize_insn (SET_SRC (x), sum, 0); 8563 1.1 mrg summarize_insn (SET_DEST (x), sum, 1); 8564 1.1 mrg break; 8565 1.1 mrg 8566 1.1 mrg case CLOBBER: 8567 1.1 mrg summarize_insn (XEXP (x, 0), sum, 1); 8568 1.1 mrg break; 8569 1.1 mrg 8570 1.1 mrg case USE: 8571 1.1 mrg summarize_insn (XEXP (x, 0), sum, 0); 8572 1.1 mrg break; 8573 1.1 mrg 8574 1.1 mrg case ASM_OPERANDS: 8575 1.1 mrg for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) 8576 1.1 mrg summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0); 8577 1.1 mrg break; 8578 1.1 mrg 8579 1.1 mrg case PARALLEL: 8580 1.1 mrg for (i = XVECLEN (x, 0) - 1; i >= 0; i--) 8581 1.1 mrg summarize_insn (XVECEXP (x, 0, i), sum, 0); 8582 1.1 mrg break; 8583 1.1 mrg 8584 1.1 mrg case SUBREG: 8585 1.1 mrg summarize_insn (SUBREG_REG (x), sum, 0); 8586 1.1 mrg break; 8587 1.1 mrg 8588 1.1 mrg case REG: 8589 1.1 mrg { 8590 1.1 mrg int regno = REGNO (x); 8591 1.1 mrg unsigned long mask = ((unsigned long) 1) << (regno % 32); 8592 1.1 mrg 8593 1.1 mrg if (regno == 31 || regno == 63) 8594 1.1 mrg break; 8595 1.1 mrg 8596 1.1 mrg if (set) 8597 1.1 mrg { 8598 1.1 mrg if (regno < 32) 8599 1.1 mrg sum->defd.i |= mask; 8600 1.1 mrg else 8601 1.1 mrg sum->defd.fp |= mask; 8602 1.1 mrg } 8603 1.1 mrg else 8604 1.1 mrg { 8605 1.1 mrg if (regno < 32) 8606 1.1 mrg sum->used.i |= mask; 8607 1.1 mrg else 8608 1.1 mrg sum->used.fp |= mask; 8609 1.1 mrg } 8610 1.1 mrg } 8611 1.1 mrg break; 8612 1.1 mrg 8613 1.1 mrg case MEM: 8614 1.1 mrg if (set) 8615 1.1 mrg sum->defd.mem = 1; 8616 1.1 mrg else 8617 1.1 mrg sum->used.mem = 1; 8618 1.1 mrg 8619 1.1 mrg /* Find the regs used in memory address computation: */ 8620 1.1 mrg summarize_insn (XEXP (x, 0), sum, 0); 8621 1.1 mrg break; 8622 1.1 mrg 8623 1.1 mrg case CONST_INT: case CONST_WIDE_INT: case CONST_DOUBLE: 8624 1.1 mrg case SYMBOL_REF: case LABEL_REF: case CONST: 8625 1.1 mrg case SCRATCH: case ASM_INPUT: 8626 1.1 mrg break; 8627 1.1 mrg 8628 1.1 mrg /* Handle common unary and binary ops for efficiency. */ 8629 1.1 mrg case COMPARE: case PLUS: case MINUS: case MULT: case DIV: 8630 1.1 mrg case MOD: case UDIV: case UMOD: case AND: case IOR: 8631 1.1 mrg case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT: 8632 1.1 mrg case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX: 8633 1.1 mrg case NE: case EQ: case GE: case GT: case LE: 8634 1.1 mrg case LT: case GEU: case GTU: case LEU: case LTU: 8635 1.1 mrg summarize_insn (XEXP (x, 0), sum, 0); 8636 1.1 mrg summarize_insn (XEXP (x, 1), sum, 0); 8637 1.1 mrg break; 8638 1.1 mrg 8639 1.1 mrg case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND: 8640 1.1 mrg case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT: 8641 1.1 mrg case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS: 8642 1.1 mrg case SQRT: case FFS: 8643 1.1 mrg summarize_insn (XEXP (x, 0), sum, 0); 8644 1.1 mrg break; 8645 1.1 mrg 8646 1.1 mrg default: 8647 1.1 mrg format_ptr = GET_RTX_FORMAT (GET_CODE (x)); 8648 1.1 mrg for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) 8649 1.1 mrg switch (format_ptr[i]) 8650 1.1 mrg { 8651 1.1 mrg case 'e': 8652 1.1 mrg summarize_insn (XEXP (x, i), sum, 0); 8653 1.1 mrg break; 8654 1.1 mrg 8655 1.1 mrg case 'E': 8656 1.1 mrg for (j = XVECLEN (x, i) - 1; j >= 0; j--) 8657 1.1 mrg summarize_insn (XVECEXP (x, i, j), sum, 0); 8658 1.1 mrg break; 8659 1.1 mrg 8660 1.1 mrg case 'i': 8661 1.1 mrg break; 8662 1.1 mrg 8663 1.1 mrg default: 8664 1.1 mrg gcc_unreachable (); 8665 1.1 mrg } 8666 1.1 mrg } 8667 1.1 mrg } 8668 1.1 mrg 8669 1.1 mrg /* Ensure a sufficient number of `trapb' insns are in the code when 8670 1.1 mrg the user requests code with a trap precision of functions or 8671 1.1 mrg instructions. 8672 1.1 mrg 8673 1.1 mrg In naive mode, when the user requests a trap-precision of 8674 1.1 mrg "instruction", a trapb is needed after every instruction that may 8675 1.1 mrg generate a trap. This ensures that the code is resumption safe but 8676 1.1 mrg it is also slow. 8677 1.1 mrg 8678 1.1 mrg When optimizations are turned on, we delay issuing a trapb as long 8679 1.1 mrg as possible. In this context, a trap shadow is the sequence of 8680 1.1 mrg instructions that starts with a (potentially) trap generating 8681 1.1 mrg instruction and extends to the next trapb or call_pal instruction 8682 1.1 mrg (but GCC never generates call_pal by itself). We can delay (and 8683 1.1 mrg therefore sometimes omit) a trapb subject to the following 8684 1.1 mrg conditions: 8685 1.1 mrg 8686 1.1 mrg (a) On entry to the trap shadow, if any Alpha register or memory 8687 1.1 mrg location contains a value that is used as an operand value by some 8688 1.1 mrg instruction in the trap shadow (live on entry), then no instruction 8689 1.1 mrg in the trap shadow may modify the register or memory location. 8690 1.1 mrg 8691 1.1 mrg (b) Within the trap shadow, the computation of the base register 8692 1.1 mrg for a memory load or store instruction may not involve using the 8693 1.1 mrg result of an instruction that might generate an UNPREDICTABLE 8694 1.1 mrg result. 8695 1.1 mrg 8696 1.1 mrg (c) Within the trap shadow, no register may be used more than once 8697 1.1 mrg as a destination register. (This is to make life easier for the 8698 1.1 mrg trap-handler.) 8699 1.1 mrg 8700 1.1 mrg (d) The trap shadow may not include any branch instructions. */ 8701 1.1 mrg 8702 1.1 mrg static void 8703 1.1 mrg alpha_handle_trap_shadows (void) 8704 1.1 mrg { 8705 1.1 mrg struct shadow_summary shadow; 8706 1.1 mrg int trap_pending, exception_nesting; 8707 1.1 mrg rtx_insn *i, *n; 8708 1.1 mrg 8709 1.1 mrg trap_pending = 0; 8710 1.1 mrg exception_nesting = 0; 8711 1.1 mrg shadow.used.i = 0; 8712 1.1 mrg shadow.used.fp = 0; 8713 1.1 mrg shadow.used.mem = 0; 8714 1.1 mrg shadow.defd = shadow.used; 8715 1.1 mrg 8716 1.1 mrg for (i = get_insns (); i ; i = NEXT_INSN (i)) 8717 1.1 mrg { 8718 1.1 mrg if (NOTE_P (i)) 8719 1.1 mrg { 8720 1.1 mrg switch (NOTE_KIND (i)) 8721 1.1 mrg { 8722 1.1 mrg case NOTE_INSN_EH_REGION_BEG: 8723 1.1 mrg exception_nesting++; 8724 1.1 mrg if (trap_pending) 8725 1.1 mrg goto close_shadow; 8726 1.1 mrg break; 8727 1.1 mrg 8728 1.1 mrg case NOTE_INSN_EH_REGION_END: 8729 1.1 mrg exception_nesting--; 8730 1.1 mrg if (trap_pending) 8731 1.1 mrg goto close_shadow; 8732 1.1 mrg break; 8733 1.1 mrg 8734 1.1 mrg case NOTE_INSN_EPILOGUE_BEG: 8735 1.1 mrg if (trap_pending && alpha_tp >= ALPHA_TP_FUNC) 8736 1.1 mrg goto close_shadow; 8737 1.1 mrg break; 8738 1.1 mrg } 8739 1.1 mrg } 8740 1.1 mrg else if (trap_pending) 8741 1.1 mrg { 8742 1.1 mrg if (alpha_tp == ALPHA_TP_FUNC) 8743 1.1 mrg { 8744 1.1 mrg if (JUMP_P (i) 8745 1.1 mrg && GET_CODE (PATTERN (i)) == RETURN) 8746 1.1 mrg goto close_shadow; 8747 1.1 mrg } 8748 1.1 mrg else if (alpha_tp == ALPHA_TP_INSN) 8749 1.1 mrg { 8750 1.1 mrg if (optimize > 0) 8751 1.1 mrg { 8752 1.1 mrg struct shadow_summary sum; 8753 1.1 mrg 8754 1.1 mrg sum.used.i = 0; 8755 1.1 mrg sum.used.fp = 0; 8756 1.1 mrg sum.used.mem = 0; 8757 1.1 mrg sum.defd = sum.used; 8758 1.1 mrg 8759 1.1 mrg switch (GET_CODE (i)) 8760 1.1 mrg { 8761 1.1 mrg case INSN: 8762 1.1 mrg /* Annoyingly, get_attr_trap will die on these. */ 8763 1.1 mrg if (GET_CODE (PATTERN (i)) == USE 8764 1.1 mrg || GET_CODE (PATTERN (i)) == CLOBBER) 8765 1.1 mrg break; 8766 1.1 mrg 8767 1.1 mrg summarize_insn (PATTERN (i), &sum, 0); 8768 1.1 mrg 8769 1.1 mrg if ((sum.defd.i & shadow.defd.i) 8770 1.1 mrg || (sum.defd.fp & shadow.defd.fp)) 8771 1.1 mrg { 8772 1.1 mrg /* (c) would be violated */ 8773 1.1 mrg goto close_shadow; 8774 1.1 mrg } 8775 1.1 mrg 8776 1.1 mrg /* Combine shadow with summary of current insn: */ 8777 1.1 mrg shadow.used.i |= sum.used.i; 8778 1.1 mrg shadow.used.fp |= sum.used.fp; 8779 1.1 mrg shadow.used.mem |= sum.used.mem; 8780 1.1 mrg shadow.defd.i |= sum.defd.i; 8781 1.1 mrg shadow.defd.fp |= sum.defd.fp; 8782 1.1 mrg shadow.defd.mem |= sum.defd.mem; 8783 1.1 mrg 8784 1.1 mrg if ((sum.defd.i & shadow.used.i) 8785 1.1 mrg || (sum.defd.fp & shadow.used.fp) 8786 1.1 mrg || (sum.defd.mem & shadow.used.mem)) 8787 1.1 mrg { 8788 1.1 mrg /* (a) would be violated (also takes care of (b)) */ 8789 1.1 mrg gcc_assert (get_attr_trap (i) != TRAP_YES 8790 1.1 mrg || (!(sum.defd.i & sum.used.i) 8791 1.1 mrg && !(sum.defd.fp & sum.used.fp))); 8792 1.1 mrg 8793 1.1 mrg goto close_shadow; 8794 1.1 mrg } 8795 1.1 mrg break; 8796 1.1 mrg 8797 1.1 mrg case BARRIER: 8798 1.1 mrg /* __builtin_unreachable can expand to no code at all, 8799 1.1 mrg leaving (barrier) RTXes in the instruction stream. */ 8800 1.1 mrg goto close_shadow_notrapb; 8801 1.1 mrg 8802 1.1 mrg case JUMP_INSN: 8803 1.1 mrg case CALL_INSN: 8804 1.1 mrg case CODE_LABEL: 8805 1.1 mrg goto close_shadow; 8806 1.1 mrg 8807 1.1 mrg case DEBUG_INSN: 8808 1.1 mrg break; 8809 1.1 mrg 8810 1.1 mrg default: 8811 1.1 mrg gcc_unreachable (); 8812 1.1 mrg } 8813 1.1 mrg } 8814 1.1 mrg else 8815 1.1 mrg { 8816 1.1 mrg close_shadow: 8817 1.1 mrg n = emit_insn_before (gen_trapb (), i); 8818 1.1 mrg PUT_MODE (n, TImode); 8819 1.1 mrg PUT_MODE (i, TImode); 8820 1.1 mrg close_shadow_notrapb: 8821 1.1 mrg trap_pending = 0; 8822 1.1 mrg shadow.used.i = 0; 8823 1.1 mrg shadow.used.fp = 0; 8824 1.1 mrg shadow.used.mem = 0; 8825 1.1 mrg shadow.defd = shadow.used; 8826 1.1 mrg } 8827 1.1 mrg } 8828 1.1 mrg } 8829 1.1 mrg 8830 1.1 mrg if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC) 8831 1.1 mrg && NONJUMP_INSN_P (i) 8832 1.1 mrg && GET_CODE (PATTERN (i)) != USE 8833 1.1 mrg && GET_CODE (PATTERN (i)) != CLOBBER 8834 1.1 mrg && get_attr_trap (i) == TRAP_YES) 8835 1.1 mrg { 8836 1.1 mrg if (optimize && !trap_pending) 8837 1.1 mrg summarize_insn (PATTERN (i), &shadow, 0); 8838 1.1 mrg trap_pending = 1; 8839 1.1 mrg } 8840 1.1 mrg } 8841 1.1 mrg } 8842 1.1 mrg 8843 1.1 mrg /* Alpha can only issue instruction groups simultaneously if they are 8845 1.1 mrg suitably aligned. This is very processor-specific. */ 8846 1.1 mrg /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe 8847 1.1 mrg that are marked "fake". These instructions do not exist on that target, 8848 1.1 mrg but it is possible to see these insns with deranged combinations of 8849 1.1 mrg command-line options, such as "-mtune=ev4 -mmax". Instead of aborting, 8850 1.1 mrg choose a result at random. */ 8851 1.1 mrg 8852 1.1 mrg enum alphaev4_pipe { 8853 1.1 mrg EV4_STOP = 0, 8854 1.1 mrg EV4_IB0 = 1, 8855 1.1 mrg EV4_IB1 = 2, 8856 1.1 mrg EV4_IBX = 4 8857 1.1 mrg }; 8858 1.1 mrg 8859 1.1 mrg enum alphaev5_pipe { 8860 1.1 mrg EV5_STOP = 0, 8861 1.1 mrg EV5_NONE = 1, 8862 1.1 mrg EV5_E01 = 2, 8863 1.1 mrg EV5_E0 = 4, 8864 1.1 mrg EV5_E1 = 8, 8865 1.1 mrg EV5_FAM = 16, 8866 1.1 mrg EV5_FA = 32, 8867 1.1 mrg EV5_FM = 64 8868 1.1 mrg }; 8869 1.1 mrg 8870 1.1 mrg static enum alphaev4_pipe 8871 1.1 mrg alphaev4_insn_pipe (rtx_insn *insn) 8872 1.1 mrg { 8873 1.1 mrg if (recog_memoized (insn) < 0) 8874 1.1 mrg return EV4_STOP; 8875 1.1 mrg if (get_attr_length (insn) != 4) 8876 1.1 mrg return EV4_STOP; 8877 1.1 mrg 8878 1.1 mrg switch (get_attr_type (insn)) 8879 1.1 mrg { 8880 1.1 mrg case TYPE_ILD: 8881 1.1 mrg case TYPE_LDSYM: 8882 1.1 mrg case TYPE_FLD: 8883 1.1 mrg case TYPE_LD_L: 8884 1.1 mrg return EV4_IBX; 8885 1.1 mrg 8886 1.1 mrg case TYPE_IADD: 8887 1.1 mrg case TYPE_ILOG: 8888 1.1 mrg case TYPE_ICMOV: 8889 1.1 mrg case TYPE_ICMP: 8890 1.1 mrg case TYPE_FST: 8891 1.1 mrg case TYPE_SHIFT: 8892 1.1 mrg case TYPE_IMUL: 8893 1.1 mrg case TYPE_FBR: 8894 1.1 mrg case TYPE_MVI: /* fake */ 8895 1.1 mrg return EV4_IB0; 8896 1.1 mrg 8897 1.1 mrg case TYPE_IST: 8898 1.1 mrg case TYPE_MISC: 8899 1.1 mrg case TYPE_IBR: 8900 1.1 mrg case TYPE_JSR: 8901 1.1 mrg case TYPE_CALLPAL: 8902 1.1 mrg case TYPE_FCPYS: 8903 1.1 mrg case TYPE_FCMOV: 8904 1.1 mrg case TYPE_FADD: 8905 1.1 mrg case TYPE_FDIV: 8906 1.1 mrg case TYPE_FMUL: 8907 1.1 mrg case TYPE_ST_C: 8908 1.1 mrg case TYPE_MB: 8909 1.1 mrg case TYPE_FSQRT: /* fake */ 8910 1.1 mrg case TYPE_FTOI: /* fake */ 8911 1.1 mrg case TYPE_ITOF: /* fake */ 8912 1.1 mrg return EV4_IB1; 8913 1.1 mrg 8914 1.1 mrg default: 8915 1.1 mrg gcc_unreachable (); 8916 1.1 mrg } 8917 1.1 mrg } 8918 1.1 mrg 8919 1.1 mrg static enum alphaev5_pipe 8920 1.1 mrg alphaev5_insn_pipe (rtx_insn *insn) 8921 1.1 mrg { 8922 1.1 mrg if (recog_memoized (insn) < 0) 8923 1.1 mrg return EV5_STOP; 8924 1.1 mrg if (get_attr_length (insn) != 4) 8925 1.1 mrg return EV5_STOP; 8926 1.1 mrg 8927 1.1 mrg switch (get_attr_type (insn)) 8928 1.1 mrg { 8929 1.1 mrg case TYPE_ILD: 8930 1.1 mrg case TYPE_FLD: 8931 1.1 mrg case TYPE_LDSYM: 8932 1.1 mrg case TYPE_IADD: 8933 1.1 mrg case TYPE_ILOG: 8934 1.1 mrg case TYPE_ICMOV: 8935 1.1 mrg case TYPE_ICMP: 8936 1.1 mrg return EV5_E01; 8937 1.1 mrg 8938 1.1 mrg case TYPE_IST: 8939 1.1 mrg case TYPE_FST: 8940 1.1 mrg case TYPE_SHIFT: 8941 1.1 mrg case TYPE_IMUL: 8942 1.1 mrg case TYPE_MISC: 8943 1.1 mrg case TYPE_MVI: 8944 1.1 mrg case TYPE_LD_L: 8945 1.1 mrg case TYPE_ST_C: 8946 1.1 mrg case TYPE_MB: 8947 1.1 mrg case TYPE_FTOI: /* fake */ 8948 1.1 mrg case TYPE_ITOF: /* fake */ 8949 1.1 mrg return EV5_E0; 8950 1.1 mrg 8951 1.1 mrg case TYPE_IBR: 8952 1.1 mrg case TYPE_JSR: 8953 1.1 mrg case TYPE_CALLPAL: 8954 1.1 mrg return EV5_E1; 8955 1.1 mrg 8956 1.1 mrg case TYPE_FCPYS: 8957 1.1 mrg return EV5_FAM; 8958 1.1 mrg 8959 1.1 mrg case TYPE_FBR: 8960 1.1 mrg case TYPE_FCMOV: 8961 1.1 mrg case TYPE_FADD: 8962 1.1 mrg case TYPE_FDIV: 8963 1.1 mrg case TYPE_FSQRT: /* fake */ 8964 1.1 mrg return EV5_FA; 8965 1.1 mrg 8966 1.1 mrg case TYPE_FMUL: 8967 1.1 mrg return EV5_FM; 8968 1.1 mrg 8969 1.1 mrg default: 8970 1.1 mrg gcc_unreachable (); 8971 1.1 mrg } 8972 1.1 mrg } 8973 1.1 mrg 8974 1.1 mrg /* IN_USE is a mask of the slots currently filled within the insn group. 8975 1.1 mrg The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then 8976 1.1 mrg the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1. 8977 1.1 mrg 8978 1.1 mrg LEN is, of course, the length of the group in bytes. */ 8979 1.1 mrg 8980 1.1 mrg static rtx_insn * 8981 1.1 mrg alphaev4_next_group (rtx_insn *insn, int *pin_use, int *plen) 8982 1.1 mrg { 8983 1.1 mrg int len, in_use; 8984 1.1 mrg 8985 1.1 mrg len = in_use = 0; 8986 1.1 mrg 8987 1.1 mrg if (! INSN_P (insn) 8988 1.1 mrg || GET_CODE (PATTERN (insn)) == CLOBBER 8989 1.1 mrg || GET_CODE (PATTERN (insn)) == USE) 8990 1.1 mrg goto next_and_done; 8991 1.1 mrg 8992 1.1 mrg while (1) 8993 1.1 mrg { 8994 1.1 mrg enum alphaev4_pipe pipe; 8995 1.1 mrg 8996 1.1 mrg pipe = alphaev4_insn_pipe (insn); 8997 1.1 mrg switch (pipe) 8998 1.1 mrg { 8999 1.1 mrg case EV4_STOP: 9000 1.1 mrg /* Force complex instructions to start new groups. */ 9001 1.1 mrg if (in_use) 9002 1.1 mrg goto done; 9003 1.1 mrg 9004 1.1 mrg /* If this is a completely unrecognized insn, it's an asm. 9005 1.1 mrg We don't know how long it is, so record length as -1 to 9006 1.1 mrg signal a needed realignment. */ 9007 1.1 mrg if (recog_memoized (insn) < 0) 9008 1.1 mrg len = -1; 9009 1.1 mrg else 9010 1.1 mrg len = get_attr_length (insn); 9011 1.1 mrg goto next_and_done; 9012 1.1 mrg 9013 1.1 mrg case EV4_IBX: 9014 1.1 mrg if (in_use & EV4_IB0) 9015 1.1 mrg { 9016 1.1 mrg if (in_use & EV4_IB1) 9017 1.1 mrg goto done; 9018 1.1 mrg in_use |= EV4_IB1; 9019 1.1 mrg } 9020 1.1 mrg else 9021 1.1 mrg in_use |= EV4_IB0 | EV4_IBX; 9022 1.1 mrg break; 9023 1.1 mrg 9024 1.1 mrg case EV4_IB0: 9025 1.1 mrg if (in_use & EV4_IB0) 9026 1.1 mrg { 9027 1.1 mrg if (!(in_use & EV4_IBX) || (in_use & EV4_IB1)) 9028 1.1 mrg goto done; 9029 1.1 mrg in_use |= EV4_IB1; 9030 1.1 mrg } 9031 1.1 mrg in_use |= EV4_IB0; 9032 1.1 mrg break; 9033 1.1 mrg 9034 1.1 mrg case EV4_IB1: 9035 1.1 mrg if (in_use & EV4_IB1) 9036 1.1 mrg goto done; 9037 1.1 mrg in_use |= EV4_IB1; 9038 1.1 mrg break; 9039 1.1 mrg 9040 1.1 mrg default: 9041 1.1 mrg gcc_unreachable (); 9042 1.1 mrg } 9043 1.1 mrg len += 4; 9044 1.1 mrg 9045 1.1 mrg /* Haifa doesn't do well scheduling branches. */ 9046 1.1 mrg if (JUMP_P (insn)) 9047 1.1 mrg goto next_and_done; 9048 1.1 mrg 9049 1.1 mrg next: 9050 1.1 mrg insn = next_nonnote_insn (insn); 9051 1.1 mrg 9052 1.1 mrg if (!insn || ! INSN_P (insn)) 9053 1.1 mrg goto done; 9054 1.1 mrg 9055 1.1 mrg /* Let Haifa tell us where it thinks insn group boundaries are. */ 9056 1.1 mrg if (GET_MODE (insn) == TImode) 9057 1.1 mrg goto done; 9058 1.1 mrg 9059 1.1 mrg if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) 9060 1.1 mrg goto next; 9061 1.1 mrg } 9062 1.1 mrg 9063 1.1 mrg next_and_done: 9064 1.1 mrg insn = next_nonnote_insn (insn); 9065 1.1 mrg 9066 1.1 mrg done: 9067 1.1 mrg *plen = len; 9068 1.1 mrg *pin_use = in_use; 9069 1.1 mrg return insn; 9070 1.1 mrg } 9071 1.1 mrg 9072 1.1 mrg /* IN_USE is a mask of the slots currently filled within the insn group. 9073 1.1 mrg The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then 9074 1.1 mrg the insn in EV5_E0 can be swapped by the hardware into EV5_E1. 9075 1.1 mrg 9076 1.1 mrg LEN is, of course, the length of the group in bytes. */ 9077 1.1 mrg 9078 1.1 mrg static rtx_insn * 9079 1.1 mrg alphaev5_next_group (rtx_insn *insn, int *pin_use, int *plen) 9080 1.1 mrg { 9081 1.1 mrg int len, in_use; 9082 1.1 mrg 9083 1.1 mrg len = in_use = 0; 9084 1.1 mrg 9085 1.1 mrg if (! INSN_P (insn) 9086 1.1 mrg || GET_CODE (PATTERN (insn)) == CLOBBER 9087 1.1 mrg || GET_CODE (PATTERN (insn)) == USE) 9088 1.1 mrg goto next_and_done; 9089 1.1 mrg 9090 1.1 mrg while (1) 9091 1.1 mrg { 9092 1.1 mrg enum alphaev5_pipe pipe; 9093 1.1 mrg 9094 1.1 mrg pipe = alphaev5_insn_pipe (insn); 9095 1.1 mrg switch (pipe) 9096 1.1 mrg { 9097 1.1 mrg case EV5_STOP: 9098 1.1 mrg /* Force complex instructions to start new groups. */ 9099 1.1 mrg if (in_use) 9100 1.1 mrg goto done; 9101 1.1 mrg 9102 1.1 mrg /* If this is a completely unrecognized insn, it's an asm. 9103 1.1 mrg We don't know how long it is, so record length as -1 to 9104 1.1 mrg signal a needed realignment. */ 9105 1.1 mrg if (recog_memoized (insn) < 0) 9106 1.1 mrg len = -1; 9107 1.1 mrg else 9108 1.1 mrg len = get_attr_length (insn); 9109 1.1 mrg goto next_and_done; 9110 1.1 mrg 9111 1.1 mrg /* ??? Most of the places below, we would like to assert never 9112 1.1 mrg happen, as it would indicate an error either in Haifa, or 9113 1.1 mrg in the scheduling description. Unfortunately, Haifa never 9114 1.1 mrg schedules the last instruction of the BB, so we don't have 9115 1.1 mrg an accurate TI bit to go off. */ 9116 1.1 mrg case EV5_E01: 9117 1.1 mrg if (in_use & EV5_E0) 9118 1.1 mrg { 9119 1.1 mrg if (in_use & EV5_E1) 9120 1.1 mrg goto done; 9121 1.1 mrg in_use |= EV5_E1; 9122 1.1 mrg } 9123 1.1 mrg else 9124 1.1 mrg in_use |= EV5_E0 | EV5_E01; 9125 1.1 mrg break; 9126 1.1 mrg 9127 1.1 mrg case EV5_E0: 9128 1.1 mrg if (in_use & EV5_E0) 9129 1.1 mrg { 9130 1.1 mrg if (!(in_use & EV5_E01) || (in_use & EV5_E1)) 9131 1.1 mrg goto done; 9132 1.1 mrg in_use |= EV5_E1; 9133 1.1 mrg } 9134 1.1 mrg in_use |= EV5_E0; 9135 1.1 mrg break; 9136 1.1 mrg 9137 1.1 mrg case EV5_E1: 9138 1.1 mrg if (in_use & EV5_E1) 9139 1.1 mrg goto done; 9140 1.1 mrg in_use |= EV5_E1; 9141 1.1 mrg break; 9142 1.1 mrg 9143 1.1 mrg case EV5_FAM: 9144 1.1 mrg if (in_use & EV5_FA) 9145 1.1 mrg { 9146 1.1 mrg if (in_use & EV5_FM) 9147 1.1 mrg goto done; 9148 1.1 mrg in_use |= EV5_FM; 9149 1.1 mrg } 9150 1.1 mrg else 9151 1.1 mrg in_use |= EV5_FA | EV5_FAM; 9152 1.1 mrg break; 9153 1.1 mrg 9154 1.1 mrg case EV5_FA: 9155 1.1 mrg if (in_use & EV5_FA) 9156 1.1 mrg goto done; 9157 1.1 mrg in_use |= EV5_FA; 9158 1.1 mrg break; 9159 1.1 mrg 9160 1.1 mrg case EV5_FM: 9161 1.1 mrg if (in_use & EV5_FM) 9162 1.1 mrg goto done; 9163 1.1 mrg in_use |= EV5_FM; 9164 1.1 mrg break; 9165 1.1 mrg 9166 1.1 mrg case EV5_NONE: 9167 1.1 mrg break; 9168 1.1 mrg 9169 1.1 mrg default: 9170 1.1 mrg gcc_unreachable (); 9171 1.1 mrg } 9172 1.1 mrg len += 4; 9173 1.1 mrg 9174 1.1 mrg /* Haifa doesn't do well scheduling branches. */ 9175 1.1 mrg /* ??? If this is predicted not-taken, slotting continues, except 9176 1.1 mrg that no more IBR, FBR, or JSR insns may be slotted. */ 9177 1.1 mrg if (JUMP_P (insn)) 9178 1.1 mrg goto next_and_done; 9179 1.1 mrg 9180 1.1 mrg next: 9181 1.1 mrg insn = next_nonnote_insn (insn); 9182 1.1 mrg 9183 1.1 mrg if (!insn || ! INSN_P (insn)) 9184 1.1 mrg goto done; 9185 1.1 mrg 9186 1.1 mrg /* Let Haifa tell us where it thinks insn group boundaries are. */ 9187 1.1 mrg if (GET_MODE (insn) == TImode) 9188 1.1 mrg goto done; 9189 1.1 mrg 9190 1.1 mrg if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) 9191 1.1 mrg goto next; 9192 1.1 mrg } 9193 1.1 mrg 9194 1.1 mrg next_and_done: 9195 1.1 mrg insn = next_nonnote_insn (insn); 9196 1.1 mrg 9197 1.1 mrg done: 9198 1.1 mrg *plen = len; 9199 1.1 mrg *pin_use = in_use; 9200 1.1 mrg return insn; 9201 1.1 mrg } 9202 1.1 mrg 9203 1.1 mrg static rtx 9204 1.1 mrg alphaev4_next_nop (int *pin_use) 9205 1.1 mrg { 9206 1.1 mrg int in_use = *pin_use; 9207 1.1 mrg rtx nop; 9208 1.1 mrg 9209 1.1 mrg if (!(in_use & EV4_IB0)) 9210 1.1 mrg { 9211 1.1 mrg in_use |= EV4_IB0; 9212 1.1 mrg nop = gen_nop (); 9213 1.1 mrg } 9214 1.1 mrg else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX) 9215 1.1 mrg { 9216 1.1 mrg in_use |= EV4_IB1; 9217 1.1 mrg nop = gen_nop (); 9218 1.1 mrg } 9219 1.1 mrg else if (TARGET_FP && !(in_use & EV4_IB1)) 9220 1.1 mrg { 9221 1.1 mrg in_use |= EV4_IB1; 9222 1.1 mrg nop = gen_fnop (); 9223 1.1 mrg } 9224 1.1 mrg else 9225 1.1 mrg nop = gen_unop (); 9226 1.1 mrg 9227 1.1 mrg *pin_use = in_use; 9228 1.1 mrg return nop; 9229 1.1 mrg } 9230 1.1 mrg 9231 1.1 mrg static rtx 9232 1.1 mrg alphaev5_next_nop (int *pin_use) 9233 1.1 mrg { 9234 1.1 mrg int in_use = *pin_use; 9235 1.1 mrg rtx nop; 9236 1.1 mrg 9237 1.1 mrg if (!(in_use & EV5_E1)) 9238 1.1 mrg { 9239 1.1 mrg in_use |= EV5_E1; 9240 1.1 mrg nop = gen_nop (); 9241 1.1 mrg } 9242 1.1 mrg else if (TARGET_FP && !(in_use & EV5_FA)) 9243 1.1 mrg { 9244 1.1 mrg in_use |= EV5_FA; 9245 1.1 mrg nop = gen_fnop (); 9246 1.1 mrg } 9247 1.1 mrg else if (TARGET_FP && !(in_use & EV5_FM)) 9248 1.1 mrg { 9249 1.1 mrg in_use |= EV5_FM; 9250 1.1 mrg nop = gen_fnop (); 9251 1.1 mrg } 9252 1.1 mrg else 9253 1.1 mrg nop = gen_unop (); 9254 1.1 mrg 9255 1.1 mrg *pin_use = in_use; 9256 1.1 mrg return nop; 9257 1.1 mrg } 9258 1.1 mrg 9259 1.1 mrg /* The instruction group alignment main loop. */ 9260 1.1 mrg 9261 1.1 mrg static void 9262 1.1 mrg alpha_align_insns_1 (unsigned int max_align, 9263 1.1 mrg rtx_insn *(*next_group) (rtx_insn *, int *, int *), 9264 1.1 mrg rtx (*next_nop) (int *)) 9265 1.1 mrg { 9266 1.1 mrg /* ALIGN is the known alignment for the insn group. */ 9267 1.1 mrg unsigned int align; 9268 1.1 mrg /* OFS is the offset of the current insn in the insn group. */ 9269 1.1 mrg int ofs; 9270 1.1 mrg int prev_in_use, in_use, len, ldgp; 9271 1.1 mrg rtx_insn *i, *next; 9272 1.1 mrg 9273 1.1 mrg /* Let shorten branches care for assigning alignments to code labels. */ 9274 1.1 mrg shorten_branches (get_insns ()); 9275 1.1 mrg 9276 1.1 mrg unsigned int option_alignment = align_functions.levels[0].get_value (); 9277 1.1 mrg if (option_alignment < 4) 9278 1.1 mrg align = 4; 9279 1.1 mrg else if ((unsigned int) option_alignment < max_align) 9280 1.1 mrg align = option_alignment; 9281 1.1 mrg else 9282 1.1 mrg align = max_align; 9283 1.1 mrg 9284 1.1 mrg ofs = prev_in_use = 0; 9285 1.1 mrg i = get_insns (); 9286 1.1 mrg if (NOTE_P (i)) 9287 1.1 mrg i = next_nonnote_insn (i); 9288 1.1 mrg 9289 1.1 mrg ldgp = alpha_function_needs_gp ? 8 : 0; 9290 1.1 mrg 9291 1.1 mrg while (i) 9292 1.1 mrg { 9293 1.1 mrg next = (*next_group) (i, &in_use, &len); 9294 1.1 mrg 9295 1.1 mrg /* When we see a label, resync alignment etc. */ 9296 1.1 mrg if (LABEL_P (i)) 9297 1.1 mrg { 9298 1.1 mrg unsigned int new_align 9299 1.1 mrg = label_to_alignment (i).levels[0].get_value (); 9300 1.1 mrg 9301 1.1 mrg if (new_align >= align) 9302 1.1 mrg { 9303 1.1 mrg align = new_align < max_align ? new_align : max_align; 9304 1.1 mrg ofs = 0; 9305 1.1 mrg } 9306 1.1 mrg 9307 1.1 mrg else if (ofs & (new_align-1)) 9308 1.1 mrg ofs = (ofs | (new_align-1)) + 1; 9309 1.1 mrg gcc_assert (!len); 9310 1.1 mrg } 9311 1.1 mrg 9312 1.1 mrg /* Handle complex instructions special. */ 9313 1.1 mrg else if (in_use == 0) 9314 1.1 mrg { 9315 1.1 mrg /* Asms will have length < 0. This is a signal that we have 9316 1.1 mrg lost alignment knowledge. Assume, however, that the asm 9317 1.1 mrg will not mis-align instructions. */ 9318 1.1 mrg if (len < 0) 9319 1.1 mrg { 9320 1.1 mrg ofs = 0; 9321 1.1 mrg align = 4; 9322 1.1 mrg len = 0; 9323 1.1 mrg } 9324 1.1 mrg } 9325 1.1 mrg 9326 1.1 mrg /* If the known alignment is smaller than the recognized insn group, 9327 1.1 mrg realign the output. */ 9328 1.1 mrg else if ((int) align < len) 9329 1.1 mrg { 9330 1.1 mrg unsigned int new_log_align = len > 8 ? 4 : 3; 9331 1.1 mrg rtx_insn *prev, *where; 9332 1.1 mrg 9333 1.1 mrg where = prev = prev_nonnote_insn (i); 9334 1.1 mrg if (!where || !LABEL_P (where)) 9335 1.1 mrg where = i; 9336 1.1 mrg 9337 1.1 mrg /* Can't realign between a call and its gp reload. */ 9338 1.1 mrg if (! (TARGET_EXPLICIT_RELOCS 9339 1.1 mrg && prev && CALL_P (prev))) 9340 1.1 mrg { 9341 1.1 mrg emit_insn_before (gen_realign (GEN_INT (new_log_align)), where); 9342 1.1 mrg align = 1 << new_log_align; 9343 1.1 mrg ofs = 0; 9344 1.1 mrg } 9345 1.1 mrg } 9346 1.1 mrg 9347 1.1 mrg /* We may not insert padding inside the initial ldgp sequence. */ 9348 1.1 mrg else if (ldgp > 0) 9349 1.1 mrg ldgp -= len; 9350 1.1 mrg 9351 1.1 mrg /* If the group won't fit in the same INT16 as the previous, 9352 1.1 mrg we need to add padding to keep the group together. Rather 9353 1.1 mrg than simply leaving the insn filling to the assembler, we 9354 1.1 mrg can make use of the knowledge of what sorts of instructions 9355 1.1 mrg were issued in the previous group to make sure that all of 9356 1.1 mrg the added nops are really free. */ 9357 1.1 mrg else if (ofs + len > (int) align) 9358 1.1 mrg { 9359 1.1 mrg int nop_count = (align - ofs) / 4; 9360 1.1 mrg rtx_insn *where; 9361 1.1 mrg 9362 1.1 mrg /* Insert nops before labels, branches, and calls to truly merge 9363 1.1 mrg the execution of the nops with the previous instruction group. */ 9364 1.1 mrg where = prev_nonnote_insn (i); 9365 1.1 mrg if (where) 9366 1.1 mrg { 9367 1.1 mrg if (LABEL_P (where)) 9368 1.1 mrg { 9369 1.1 mrg rtx_insn *where2 = prev_nonnote_insn (where); 9370 1.1 mrg if (where2 && JUMP_P (where2)) 9371 1.1 mrg where = where2; 9372 1.1 mrg } 9373 1.1 mrg else if (NONJUMP_INSN_P (where)) 9374 1.1 mrg where = i; 9375 1.1 mrg } 9376 1.1 mrg else 9377 1.1 mrg where = i; 9378 1.1 mrg 9379 1.1 mrg do 9380 1.1 mrg emit_insn_before ((*next_nop)(&prev_in_use), where); 9381 1.1 mrg while (--nop_count); 9382 1.1 mrg ofs = 0; 9383 1.1 mrg } 9384 1.1 mrg 9385 1.1 mrg ofs = (ofs + len) & (align - 1); 9386 1.1 mrg prev_in_use = in_use; 9387 1.1 mrg i = next; 9388 1.1 mrg } 9389 1.1 mrg } 9390 1.1 mrg 9391 1.1 mrg static void 9392 1.1 mrg alpha_align_insns (void) 9393 1.1 mrg { 9394 1.1 mrg if (alpha_tune == PROCESSOR_EV4) 9395 1.1 mrg alpha_align_insns_1 (8, alphaev4_next_group, alphaev4_next_nop); 9396 1.1 mrg else if (alpha_tune == PROCESSOR_EV5) 9397 1.1 mrg alpha_align_insns_1 (16, alphaev5_next_group, alphaev5_next_nop); 9398 1.1 mrg else 9399 1.1 mrg gcc_unreachable (); 9400 1.1 mrg } 9401 1.1 mrg 9402 1.1 mrg /* Insert an unop between sibcall or noreturn function call and GP load. */ 9403 1.1 mrg 9404 1.1 mrg static void 9405 1.1 mrg alpha_pad_function_end (void) 9406 1.1 mrg { 9407 1.1 mrg rtx_insn *insn, *next; 9408 1.1 mrg 9409 1.1 mrg for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 9410 1.1 mrg { 9411 1.1 mrg if (!CALL_P (insn) 9412 1.1 mrg || !(SIBLING_CALL_P (insn) 9413 1.1 mrg || find_reg_note (insn, REG_NORETURN, NULL_RTX))) 9414 1.1 mrg continue; 9415 1.1 mrg 9416 1.1 mrg next = next_active_insn (insn); 9417 1.1 mrg if (next) 9418 1.1 mrg { 9419 1.1 mrg rtx pat = PATTERN (next); 9420 1.1 mrg 9421 1.1 mrg if (GET_CODE (pat) == SET 9422 1.1 mrg && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE 9423 1.1 mrg && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1) 9424 1.1 mrg emit_insn_after (gen_unop (), insn); 9425 1.1 mrg } 9426 1.1 mrg } 9427 1.1 mrg } 9428 1.1 mrg 9429 1.1 mrg /* Machine dependent reorg pass. */ 9431 1.1 mrg 9432 1.1 mrg static void 9433 1.1 mrg alpha_reorg (void) 9434 1.1 mrg { 9435 1.1 mrg /* Workaround for a linker error that triggers when an exception 9436 1.1 mrg handler immediatelly follows a sibcall or a noreturn function. 9437 1.1 mrg 9438 1.1 mrg In the sibcall case: 9439 1.1 mrg 9440 1.1 mrg The instruction stream from an object file: 9441 1.1 mrg 9442 1.1 mrg 1d8: 00 00 fb 6b jmp (t12) 9443 1.1 mrg 1dc: 00 00 ba 27 ldah gp,0(ra) 9444 1.1 mrg 1e0: 00 00 bd 23 lda gp,0(gp) 9445 1.1 mrg 1e4: 00 00 7d a7 ldq t12,0(gp) 9446 1.1 mrg 1e8: 00 40 5b 6b jsr ra,(t12),1ec <__funcZ+0x1ec> 9447 1.1 mrg 9448 1.1 mrg was converted in the final link pass to: 9449 1.1 mrg 9450 1.1 mrg 12003aa88: 67 fa ff c3 br 120039428 <...> 9451 1.1 mrg 12003aa8c: 00 00 fe 2f unop 9452 1.1 mrg 12003aa90: 00 00 fe 2f unop 9453 1.1 mrg 12003aa94: 48 83 7d a7 ldq t12,-31928(gp) 9454 1.1 mrg 12003aa98: 00 40 5b 6b jsr ra,(t12),12003aa9c <__func+0x1ec> 9455 1.1 mrg 9456 1.1 mrg And in the noreturn case: 9457 1.1 mrg 9458 1.1 mrg The instruction stream from an object file: 9459 1.1 mrg 9460 1.1 mrg 54: 00 40 5b 6b jsr ra,(t12),58 <__func+0x58> 9461 1.1 mrg 58: 00 00 ba 27 ldah gp,0(ra) 9462 1.1 mrg 5c: 00 00 bd 23 lda gp,0(gp) 9463 1.1 mrg 60: 00 00 7d a7 ldq t12,0(gp) 9464 1.1 mrg 64: 00 40 5b 6b jsr ra,(t12),68 <__func+0x68> 9465 1.1 mrg 9466 1.1 mrg was converted in the final link pass to: 9467 1.1 mrg 9468 1.1 mrg fdb24: a0 03 40 d3 bsr ra,fe9a8 <_called_func+0x8> 9469 1.1 mrg fdb28: 00 00 fe 2f unop 9470 1.1 mrg fdb2c: 00 00 fe 2f unop 9471 1.1 mrg fdb30: 30 82 7d a7 ldq t12,-32208(gp) 9472 1.1 mrg fdb34: 00 40 5b 6b jsr ra,(t12),fdb38 <__func+0x68> 9473 1.1 mrg 9474 1.1 mrg GP load instructions were wrongly cleared by the linker relaxation 9475 1.1 mrg pass. This workaround prevents removal of GP loads by inserting 9476 1.1 mrg an unop instruction between a sibcall or noreturn function call and 9477 1.1 mrg exception handler prologue. */ 9478 1.1 mrg 9479 1.1 mrg if (current_function_has_exception_handlers ()) 9480 1.1 mrg alpha_pad_function_end (); 9481 1.1 mrg 9482 1.1 mrg /* CALL_PAL that implements trap insn, updates program counter to point 9483 1.1 mrg after the insn. In case trap is the last insn in the function, 9484 1.1 mrg emit NOP to guarantee that PC remains inside function boundaries. 9485 1.1 mrg This workaround is needed to get reliable backtraces. */ 9486 1.1 mrg 9487 1.1 mrg rtx_insn *insn = prev_active_insn (get_last_insn ()); 9488 1.1 mrg 9489 1.1 mrg if (insn && NONJUMP_INSN_P (insn)) 9490 1.1 mrg { 9491 1.1 mrg rtx pat = PATTERN (insn); 9492 1.1 mrg if (GET_CODE (pat) == PARALLEL) 9493 1.1 mrg { 9494 1.1 mrg rtx vec = XVECEXP (pat, 0, 0); 9495 1.1 mrg if (GET_CODE (vec) == TRAP_IF 9496 1.1 mrg && XEXP (vec, 0) == const1_rtx) 9497 1.1 mrg emit_insn_after (gen_unop (), insn); 9498 1.1 mrg } 9499 1.1 mrg } 9500 1.1 mrg } 9501 1.1 mrg 9502 1.1 mrg static void 9504 1.1 mrg alpha_file_start (void) 9505 1.1 mrg { 9506 1.1 mrg default_file_start (); 9507 1.1 mrg 9508 1.1 mrg fputs ("\t.set noreorder\n", asm_out_file); 9509 1.1 mrg fputs ("\t.set volatile\n", asm_out_file); 9510 1.1 mrg if (TARGET_ABI_OSF) 9511 1.1 mrg fputs ("\t.set noat\n", asm_out_file); 9512 1.1 mrg if (TARGET_EXPLICIT_RELOCS) 9513 1.1 mrg fputs ("\t.set nomacro\n", asm_out_file); 9514 1.1 mrg if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) 9515 1.1 mrg { 9516 1.1 mrg const char *arch; 9517 1.1 mrg 9518 1.1 mrg if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX) 9519 1.1 mrg arch = "ev6"; 9520 1.1 mrg else if (TARGET_MAX) 9521 1.1 mrg arch = "pca56"; 9522 1.1 mrg else if (TARGET_BWX) 9523 1.1 mrg arch = "ev56"; 9524 1.1 mrg else if (alpha_cpu == PROCESSOR_EV5) 9525 1.1 mrg arch = "ev5"; 9526 1.1 mrg else 9527 1.1 mrg arch = "ev4"; 9528 1.1 mrg 9529 1.1 mrg fprintf (asm_out_file, "\t.arch %s\n", arch); 9530 1.1 mrg } 9531 1.1 mrg } 9532 1.1 mrg 9533 1.1 mrg /* Since we don't have a .dynbss section, we should not allow global 9534 1.1 mrg relocations in the .rodata section. */ 9535 1.1 mrg 9536 1.1 mrg static int 9537 1.1 mrg alpha_elf_reloc_rw_mask (void) 9538 1.1 mrg { 9539 1.1 mrg return flag_pic ? 3 : 2; 9540 1.1 mrg } 9541 1.1 mrg 9542 1.1 mrg /* Return a section for X. The only special thing we do here is to 9543 1.1 mrg honor small data. */ 9544 1.1 mrg 9545 1.1 mrg static section * 9546 1.1 mrg alpha_elf_select_rtx_section (machine_mode mode, rtx x, 9547 1.1 mrg unsigned HOST_WIDE_INT align) 9548 1.1 mrg { 9549 1.1 mrg if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value) 9550 1.1 mrg /* ??? Consider using mergeable sdata sections. */ 9551 1.1 mrg return sdata_section; 9552 1.1 mrg else 9553 1.1 mrg return default_elf_select_rtx_section (mode, x, align); 9554 1.1 mrg } 9555 1.1 mrg 9556 1.1 mrg static unsigned int 9557 1.1 mrg alpha_elf_section_type_flags (tree decl, const char *name, int reloc) 9558 1.1 mrg { 9559 1.1 mrg unsigned int flags = 0; 9560 1.1 mrg 9561 1.1 mrg if (strcmp (name, ".sdata") == 0 9562 1.1 mrg || startswith (name, ".sdata.") 9563 1.1 mrg || startswith (name, ".gnu.linkonce.s.") 9564 1.1 mrg || strcmp (name, ".sbss") == 0 9565 1.1 mrg || startswith (name, ".sbss.") 9566 1.1 mrg || startswith (name, ".gnu.linkonce.sb.")) 9567 1.1 mrg flags = SECTION_SMALL; 9568 1.1 mrg 9569 1.1 mrg flags |= default_section_type_flags (decl, name, reloc); 9570 1.1 mrg return flags; 9571 1.1 mrg } 9572 1.1 mrg 9573 1.1 mrg /* Structure to collect function names for final output in link section. */ 9575 1.1 mrg /* Note that items marked with GTY can't be ifdef'ed out. */ 9576 1.1 mrg 9577 1.1 mrg enum reloc_kind 9578 1.1 mrg { 9579 1.1 mrg KIND_LINKAGE, 9580 1.1 mrg KIND_CODEADDR 9581 1.1 mrg }; 9582 1.1 mrg 9583 1.1 mrg struct GTY(()) alpha_links 9584 1.1 mrg { 9585 1.1 mrg rtx func; 9586 1.1 mrg rtx linkage; 9587 1.1 mrg enum reloc_kind rkind; 9588 1.1 mrg }; 9589 1.1 mrg 9590 1.1 mrg #if TARGET_ABI_OPEN_VMS 9591 1.1 mrg 9592 1.1 mrg /* Return the VMS argument type corresponding to MODE. */ 9593 1.1 mrg 9594 1.1 mrg enum avms_arg_type 9595 1.1 mrg alpha_arg_type (machine_mode mode) 9596 1.1 mrg { 9597 1.1 mrg switch (mode) 9598 1.1 mrg { 9599 1.1 mrg case E_SFmode: 9600 1.1 mrg return TARGET_FLOAT_VAX ? FF : FS; 9601 1.1 mrg case E_DFmode: 9602 1.1 mrg return TARGET_FLOAT_VAX ? FD : FT; 9603 1.1 mrg default: 9604 1.1 mrg return I64; 9605 1.1 mrg } 9606 1.1 mrg } 9607 1.1 mrg 9608 1.1 mrg /* Return an rtx for an integer representing the VMS Argument Information 9609 1.1 mrg register value. */ 9610 1.1 mrg 9611 1.1 mrg rtx 9612 1.1 mrg alpha_arg_info_reg_val (CUMULATIVE_ARGS cum) 9613 1.1 mrg { 9614 1.1 mrg unsigned HOST_WIDE_INT regval = cum.num_args; 9615 1.1 mrg int i; 9616 1.1 mrg 9617 1.1 mrg for (i = 0; i < 6; i++) 9618 1.1 mrg regval |= ((int) cum.atypes[i]) << (i * 3 + 8); 9619 1.1 mrg 9620 1.1 mrg return GEN_INT (regval); 9621 1.1 mrg } 9622 1.1 mrg 9623 1.1 mrg 9625 1.1 mrg /* Return a SYMBOL_REF representing the reference to the .linkage entry 9626 1.1 mrg of function FUNC built for calls made from CFUNDECL. LFLAG is 1 if 9627 1.1 mrg this is the reference to the linkage pointer value, 0 if this is the 9628 1.1 mrg reference to the function entry value. RFLAG is 1 if this a reduced 9629 1.1 mrg reference (code address only), 0 if this is a full reference. */ 9630 1.1 mrg 9631 1.1 mrg rtx 9632 1.1 mrg alpha_use_linkage (rtx func, bool lflag, bool rflag) 9633 1.1 mrg { 9634 1.1 mrg struct alpha_links *al = NULL; 9635 1.1 mrg const char *name = XSTR (func, 0); 9636 1.1 mrg 9637 1.1 mrg if (cfun->machine->links) 9638 1.1 mrg { 9639 1.1 mrg /* Is this name already defined? */ 9640 1.1 mrg alpha_links **slot = cfun->machine->links->get (name); 9641 1.1 mrg if (slot) 9642 1.1 mrg al = *slot; 9643 1.1 mrg } 9644 1.1 mrg else 9645 1.1 mrg cfun->machine->links 9646 1.1 mrg = hash_map<nofree_string_hash, alpha_links *>::create_ggc (64); 9647 1.1 mrg 9648 1.1 mrg if (al == NULL) 9649 1.1 mrg { 9650 1.1 mrg size_t buf_len; 9651 1.1 mrg char *linksym; 9652 1.1 mrg tree id; 9653 1.1 mrg 9654 1.1 mrg if (name[0] == '*') 9655 1.1 mrg name++; 9656 1.1 mrg 9657 1.1 mrg /* Follow transparent alias, as this is used for CRTL translations. */ 9658 1.1 mrg id = maybe_get_identifier (name); 9659 1.1 mrg if (id) 9660 1.1 mrg { 9661 1.1 mrg while (IDENTIFIER_TRANSPARENT_ALIAS (id)) 9662 1.1 mrg id = TREE_CHAIN (id); 9663 1.1 mrg name = IDENTIFIER_POINTER (id); 9664 1.1 mrg } 9665 1.1 mrg 9666 1.1 mrg buf_len = strlen (name) + 8 + 9; 9667 1.1 mrg linksym = (char *) alloca (buf_len); 9668 1.1 mrg snprintf (linksym, buf_len, "$%d..%s..lk", cfun->funcdef_no, name); 9669 1.1 mrg 9670 1.1 mrg al = ggc_alloc<alpha_links> (); 9671 1.1 mrg al->func = func; 9672 1.1 mrg al->linkage = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (linksym)); 9673 1.1 mrg 9674 1.1 mrg cfun->machine->links->put (ggc_strdup (name), al); 9675 1.1 mrg } 9676 1.1 mrg 9677 1.1 mrg al->rkind = rflag ? KIND_CODEADDR : KIND_LINKAGE; 9678 1.1 mrg 9679 1.1 mrg if (lflag) 9680 1.1 mrg return gen_rtx_MEM (Pmode, plus_constant (Pmode, al->linkage, 8)); 9681 1.1 mrg else 9682 1.1 mrg return al->linkage; 9683 1.1 mrg } 9684 1.1 mrg 9685 1.1 mrg static int 9686 1.1 mrg alpha_write_one_linkage (const char *name, alpha_links *link, FILE *stream) 9687 1.1 mrg { 9688 1.1 mrg ASM_OUTPUT_INTERNAL_LABEL (stream, XSTR (link->linkage, 0)); 9689 1.1 mrg if (link->rkind == KIND_CODEADDR) 9690 1.1 mrg { 9691 1.1 mrg /* External and used, request code address. */ 9692 1.1 mrg fprintf (stream, "\t.code_address "); 9693 1.1 mrg } 9694 1.1 mrg else 9695 1.1 mrg { 9696 1.1 mrg if (!SYMBOL_REF_EXTERNAL_P (link->func) 9697 1.1 mrg && SYMBOL_REF_LOCAL_P (link->func)) 9698 1.1 mrg { 9699 1.1 mrg /* Locally defined, build linkage pair. */ 9700 1.1 mrg fprintf (stream, "\t.quad %s..en\n", name); 9701 1.1 mrg fprintf (stream, "\t.quad "); 9702 1.1 mrg } 9703 1.1 mrg else 9704 1.1 mrg { 9705 1.1 mrg /* External, request linkage pair. */ 9706 1.1 mrg fprintf (stream, "\t.linkage "); 9707 1.1 mrg } 9708 1.1 mrg } 9709 1.1 mrg assemble_name (stream, name); 9710 1.1 mrg fputs ("\n", stream); 9711 1.1 mrg 9712 1.1 mrg return 0; 9713 1.1 mrg } 9714 1.1 mrg 9715 1.1 mrg static void 9716 1.1 mrg alpha_write_linkage (FILE *stream, const char *funname) 9717 1.1 mrg { 9718 1.1 mrg fprintf (stream, "\t.link\n"); 9719 1.1 mrg fprintf (stream, "\t.align 3\n"); 9720 1.1 mrg in_section = NULL; 9721 1.1 mrg 9722 1.1 mrg #ifdef TARGET_VMS_CRASH_DEBUG 9723 1.1 mrg fputs ("\t.name ", stream); 9724 1.1 mrg assemble_name (stream, funname); 9725 1.1 mrg fputs ("..na\n", stream); 9726 1.1 mrg #endif 9727 1.1 mrg 9728 1.1 mrg ASM_OUTPUT_LABEL (stream, funname); 9729 1.1 mrg fprintf (stream, "\t.pdesc "); 9730 1.1 mrg assemble_name (stream, funname); 9731 1.1 mrg fprintf (stream, "..en,%s\n", 9732 1.1 mrg alpha_procedure_type == PT_STACK ? "stack" 9733 1.1 mrg : alpha_procedure_type == PT_REGISTER ? "reg" : "null"); 9734 1.1 mrg 9735 1.1 mrg if (cfun->machine->links) 9736 1.1 mrg { 9737 1.1 mrg hash_map<nofree_string_hash, alpha_links *>::iterator iter 9738 1.1 mrg = cfun->machine->links->begin (); 9739 1.1 mrg for (; iter != cfun->machine->links->end (); ++iter) 9740 1.1 mrg alpha_write_one_linkage ((*iter).first, (*iter).second, stream); 9741 1.1 mrg } 9742 1.1 mrg } 9743 1.1 mrg 9744 1.1 mrg /* Switch to an arbitrary section NAME with attributes as specified 9745 1.1 mrg by FLAGS. ALIGN specifies any known alignment requirements for 9746 1.1 mrg the section; 0 if the default should be used. */ 9747 1.1 mrg 9748 1.1 mrg static void 9749 1.1 mrg vms_asm_named_section (const char *name, unsigned int flags, 9750 1.1 mrg tree decl ATTRIBUTE_UNUSED) 9751 1.1 mrg { 9752 1.1 mrg fputc ('\n', asm_out_file); 9753 1.1 mrg fprintf (asm_out_file, ".section\t%s", name); 9754 1.1 mrg 9755 1.1 mrg if (flags & SECTION_DEBUG) 9756 1.1 mrg fprintf (asm_out_file, ",NOWRT"); 9757 1.1 mrg 9758 1.1 mrg fputc ('\n', asm_out_file); 9759 1.1 mrg } 9760 1.1 mrg 9761 1.1 mrg /* Record an element in the table of global constructors. SYMBOL is 9762 1.1 mrg a SYMBOL_REF of the function to be called; PRIORITY is a number 9763 1.1 mrg between 0 and MAX_INIT_PRIORITY. 9764 1.1 mrg 9765 1.1 mrg Differs from default_ctors_section_asm_out_constructor in that the 9766 1.1 mrg width of the .ctors entry is always 64 bits, rather than the 32 bits 9767 1.1 mrg used by a normal pointer. */ 9768 1.1 mrg 9769 1.1 mrg static void 9770 1.1 mrg vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) 9771 1.1 mrg { 9772 1.1 mrg switch_to_section (ctors_section); 9773 1.1 mrg assemble_align (BITS_PER_WORD); 9774 1.1 mrg assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1); 9775 1.1 mrg } 9776 1.1 mrg 9777 1.1 mrg static void 9778 1.1 mrg vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) 9779 1.1 mrg { 9780 1.1 mrg switch_to_section (dtors_section); 9781 1.1 mrg assemble_align (BITS_PER_WORD); 9782 1.1 mrg assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1); 9783 1.1 mrg } 9784 1.1 mrg #else 9785 1.1 mrg rtx 9786 1.1 mrg alpha_use_linkage (rtx func ATTRIBUTE_UNUSED, 9787 1.1 mrg bool lflag ATTRIBUTE_UNUSED, 9788 1.1 mrg bool rflag ATTRIBUTE_UNUSED) 9789 1.1 mrg { 9790 1.1 mrg return NULL_RTX; 9791 1.1 mrg } 9792 1.1 mrg 9793 1.1 mrg #endif /* TARGET_ABI_OPEN_VMS */ 9794 1.1 mrg 9795 1.1 mrg static void 9797 1.1 mrg alpha_init_libfuncs (void) 9798 1.1 mrg { 9799 1.1 mrg if (TARGET_ABI_OPEN_VMS) 9800 1.1 mrg { 9801 1.1 mrg /* Use the VMS runtime library functions for division and 9802 1.1 mrg remainder. */ 9803 1.1 mrg set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I"); 9804 1.1 mrg set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L"); 9805 1.1 mrg set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI"); 9806 1.1 mrg set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL"); 9807 1.1 mrg set_optab_libfunc (smod_optab, SImode, "OTS$REM_I"); 9808 1.1 mrg set_optab_libfunc (smod_optab, DImode, "OTS$REM_L"); 9809 1.1 mrg set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI"); 9810 1.1 mrg set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL"); 9811 1.1 mrg #ifdef MEM_LIBFUNCS_INIT 9812 1.1 mrg MEM_LIBFUNCS_INIT; 9813 1.1 mrg #endif 9814 1.1 mrg } 9815 1.1 mrg } 9816 1.1 mrg 9817 1.1 mrg /* On the Alpha, we use this to disable the floating-point registers 9818 1.1 mrg when they don't exist. */ 9819 1.1 mrg 9820 1.1 mrg static void 9821 1.1 mrg alpha_conditional_register_usage (void) 9822 1.1 mrg { 9823 1.1 mrg int i; 9824 1.1 mrg if (! TARGET_FPREGS) 9825 1.1 mrg for (i = 32; i < 63; i++) 9826 1.1 mrg fixed_regs[i] = call_used_regs[i] = 1; 9827 1.1 mrg } 9828 1.1 mrg 9829 1.1 mrg /* Canonicalize a comparison from one we don't have to one we do have. */ 9830 1.1 mrg 9831 1.1 mrg static void 9832 1.1 mrg alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1, 9833 1.1 mrg bool op0_preserve_value) 9834 1.1 mrg { 9835 1.1 mrg if (!op0_preserve_value 9836 1.1 mrg && (*code == GE || *code == GT || *code == GEU || *code == GTU) 9837 1.1 mrg && (REG_P (*op1) || *op1 == const0_rtx)) 9838 1.1 mrg { 9839 1.1 mrg std::swap (*op0, *op1); 9840 1.1 mrg *code = (int)swap_condition ((enum rtx_code)*code); 9841 1.1 mrg } 9842 1.1 mrg 9843 1.1 mrg if ((*code == LT || *code == LTU) 9844 1.1 mrg && CONST_INT_P (*op1) && INTVAL (*op1) == 256) 9845 1.1 mrg { 9846 1.1 mrg *code = *code == LT ? LE : LEU; 9847 1.1 mrg *op1 = GEN_INT (255); 9848 1.1 mrg } 9849 1.1 mrg } 9850 1.1 mrg 9851 1.1 mrg /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */ 9852 1.1 mrg 9853 1.1 mrg static void 9854 1.1 mrg alpha_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) 9855 1.1 mrg { 9856 1.1 mrg const unsigned HOST_WIDE_INT SWCR_STATUS_MASK = (0x3fUL << 17); 9857 1.1 mrg 9858 1.1 mrg tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv; 9859 1.1 mrg tree new_fenv_var, reload_fenv, restore_fnenv; 9860 1.1 mrg tree update_call, atomic_feraiseexcept, hold_fnclex; 9861 1.1 mrg 9862 1.1 mrg /* Assume OSF/1 compatible interfaces. */ 9863 1.1 mrg if (!TARGET_ABI_OSF) 9864 1.1 mrg return; 9865 1.1 mrg 9866 1.1 mrg /* Generate the equivalent of : 9867 1.1 mrg unsigned long fenv_var; 9868 1.1 mrg fenv_var = __ieee_get_fp_control (); 9869 1.1 mrg 9870 1.1 mrg unsigned long masked_fenv; 9871 1.1 mrg masked_fenv = fenv_var & mask; 9872 1.1 mrg 9873 1.1 mrg __ieee_set_fp_control (masked_fenv); */ 9874 1.1 mrg 9875 1.1 mrg fenv_var = create_tmp_var_raw (long_unsigned_type_node); 9876 1.1 mrg get_fpscr 9877 1.1 mrg = build_fn_decl ("__ieee_get_fp_control", 9878 1.1 mrg build_function_type_list (long_unsigned_type_node, NULL)); 9879 1.1 mrg set_fpscr 9880 1.1 mrg = build_fn_decl ("__ieee_set_fp_control", 9881 1.1 mrg build_function_type_list (void_type_node, NULL)); 9882 1.1 mrg mask = build_int_cst (long_unsigned_type_node, ~SWCR_STATUS_MASK); 9883 1.1 mrg ld_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, fenv_var, 9884 1.1 mrg build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE); 9885 1.1 mrg masked_fenv = build2 (BIT_AND_EXPR, long_unsigned_type_node, fenv_var, mask); 9886 1.1 mrg hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv); 9887 1.1 mrg *hold = build2 (COMPOUND_EXPR, void_type_node, 9888 1.1 mrg build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv), 9889 1.1 mrg hold_fnclex); 9890 1.1 mrg 9891 1.1 mrg /* Store the value of masked_fenv to clear the exceptions: 9892 1.1 mrg __ieee_set_fp_control (masked_fenv); */ 9893 1.1 mrg 9894 1.1 mrg *clear = build_call_expr (set_fpscr, 1, masked_fenv); 9895 1.1 mrg 9896 1.1 mrg /* Generate the equivalent of : 9897 1.1 mrg unsigned long new_fenv_var; 9898 1.1 mrg new_fenv_var = __ieee_get_fp_control (); 9899 1.1 mrg 9900 1.1 mrg __ieee_set_fp_control (fenv_var); 9901 1.1 mrg 9902 1.1 mrg __atomic_feraiseexcept (new_fenv_var); */ 9903 1.1 mrg 9904 1.1 mrg new_fenv_var = create_tmp_var_raw (long_unsigned_type_node); 9905 1.1 mrg reload_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, new_fenv_var, 9906 1.1 mrg build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE); 9907 1.1 mrg restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var); 9908 1.1 mrg atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT); 9909 1.1 mrg update_call 9910 1.1 mrg = build_call_expr (atomic_feraiseexcept, 1, 9911 1.1 mrg fold_convert (integer_type_node, new_fenv_var)); 9912 1.1 mrg *update = build2 (COMPOUND_EXPR, void_type_node, 9913 1.1 mrg build2 (COMPOUND_EXPR, void_type_node, 9914 1.1 mrg reload_fenv, restore_fnenv), update_call); 9915 1.1 mrg } 9916 1.1 mrg 9917 1.1 mrg /* Implement TARGET_HARD_REGNO_MODE_OK. On Alpha, the integer registers 9918 1.1 mrg can hold any mode. The floating-point registers can hold 64-bit 9919 1.1 mrg integers as well, but not smaller values. */ 9920 1.1 mrg 9921 1.1 mrg static bool 9922 1.1 mrg alpha_hard_regno_mode_ok (unsigned int regno, machine_mode mode) 9923 1.1 mrg { 9924 1.1 mrg if (IN_RANGE (regno, 32, 62)) 9925 1.1 mrg return (mode == SFmode 9926 1.1 mrg || mode == DFmode 9927 1.1 mrg || mode == DImode 9928 1.1 mrg || mode == SCmode 9929 1.1 mrg || mode == DCmode); 9930 1.1 mrg return true; 9931 1.1 mrg } 9932 1.1 mrg 9933 1.1 mrg /* Implement TARGET_MODES_TIEABLE_P. This asymmetric test is true when 9934 1.1 mrg MODE1 could be put in an FP register but MODE2 could not. */ 9935 1.1 mrg 9936 1.1 mrg static bool 9937 1.1 mrg alpha_modes_tieable_p (machine_mode mode1, machine_mode mode2) 9938 1.1 mrg { 9939 1.1 mrg return (alpha_hard_regno_mode_ok (32, mode1) 9940 1.1 mrg ? alpha_hard_regno_mode_ok (32, mode2) 9941 1.1 mrg : true); 9942 1.1 mrg } 9943 1.1 mrg 9944 1.1 mrg /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */ 9945 1.1 mrg 9946 1.1 mrg static bool 9947 1.1 mrg alpha_can_change_mode_class (machine_mode from, machine_mode to, 9948 1.1 mrg reg_class_t rclass) 9949 1.1 mrg { 9950 1.1 mrg return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to) 9951 1.1 mrg || !reg_classes_intersect_p (FLOAT_REGS, rclass)); 9952 1.1 mrg } 9953 1.1 mrg 9954 1.1 mrg /* Initialize the GCC target structure. */ 9956 1.1 mrg #if TARGET_ABI_OPEN_VMS 9957 1.1 mrg # undef TARGET_ATTRIBUTE_TABLE 9958 1.1 mrg # define TARGET_ATTRIBUTE_TABLE vms_attribute_table 9959 1.1 mrg # undef TARGET_CAN_ELIMINATE 9960 1.1 mrg # define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate 9961 1.1 mrg #endif 9962 1.1 mrg 9963 1.1 mrg #undef TARGET_IN_SMALL_DATA_P 9964 1.1 mrg #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p 9965 1.1 mrg 9966 1.1 mrg #undef TARGET_ASM_ALIGNED_HI_OP 9967 1.1 mrg #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" 9968 1.1 mrg #undef TARGET_ASM_ALIGNED_DI_OP 9969 1.1 mrg #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" 9970 1.1 mrg 9971 1.1 mrg /* Default unaligned ops are provided for ELF systems. To get unaligned 9972 1.1 mrg data for non-ELF systems, we have to turn off auto alignment. */ 9973 1.1 mrg #if TARGET_ABI_OPEN_VMS 9974 1.1 mrg #undef TARGET_ASM_UNALIGNED_HI_OP 9975 1.1 mrg #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t" 9976 1.1 mrg #undef TARGET_ASM_UNALIGNED_SI_OP 9977 1.1 mrg #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t" 9978 1.1 mrg #undef TARGET_ASM_UNALIGNED_DI_OP 9979 1.1 mrg #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t" 9980 1.1 mrg #endif 9981 1.1 mrg 9982 1.1 mrg #undef TARGET_ASM_RELOC_RW_MASK 9983 1.1 mrg #define TARGET_ASM_RELOC_RW_MASK alpha_elf_reloc_rw_mask 9984 1.1 mrg #undef TARGET_ASM_SELECT_RTX_SECTION 9985 1.1 mrg #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section 9986 1.1 mrg #undef TARGET_SECTION_TYPE_FLAGS 9987 1.1 mrg #define TARGET_SECTION_TYPE_FLAGS alpha_elf_section_type_flags 9988 1.1 mrg 9989 1.1 mrg #undef TARGET_ASM_FUNCTION_END_PROLOGUE 9990 1.1 mrg #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue 9991 1.1 mrg 9992 1.1 mrg #undef TARGET_INIT_LIBFUNCS 9993 1.1 mrg #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs 9994 1.1 mrg 9995 1.1 mrg #undef TARGET_LEGITIMIZE_ADDRESS 9996 1.1 mrg #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address 9997 1.1 mrg #undef TARGET_MODE_DEPENDENT_ADDRESS_P 9998 1.1 mrg #define TARGET_MODE_DEPENDENT_ADDRESS_P alpha_mode_dependent_address_p 9999 1.1 mrg 10000 1.1 mrg #undef TARGET_ASM_FILE_START 10001 1.1 mrg #define TARGET_ASM_FILE_START alpha_file_start 10002 1.1 mrg 10003 1.1 mrg #undef TARGET_SCHED_ADJUST_COST 10004 1.1 mrg #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost 10005 1.1 mrg #undef TARGET_SCHED_ISSUE_RATE 10006 1.1 mrg #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate 10007 1.1 mrg #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 10008 1.1 mrg #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ 10009 1.1 mrg alpha_multipass_dfa_lookahead 10010 1.1 mrg 10011 1.1 mrg #undef TARGET_HAVE_TLS 10012 1.1 mrg #define TARGET_HAVE_TLS HAVE_AS_TLS 10013 1.1 mrg 10014 1.1 mrg #undef TARGET_BUILTIN_DECL 10015 1.1 mrg #define TARGET_BUILTIN_DECL alpha_builtin_decl 10016 1.1 mrg #undef TARGET_INIT_BUILTINS 10017 1.1 mrg #define TARGET_INIT_BUILTINS alpha_init_builtins 10018 1.1 mrg #undef TARGET_EXPAND_BUILTIN 10019 1.1 mrg #define TARGET_EXPAND_BUILTIN alpha_expand_builtin 10020 1.1 mrg #undef TARGET_FOLD_BUILTIN 10021 1.1 mrg #define TARGET_FOLD_BUILTIN alpha_fold_builtin 10022 1.1 mrg #undef TARGET_GIMPLE_FOLD_BUILTIN 10023 1.1 mrg #define TARGET_GIMPLE_FOLD_BUILTIN alpha_gimple_fold_builtin 10024 1.1 mrg 10025 1.1 mrg #undef TARGET_FUNCTION_OK_FOR_SIBCALL 10026 1.1 mrg #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall 10027 1.1 mrg #undef TARGET_CANNOT_COPY_INSN_P 10028 1.1 mrg #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p 10029 1.1 mrg #undef TARGET_LEGITIMATE_CONSTANT_P 10030 1.1 mrg #define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p 10031 1.1 mrg #undef TARGET_CANNOT_FORCE_CONST_MEM 10032 1.1 mrg #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem 10033 1.1 mrg 10034 1.1 mrg #if TARGET_ABI_OSF 10035 1.1 mrg #undef TARGET_ASM_OUTPUT_MI_THUNK 10036 1.1 mrg #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf 10037 1.1 mrg #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 10038 1.1 mrg #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true 10039 1.1 mrg #undef TARGET_STDARG_OPTIMIZE_HOOK 10040 1.1 mrg #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook 10041 1.1 mrg #endif 10042 1.1 mrg 10043 1.1 mrg #undef TARGET_PRINT_OPERAND 10044 1.1 mrg #define TARGET_PRINT_OPERAND alpha_print_operand 10045 1.1 mrg #undef TARGET_PRINT_OPERAND_ADDRESS 10046 1.1 mrg #define TARGET_PRINT_OPERAND_ADDRESS alpha_print_operand_address 10047 1.1 mrg #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P 10048 1.1 mrg #define TARGET_PRINT_OPERAND_PUNCT_VALID_P alpha_print_operand_punct_valid_p 10049 1.1 mrg 10050 1.1 mrg /* Use 16-bits anchor. */ 10051 1.1 mrg #undef TARGET_MIN_ANCHOR_OFFSET 10052 1.1 mrg #define TARGET_MIN_ANCHOR_OFFSET -0x7fff - 1 10053 1.1 mrg #undef TARGET_MAX_ANCHOR_OFFSET 10054 1.1 mrg #define TARGET_MAX_ANCHOR_OFFSET 0x7fff 10055 1.1 mrg #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P 10056 1.1 mrg #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true 10057 1.1 mrg 10058 1.1 mrg #undef TARGET_REGISTER_MOVE_COST 10059 1.1 mrg #define TARGET_REGISTER_MOVE_COST alpha_register_move_cost 10060 1.1 mrg #undef TARGET_MEMORY_MOVE_COST 10061 1.1 mrg #define TARGET_MEMORY_MOVE_COST alpha_memory_move_cost 10062 1.1 mrg #undef TARGET_RTX_COSTS 10063 1.1 mrg #define TARGET_RTX_COSTS alpha_rtx_costs 10064 1.1 mrg #undef TARGET_ADDRESS_COST 10065 1.1 mrg #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 10066 1.1 mrg 10067 1.1 mrg #undef TARGET_MACHINE_DEPENDENT_REORG 10068 1.1 mrg #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg 10069 1.1 mrg 10070 1.1 mrg #undef TARGET_PROMOTE_FUNCTION_MODE 10071 1.1 mrg #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote 10072 1.1 mrg #undef TARGET_PROMOTE_PROTOTYPES 10073 1.1 mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false 10074 1.1 mrg 10075 1.1 mrg #undef TARGET_FUNCTION_VALUE 10076 1.1 mrg #define TARGET_FUNCTION_VALUE alpha_function_value 10077 1.1 mrg #undef TARGET_LIBCALL_VALUE 10078 1.1 mrg #define TARGET_LIBCALL_VALUE alpha_libcall_value 10079 1.1 mrg #undef TARGET_FUNCTION_VALUE_REGNO_P 10080 1.1 mrg #define TARGET_FUNCTION_VALUE_REGNO_P alpha_function_value_regno_p 10081 1.1 mrg #undef TARGET_RETURN_IN_MEMORY 10082 1.1 mrg #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory 10083 1.1 mrg #undef TARGET_PASS_BY_REFERENCE 10084 1.1 mrg #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference 10085 1.1 mrg #undef TARGET_SETUP_INCOMING_VARARGS 10086 1.1 mrg #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs 10087 1.1 mrg #undef TARGET_STRICT_ARGUMENT_NAMING 10088 1.1 mrg #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 10089 1.1 mrg #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED 10090 1.1 mrg #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true 10091 1.1 mrg #undef TARGET_SPLIT_COMPLEX_ARG 10092 1.1 mrg #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg 10093 1.1 mrg #undef TARGET_GIMPLIFY_VA_ARG_EXPR 10094 1.1 mrg #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg 10095 1.1 mrg #undef TARGET_ARG_PARTIAL_BYTES 10096 1.1 mrg #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes 10097 1.1 mrg #undef TARGET_FUNCTION_ARG 10098 1.1 mrg #define TARGET_FUNCTION_ARG alpha_function_arg 10099 1.1 mrg #undef TARGET_FUNCTION_ARG_ADVANCE 10100 1.1 mrg #define TARGET_FUNCTION_ARG_ADVANCE alpha_function_arg_advance 10101 1.1 mrg #undef TARGET_TRAMPOLINE_INIT 10102 1.1 mrg #define TARGET_TRAMPOLINE_INIT alpha_trampoline_init 10103 1.1 mrg 10104 1.1 mrg #undef TARGET_INSTANTIATE_DECLS 10105 1.1 mrg #define TARGET_INSTANTIATE_DECLS alpha_instantiate_decls 10106 1.1 mrg 10107 1.1 mrg #undef TARGET_SECONDARY_RELOAD 10108 1.1 mrg #define TARGET_SECONDARY_RELOAD alpha_secondary_reload 10109 1.1 mrg #undef TARGET_SECONDARY_MEMORY_NEEDED 10110 1.1 mrg #define TARGET_SECONDARY_MEMORY_NEEDED alpha_secondary_memory_needed 10111 1.1 mrg #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE 10112 1.1 mrg #define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode 10113 1.1 mrg 10114 1.1 mrg #undef TARGET_SCALAR_MODE_SUPPORTED_P 10115 1.1 mrg #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p 10116 1.1 mrg #undef TARGET_VECTOR_MODE_SUPPORTED_P 10117 1.1 mrg #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p 10118 1.1 mrg 10119 1.1 mrg #undef TARGET_BUILD_BUILTIN_VA_LIST 10120 1.1 mrg #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list 10121 1.1 mrg 10122 1.1 mrg #undef TARGET_EXPAND_BUILTIN_VA_START 10123 1.1 mrg #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start 10124 1.1 mrg 10125 1.1 mrg #undef TARGET_OPTION_OVERRIDE 10126 1.1 mrg #define TARGET_OPTION_OVERRIDE alpha_option_override 10127 1.1 mrg 10128 1.1 mrg #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE 10129 1.1 mrg #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE \ 10130 1.1 mrg alpha_override_options_after_change 10131 1.1 mrg 10132 1.1 mrg #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING 10133 1.1 mrg #undef TARGET_MANGLE_TYPE 10134 1.1 mrg #define TARGET_MANGLE_TYPE alpha_mangle_type 10135 1.1 mrg #endif 10136 1.1 mrg 10137 #undef TARGET_LRA_P 10138 #define TARGET_LRA_P hook_bool_void_false 10139 10140 #undef TARGET_LEGITIMATE_ADDRESS_P 10141 #define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p 10142 10143 #undef TARGET_CONDITIONAL_REGISTER_USAGE 10144 #define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage 10145 10146 #undef TARGET_CANONICALIZE_COMPARISON 10147 #define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison 10148 10149 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV 10150 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV alpha_atomic_assign_expand_fenv 10151 10152 #undef TARGET_HARD_REGNO_MODE_OK 10153 #define TARGET_HARD_REGNO_MODE_OK alpha_hard_regno_mode_ok 10154 10155 #undef TARGET_MODES_TIEABLE_P 10156 #define TARGET_MODES_TIEABLE_P alpha_modes_tieable_p 10157 10158 #undef TARGET_CAN_CHANGE_MODE_CLASS 10159 #define TARGET_CAN_CHANGE_MODE_CLASS alpha_can_change_mode_class 10160 10161 struct gcc_target targetm = TARGET_INITIALIZER; 10162 10163 10164 #include "gt-alpha.h" 10166