1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 2, or (at your
12 option) any later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "recog.h"
37 #include "obstack.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "except.h"
42 #include "function.h"
43 #include "output.h"
44 #include "basic-block.h"
45 #include "integrate.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "hashtab.h"
49 #include "tm_p.h"
50 #include "target.h"
51 #include "target-def.h"
52 #include "langhooks.h"
53 #include "reload.h"
54 #include "cfglayout.h"
55 #include "sched-int.h"
56 #include "tree-gimple.h"
57 #include "intl.h"
58 #include "params.h"
59 #if TARGET_XCOFF
60 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
61 #endif
62 #if TARGET_MACHO
63 #include "gstab.h" /* for N_SLINE */
64 #endif
65
66 #ifndef TARGET_NO_PROTOTYPE
67 #define TARGET_NO_PROTOTYPE 0
68 #endif
69
70 #define min(A,B) ((A) < (B) ? (A) : (B))
71 #define max(A,B) ((A) > (B) ? (A) : (B))
72
73 /* Structure used to define the rs6000 stack */
74 typedef struct rs6000_stack {
75 int first_gp_reg_save; /* first callee saved GP register used */
76 int first_fp_reg_save; /* first callee saved FP register used */
77 int first_altivec_reg_save; /* first callee saved AltiVec register used */
78 int lr_save_p; /* true if the link reg needs to be saved */
79 int cr_save_p; /* true if the CR reg needs to be saved */
80 unsigned int vrsave_mask; /* mask of vec registers to save */
81 int toc_save_p; /* true if the TOC needs to be saved */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int toc_save_offset; /* offset to save the TOC pointer */
95 int varargs_save_offset; /* offset to save the varargs registers */
96 int ehrd_offset; /* offset to EH return data */
97 int reg_size; /* register size (4 or 8) */
98 HOST_WIDE_INT vars_size; /* variable save area size */
99 int parm_size; /* outgoing parameter size */
100 int save_size; /* save area size */
101 int fixed_size; /* fixed size of stack frame */
102 int gp_size; /* size of saved GP registers */
103 int fp_size; /* size of saved FP registers */
104 int altivec_size; /* size of saved AltiVec registers */
105 int cr_size; /* size to hold CR if not in save_size */
106 int lr_size; /* size to hold LR if not in save_size */
107 int vrsave_size; /* size to hold VRSAVE if not in save_size */
108 int altivec_padding_size; /* size of altivec alignment padding if
109 not in save_size */
110 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
111 int spe_padding_size;
112 int toc_size; /* size to hold TOC if not in save_size */
113 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
114 int spe_64bit_regs_used;
115 } rs6000_stack_t;
116
117 /* A C structure for machine-specific, per-function data.
118 This is added to the cfun structure. */
119 typedef struct machine_function GTY(())
120 {
121 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
122 int ra_needs_full_frame;
123 /* Some local-dynamic symbol. */
124 const char *some_ld_name;
125 /* Whether the instruction chain has been scanned already. */
126 int insn_chain_scanned_p;
127 /* Flags if __builtin_return_address (0) was used. */
128 int ra_need_lr;
129 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
130 varargs save area. */
131 HOST_WIDE_INT varargs_save_offset;
132 } machine_function;
133
134 /* Target cpu type */
135
136 enum processor_type rs6000_cpu;
137 struct rs6000_cpu_select rs6000_select[3] =
138 {
139 /* switch name, tune arch */
140 { (const char *)0, "--with-cpu=", 1, 1 },
141 { (const char *)0, "-mcpu=", 1, 1 },
142 { (const char *)0, "-mtune=", 1, 0 },
143 };
144
145 /* Always emit branch hint bits. */
146 static GTY(()) bool rs6000_always_hint;
147
148 /* Schedule instructions for group formation. */
149 static GTY(()) bool rs6000_sched_groups;
150
151 /* Support for -msched-costly-dep option. */
152 const char *rs6000_sched_costly_dep_str;
153 enum rs6000_dependence_cost rs6000_sched_costly_dep;
154
155 /* Support for -minsert-sched-nops option. */
156 const char *rs6000_sched_insert_nops_str;
157 enum rs6000_nop_insertion rs6000_sched_insert_nops;
158
159 /* Support targetm.vectorize.builtin_mask_for_load. */
160 static GTY(()) tree altivec_builtin_mask_for_load;
161
162 /* Size of long double. */
163 int rs6000_long_double_type_size;
164
165 /* IEEE quad extended precision long double. */
166 int rs6000_ieeequad;
167
168 /* Whether -mabi=altivec has appeared. */
169 int rs6000_altivec_abi;
170
171 /* Nonzero if we want SPE ABI extensions. */
172 int rs6000_spe_abi;
173
174 /* Nonzero if floating point operations are done in the GPRs. */
175 int rs6000_float_gprs = 0;
176
177 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
178 int rs6000_darwin64_abi;
179
180 /* Set to nonzero once AIX common-mode calls have been defined. */
181 static GTY(()) int common_mode_defined;
182
183 /* Save information from a "cmpxx" operation until the branch or scc is
184 emitted. */
185 rtx rs6000_compare_op0, rs6000_compare_op1;
186 int rs6000_compare_fp_p;
187
188 /* Label number of label created for -mrelocatable, to call to so we can
189 get the address of the GOT section */
190 int rs6000_pic_labelno;
191
192 #ifdef USING_ELFOS_H
193 /* Which abi to adhere to */
194 const char *rs6000_abi_name;
195
196 /* Semantics of the small data area */
197 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
198
199 /* Which small data model to use */
200 const char *rs6000_sdata_name = (char *)0;
201
202 /* Counter for labels which are to be placed in .fixup. */
203 int fixuplabelno = 0;
204 #endif
205
206 /* Bit size of immediate TLS offsets and string from which it is decoded. */
207 int rs6000_tls_size = 32;
208 const char *rs6000_tls_size_string;
209
210 /* ABI enumeration available for subtarget to use. */
211 enum rs6000_abi rs6000_current_abi;
212
213 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
214 int dot_symbols;
215
216 /* Debug flags */
217 const char *rs6000_debug_name;
218 int rs6000_debug_stack; /* debug stack applications */
219 int rs6000_debug_arg; /* debug argument handling */
220
221 /* Value is TRUE if register/mode pair is acceptable. */
222 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
223
224 /* Built in types. */
225
226 tree rs6000_builtin_types[RS6000_BTI_MAX];
227 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
228
229 const char *rs6000_traceback_name;
230 static enum {
231 traceback_default = 0,
232 traceback_none,
233 traceback_part,
234 traceback_full
235 } rs6000_traceback;
236
237 /* Flag to say the TOC is initialized */
238 int toc_initialized;
239 char toc_label_name[10];
240
241 /* Alias set for saves and restores from the rs6000 stack. */
242 static GTY(()) int rs6000_sr_alias_set;
243
244 /* Control alignment for fields within structures. */
245 /* String from -malign-XXXXX. */
246 int rs6000_alignment_flags;
247
248 /* True for any options that were explicitly set. */
249 struct {
250 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
251 bool alignment; /* True if -malign- was used. */
252 bool abi; /* True if -mabi=spe/nospe was used. */
253 bool spe; /* True if -mspe= was used. */
254 bool float_gprs; /* True if -mfloat-gprs= was used. */
255 bool isel; /* True if -misel was used. */
256 bool long_double; /* True if -mlong-double- was used. */
257 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
258 } rs6000_explicit_options;
259
260 struct builtin_description
261 {
262 /* mask is not const because we're going to alter it below. This
263 nonsense will go away when we rewrite the -march infrastructure
264 to give us more target flag bits. */
265 unsigned int mask;
266 const enum insn_code icode;
267 const char *const name;
268 const enum rs6000_builtins code;
269 };
270
271 /* Target cpu costs. */
272
273 struct processor_costs {
274 const int mulsi; /* cost of SImode multiplication. */
275 const int mulsi_const; /* cost of SImode multiplication by constant. */
276 const int mulsi_const9; /* cost of SImode mult by short constant. */
277 const int muldi; /* cost of DImode multiplication. */
278 const int divsi; /* cost of SImode division. */
279 const int divdi; /* cost of DImode division. */
280 const int fp; /* cost of simple SFmode and DFmode insns. */
281 const int dmul; /* cost of DFmode multiplication (and fmadd). */
282 const int sdiv; /* cost of SFmode division (fdivs). */
283 const int ddiv; /* cost of DFmode division (fdiv). */
284 };
285
286 const struct processor_costs *rs6000_cost;
287
288 /* Processor costs (relative to an add) */
289
290 /* Instruction size costs on 32bit processors. */
291 static const
292 struct processor_costs size32_cost = {
293 COSTS_N_INSNS (1), /* mulsi */
294 COSTS_N_INSNS (1), /* mulsi_const */
295 COSTS_N_INSNS (1), /* mulsi_const9 */
296 COSTS_N_INSNS (1), /* muldi */
297 COSTS_N_INSNS (1), /* divsi */
298 COSTS_N_INSNS (1), /* divdi */
299 COSTS_N_INSNS (1), /* fp */
300 COSTS_N_INSNS (1), /* dmul */
301 COSTS_N_INSNS (1), /* sdiv */
302 COSTS_N_INSNS (1), /* ddiv */
303 };
304
305 /* Instruction size costs on 64bit processors. */
306 static const
307 struct processor_costs size64_cost = {
308 COSTS_N_INSNS (1), /* mulsi */
309 COSTS_N_INSNS (1), /* mulsi_const */
310 COSTS_N_INSNS (1), /* mulsi_const9 */
311 COSTS_N_INSNS (1), /* muldi */
312 COSTS_N_INSNS (1), /* divsi */
313 COSTS_N_INSNS (1), /* divdi */
314 COSTS_N_INSNS (1), /* fp */
315 COSTS_N_INSNS (1), /* dmul */
316 COSTS_N_INSNS (1), /* sdiv */
317 COSTS_N_INSNS (1), /* ddiv */
318 };
319
320 /* Instruction costs on RIOS1 processors. */
321 static const
322 struct processor_costs rios1_cost = {
323 COSTS_N_INSNS (5), /* mulsi */
324 COSTS_N_INSNS (4), /* mulsi_const */
325 COSTS_N_INSNS (3), /* mulsi_const9 */
326 COSTS_N_INSNS (5), /* muldi */
327 COSTS_N_INSNS (19), /* divsi */
328 COSTS_N_INSNS (19), /* divdi */
329 COSTS_N_INSNS (2), /* fp */
330 COSTS_N_INSNS (2), /* dmul */
331 COSTS_N_INSNS (19), /* sdiv */
332 COSTS_N_INSNS (19), /* ddiv */
333 };
334
335 /* Instruction costs on RIOS2 processors. */
336 static const
337 struct processor_costs rios2_cost = {
338 COSTS_N_INSNS (2), /* mulsi */
339 COSTS_N_INSNS (2), /* mulsi_const */
340 COSTS_N_INSNS (2), /* mulsi_const9 */
341 COSTS_N_INSNS (2), /* muldi */
342 COSTS_N_INSNS (13), /* divsi */
343 COSTS_N_INSNS (13), /* divdi */
344 COSTS_N_INSNS (2), /* fp */
345 COSTS_N_INSNS (2), /* dmul */
346 COSTS_N_INSNS (17), /* sdiv */
347 COSTS_N_INSNS (17), /* ddiv */
348 };
349
350 /* Instruction costs on RS64A processors. */
351 static const
352 struct processor_costs rs64a_cost = {
353 COSTS_N_INSNS (20), /* mulsi */
354 COSTS_N_INSNS (12), /* mulsi_const */
355 COSTS_N_INSNS (8), /* mulsi_const9 */
356 COSTS_N_INSNS (34), /* muldi */
357 COSTS_N_INSNS (65), /* divsi */
358 COSTS_N_INSNS (67), /* divdi */
359 COSTS_N_INSNS (4), /* fp */
360 COSTS_N_INSNS (4), /* dmul */
361 COSTS_N_INSNS (31), /* sdiv */
362 COSTS_N_INSNS (31), /* ddiv */
363 };
364
365 /* Instruction costs on MPCCORE processors. */
366 static const
367 struct processor_costs mpccore_cost = {
368 COSTS_N_INSNS (2), /* mulsi */
369 COSTS_N_INSNS (2), /* mulsi_const */
370 COSTS_N_INSNS (2), /* mulsi_const9 */
371 COSTS_N_INSNS (2), /* muldi */
372 COSTS_N_INSNS (6), /* divsi */
373 COSTS_N_INSNS (6), /* divdi */
374 COSTS_N_INSNS (4), /* fp */
375 COSTS_N_INSNS (5), /* dmul */
376 COSTS_N_INSNS (10), /* sdiv */
377 COSTS_N_INSNS (17), /* ddiv */
378 };
379
380 /* Instruction costs on PPC403 processors. */
381 static const
382 struct processor_costs ppc403_cost = {
383 COSTS_N_INSNS (4), /* mulsi */
384 COSTS_N_INSNS (4), /* mulsi_const */
385 COSTS_N_INSNS (4), /* mulsi_const9 */
386 COSTS_N_INSNS (4), /* muldi */
387 COSTS_N_INSNS (33), /* divsi */
388 COSTS_N_INSNS (33), /* divdi */
389 COSTS_N_INSNS (11), /* fp */
390 COSTS_N_INSNS (11), /* dmul */
391 COSTS_N_INSNS (11), /* sdiv */
392 COSTS_N_INSNS (11), /* ddiv */
393 };
394
395 /* Instruction costs on PPC405 processors. */
396 static const
397 struct processor_costs ppc405_cost = {
398 COSTS_N_INSNS (5), /* mulsi */
399 COSTS_N_INSNS (4), /* mulsi_const */
400 COSTS_N_INSNS (3), /* mulsi_const9 */
401 COSTS_N_INSNS (5), /* muldi */
402 COSTS_N_INSNS (35), /* divsi */
403 COSTS_N_INSNS (35), /* divdi */
404 COSTS_N_INSNS (11), /* fp */
405 COSTS_N_INSNS (11), /* dmul */
406 COSTS_N_INSNS (11), /* sdiv */
407 COSTS_N_INSNS (11), /* ddiv */
408 };
409
410 /* Instruction costs on PPC440 processors. */
411 static const
412 struct processor_costs ppc440_cost = {
413 COSTS_N_INSNS (3), /* mulsi */
414 COSTS_N_INSNS (2), /* mulsi_const */
415 COSTS_N_INSNS (2), /* mulsi_const9 */
416 COSTS_N_INSNS (3), /* muldi */
417 COSTS_N_INSNS (34), /* divsi */
418 COSTS_N_INSNS (34), /* divdi */
419 COSTS_N_INSNS (5), /* fp */
420 COSTS_N_INSNS (5), /* dmul */
421 COSTS_N_INSNS (19), /* sdiv */
422 COSTS_N_INSNS (33), /* ddiv */
423 };
424
425 /* Instruction costs on PPC601 processors. */
426 static const
427 struct processor_costs ppc601_cost = {
428 COSTS_N_INSNS (5), /* mulsi */
429 COSTS_N_INSNS (5), /* mulsi_const */
430 COSTS_N_INSNS (5), /* mulsi_const9 */
431 COSTS_N_INSNS (5), /* muldi */
432 COSTS_N_INSNS (36), /* divsi */
433 COSTS_N_INSNS (36), /* divdi */
434 COSTS_N_INSNS (4), /* fp */
435 COSTS_N_INSNS (5), /* dmul */
436 COSTS_N_INSNS (17), /* sdiv */
437 COSTS_N_INSNS (31), /* ddiv */
438 };
439
440 /* Instruction costs on PPC603 processors. */
441 static const
442 struct processor_costs ppc603_cost = {
443 COSTS_N_INSNS (5), /* mulsi */
444 COSTS_N_INSNS (3), /* mulsi_const */
445 COSTS_N_INSNS (2), /* mulsi_const9 */
446 COSTS_N_INSNS (5), /* muldi */
447 COSTS_N_INSNS (37), /* divsi */
448 COSTS_N_INSNS (37), /* divdi */
449 COSTS_N_INSNS (3), /* fp */
450 COSTS_N_INSNS (4), /* dmul */
451 COSTS_N_INSNS (18), /* sdiv */
452 COSTS_N_INSNS (33), /* ddiv */
453 };
454
455 /* Instruction costs on PPC604 processors. */
456 static const
457 struct processor_costs ppc604_cost = {
458 COSTS_N_INSNS (4), /* mulsi */
459 COSTS_N_INSNS (4), /* mulsi_const */
460 COSTS_N_INSNS (4), /* mulsi_const9 */
461 COSTS_N_INSNS (4), /* muldi */
462 COSTS_N_INSNS (20), /* divsi */
463 COSTS_N_INSNS (20), /* divdi */
464 COSTS_N_INSNS (3), /* fp */
465 COSTS_N_INSNS (3), /* dmul */
466 COSTS_N_INSNS (18), /* sdiv */
467 COSTS_N_INSNS (32), /* ddiv */
468 };
469
470 /* Instruction costs on PPC604e processors. */
471 static const
472 struct processor_costs ppc604e_cost = {
473 COSTS_N_INSNS (2), /* mulsi */
474 COSTS_N_INSNS (2), /* mulsi_const */
475 COSTS_N_INSNS (2), /* mulsi_const9 */
476 COSTS_N_INSNS (2), /* muldi */
477 COSTS_N_INSNS (20), /* divsi */
478 COSTS_N_INSNS (20), /* divdi */
479 COSTS_N_INSNS (3), /* fp */
480 COSTS_N_INSNS (3), /* dmul */
481 COSTS_N_INSNS (18), /* sdiv */
482 COSTS_N_INSNS (32), /* ddiv */
483 };
484
485 /* Instruction costs on PPC620 processors. */
486 static const
487 struct processor_costs ppc620_cost = {
488 COSTS_N_INSNS (5), /* mulsi */
489 COSTS_N_INSNS (4), /* mulsi_const */
490 COSTS_N_INSNS (3), /* mulsi_const9 */
491 COSTS_N_INSNS (7), /* muldi */
492 COSTS_N_INSNS (21), /* divsi */
493 COSTS_N_INSNS (37), /* divdi */
494 COSTS_N_INSNS (3), /* fp */
495 COSTS_N_INSNS (3), /* dmul */
496 COSTS_N_INSNS (18), /* sdiv */
497 COSTS_N_INSNS (32), /* ddiv */
498 };
499
500 /* Instruction costs on PPC630 processors. */
501 static const
502 struct processor_costs ppc630_cost = {
503 COSTS_N_INSNS (5), /* mulsi */
504 COSTS_N_INSNS (4), /* mulsi_const */
505 COSTS_N_INSNS (3), /* mulsi_const9 */
506 COSTS_N_INSNS (7), /* muldi */
507 COSTS_N_INSNS (21), /* divsi */
508 COSTS_N_INSNS (37), /* divdi */
509 COSTS_N_INSNS (3), /* fp */
510 COSTS_N_INSNS (3), /* dmul */
511 COSTS_N_INSNS (17), /* sdiv */
512 COSTS_N_INSNS (21), /* ddiv */
513 };
514
515 /* Instruction costs on PPC750 and PPC7400 processors. */
516 static const
517 struct processor_costs ppc750_cost = {
518 COSTS_N_INSNS (5), /* mulsi */
519 COSTS_N_INSNS (3), /* mulsi_const */
520 COSTS_N_INSNS (2), /* mulsi_const9 */
521 COSTS_N_INSNS (5), /* muldi */
522 COSTS_N_INSNS (17), /* divsi */
523 COSTS_N_INSNS (17), /* divdi */
524 COSTS_N_INSNS (3), /* fp */
525 COSTS_N_INSNS (3), /* dmul */
526 COSTS_N_INSNS (17), /* sdiv */
527 COSTS_N_INSNS (31), /* ddiv */
528 };
529
530 /* Instruction costs on PPC7450 processors. */
531 static const
532 struct processor_costs ppc7450_cost = {
533 COSTS_N_INSNS (4), /* mulsi */
534 COSTS_N_INSNS (3), /* mulsi_const */
535 COSTS_N_INSNS (3), /* mulsi_const9 */
536 COSTS_N_INSNS (4), /* muldi */
537 COSTS_N_INSNS (23), /* divsi */
538 COSTS_N_INSNS (23), /* divdi */
539 COSTS_N_INSNS (5), /* fp */
540 COSTS_N_INSNS (5), /* dmul */
541 COSTS_N_INSNS (21), /* sdiv */
542 COSTS_N_INSNS (35), /* ddiv */
543 };
544
545 /* Instruction costs on PPC8540 processors. */
546 static const
547 struct processor_costs ppc8540_cost = {
548 COSTS_N_INSNS (4), /* mulsi */
549 COSTS_N_INSNS (4), /* mulsi_const */
550 COSTS_N_INSNS (4), /* mulsi_const9 */
551 COSTS_N_INSNS (4), /* muldi */
552 COSTS_N_INSNS (19), /* divsi */
553 COSTS_N_INSNS (19), /* divdi */
554 COSTS_N_INSNS (4), /* fp */
555 COSTS_N_INSNS (4), /* dmul */
556 COSTS_N_INSNS (29), /* sdiv */
557 COSTS_N_INSNS (29), /* ddiv */
558 };
559
560 /* Instruction costs on POWER4 and POWER5 processors. */
561 static const
562 struct processor_costs power4_cost = {
563 COSTS_N_INSNS (3), /* mulsi */
564 COSTS_N_INSNS (2), /* mulsi_const */
565 COSTS_N_INSNS (2), /* mulsi_const9 */
566 COSTS_N_INSNS (4), /* muldi */
567 COSTS_N_INSNS (18), /* divsi */
568 COSTS_N_INSNS (34), /* divdi */
569 COSTS_N_INSNS (3), /* fp */
570 COSTS_N_INSNS (3), /* dmul */
571 COSTS_N_INSNS (17), /* sdiv */
572 COSTS_N_INSNS (17), /* ddiv */
573 };
574
575
576 static bool rs6000_function_ok_for_sibcall (tree, tree);
577 static const char *rs6000_invalid_within_doloop (rtx);
578 static rtx rs6000_generate_compare (enum rtx_code);
579 static void rs6000_maybe_dead (rtx);
580 static void rs6000_emit_stack_tie (void);
581 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
582 static rtx spe_synthesize_frame_save (rtx);
583 static bool spe_func_has_64bit_regs_p (void);
584 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
585 int, HOST_WIDE_INT);
586 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
587 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
588 static unsigned rs6000_hash_constant (rtx);
589 static unsigned toc_hash_function (const void *);
590 static int toc_hash_eq (const void *, const void *);
591 static int constant_pool_expr_1 (rtx, int *, int *);
592 static bool constant_pool_expr_p (rtx);
593 static bool legitimate_indexed_address_p (rtx, int);
594 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
595 static struct machine_function * rs6000_init_machine_status (void);
596 static bool rs6000_assemble_integer (rtx, unsigned int, int);
597 static bool no_global_regs_above (int);
598 #ifdef HAVE_GAS_HIDDEN
599 static void rs6000_assemble_visibility (tree, int);
600 #endif
601 static int rs6000_ra_ever_killed (void);
602 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
603 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
604 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
605 static const char *rs6000_mangle_fundamental_type (tree);
606 extern const struct attribute_spec rs6000_attribute_table[];
607 static void rs6000_set_default_type_attributes (tree);
608 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
609 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
610 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
611 tree);
612 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
613 static bool rs6000_return_in_memory (tree, tree);
614 static void rs6000_file_start (void);
615 #if TARGET_ELF
616 static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
617 static void rs6000_elf_asm_out_constructor (rtx, int);
618 static void rs6000_elf_asm_out_destructor (rtx, int);
619 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
620 static void rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
621 static void rs6000_elf_unique_section (tree, int);
622 static void rs6000_elf_select_rtx_section (enum machine_mode, rtx,
623 unsigned HOST_WIDE_INT);
624 static void rs6000_elf_encode_section_info (tree, rtx, int)
625 ATTRIBUTE_UNUSED;
626 static bool rs6000_elf_in_small_data_p (tree);
627 #endif
628 #if TARGET_XCOFF
629 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
630 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
631 static void rs6000_xcoff_select_section (tree, int, unsigned HOST_WIDE_INT);
632 static void rs6000_xcoff_unique_section (tree, int);
633 static void rs6000_xcoff_select_rtx_section (enum machine_mode, rtx,
634 unsigned HOST_WIDE_INT);
635 static const char * rs6000_xcoff_strip_name_encoding (const char *);
636 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
637 static void rs6000_xcoff_file_start (void);
638 static void rs6000_xcoff_file_end (void);
639 #endif
640 static int rs6000_variable_issue (FILE *, int, rtx, int);
641 static bool rs6000_rtx_costs (rtx, int, int, int *);
642 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
643 static bool is_microcoded_insn (rtx);
644 static int is_dispatch_slot_restricted (rtx);
645 static bool is_cracked_insn (rtx);
646 static bool is_branch_slot_insn (rtx);
647 static int rs6000_adjust_priority (rtx, int);
648 static int rs6000_issue_rate (void);
649 static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
650 static rtx get_next_active_insn (rtx, rtx);
651 static bool insn_terminates_group_p (rtx , enum group_termination);
652 static bool is_costly_group (rtx *, rtx);
653 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
654 static int redefine_groups (FILE *, int, rtx, rtx);
655 static int pad_groups (FILE *, int, rtx, rtx);
656 static void rs6000_sched_finish (FILE *, int);
657 static int rs6000_use_sched_lookahead (void);
658 static tree rs6000_builtin_mask_for_load (void);
659
660 static void def_builtin (int, const char *, tree, int);
661 static void rs6000_init_builtins (void);
662 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
663 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
664 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
665 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
666 static void altivec_init_builtins (void);
667 static void rs6000_common_init_builtins (void);
668 static void rs6000_init_libfuncs (void);
669
670 static void enable_mask_for_builtins (struct builtin_description *, int,
671 enum rs6000_builtins,
672 enum rs6000_builtins);
673 static tree build_opaque_vector_type (tree, int);
674 static void spe_init_builtins (void);
675 static rtx spe_expand_builtin (tree, rtx, bool *);
676 static rtx spe_expand_stv_builtin (enum insn_code, tree);
677 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
678 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
679 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
680 static rs6000_stack_t *rs6000_stack_info (void);
681 static void debug_stack_info (rs6000_stack_t *);
682
683 static rtx altivec_expand_builtin (tree, rtx, bool *);
684 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
685 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
686 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
687 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
688 static rtx altivec_expand_predicate_builtin (enum insn_code,
689 const char *, tree, rtx);
690 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
691 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
692 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
693 static rtx altivec_expand_vec_set_builtin (tree);
694 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
695 static int get_element_number (tree, tree);
696 static bool rs6000_handle_option (size_t, const char *, int);
697 static void rs6000_parse_tls_size_option (void);
698 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
699 static int first_altivec_reg_to_save (void);
700 static unsigned int compute_vrsave_mask (void);
701 static void compute_save_world_info (rs6000_stack_t *info_ptr);
702 static void is_altivec_return_reg (rtx, void *);
703 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
704 int easy_vector_constant (rtx, enum machine_mode);
705 static bool rs6000_is_opaque_type (tree);
706 static rtx rs6000_dwarf_register_span (rtx);
707 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
708 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
709 static rtx rs6000_tls_get_addr (void);
710 static rtx rs6000_got_sym (void);
711 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
712 static const char *rs6000_get_some_local_dynamic_name (void);
713 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
714 static rtx rs6000_complex_function_value (enum machine_mode);
715 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
716 enum machine_mode, tree);
717 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
718 HOST_WIDE_INT);
719 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
720 tree, HOST_WIDE_INT);
721 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
722 HOST_WIDE_INT,
723 rtx[], int *);
724 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
725 tree, HOST_WIDE_INT,
726 rtx[], int *);
727 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
728 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
729 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
730 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
731 enum machine_mode, tree,
732 int *, int);
733 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
734 tree, bool);
735 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
736 tree, bool);
737 static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
738 #if TARGET_MACHO
739 static void macho_branch_islands (void);
740 static void add_compiler_branch_island (tree, tree, int);
741 static int no_previous_def (tree function_name);
742 static tree get_prev_label (tree function_name);
743 static void rs6000_darwin_file_start (void);
744 #endif
745
746 static tree rs6000_build_builtin_va_list (void);
747 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
748 static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
749 static bool rs6000_vector_mode_supported_p (enum machine_mode);
750 static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
751 enum machine_mode);
752 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
753 enum machine_mode);
754 static int get_vsel_insn (enum machine_mode);
755 static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
756 static tree rs6000_stack_protect_fail (void);
757
758 const int INSN_NOT_AVAILABLE = -1;
759 static enum machine_mode rs6000_eh_return_filter_mode (void);
760
761 /* Hash table stuff for keeping track of TOC entries. */
762
763 struct toc_hash_struct GTY(())
764 {
765 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
766 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
767 rtx key;
768 enum machine_mode key_mode;
769 int labelno;
770 };
771
772 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
773
774 /* Default register names. */
775 char rs6000_reg_names[][8] =
776 {
777 "0", "1", "2", "3", "4", "5", "6", "7",
778 "8", "9", "10", "11", "12", "13", "14", "15",
779 "16", "17", "18", "19", "20", "21", "22", "23",
780 "24", "25", "26", "27", "28", "29", "30", "31",
781 "0", "1", "2", "3", "4", "5", "6", "7",
782 "8", "9", "10", "11", "12", "13", "14", "15",
783 "16", "17", "18", "19", "20", "21", "22", "23",
784 "24", "25", "26", "27", "28", "29", "30", "31",
785 "mq", "lr", "ctr","ap",
786 "0", "1", "2", "3", "4", "5", "6", "7",
787 "xer",
788 /* AltiVec registers. */
789 "0", "1", "2", "3", "4", "5", "6", "7",
790 "8", "9", "10", "11", "12", "13", "14", "15",
791 "16", "17", "18", "19", "20", "21", "22", "23",
792 "24", "25", "26", "27", "28", "29", "30", "31",
793 "vrsave", "vscr",
794 /* SPE registers. */
795 "spe_acc", "spefscr",
796 /* Soft frame pointer. */
797 "sfp"
798 };
799
800 #ifdef TARGET_REGNAMES
801 static const char alt_reg_names[][8] =
802 {
803 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
804 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
805 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
806 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
807 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
808 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
809 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
810 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
811 "mq", "lr", "ctr", "ap",
812 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
813 "xer",
814 /* AltiVec registers. */
815 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
816 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
817 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
818 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
819 "vrsave", "vscr",
820 /* SPE registers. */
821 "spe_acc", "spefscr",
822 /* Soft frame pointer. */
823 "sfp"
824 };
825 #endif
826
827 #ifndef MASK_STRICT_ALIGN
828 #define MASK_STRICT_ALIGN 0
829 #endif
830 #ifndef TARGET_PROFILE_KERNEL
831 #define TARGET_PROFILE_KERNEL 0
832 #endif
833
834 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
835 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
836
837 /* Initialize the GCC target structure. */
838 #undef TARGET_ATTRIBUTE_TABLE
839 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
840 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
841 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
842
843 #undef TARGET_ASM_ALIGNED_DI_OP
844 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
845
846 /* Default unaligned ops are only provided for ELF. Find the ops needed
847 for non-ELF systems. */
848 #ifndef OBJECT_FORMAT_ELF
849 #if TARGET_XCOFF
850 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
851 64-bit targets. */
852 #undef TARGET_ASM_UNALIGNED_HI_OP
853 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
854 #undef TARGET_ASM_UNALIGNED_SI_OP
855 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
856 #undef TARGET_ASM_UNALIGNED_DI_OP
857 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
858 #else
859 /* For Darwin. */
860 #undef TARGET_ASM_UNALIGNED_HI_OP
861 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
862 #undef TARGET_ASM_UNALIGNED_SI_OP
863 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
864 #undef TARGET_ASM_UNALIGNED_DI_OP
865 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
866 #undef TARGET_ASM_ALIGNED_DI_OP
867 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
868 #endif
869 #endif
870
871 /* This hook deals with fixups for relocatable code and DI-mode objects
872 in 64-bit code. */
873 #undef TARGET_ASM_INTEGER
874 #define TARGET_ASM_INTEGER rs6000_assemble_integer
875
876 #ifdef HAVE_GAS_HIDDEN
877 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
878 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
879 #endif
880
881 #undef TARGET_HAVE_TLS
882 #define TARGET_HAVE_TLS HAVE_AS_TLS
883
884 #undef TARGET_CANNOT_FORCE_CONST_MEM
885 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
886
887 #undef TARGET_ASM_FUNCTION_PROLOGUE
888 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
889 #undef TARGET_ASM_FUNCTION_EPILOGUE
890 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
891
892 #undef TARGET_SCHED_VARIABLE_ISSUE
893 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
894
895 #undef TARGET_SCHED_ISSUE_RATE
896 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
897 #undef TARGET_SCHED_ADJUST_COST
898 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
899 #undef TARGET_SCHED_ADJUST_PRIORITY
900 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
901 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
902 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
903 #undef TARGET_SCHED_FINISH
904 #define TARGET_SCHED_FINISH rs6000_sched_finish
905
906 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
907 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
908
909 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
910 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
911
912 #undef TARGET_INIT_BUILTINS
913 #define TARGET_INIT_BUILTINS rs6000_init_builtins
914
915 #undef TARGET_EXPAND_BUILTIN
916 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
917
918 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
919 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
920
921 #undef TARGET_INIT_LIBFUNCS
922 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
923
924 #if TARGET_MACHO
925 #undef TARGET_BINDS_LOCAL_P
926 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
927 #endif
928
929 #undef TARGET_ASM_OUTPUT_MI_THUNK
930 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
931
932 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
933 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
934
935 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
936 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
937
938 #undef TARGET_INVALID_WITHIN_DOLOOP
939 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
940
941 #undef TARGET_RTX_COSTS
942 #define TARGET_RTX_COSTS rs6000_rtx_costs
943 #undef TARGET_ADDRESS_COST
944 #define TARGET_ADDRESS_COST hook_int_rtx_0
945
946 #undef TARGET_VECTOR_OPAQUE_P
947 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
948
949 #undef TARGET_DWARF_REGISTER_SPAN
950 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
951
952 /* On rs6000, function arguments are promoted, as are function return
953 values. */
954 #undef TARGET_PROMOTE_FUNCTION_ARGS
955 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
956 #undef TARGET_PROMOTE_FUNCTION_RETURN
957 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
958
959 #undef TARGET_RETURN_IN_MEMORY
960 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
961
962 #undef TARGET_SETUP_INCOMING_VARARGS
963 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
964
965 /* Always strict argument naming on rs6000. */
966 #undef TARGET_STRICT_ARGUMENT_NAMING
967 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
968 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
969 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
970 #undef TARGET_SPLIT_COMPLEX_ARG
971 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
972 #undef TARGET_MUST_PASS_IN_STACK
973 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
974 #undef TARGET_PASS_BY_REFERENCE
975 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
976 #undef TARGET_ARG_PARTIAL_BYTES
977 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
978
979 #undef TARGET_BUILD_BUILTIN_VA_LIST
980 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
981
982 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
983 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
984
985 #undef TARGET_EH_RETURN_FILTER_MODE
986 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
987
988 #undef TARGET_VECTOR_MODE_SUPPORTED_P
989 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
990
991 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
992 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
993
994 #undef TARGET_HANDLE_OPTION
995 #define TARGET_HANDLE_OPTION rs6000_handle_option
996
997 #undef TARGET_DEFAULT_TARGET_FLAGS
998 #define TARGET_DEFAULT_TARGET_FLAGS \
999 (TARGET_DEFAULT | MASK_SCHED_PROLOG)
1000
1001 #undef TARGET_STACK_PROTECT_FAIL
1002 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1003
1004 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1005 The PowerPC architecture requires only weak consistency among
1006 processors--that is, memory accesses between processors need not be
1007 sequentially consistent and memory accesses among processors can occur
1008 in any order. The ability to order memory accesses weakly provides
1009 opportunities for more efficient use of the system bus. Unless a
1010 dependency exists, the 604e allows read operations to precede store
1011 operations. */
1012 #undef TARGET_RELAXED_ORDERING
1013 #define TARGET_RELAXED_ORDERING true
1014
1015 #ifdef HAVE_AS_TLS
1016 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1017 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1018 #endif
1019
1020 struct gcc_target targetm = TARGET_INITIALIZER;
1021
1022
1023 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1024 MODE. */
1025 static int
rs6000_hard_regno_mode_ok(int regno,enum machine_mode mode)1026 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1027 {
1028 /* The GPRs can hold any mode, but values bigger than one register
1029 cannot go past R31. */
1030 if (INT_REGNO_P (regno))
1031 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1032
1033 /* The float registers can only hold floating modes and DImode. */
1034 if (FP_REGNO_P (regno))
1035 return
1036 (GET_MODE_CLASS (mode) == MODE_FLOAT
1037 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1038 || (GET_MODE_CLASS (mode) == MODE_INT
1039 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
1040
1041 /* The CR register can only hold CC modes. */
1042 if (CR_REGNO_P (regno))
1043 return GET_MODE_CLASS (mode) == MODE_CC;
1044
1045 if (XER_REGNO_P (regno))
1046 return mode == PSImode;
1047
1048 /* AltiVec only in AldyVec registers. */
1049 if (ALTIVEC_REGNO_P (regno))
1050 return ALTIVEC_VECTOR_MODE (mode);
1051
1052 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1053 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1054 return 1;
1055
1056 /* We cannot put TImode anywhere except general register and it must be
1057 able to fit within the register set. */
1058
1059 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1060 }
1061
1062 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1063 static void
rs6000_init_hard_regno_mode_ok(void)1064 rs6000_init_hard_regno_mode_ok (void)
1065 {
1066 int r, m;
1067
1068 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1069 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1070 if (rs6000_hard_regno_mode_ok (r, m))
1071 rs6000_hard_regno_mode_ok_p[m][r] = true;
1072 }
1073
1074 /* If not otherwise specified by a target, make 'long double' equivalent to
1075 'double'. */
1076
1077 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1078 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1079 #endif
1080
1081 /* Override command line options. Mostly we process the processor
1082 type and sometimes adjust other TARGET_ options. */
1083
1084 void
rs6000_override_options(const char * default_cpu)1085 rs6000_override_options (const char *default_cpu)
1086 {
1087 size_t i, j;
1088 struct rs6000_cpu_select *ptr;
1089 int set_masks;
1090
1091 /* Simplifications for entries below. */
1092
1093 enum {
1094 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1095 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1096 };
1097
1098 /* This table occasionally claims that a processor does not support
1099 a particular feature even though it does, but the feature is slower
1100 than the alternative. Thus, it shouldn't be relied on as a
1101 complete description of the processor's support.
1102
1103 Please keep this list in order, and don't forget to update the
1104 documentation in invoke.texi when adding a new processor or
1105 flag. */
1106 static struct ptt
1107 {
1108 const char *const name; /* Canonical processor name. */
1109 const enum processor_type processor; /* Processor type enum value. */
1110 const int target_enable; /* Target flags to enable. */
1111 } const processor_target_table[]
1112 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1113 {"403", PROCESSOR_PPC403,
1114 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1115 {"405", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1116 {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK},
1117 {"440", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1118 {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK},
1119 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1120 {"601", PROCESSOR_PPC601,
1121 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1122 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1123 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1124 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1125 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1126 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1127 {"620", PROCESSOR_PPC620,
1128 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1129 {"630", PROCESSOR_PPC630,
1130 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1131 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1132 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1133 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1134 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1135 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1136 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1137 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1138 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1139 /* 8548 has a dummy entry for now. */
1140 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1141 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1142 {"970", PROCESSOR_POWER4,
1143 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1144 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1145 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1146 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1147 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1148 {"G5", PROCESSOR_POWER4,
1149 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1150 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1151 {"power2", PROCESSOR_POWER,
1152 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1153 {"power3", PROCESSOR_PPC630,
1154 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1155 {"power4", PROCESSOR_POWER4,
1156 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
1157 {"power5", PROCESSOR_POWER5,
1158 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1159 | MASK_MFCRF | MASK_POPCNTB},
1160 {"power5+", PROCESSOR_POWER5,
1161 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1162 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1163 {"power6", PROCESSOR_POWER5,
1164 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1165 | MASK_FPRND},
1166 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1167 {"powerpc64", PROCESSOR_POWERPC64,
1168 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1169 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1170 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1171 {"rios2", PROCESSOR_RIOS2,
1172 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1173 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1174 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1175 {"rs64", PROCESSOR_RS64A,
1176 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1177 };
1178
1179 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
1180
1181 /* Some OSs don't support saving the high part of 64-bit registers on
1182 context switch. Other OSs don't support saving Altivec registers.
1183 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1184 settings; if the user wants either, the user must explicitly specify
1185 them and we won't interfere with the user's specification. */
1186
1187 enum {
1188 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1189 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
1190 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1191 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND)
1192 };
1193
1194 rs6000_init_hard_regno_mode_ok ();
1195
1196 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
1197 #ifdef OS_MISSING_POWERPC64
1198 if (OS_MISSING_POWERPC64)
1199 set_masks &= ~MASK_POWERPC64;
1200 #endif
1201 #ifdef OS_MISSING_ALTIVEC
1202 if (OS_MISSING_ALTIVEC)
1203 set_masks &= ~MASK_ALTIVEC;
1204 #endif
1205
1206 /* Don't override by the processor default if given explicitly. */
1207 set_masks &= ~target_flags_explicit;
1208
1209 /* Identify the processor type. */
1210 rs6000_select[0].string = default_cpu;
1211 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
1212
1213 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1214 {
1215 ptr = &rs6000_select[i];
1216 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1217 {
1218 for (j = 0; j < ptt_size; j++)
1219 if (! strcmp (ptr->string, processor_target_table[j].name))
1220 {
1221 if (ptr->set_tune_p)
1222 rs6000_cpu = processor_target_table[j].processor;
1223
1224 if (ptr->set_arch_p)
1225 {
1226 target_flags &= ~set_masks;
1227 target_flags |= (processor_target_table[j].target_enable
1228 & set_masks);
1229 }
1230 break;
1231 }
1232
1233 if (j == ptt_size)
1234 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
1235 }
1236 }
1237
1238 if (TARGET_E500)
1239 rs6000_isel = 1;
1240
1241 /* If we are optimizing big endian systems for space, use the load/store
1242 multiple and string instructions. */
1243 if (BYTES_BIG_ENDIAN && optimize_size)
1244 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
1245
1246 /* Don't allow -mmultiple or -mstring on little endian systems
1247 unless the cpu is a 750, because the hardware doesn't support the
1248 instructions used in little endian mode, and causes an alignment
1249 trap. The 750 does not cause an alignment trap (except when the
1250 target is unaligned). */
1251
1252 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
1253 {
1254 if (TARGET_MULTIPLE)
1255 {
1256 target_flags &= ~MASK_MULTIPLE;
1257 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
1258 warning (0, "-mmultiple is not supported on little endian systems");
1259 }
1260
1261 if (TARGET_STRING)
1262 {
1263 target_flags &= ~MASK_STRING;
1264 if ((target_flags_explicit & MASK_STRING) != 0)
1265 warning (0, "-mstring is not supported on little endian systems");
1266 }
1267 }
1268
1269 /* Set debug flags */
1270 if (rs6000_debug_name)
1271 {
1272 if (! strcmp (rs6000_debug_name, "all"))
1273 rs6000_debug_stack = rs6000_debug_arg = 1;
1274 else if (! strcmp (rs6000_debug_name, "stack"))
1275 rs6000_debug_stack = 1;
1276 else if (! strcmp (rs6000_debug_name, "arg"))
1277 rs6000_debug_arg = 1;
1278 else
1279 error ("unknown -mdebug-%s switch", rs6000_debug_name);
1280 }
1281
1282 if (rs6000_traceback_name)
1283 {
1284 if (! strncmp (rs6000_traceback_name, "full", 4))
1285 rs6000_traceback = traceback_full;
1286 else if (! strncmp (rs6000_traceback_name, "part", 4))
1287 rs6000_traceback = traceback_part;
1288 else if (! strncmp (rs6000_traceback_name, "no", 2))
1289 rs6000_traceback = traceback_none;
1290 else
1291 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1292 rs6000_traceback_name);
1293 }
1294
1295 if (!rs6000_explicit_options.long_double)
1296 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1297
1298 #ifndef POWERPC_LINUX
1299 if (!rs6000_explicit_options.ieee)
1300 rs6000_ieeequad = 1;
1301 #endif
1302
1303 /* Set Altivec ABI as default for powerpc64 linux. */
1304 if (TARGET_ELF && TARGET_64BIT)
1305 {
1306 rs6000_altivec_abi = 1;
1307 TARGET_ALTIVEC_VRSAVE = 1;
1308 }
1309
1310 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1311 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1312 {
1313 rs6000_darwin64_abi = 1;
1314 #if TARGET_MACHO
1315 darwin_one_byte_bool = 1;
1316 #endif
1317 /* Default to natural alignment, for better performance. */
1318 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1319 }
1320
1321 /* Handle -mtls-size option. */
1322 rs6000_parse_tls_size_option ();
1323
1324 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1325 SUBTARGET_OVERRIDE_OPTIONS;
1326 #endif
1327 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1328 SUBSUBTARGET_OVERRIDE_OPTIONS;
1329 #endif
1330 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1331 SUB3TARGET_OVERRIDE_OPTIONS;
1332 #endif
1333
1334 if (TARGET_E500)
1335 {
1336 if (TARGET_ALTIVEC)
1337 error ("AltiVec and E500 instructions cannot coexist");
1338
1339 /* The e500 does not have string instructions, and we set
1340 MASK_STRING above when optimizing for size. */
1341 if ((target_flags & MASK_STRING) != 0)
1342 target_flags = target_flags & ~MASK_STRING;
1343 }
1344 else if (rs6000_select[1].string != NULL)
1345 {
1346 /* For the powerpc-eabispe configuration, we set all these by
1347 default, so let's unset them if we manually set another
1348 CPU that is not the E500. */
1349 if (!rs6000_explicit_options.abi)
1350 rs6000_spe_abi = 0;
1351 if (!rs6000_explicit_options.spe)
1352 rs6000_spe = 0;
1353 if (!rs6000_explicit_options.float_gprs)
1354 rs6000_float_gprs = 0;
1355 if (!rs6000_explicit_options.isel)
1356 rs6000_isel = 0;
1357 if (!rs6000_explicit_options.long_double)
1358 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1359 }
1360
1361 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1362 && rs6000_cpu != PROCESSOR_POWER5);
1363 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1364 || rs6000_cpu == PROCESSOR_POWER5);
1365
1366 rs6000_sched_restricted_insns_priority
1367 = (rs6000_sched_groups ? 1 : 0);
1368
1369 /* Handle -msched-costly-dep option. */
1370 rs6000_sched_costly_dep
1371 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1372
1373 if (rs6000_sched_costly_dep_str)
1374 {
1375 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1376 rs6000_sched_costly_dep = no_dep_costly;
1377 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1378 rs6000_sched_costly_dep = all_deps_costly;
1379 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1380 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1381 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1382 rs6000_sched_costly_dep = store_to_load_dep_costly;
1383 else
1384 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1385 }
1386
1387 /* Handle -minsert-sched-nops option. */
1388 rs6000_sched_insert_nops
1389 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1390
1391 if (rs6000_sched_insert_nops_str)
1392 {
1393 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1394 rs6000_sched_insert_nops = sched_finish_none;
1395 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1396 rs6000_sched_insert_nops = sched_finish_pad_groups;
1397 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1398 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1399 else
1400 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1401 }
1402
1403 #ifdef TARGET_REGNAMES
1404 /* If the user desires alternate register names, copy in the
1405 alternate names now. */
1406 if (TARGET_REGNAMES)
1407 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1408 #endif
1409
1410 /* Set aix_struct_return last, after the ABI is determined.
1411 If -maix-struct-return or -msvr4-struct-return was explicitly
1412 used, don't override with the ABI default. */
1413 if (!rs6000_explicit_options.aix_struct_ret)
1414 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1415
1416 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
1417 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1418
1419 /* Allocate an alias set for register saves & restores from stack. */
1420 rs6000_sr_alias_set = new_alias_set ();
1421
1422 if (TARGET_TOC)
1423 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1424
1425 /* We can only guarantee the availability of DI pseudo-ops when
1426 assembling for 64-bit targets. */
1427 if (!TARGET_64BIT)
1428 {
1429 targetm.asm_out.aligned_op.di = NULL;
1430 targetm.asm_out.unaligned_op.di = NULL;
1431 }
1432
1433 /* Set branch target alignment, if not optimizing for size. */
1434 if (!optimize_size)
1435 {
1436 if (rs6000_sched_groups)
1437 {
1438 if (align_functions <= 0)
1439 align_functions = 16;
1440 if (align_jumps <= 0)
1441 align_jumps = 16;
1442 if (align_loops <= 0)
1443 align_loops = 16;
1444 }
1445 if (align_jumps_max_skip <= 0)
1446 align_jumps_max_skip = 15;
1447 if (align_loops_max_skip <= 0)
1448 align_loops_max_skip = 15;
1449 }
1450
1451 /* Arrange to save and restore machine status around nested functions. */
1452 init_machine_status = rs6000_init_machine_status;
1453
1454 /* We should always be splitting complex arguments, but we can't break
1455 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1456 if (DEFAULT_ABI != ABI_AIX)
1457 targetm.calls.split_complex_arg = NULL;
1458
1459 /* Initialize rs6000_cost with the appropriate target costs. */
1460 if (optimize_size)
1461 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1462 else
1463 switch (rs6000_cpu)
1464 {
1465 case PROCESSOR_RIOS1:
1466 rs6000_cost = &rios1_cost;
1467 break;
1468
1469 case PROCESSOR_RIOS2:
1470 rs6000_cost = &rios2_cost;
1471 break;
1472
1473 case PROCESSOR_RS64A:
1474 rs6000_cost = &rs64a_cost;
1475 break;
1476
1477 case PROCESSOR_MPCCORE:
1478 rs6000_cost = &mpccore_cost;
1479 break;
1480
1481 case PROCESSOR_PPC403:
1482 rs6000_cost = &ppc403_cost;
1483 break;
1484
1485 case PROCESSOR_PPC405:
1486 rs6000_cost = &ppc405_cost;
1487 break;
1488
1489 case PROCESSOR_PPC440:
1490 rs6000_cost = &ppc440_cost;
1491 break;
1492
1493 case PROCESSOR_PPC601:
1494 rs6000_cost = &ppc601_cost;
1495 break;
1496
1497 case PROCESSOR_PPC603:
1498 rs6000_cost = &ppc603_cost;
1499 break;
1500
1501 case PROCESSOR_PPC604:
1502 rs6000_cost = &ppc604_cost;
1503 break;
1504
1505 case PROCESSOR_PPC604e:
1506 rs6000_cost = &ppc604e_cost;
1507 break;
1508
1509 case PROCESSOR_PPC620:
1510 rs6000_cost = &ppc620_cost;
1511 break;
1512
1513 case PROCESSOR_PPC630:
1514 rs6000_cost = &ppc630_cost;
1515 break;
1516
1517 case PROCESSOR_PPC750:
1518 case PROCESSOR_PPC7400:
1519 rs6000_cost = &ppc750_cost;
1520 break;
1521
1522 case PROCESSOR_PPC7450:
1523 rs6000_cost = &ppc7450_cost;
1524 break;
1525
1526 case PROCESSOR_PPC8540:
1527 rs6000_cost = &ppc8540_cost;
1528 break;
1529
1530 case PROCESSOR_POWER4:
1531 case PROCESSOR_POWER5:
1532 rs6000_cost = &power4_cost;
1533 break;
1534
1535 default:
1536 gcc_unreachable ();
1537 }
1538 }
1539
1540 /* Implement targetm.vectorize.builtin_mask_for_load. */
1541 static tree
rs6000_builtin_mask_for_load(void)1542 rs6000_builtin_mask_for_load (void)
1543 {
1544 if (TARGET_ALTIVEC)
1545 return altivec_builtin_mask_for_load;
1546 else
1547 return 0;
1548 }
1549
1550 /* Handle generic options of the form -mfoo=yes/no.
1551 NAME is the option name.
1552 VALUE is the option value.
1553 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1554 whether the option value is 'yes' or 'no' respectively. */
1555 static void
rs6000_parse_yes_no_option(const char * name,const char * value,int * flag)1556 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
1557 {
1558 if (value == 0)
1559 return;
1560 else if (!strcmp (value, "yes"))
1561 *flag = 1;
1562 else if (!strcmp (value, "no"))
1563 *flag = 0;
1564 else
1565 error ("unknown -m%s= option specified: '%s'", name, value);
1566 }
1567
1568 /* Validate and record the size specified with the -mtls-size option. */
1569
1570 static void
rs6000_parse_tls_size_option(void)1571 rs6000_parse_tls_size_option (void)
1572 {
1573 if (rs6000_tls_size_string == 0)
1574 return;
1575 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1576 rs6000_tls_size = 16;
1577 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1578 rs6000_tls_size = 32;
1579 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1580 rs6000_tls_size = 64;
1581 else
1582 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
1583 }
1584
1585 void
optimization_options(int level ATTRIBUTE_UNUSED,int size ATTRIBUTE_UNUSED)1586 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1587 {
1588 if (DEFAULT_ABI == ABI_DARWIN)
1589 /* The Darwin libraries never set errno, so we might as well
1590 avoid calling them when that's the only reason we would. */
1591 flag_errno_math = 0;
1592
1593 /* Double growth factor to counter reduced min jump length. */
1594 set_param_value ("max-grow-copy-bb-insns", 16);
1595 }
1596
1597 /* Implement TARGET_HANDLE_OPTION. */
1598
1599 static bool
rs6000_handle_option(size_t code,const char * arg,int value)1600 rs6000_handle_option (size_t code, const char *arg, int value)
1601 {
1602 switch (code)
1603 {
1604 case OPT_mno_power:
1605 target_flags &= ~(MASK_POWER | MASK_POWER2
1606 | MASK_MULTIPLE | MASK_STRING);
1607 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1608 | MASK_MULTIPLE | MASK_STRING);
1609 break;
1610 case OPT_mno_powerpc:
1611 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1612 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1613 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1614 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1615 break;
1616 case OPT_mfull_toc:
1617 target_flags &= ~(MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC
1618 | MASK_NO_SUM_IN_TOC);
1619 target_flags_explicit |= (MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC
1620 | MASK_NO_SUM_IN_TOC);
1621 #ifdef TARGET_USES_SYSV4_OPT
1622 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1623 just the same as -mminimal-toc. */
1624 target_flags |= MASK_MINIMAL_TOC;
1625 target_flags_explicit |= MASK_MINIMAL_TOC;
1626 #endif
1627 break;
1628
1629 #ifdef TARGET_USES_SYSV4_OPT
1630 case OPT_mtoc:
1631 /* Make -mtoc behave like -mminimal-toc. */
1632 target_flags |= MASK_MINIMAL_TOC;
1633 target_flags_explicit |= MASK_MINIMAL_TOC;
1634 break;
1635 #endif
1636
1637 #ifdef TARGET_USES_AIX64_OPT
1638 case OPT_maix64:
1639 #else
1640 case OPT_m64:
1641 #endif
1642 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
1643 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
1644 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
1645 break;
1646
1647 #ifdef TARGET_USES_AIX64_OPT
1648 case OPT_maix32:
1649 #else
1650 case OPT_m32:
1651 #endif
1652 target_flags &= ~MASK_POWERPC64;
1653 target_flags_explicit |= MASK_POWERPC64;
1654 break;
1655
1656 case OPT_minsert_sched_nops_:
1657 rs6000_sched_insert_nops_str = arg;
1658 break;
1659
1660 case OPT_mminimal_toc:
1661 if (value == 1)
1662 {
1663 target_flags &= ~(MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC);
1664 target_flags_explicit |= (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC);
1665 }
1666 break;
1667
1668 case OPT_mpower:
1669 if (value == 1)
1670 {
1671 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1672 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1673 }
1674 break;
1675
1676 case OPT_mpower2:
1677 if (value == 1)
1678 {
1679 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1680 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1681 }
1682 break;
1683
1684 case OPT_mpowerpc_gpopt:
1685 case OPT_mpowerpc_gfxopt:
1686 if (value == 1)
1687 {
1688 target_flags |= MASK_POWERPC;
1689 target_flags_explicit |= MASK_POWERPC;
1690 }
1691 break;
1692
1693 case OPT_maix_struct_return:
1694 case OPT_msvr4_struct_return:
1695 rs6000_explicit_options.aix_struct_ret = true;
1696 break;
1697
1698 case OPT_mvrsave_:
1699 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1700 break;
1701
1702 case OPT_misel_:
1703 rs6000_explicit_options.isel = true;
1704 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1705 break;
1706
1707 case OPT_mspe_:
1708 rs6000_explicit_options.spe = true;
1709 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1710 /* No SPE means 64-bit long doubles, even if an E500. */
1711 if (!rs6000_spe)
1712 rs6000_long_double_type_size = 64;
1713 break;
1714
1715 case OPT_mdebug_:
1716 rs6000_debug_name = arg;
1717 break;
1718
1719 #ifdef TARGET_USES_SYSV4_OPT
1720 case OPT_mcall_:
1721 rs6000_abi_name = arg;
1722 break;
1723
1724 case OPT_msdata_:
1725 rs6000_sdata_name = arg;
1726 break;
1727
1728 case OPT_mtls_size_:
1729 rs6000_tls_size_string = arg;
1730 break;
1731
1732 case OPT_mrelocatable:
1733 if (value == 1)
1734 {
1735 target_flags |= MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC;
1736 target_flags_explicit |= MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC;
1737 }
1738 break;
1739
1740 case OPT_mrelocatable_lib:
1741 if (value == 1)
1742 {
1743 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC
1744 | MASK_NO_FP_IN_TOC;
1745 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC
1746 | MASK_NO_FP_IN_TOC;
1747 }
1748 else
1749 {
1750 target_flags &= ~MASK_RELOCATABLE;
1751 target_flags_explicit |= MASK_RELOCATABLE;
1752 }
1753 break;
1754 #endif
1755
1756 case OPT_mabi_:
1757 if (!strcmp (arg, "altivec"))
1758 {
1759 rs6000_explicit_options.abi = true;
1760 rs6000_altivec_abi = 1;
1761 rs6000_spe_abi = 0;
1762 }
1763 else if (! strcmp (arg, "no-altivec"))
1764 {
1765 /* ??? Don't set rs6000_explicit_options.abi here, to allow
1766 the default for rs6000_spe_abi to be chosen later. */
1767 rs6000_altivec_abi = 0;
1768 }
1769 else if (! strcmp (arg, "spe"))
1770 {
1771 rs6000_explicit_options.abi = true;
1772 rs6000_spe_abi = 1;
1773 rs6000_altivec_abi = 0;
1774 if (!TARGET_SPE_ABI)
1775 error ("not configured for ABI: '%s'", arg);
1776 }
1777 else if (! strcmp (arg, "no-spe"))
1778 {
1779 rs6000_explicit_options.abi = true;
1780 rs6000_spe_abi = 0;
1781 }
1782
1783 /* These are here for testing during development only, do not
1784 document in the manual please. */
1785 else if (! strcmp (arg, "d64"))
1786 {
1787 rs6000_darwin64_abi = 1;
1788 warning (0, "Using darwin64 ABI");
1789 }
1790 else if (! strcmp (arg, "d32"))
1791 {
1792 rs6000_darwin64_abi = 0;
1793 warning (0, "Using old darwin ABI");
1794 }
1795
1796 else if (! strcmp (arg, "ibmlongdouble"))
1797 {
1798 rs6000_explicit_options.ieee = true;
1799 rs6000_ieeequad = 0;
1800 warning (0, "Using IBM extended precision long double");
1801 }
1802 else if (! strcmp (arg, "ieeelongdouble"))
1803 {
1804 rs6000_explicit_options.ieee = true;
1805 rs6000_ieeequad = 1;
1806 warning (0, "Using IEEE extended precision long double");
1807 }
1808
1809 else
1810 {
1811 error ("unknown ABI specified: '%s'", arg);
1812 return false;
1813 }
1814 break;
1815
1816 case OPT_mcpu_:
1817 rs6000_select[1].string = arg;
1818 break;
1819
1820 case OPT_mtune_:
1821 rs6000_select[2].string = arg;
1822 break;
1823
1824 case OPT_mtraceback_:
1825 rs6000_traceback_name = arg;
1826 break;
1827
1828 case OPT_mfloat_gprs_:
1829 rs6000_explicit_options.float_gprs = true;
1830 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
1831 rs6000_float_gprs = 1;
1832 else if (! strcmp (arg, "double"))
1833 rs6000_float_gprs = 2;
1834 else if (! strcmp (arg, "no"))
1835 rs6000_float_gprs = 0;
1836 else
1837 {
1838 error ("invalid option for -mfloat-gprs: '%s'", arg);
1839 return false;
1840 }
1841 break;
1842
1843 case OPT_mlong_double_:
1844 rs6000_explicit_options.long_double = true;
1845 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1846 if (value != 64 && value != 128)
1847 {
1848 error ("Unknown switch -mlong-double-%s", arg);
1849 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1850 return false;
1851 }
1852 else
1853 rs6000_long_double_type_size = value;
1854 break;
1855
1856 case OPT_msched_costly_dep_:
1857 rs6000_sched_costly_dep_str = arg;
1858 break;
1859
1860 case OPT_malign_:
1861 rs6000_explicit_options.alignment = true;
1862 if (! strcmp (arg, "power"))
1863 {
1864 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1865 some C library functions, so warn about it. The flag may be
1866 useful for performance studies from time to time though, so
1867 don't disable it entirely. */
1868 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1869 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1870 " it is incompatible with the installed C and C++ libraries");
1871 rs6000_alignment_flags = MASK_ALIGN_POWER;
1872 }
1873 else if (! strcmp (arg, "natural"))
1874 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1875 else
1876 {
1877 error ("unknown -malign-XXXXX option specified: '%s'", arg);
1878 return false;
1879 }
1880 break;
1881 }
1882 return true;
1883 }
1884
1885 /* Do anything needed at the start of the asm file. */
1886
1887 static void
rs6000_file_start(void)1888 rs6000_file_start (void)
1889 {
1890 size_t i;
1891 char buffer[80];
1892 const char *start = buffer;
1893 struct rs6000_cpu_select *ptr;
1894 const char *default_cpu = TARGET_CPU_DEFAULT;
1895 FILE *file = asm_out_file;
1896
1897 default_file_start ();
1898
1899 #ifdef TARGET_BI_ARCH
1900 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
1901 default_cpu = 0;
1902 #endif
1903
1904 if (flag_verbose_asm)
1905 {
1906 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
1907 rs6000_select[0].string = default_cpu;
1908
1909 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1910 {
1911 ptr = &rs6000_select[i];
1912 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1913 {
1914 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
1915 start = "";
1916 }
1917 }
1918
1919 if (PPC405_ERRATUM77)
1920 {
1921 fprintf (file, "%s PPC405CR_ERRATUM77", start);
1922 start = "";
1923 }
1924
1925 #ifdef USING_ELFOS_H
1926 switch (rs6000_sdata)
1927 {
1928 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
1929 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
1930 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
1931 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
1932 }
1933
1934 if (rs6000_sdata && g_switch_value)
1935 {
1936 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
1937 g_switch_value);
1938 start = "";
1939 }
1940 #endif
1941
1942 if (*start == '\0')
1943 putc ('\n', file);
1944 }
1945
1946 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
1947 {
1948 toc_section ();
1949 text_section ();
1950 }
1951 }
1952
1953
1954 /* Return nonzero if this function is known to have a null epilogue. */
1955
1956 int
direct_return(void)1957 direct_return (void)
1958 {
1959 if (reload_completed)
1960 {
1961 rs6000_stack_t *info = rs6000_stack_info ();
1962
1963 if (info->first_gp_reg_save == 32
1964 && info->first_fp_reg_save == 64
1965 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
1966 && ! info->lr_save_p
1967 && ! info->cr_save_p
1968 && info->vrsave_mask == 0
1969 && ! info->push_p)
1970 return 1;
1971 }
1972
1973 return 0;
1974 }
1975
1976 /* Return the number of instructions it takes to form a constant in an
1977 integer register. */
1978
1979 int
num_insns_constant_wide(HOST_WIDE_INT value)1980 num_insns_constant_wide (HOST_WIDE_INT value)
1981 {
1982 /* signed constant loadable with {cal|addi} */
1983 if (CONST_OK_FOR_LETTER_P (value, 'I'))
1984 return 1;
1985
1986 /* constant loadable with {cau|addis} */
1987 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
1988 return 1;
1989
1990 #if HOST_BITS_PER_WIDE_INT == 64
1991 else if (TARGET_POWERPC64)
1992 {
1993 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1994 HOST_WIDE_INT high = value >> 31;
1995
1996 if (high == 0 || high == -1)
1997 return 2;
1998
1999 high >>= 1;
2000
2001 if (low == 0)
2002 return num_insns_constant_wide (high) + 1;
2003 else
2004 return (num_insns_constant_wide (high)
2005 + num_insns_constant_wide (low) + 1);
2006 }
2007 #endif
2008
2009 else
2010 return 2;
2011 }
2012
2013 int
num_insns_constant(rtx op,enum machine_mode mode)2014 num_insns_constant (rtx op, enum machine_mode mode)
2015 {
2016 HOST_WIDE_INT low, high;
2017
2018 switch (GET_CODE (op))
2019 {
2020 case CONST_INT:
2021 #if HOST_BITS_PER_WIDE_INT == 64
2022 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
2023 && mask64_operand (op, mode))
2024 return 2;
2025 else
2026 #endif
2027 return num_insns_constant_wide (INTVAL (op));
2028
2029 case CONST_DOUBLE:
2030 if (mode == SFmode)
2031 {
2032 long l;
2033 REAL_VALUE_TYPE rv;
2034
2035 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2036 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2037 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2038 }
2039
2040 if (mode == VOIDmode || mode == DImode)
2041 {
2042 high = CONST_DOUBLE_HIGH (op);
2043 low = CONST_DOUBLE_LOW (op);
2044 }
2045 else
2046 {
2047 long l[2];
2048 REAL_VALUE_TYPE rv;
2049
2050 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2051 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2052 high = l[WORDS_BIG_ENDIAN == 0];
2053 low = l[WORDS_BIG_ENDIAN != 0];
2054 }
2055
2056 if (TARGET_32BIT)
2057 return (num_insns_constant_wide (low)
2058 + num_insns_constant_wide (high));
2059 else
2060 {
2061 if ((high == 0 && low >= 0)
2062 || (high == -1 && low < 0))
2063 return num_insns_constant_wide (low);
2064
2065 else if (mask64_operand (op, mode))
2066 return 2;
2067
2068 else if (low == 0)
2069 return num_insns_constant_wide (high) + 1;
2070
2071 else
2072 return (num_insns_constant_wide (high)
2073 + num_insns_constant_wide (low) + 1);
2074 }
2075
2076 default:
2077 gcc_unreachable ();
2078 }
2079 }
2080
2081
2082 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2083 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2084 corresponding element of the vector, but for V4SFmode and V2SFmode,
2085 the corresponding "float" is interpreted as an SImode integer. */
2086
2087 static HOST_WIDE_INT
const_vector_elt_as_int(rtx op,unsigned int elt)2088 const_vector_elt_as_int (rtx op, unsigned int elt)
2089 {
2090 rtx tmp = CONST_VECTOR_ELT (op, elt);
2091 if (GET_MODE (op) == V4SFmode
2092 || GET_MODE (op) == V2SFmode)
2093 tmp = gen_lowpart (SImode, tmp);
2094 return INTVAL (tmp);
2095 }
2096
2097
2098 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2099 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2100 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2101 all items are set to the same value and contain COPIES replicas of the
2102 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2103 operand and the others are set to the value of the operand's msb. */
2104
2105 static bool
vspltis_constant(rtx op,unsigned step,unsigned copies)2106 vspltis_constant (rtx op, unsigned step, unsigned copies)
2107 {
2108 enum machine_mode mode = GET_MODE (op);
2109 enum machine_mode inner = GET_MODE_INNER (mode);
2110
2111 unsigned i;
2112 unsigned nunits = GET_MODE_NUNITS (mode);
2113 unsigned bitsize = GET_MODE_BITSIZE (inner);
2114 unsigned mask = GET_MODE_MASK (inner);
2115
2116 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
2117 HOST_WIDE_INT splat_val = val;
2118 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2119
2120 /* Construct the value to be splatted, if possible. If not, return 0. */
2121 for (i = 2; i <= copies; i *= 2)
2122 {
2123 HOST_WIDE_INT small_val;
2124 bitsize /= 2;
2125 small_val = splat_val >> bitsize;
2126 mask >>= bitsize;
2127 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2128 return false;
2129 splat_val = small_val;
2130 }
2131
2132 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2133 if (EASY_VECTOR_15 (splat_val))
2134 ;
2135
2136 /* Also check if we can splat, and then add the result to itself. Do so if
2137 the value is positive, of if the splat instruction is using OP's mode;
2138 for splat_val < 0, the splat and the add should use the same mode. */
2139 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2140 && (splat_val >= 0 || (step == 1 && copies == 1)))
2141 ;
2142
2143 else
2144 return false;
2145
2146 /* Check if VAL is present in every STEP-th element, and the
2147 other elements are filled with its most significant bit. */
2148 for (i = 0; i < nunits - 1; ++i)
2149 {
2150 HOST_WIDE_INT desired_val;
2151 if (((i + 1) & (step - 1)) == 0)
2152 desired_val = val;
2153 else
2154 desired_val = msb_val;
2155
2156 if (desired_val != const_vector_elt_as_int (op, i))
2157 return false;
2158 }
2159
2160 return true;
2161 }
2162
2163
2164 /* Return true if OP is of the given MODE and can be synthesized
2165 with a vspltisb, vspltish or vspltisw. */
2166
2167 bool
easy_altivec_constant(rtx op,enum machine_mode mode)2168 easy_altivec_constant (rtx op, enum machine_mode mode)
2169 {
2170 unsigned step, copies;
2171
2172 if (mode == VOIDmode)
2173 mode = GET_MODE (op);
2174 else if (mode != GET_MODE (op))
2175 return false;
2176
2177 /* Start with a vspltisw. */
2178 step = GET_MODE_NUNITS (mode) / 4;
2179 copies = 1;
2180
2181 if (vspltis_constant (op, step, copies))
2182 return true;
2183
2184 /* Then try with a vspltish. */
2185 if (step == 1)
2186 copies <<= 1;
2187 else
2188 step >>= 1;
2189
2190 if (vspltis_constant (op, step, copies))
2191 return true;
2192
2193 /* And finally a vspltisb. */
2194 if (step == 1)
2195 copies <<= 1;
2196 else
2197 step >>= 1;
2198
2199 if (vspltis_constant (op, step, copies))
2200 return true;
2201
2202 return false;
2203 }
2204
2205 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2206 result is OP. Abort if it is not possible. */
2207
2208 rtx
gen_easy_altivec_constant(rtx op)2209 gen_easy_altivec_constant (rtx op)
2210 {
2211 enum machine_mode mode = GET_MODE (op);
2212 int nunits = GET_MODE_NUNITS (mode);
2213 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2214 unsigned step = nunits / 4;
2215 unsigned copies = 1;
2216
2217 /* Start with a vspltisw. */
2218 if (vspltis_constant (op, step, copies))
2219 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2220
2221 /* Then try with a vspltish. */
2222 if (step == 1)
2223 copies <<= 1;
2224 else
2225 step >>= 1;
2226
2227 if (vspltis_constant (op, step, copies))
2228 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2229
2230 /* And finally a vspltisb. */
2231 if (step == 1)
2232 copies <<= 1;
2233 else
2234 step >>= 1;
2235
2236 if (vspltis_constant (op, step, copies))
2237 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2238
2239 gcc_unreachable ();
2240 }
2241
2242 const char *
output_vec_const_move(rtx * operands)2243 output_vec_const_move (rtx *operands)
2244 {
2245 int cst, cst2;
2246 enum machine_mode mode;
2247 rtx dest, vec;
2248
2249 dest = operands[0];
2250 vec = operands[1];
2251 mode = GET_MODE (dest);
2252
2253 if (TARGET_ALTIVEC)
2254 {
2255 rtx splat_vec;
2256 if (zero_constant (vec, mode))
2257 return "vxor %0,%0,%0";
2258
2259 splat_vec = gen_easy_altivec_constant (vec);
2260 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2261 operands[1] = XEXP (splat_vec, 0);
2262 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2263 return "#";
2264
2265 switch (GET_MODE (splat_vec))
2266 {
2267 case V4SImode:
2268 return "vspltisw %0,%1";
2269
2270 case V8HImode:
2271 return "vspltish %0,%1";
2272
2273 case V16QImode:
2274 return "vspltisb %0,%1";
2275
2276 default:
2277 gcc_unreachable ();
2278 }
2279 }
2280
2281 gcc_assert (TARGET_SPE);
2282
2283 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2284 pattern of V1DI, V4HI, and V2SF.
2285
2286 FIXME: We should probably return # and add post reload
2287 splitters for these, but this way is so easy ;-). */
2288 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2289 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2290 operands[1] = CONST_VECTOR_ELT (vec, 0);
2291 operands[2] = CONST_VECTOR_ELT (vec, 1);
2292 if (cst == cst2)
2293 return "li %0,%1\n\tevmergelo %0,%0,%0";
2294 else
2295 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2296 }
2297
2298 /* Initialize vector TARGET to VALS. */
2299
2300 void
rs6000_expand_vector_init(rtx target,rtx vals)2301 rs6000_expand_vector_init (rtx target, rtx vals)
2302 {
2303 enum machine_mode mode = GET_MODE (target);
2304 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2305 int n_elts = GET_MODE_NUNITS (mode);
2306 int n_var = 0, one_var = -1;
2307 bool all_same = true, all_const_zero = true;
2308 rtx x, mem;
2309 int i;
2310
2311 for (i = 0; i < n_elts; ++i)
2312 {
2313 x = XVECEXP (vals, 0, i);
2314 if (!CONSTANT_P (x))
2315 ++n_var, one_var = i;
2316 else if (x != CONST0_RTX (inner_mode))
2317 all_const_zero = false;
2318
2319 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2320 all_same = false;
2321 }
2322
2323 if (n_var == 0)
2324 {
2325 if (mode != V4SFmode && all_const_zero)
2326 {
2327 /* Zero register. */
2328 emit_insn (gen_rtx_SET (VOIDmode, target,
2329 gen_rtx_XOR (mode, target, target)));
2330 return;
2331 }
2332 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
2333 {
2334 /* Splat immediate. */
2335 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
2336 return;
2337 }
2338 else if (all_same)
2339 ; /* Splat vector element. */
2340 else
2341 {
2342 /* Load from constant pool. */
2343 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2344 return;
2345 }
2346 }
2347
2348 /* Store value to stack temp. Load vector element. Splat. */
2349 if (all_same)
2350 {
2351 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2352 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2353 XVECEXP (vals, 0, 0));
2354 x = gen_rtx_UNSPEC (VOIDmode,
2355 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2356 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2357 gen_rtvec (2,
2358 gen_rtx_SET (VOIDmode,
2359 target, mem),
2360 x)));
2361 x = gen_rtx_VEC_SELECT (inner_mode, target,
2362 gen_rtx_PARALLEL (VOIDmode,
2363 gen_rtvec (1, const0_rtx)));
2364 emit_insn (gen_rtx_SET (VOIDmode, target,
2365 gen_rtx_VEC_DUPLICATE (mode, x)));
2366 return;
2367 }
2368
2369 /* One field is non-constant. Load constant then overwrite
2370 varying field. */
2371 if (n_var == 1)
2372 {
2373 rtx copy = copy_rtx (vals);
2374
2375 /* Load constant part of vector, substitute neighboring value for
2376 varying element. */
2377 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2378 rs6000_expand_vector_init (target, copy);
2379
2380 /* Insert variable. */
2381 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2382 return;
2383 }
2384
2385 /* Construct the vector in memory one field at a time
2386 and load the whole vector. */
2387 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2388 for (i = 0; i < n_elts; i++)
2389 emit_move_insn (adjust_address_nv (mem, inner_mode,
2390 i * GET_MODE_SIZE (inner_mode)),
2391 XVECEXP (vals, 0, i));
2392 emit_move_insn (target, mem);
2393 }
2394
2395 /* Set field ELT of TARGET to VAL. */
2396
2397 void
rs6000_expand_vector_set(rtx target,rtx val,int elt)2398 rs6000_expand_vector_set (rtx target, rtx val, int elt)
2399 {
2400 enum machine_mode mode = GET_MODE (target);
2401 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2402 rtx reg = gen_reg_rtx (mode);
2403 rtx mask, mem, x;
2404 int width = GET_MODE_SIZE (inner_mode);
2405 int i;
2406
2407 /* Load single variable value. */
2408 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2409 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2410 x = gen_rtx_UNSPEC (VOIDmode,
2411 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2412 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2413 gen_rtvec (2,
2414 gen_rtx_SET (VOIDmode,
2415 reg, mem),
2416 x)));
2417
2418 /* Linear sequence. */
2419 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2420 for (i = 0; i < 16; ++i)
2421 XVECEXP (mask, 0, i) = GEN_INT (i);
2422
2423 /* Set permute mask to insert element into target. */
2424 for (i = 0; i < width; ++i)
2425 XVECEXP (mask, 0, elt*width + i)
2426 = GEN_INT (i + 0x10);
2427 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2428 x = gen_rtx_UNSPEC (mode,
2429 gen_rtvec (3, target, reg,
2430 force_reg (V16QImode, x)),
2431 UNSPEC_VPERM);
2432 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2433 }
2434
2435 /* Extract field ELT from VEC into TARGET. */
2436
2437 void
rs6000_expand_vector_extract(rtx target,rtx vec,int elt)2438 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2439 {
2440 enum machine_mode mode = GET_MODE (vec);
2441 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2442 rtx mem, x;
2443
2444 /* Allocate mode-sized buffer. */
2445 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2446
2447 /* Add offset to field within buffer matching vector element. */
2448 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2449
2450 /* Store single field into mode-sized buffer. */
2451 x = gen_rtx_UNSPEC (VOIDmode,
2452 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2453 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2454 gen_rtvec (2,
2455 gen_rtx_SET (VOIDmode,
2456 mem, vec),
2457 x)));
2458 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2459 }
2460
2461 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2462 implement ANDing by the mask IN. */
2463 void
build_mask64_2_operands(rtx in,rtx * out)2464 build_mask64_2_operands (rtx in, rtx *out)
2465 {
2466 #if HOST_BITS_PER_WIDE_INT >= 64
2467 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2468 int shift;
2469
2470 gcc_assert (GET_CODE (in) == CONST_INT);
2471
2472 c = INTVAL (in);
2473 if (c & 1)
2474 {
2475 /* Assume c initially something like 0x00fff000000fffff. The idea
2476 is to rotate the word so that the middle ^^^^^^ group of zeros
2477 is at the MS end and can be cleared with an rldicl mask. We then
2478 rotate back and clear off the MS ^^ group of zeros with a
2479 second rldicl. */
2480 c = ~c; /* c == 0xff000ffffff00000 */
2481 lsb = c & -c; /* lsb == 0x0000000000100000 */
2482 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2483 c = ~c; /* c == 0x00fff000000fffff */
2484 c &= -lsb; /* c == 0x00fff00000000000 */
2485 lsb = c & -c; /* lsb == 0x0000100000000000 */
2486 c = ~c; /* c == 0xff000fffffffffff */
2487 c &= -lsb; /* c == 0xff00000000000000 */
2488 shift = 0;
2489 while ((lsb >>= 1) != 0)
2490 shift++; /* shift == 44 on exit from loop */
2491 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2492 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2493 m2 = ~c; /* m2 == 0x00ffffffffffffff */
2494 }
2495 else
2496 {
2497 /* Assume c initially something like 0xff000f0000000000. The idea
2498 is to rotate the word so that the ^^^ middle group of zeros
2499 is at the LS end and can be cleared with an rldicr mask. We then
2500 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2501 a second rldicr. */
2502 lsb = c & -c; /* lsb == 0x0000010000000000 */
2503 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2504 c = ~c; /* c == 0x00fff0ffffffffff */
2505 c &= -lsb; /* c == 0x00fff00000000000 */
2506 lsb = c & -c; /* lsb == 0x0000100000000000 */
2507 c = ~c; /* c == 0xff000fffffffffff */
2508 c &= -lsb; /* c == 0xff00000000000000 */
2509 shift = 0;
2510 while ((lsb >>= 1) != 0)
2511 shift++; /* shift == 44 on exit from loop */
2512 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2513 m1 >>= shift; /* m1 == 0x0000000000000fff */
2514 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2515 }
2516
2517 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2518 masks will be all 1's. We are guaranteed more than one transition. */
2519 out[0] = GEN_INT (64 - shift);
2520 out[1] = GEN_INT (m1);
2521 out[2] = GEN_INT (shift);
2522 out[3] = GEN_INT (m2);
2523 #else
2524 (void)in;
2525 (void)out;
2526 gcc_unreachable ();
2527 #endif
2528 }
2529
2530 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2531
2532 bool
invalid_e500_subreg(rtx op,enum machine_mode mode)2533 invalid_e500_subreg (rtx op, enum machine_mode mode)
2534 {
2535 /* Reject (subreg:SI (reg:DF)). */
2536 if (GET_CODE (op) == SUBREG
2537 && mode == SImode
2538 && REG_P (SUBREG_REG (op))
2539 && GET_MODE (SUBREG_REG (op)) == DFmode)
2540 return true;
2541
2542 /* Reject (subreg:DF (reg:DI)). */
2543 if (GET_CODE (op) == SUBREG
2544 && mode == DFmode
2545 && REG_P (SUBREG_REG (op))
2546 && GET_MODE (SUBREG_REG (op)) == DImode)
2547 return true;
2548
2549 return false;
2550 }
2551
2552 /* Darwin, AIX increases natural record alignment to doubleword if the first
2553 field is an FP double while the FP fields remain word aligned. */
2554
2555 unsigned int
rs6000_special_round_type_align(tree type,int computed,int specified)2556 rs6000_special_round_type_align (tree type, int computed, int specified)
2557 {
2558 tree field = TYPE_FIELDS (type);
2559
2560 /* Skip all non field decls */
2561 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2562 field = TREE_CHAIN (field);
2563
2564 if (field == NULL || field == type || DECL_MODE (field) != DFmode)
2565 return MAX (computed, specified);
2566
2567 return MAX (MAX (computed, specified), 64);
2568 }
2569
2570 /* Return 1 for an operand in small memory on V.4/eabi. */
2571
2572 int
small_data_operand(rtx op ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED)2573 small_data_operand (rtx op ATTRIBUTE_UNUSED,
2574 enum machine_mode mode ATTRIBUTE_UNUSED)
2575 {
2576 #if TARGET_ELF
2577 rtx sym_ref;
2578
2579 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
2580 return 0;
2581
2582 if (DEFAULT_ABI != ABI_V4)
2583 return 0;
2584
2585 if (GET_CODE (op) == SYMBOL_REF)
2586 sym_ref = op;
2587
2588 else if (GET_CODE (op) != CONST
2589 || GET_CODE (XEXP (op, 0)) != PLUS
2590 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2591 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
2592 return 0;
2593
2594 else
2595 {
2596 rtx sum = XEXP (op, 0);
2597 HOST_WIDE_INT summand;
2598
2599 /* We have to be careful here, because it is the referenced address
2600 that must be 32k from _SDA_BASE_, not just the symbol. */
2601 summand = INTVAL (XEXP (sum, 1));
2602 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
2603 return 0;
2604
2605 sym_ref = XEXP (sum, 0);
2606 }
2607
2608 return SYMBOL_REF_SMALL_P (sym_ref);
2609 #else
2610 return 0;
2611 #endif
2612 }
2613
2614 /* Return true if either operand is a general purpose register. */
2615
2616 bool
gpr_or_gpr_p(rtx op0,rtx op1)2617 gpr_or_gpr_p (rtx op0, rtx op1)
2618 {
2619 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2620 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
2621 }
2622
2623
2624 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2625
2626 static int
constant_pool_expr_1(rtx op,int * have_sym,int * have_toc)2627 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
2628 {
2629 switch (GET_CODE (op))
2630 {
2631 case SYMBOL_REF:
2632 if (RS6000_SYMBOL_REF_TLS_P (op))
2633 return 0;
2634 else if (CONSTANT_POOL_ADDRESS_P (op))
2635 {
2636 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2637 {
2638 *have_sym = 1;
2639 return 1;
2640 }
2641 else
2642 return 0;
2643 }
2644 else if (! strcmp (XSTR (op, 0), toc_label_name))
2645 {
2646 *have_toc = 1;
2647 return 1;
2648 }
2649 else
2650 return 0;
2651 case PLUS:
2652 case MINUS:
2653 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2654 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
2655 case CONST:
2656 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
2657 case CONST_INT:
2658 return 1;
2659 default:
2660 return 0;
2661 }
2662 }
2663
2664 static bool
constant_pool_expr_p(rtx op)2665 constant_pool_expr_p (rtx op)
2666 {
2667 int have_sym = 0;
2668 int have_toc = 0;
2669 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2670 }
2671
2672 bool
toc_relative_expr_p(rtx op)2673 toc_relative_expr_p (rtx op)
2674 {
2675 int have_sym = 0;
2676 int have_toc = 0;
2677 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2678 }
2679
2680 bool
legitimate_constant_pool_address_p(rtx x)2681 legitimate_constant_pool_address_p (rtx x)
2682 {
2683 return (TARGET_TOC
2684 && GET_CODE (x) == PLUS
2685 && GET_CODE (XEXP (x, 0)) == REG
2686 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2687 && constant_pool_expr_p (XEXP (x, 1)));
2688 }
2689
2690 bool
rs6000_legitimate_small_data_p(enum machine_mode mode,rtx x)2691 rs6000_legitimate_small_data_p (enum machine_mode mode, rtx x)
2692 {
2693 return (DEFAULT_ABI == ABI_V4
2694 && !flag_pic && !TARGET_TOC
2695 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2696 && small_data_operand (x, mode));
2697 }
2698
2699 /* SPE offset addressing is limited to 5-bits worth of double words. */
2700 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2701
2702 bool
rs6000_legitimate_offset_address_p(enum machine_mode mode,rtx x,int strict)2703 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
2704 {
2705 unsigned HOST_WIDE_INT offset, extra;
2706
2707 if (GET_CODE (x) != PLUS)
2708 return false;
2709 if (GET_CODE (XEXP (x, 0)) != REG)
2710 return false;
2711 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2712 return false;
2713 if (legitimate_constant_pool_address_p (x))
2714 return true;
2715 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2716 return false;
2717
2718 offset = INTVAL (XEXP (x, 1));
2719 extra = 0;
2720 switch (mode)
2721 {
2722 case V16QImode:
2723 case V8HImode:
2724 case V4SFmode:
2725 case V4SImode:
2726 /* AltiVec vector modes. Only reg+reg addressing is valid and
2727 constant offset zero should not occur due to canonicalization.
2728 Allow any offset when not strict before reload. */
2729 return !strict;
2730
2731 case V4HImode:
2732 case V2SImode:
2733 case V1DImode:
2734 case V2SFmode:
2735 /* SPE vector modes. */
2736 return SPE_CONST_OFFSET_OK (offset);
2737
2738 case DFmode:
2739 if (TARGET_E500_DOUBLE)
2740 return SPE_CONST_OFFSET_OK (offset);
2741
2742 case DImode:
2743 /* On e500v2, we may have:
2744
2745 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2746
2747 Which gets addressed with evldd instructions. */
2748 if (TARGET_E500_DOUBLE)
2749 return SPE_CONST_OFFSET_OK (offset);
2750
2751 if (mode == DFmode || !TARGET_POWERPC64)
2752 extra = 4;
2753 else if (offset & 3)
2754 return false;
2755 break;
2756
2757 case TFmode:
2758 case TImode:
2759 if (mode == TFmode || !TARGET_POWERPC64)
2760 extra = 12;
2761 else if (offset & 3)
2762 return false;
2763 else
2764 extra = 8;
2765 break;
2766
2767 default:
2768 break;
2769 }
2770
2771 offset += 0x8000;
2772 return (offset < 0x10000) && (offset + extra < 0x10000);
2773 }
2774
2775 static bool
legitimate_indexed_address_p(rtx x,int strict)2776 legitimate_indexed_address_p (rtx x, int strict)
2777 {
2778 rtx op0, op1;
2779
2780 if (GET_CODE (x) != PLUS)
2781 return false;
2782
2783 op0 = XEXP (x, 0);
2784 op1 = XEXP (x, 1);
2785
2786 /* Recognize the rtl generated by reload which we know will later be
2787 replaced with proper base and index regs. */
2788 if (!strict
2789 && reload_in_progress
2790 && (REG_P (op0) || GET_CODE (op0) == PLUS)
2791 && REG_P (op1))
2792 return true;
2793
2794 return (REG_P (op0) && REG_P (op1)
2795 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
2796 && INT_REG_OK_FOR_INDEX_P (op1, strict))
2797 || (INT_REG_OK_FOR_BASE_P (op1, strict)
2798 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
2799 }
2800
2801 inline bool
legitimate_indirect_address_p(rtx x,int strict)2802 legitimate_indirect_address_p (rtx x, int strict)
2803 {
2804 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
2805 }
2806
2807 bool
macho_lo_sum_memory_operand(rtx x,enum machine_mode mode)2808 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
2809 {
2810 if (!TARGET_MACHO || !flag_pic
2811 || mode != SImode || GET_CODE (x) != MEM)
2812 return false;
2813 x = XEXP (x, 0);
2814
2815 if (GET_CODE (x) != LO_SUM)
2816 return false;
2817 if (GET_CODE (XEXP (x, 0)) != REG)
2818 return false;
2819 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
2820 return false;
2821 x = XEXP (x, 1);
2822
2823 return CONSTANT_P (x);
2824 }
2825
2826 static bool
legitimate_lo_sum_address_p(enum machine_mode mode,rtx x,int strict)2827 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
2828 {
2829 if (GET_CODE (x) != LO_SUM)
2830 return false;
2831 if (GET_CODE (XEXP (x, 0)) != REG)
2832 return false;
2833 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2834 return false;
2835 /* Restrict addressing for DI because of our SUBREG hackery. */
2836 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
2837 return false;
2838 x = XEXP (x, 1);
2839
2840 if (TARGET_ELF || TARGET_MACHO)
2841 {
2842 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
2843 return false;
2844 if (TARGET_TOC)
2845 return false;
2846 if (GET_MODE_NUNITS (mode) != 1)
2847 return false;
2848 if (GET_MODE_BITSIZE (mode) > 64
2849 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
2850 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
2851 return false;
2852
2853 return CONSTANT_P (x);
2854 }
2855
2856 return false;
2857 }
2858
2859
2860 /* Try machine-dependent ways of modifying an illegitimate address
2861 to be legitimate. If we find one, return the new, valid address.
2862 This is used from only one place: `memory_address' in explow.c.
2863
2864 OLDX is the address as it was before break_out_memory_refs was
2865 called. In some cases it is useful to look at this to decide what
2866 needs to be done.
2867
2868 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
2869
2870 It is always safe for this function to do nothing. It exists to
2871 recognize opportunities to optimize the output.
2872
2873 On RS/6000, first check for the sum of a register with a constant
2874 integer that is out of range. If so, generate code to add the
2875 constant with the low-order 16 bits masked to the register and force
2876 this result into another register (this can be done with `cau').
2877 Then generate an address of REG+(CONST&0xffff), allowing for the
2878 possibility of bit 16 being a one.
2879
2880 Then check for the sum of a register and something not constant, try to
2881 load the other things into a register and return the sum. */
2882
2883 rtx
rs6000_legitimize_address(rtx x,rtx oldx ATTRIBUTE_UNUSED,enum machine_mode mode)2884 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
2885 enum machine_mode mode)
2886 {
2887 if (GET_CODE (x) == SYMBOL_REF)
2888 {
2889 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
2890 if (model != 0)
2891 return rs6000_legitimize_tls_address (x, model);
2892 }
2893
2894 if (GET_CODE (x) == PLUS
2895 && GET_CODE (XEXP (x, 0)) == REG
2896 && GET_CODE (XEXP (x, 1)) == CONST_INT
2897 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2898 {
2899 HOST_WIDE_INT high_int, low_int;
2900 rtx sum;
2901 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2902 high_int = INTVAL (XEXP (x, 1)) - low_int;
2903 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2904 GEN_INT (high_int)), 0);
2905 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2906 }
2907 else if (GET_CODE (x) == PLUS
2908 && GET_CODE (XEXP (x, 0)) == REG
2909 && GET_CODE (XEXP (x, 1)) != CONST_INT
2910 && GET_MODE_NUNITS (mode) == 1
2911 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2912 || TARGET_POWERPC64
2913 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
2914 && mode != TFmode))
2915 && (TARGET_POWERPC64 || mode != DImode)
2916 && mode != TImode)
2917 {
2918 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2919 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2920 }
2921 else if (ALTIVEC_VECTOR_MODE (mode))
2922 {
2923 rtx reg;
2924
2925 /* Make sure both operands are registers. */
2926 if (GET_CODE (x) == PLUS)
2927 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
2928 force_reg (Pmode, XEXP (x, 1)));
2929
2930 reg = force_reg (Pmode, x);
2931 return reg;
2932 }
2933 else if (SPE_VECTOR_MODE (mode)
2934 || (TARGET_E500_DOUBLE && (mode == DFmode
2935 || mode == DImode)))
2936 {
2937 if (mode == DImode)
2938 return NULL_RTX;
2939 /* We accept [reg + reg] and [reg + OFFSET]. */
2940
2941 if (GET_CODE (x) == PLUS)
2942 {
2943 rtx op1 = XEXP (x, 0);
2944 rtx op2 = XEXP (x, 1);
2945
2946 op1 = force_reg (Pmode, op1);
2947
2948 if (GET_CODE (op2) != REG
2949 && (GET_CODE (op2) != CONST_INT
2950 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2951 op2 = force_reg (Pmode, op2);
2952
2953 return gen_rtx_PLUS (Pmode, op1, op2);
2954 }
2955
2956 return force_reg (Pmode, x);
2957 }
2958 else if (TARGET_ELF
2959 && TARGET_32BIT
2960 && TARGET_NO_TOC
2961 && ! flag_pic
2962 && GET_CODE (x) != CONST_INT
2963 && GET_CODE (x) != CONST_DOUBLE
2964 && CONSTANT_P (x)
2965 && GET_MODE_NUNITS (mode) == 1
2966 && (GET_MODE_BITSIZE (mode) <= 32
2967 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
2968 {
2969 rtx reg = gen_reg_rtx (Pmode);
2970 emit_insn (gen_elf_high (reg, x));
2971 return gen_rtx_LO_SUM (Pmode, reg, x);
2972 }
2973 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2974 && ! flag_pic
2975 #if TARGET_MACHO
2976 && ! MACHO_DYNAMIC_NO_PIC_P
2977 #endif
2978 && GET_CODE (x) != CONST_INT
2979 && GET_CODE (x) != CONST_DOUBLE
2980 && CONSTANT_P (x)
2981 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
2982 && mode != DImode
2983 && mode != TImode)
2984 {
2985 rtx reg = gen_reg_rtx (Pmode);
2986 emit_insn (gen_macho_high (reg, x));
2987 return gen_rtx_LO_SUM (Pmode, reg, x);
2988 }
2989 else if (TARGET_TOC
2990 && constant_pool_expr_p (x)
2991 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
2992 {
2993 return create_TOC_reference (x);
2994 }
2995 else
2996 return NULL_RTX;
2997 }
2998
2999 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3000 We need to emit DTP-relative relocations. */
3001
3002 static void
rs6000_output_dwarf_dtprel(FILE * file,int size,rtx x)3003 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3004 {
3005 switch (size)
3006 {
3007 case 4:
3008 fputs ("\t.long\t", file);
3009 break;
3010 case 8:
3011 fputs (DOUBLE_INT_ASM_OP, file);
3012 break;
3013 default:
3014 gcc_unreachable ();
3015 }
3016 output_addr_const (file, x);
3017 fputs ("@dtprel+0x8000", file);
3018 }
3019
3020 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3021
3022 static GTY(()) rtx rs6000_tls_symbol;
3023 static rtx
rs6000_tls_get_addr(void)3024 rs6000_tls_get_addr (void)
3025 {
3026 if (!rs6000_tls_symbol)
3027 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3028
3029 return rs6000_tls_symbol;
3030 }
3031
3032 /* Construct the SYMBOL_REF for TLS GOT references. */
3033
3034 static GTY(()) rtx rs6000_got_symbol;
3035 static rtx
rs6000_got_sym(void)3036 rs6000_got_sym (void)
3037 {
3038 if (!rs6000_got_symbol)
3039 {
3040 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3041 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3042 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
3043 }
3044
3045 return rs6000_got_symbol;
3046 }
3047
3048 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3049 this (thread-local) address. */
3050
3051 static rtx
rs6000_legitimize_tls_address(rtx addr,enum tls_model model)3052 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
3053 {
3054 rtx dest, insn;
3055
3056 dest = gen_reg_rtx (Pmode);
3057 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3058 {
3059 rtx tlsreg;
3060
3061 if (TARGET_64BIT)
3062 {
3063 tlsreg = gen_rtx_REG (Pmode, 13);
3064 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3065 }
3066 else
3067 {
3068 tlsreg = gen_rtx_REG (Pmode, 2);
3069 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3070 }
3071 emit_insn (insn);
3072 }
3073 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3074 {
3075 rtx tlsreg, tmp;
3076
3077 tmp = gen_reg_rtx (Pmode);
3078 if (TARGET_64BIT)
3079 {
3080 tlsreg = gen_rtx_REG (Pmode, 13);
3081 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3082 }
3083 else
3084 {
3085 tlsreg = gen_rtx_REG (Pmode, 2);
3086 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3087 }
3088 emit_insn (insn);
3089 if (TARGET_64BIT)
3090 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3091 else
3092 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3093 emit_insn (insn);
3094 }
3095 else
3096 {
3097 rtx r3, got, tga, tmp1, tmp2, eqv;
3098
3099 /* We currently use relocations like @got@tlsgd for tls, which
3100 means the linker will handle allocation of tls entries, placing
3101 them in the .got section. So use a pointer to the .got section,
3102 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3103 or to secondary GOT sections used by 32-bit -fPIC. */
3104 if (TARGET_64BIT)
3105 got = gen_rtx_REG (Pmode, 2);
3106 else
3107 {
3108 if (flag_pic == 1)
3109 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3110 else
3111 {
3112 rtx gsym = rs6000_got_sym ();
3113 got = gen_reg_rtx (Pmode);
3114 if (flag_pic == 0)
3115 rs6000_emit_move (got, gsym, Pmode);
3116 else
3117 {
3118 rtx tempLR, tmp3, mem;
3119 rtx first, last;
3120
3121 tempLR = gen_reg_rtx (Pmode);
3122 tmp1 = gen_reg_rtx (Pmode);
3123 tmp2 = gen_reg_rtx (Pmode);
3124 tmp3 = gen_reg_rtx (Pmode);
3125 mem = gen_const_mem (Pmode, tmp1);
3126
3127 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
3128 emit_move_insn (tmp1, tempLR);
3129 emit_move_insn (tmp2, mem);
3130 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3131 last = emit_move_insn (got, tmp3);
3132 REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
3133 REG_NOTES (last));
3134 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3135 REG_NOTES (first));
3136 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3137 REG_NOTES (last));
3138 }
3139 }
3140 }
3141
3142 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3143 {
3144 r3 = gen_rtx_REG (Pmode, 3);
3145 if (TARGET_64BIT)
3146 insn = gen_tls_gd_64 (r3, got, addr);
3147 else
3148 insn = gen_tls_gd_32 (r3, got, addr);
3149 start_sequence ();
3150 emit_insn (insn);
3151 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3152 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3153 insn = emit_call_insn (insn);
3154 CONST_OR_PURE_CALL_P (insn) = 1;
3155 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3156 insn = get_insns ();
3157 end_sequence ();
3158 emit_libcall_block (insn, dest, r3, addr);
3159 }
3160 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3161 {
3162 r3 = gen_rtx_REG (Pmode, 3);
3163 if (TARGET_64BIT)
3164 insn = gen_tls_ld_64 (r3, got);
3165 else
3166 insn = gen_tls_ld_32 (r3, got);
3167 start_sequence ();
3168 emit_insn (insn);
3169 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3170 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3171 insn = emit_call_insn (insn);
3172 CONST_OR_PURE_CALL_P (insn) = 1;
3173 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3174 insn = get_insns ();
3175 end_sequence ();
3176 tmp1 = gen_reg_rtx (Pmode);
3177 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3178 UNSPEC_TLSLD);
3179 emit_libcall_block (insn, tmp1, r3, eqv);
3180 if (rs6000_tls_size == 16)
3181 {
3182 if (TARGET_64BIT)
3183 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3184 else
3185 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3186 }
3187 else if (rs6000_tls_size == 32)
3188 {
3189 tmp2 = gen_reg_rtx (Pmode);
3190 if (TARGET_64BIT)
3191 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3192 else
3193 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3194 emit_insn (insn);
3195 if (TARGET_64BIT)
3196 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3197 else
3198 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3199 }
3200 else
3201 {
3202 tmp2 = gen_reg_rtx (Pmode);
3203 if (TARGET_64BIT)
3204 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3205 else
3206 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3207 emit_insn (insn);
3208 insn = gen_rtx_SET (Pmode, dest,
3209 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3210 }
3211 emit_insn (insn);
3212 }
3213 else
3214 {
3215 /* IE, or 64 bit offset LE. */
3216 tmp2 = gen_reg_rtx (Pmode);
3217 if (TARGET_64BIT)
3218 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3219 else
3220 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3221 emit_insn (insn);
3222 if (TARGET_64BIT)
3223 insn = gen_tls_tls_64 (dest, tmp2, addr);
3224 else
3225 insn = gen_tls_tls_32 (dest, tmp2, addr);
3226 emit_insn (insn);
3227 }
3228 }
3229
3230 return dest;
3231 }
3232
3233 /* Return 1 if X contains a thread-local symbol. */
3234
3235 bool
rs6000_tls_referenced_p(rtx x)3236 rs6000_tls_referenced_p (rtx x)
3237 {
3238 if (! TARGET_HAVE_TLS)
3239 return false;
3240
3241 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3242 }
3243
3244 /* Return 1 if *X is a thread-local symbol. This is the same as
3245 rs6000_tls_symbol_ref except for the type of the unused argument. */
3246
3247 static int
rs6000_tls_symbol_ref_1(rtx * x,void * data ATTRIBUTE_UNUSED)3248 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
3249 {
3250 return RS6000_SYMBOL_REF_TLS_P (*x);
3251 }
3252
3253 /* The convention appears to be to define this wherever it is used.
3254 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3255 is now used here. */
3256 #ifndef REG_MODE_OK_FOR_BASE_P
3257 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3258 #endif
3259
3260 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3261 replace the input X, or the original X if no replacement is called for.
3262 The output parameter *WIN is 1 if the calling macro should goto WIN,
3263 0 if it should not.
3264
3265 For RS/6000, we wish to handle large displacements off a base
3266 register by splitting the addend across an addiu/addis and the mem insn.
3267 This cuts number of extra insns needed from 3 to 1.
3268
3269 On Darwin, we use this to generate code for floating point constants.
3270 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3271 The Darwin code is inside #if TARGET_MACHO because only then is
3272 machopic_function_base_name() defined. */
3273 rtx
rs6000_legitimize_reload_address(rtx x,enum machine_mode mode,int opnum,int type,int ind_levels ATTRIBUTE_UNUSED,int * win)3274 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
3275 int opnum, int type,
3276 int ind_levels ATTRIBUTE_UNUSED, int *win)
3277 {
3278 /* We must recognize output that we have already generated ourselves. */
3279 if (GET_CODE (x) == PLUS
3280 && GET_CODE (XEXP (x, 0)) == PLUS
3281 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3282 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3283 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3284 {
3285 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3286 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3287 opnum, (enum reload_type)type);
3288 *win = 1;
3289 return x;
3290 }
3291
3292 #if TARGET_MACHO
3293 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3294 && GET_CODE (x) == LO_SUM
3295 && GET_CODE (XEXP (x, 0)) == PLUS
3296 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3297 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3298 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3299 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3300 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3301 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3302 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3303 {
3304 /* Result of previous invocation of this function on Darwin
3305 floating point constant. */
3306 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3307 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3308 opnum, (enum reload_type)type);
3309 *win = 1;
3310 return x;
3311 }
3312 #endif
3313
3314 /* Force ld/std non-word aligned offset into base register by wrapping
3315 in offset 0. */
3316 if (GET_CODE (x) == PLUS
3317 && GET_CODE (XEXP (x, 0)) == REG
3318 && REGNO (XEXP (x, 0)) < 32
3319 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3320 && GET_CODE (XEXP (x, 1)) == CONST_INT
3321 && (INTVAL (XEXP (x, 1)) & 3) != 0
3322 && !ALTIVEC_VECTOR_MODE (mode)
3323 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3324 && TARGET_POWERPC64)
3325 {
3326 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3327 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3328 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3329 opnum, (enum reload_type) type);
3330 *win = 1;
3331 return x;
3332 }
3333
3334 if (GET_CODE (x) == PLUS
3335 && GET_CODE (XEXP (x, 0)) == REG
3336 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3337 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3338 && GET_CODE (XEXP (x, 1)) == CONST_INT
3339 && !SPE_VECTOR_MODE (mode)
3340 && !(TARGET_E500_DOUBLE && (mode == DFmode
3341 || mode == DImode))
3342 && !ALTIVEC_VECTOR_MODE (mode))
3343 {
3344 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3345 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3346 HOST_WIDE_INT high
3347 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3348
3349 /* Check for 32-bit overflow. */
3350 if (high + low != val)
3351 {
3352 *win = 0;
3353 return x;
3354 }
3355
3356 /* Reload the high part into a base reg; leave the low part
3357 in the mem directly. */
3358
3359 x = gen_rtx_PLUS (GET_MODE (x),
3360 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3361 GEN_INT (high)),
3362 GEN_INT (low));
3363
3364 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3365 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3366 opnum, (enum reload_type)type);
3367 *win = 1;
3368 return x;
3369 }
3370
3371 if (GET_CODE (x) == SYMBOL_REF
3372 && !ALTIVEC_VECTOR_MODE (mode)
3373 #if TARGET_MACHO
3374 && DEFAULT_ABI == ABI_DARWIN
3375 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
3376 #else
3377 && DEFAULT_ABI == ABI_V4
3378 && !flag_pic
3379 #endif
3380 /* Don't do this for TFmode, since the result isn't offsettable.
3381 The same goes for DImode without 64-bit gprs and DFmode
3382 without fprs. */
3383 && mode != TFmode
3384 && (mode != DImode || TARGET_POWERPC64)
3385 && (mode != DFmode || TARGET_POWERPC64
3386 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
3387 {
3388 #if TARGET_MACHO
3389 if (flag_pic)
3390 {
3391 rtx offset = gen_rtx_CONST (Pmode,
3392 gen_rtx_MINUS (Pmode, x,
3393 machopic_function_base_sym ()));
3394 x = gen_rtx_LO_SUM (GET_MODE (x),
3395 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3396 gen_rtx_HIGH (Pmode, offset)), offset);
3397 }
3398 else
3399 #endif
3400 x = gen_rtx_LO_SUM (GET_MODE (x),
3401 gen_rtx_HIGH (Pmode, x), x);
3402
3403 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3404 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3405 opnum, (enum reload_type)type);
3406 *win = 1;
3407 return x;
3408 }
3409
3410 /* Reload an offset address wrapped by an AND that represents the
3411 masking of the lower bits. Strip the outer AND and let reload
3412 convert the offset address into an indirect address. */
3413 if (TARGET_ALTIVEC
3414 && ALTIVEC_VECTOR_MODE (mode)
3415 && GET_CODE (x) == AND
3416 && GET_CODE (XEXP (x, 0)) == PLUS
3417 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3418 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3419 && GET_CODE (XEXP (x, 1)) == CONST_INT
3420 && INTVAL (XEXP (x, 1)) == -16)
3421 {
3422 x = XEXP (x, 0);
3423 *win = 1;
3424 return x;
3425 }
3426
3427 if (TARGET_TOC
3428 && constant_pool_expr_p (x)
3429 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
3430 {
3431 (x) = create_TOC_reference (x);
3432 *win = 1;
3433 return x;
3434 }
3435 *win = 0;
3436 return x;
3437 }
3438
3439 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3440 that is a valid memory address for an instruction.
3441 The MODE argument is the machine mode for the MEM expression
3442 that wants to use this address.
3443
3444 On the RS/6000, there are four valid address: a SYMBOL_REF that
3445 refers to a constant pool entry of an address (or the sum of it
3446 plus a constant), a short (16-bit signed) constant plus a register,
3447 the sum of two registers, or a register indirect, possibly with an
3448 auto-increment. For DFmode and DImode with a constant plus register,
3449 we must ensure that both words are addressable or PowerPC64 with offset
3450 word aligned.
3451
3452 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3453 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3454 adjacent memory cells are accessed by adding word-sized offsets
3455 during assembly output. */
3456 int
rs6000_legitimate_address(enum machine_mode mode,rtx x,int reg_ok_strict)3457 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
3458 {
3459 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3460 if (TARGET_ALTIVEC
3461 && ALTIVEC_VECTOR_MODE (mode)
3462 && GET_CODE (x) == AND
3463 && GET_CODE (XEXP (x, 1)) == CONST_INT
3464 && INTVAL (XEXP (x, 1)) == -16)
3465 x = XEXP (x, 0);
3466
3467 if (RS6000_SYMBOL_REF_TLS_P (x))
3468 return 0;
3469 if (legitimate_indirect_address_p (x, reg_ok_strict))
3470 return 1;
3471 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
3472 && !ALTIVEC_VECTOR_MODE (mode)
3473 && !SPE_VECTOR_MODE (mode)
3474 && mode != TFmode
3475 /* Restrict addressing for DI because of our SUBREG hackery. */
3476 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
3477 && TARGET_UPDATE
3478 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
3479 return 1;
3480 if (rs6000_legitimate_small_data_p (mode, x))
3481 return 1;
3482 if (legitimate_constant_pool_address_p (x))
3483 return 1;
3484 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3485 if (! reg_ok_strict
3486 && GET_CODE (x) == PLUS
3487 && GET_CODE (XEXP (x, 0)) == REG
3488 && (XEXP (x, 0) == virtual_stack_vars_rtx
3489 || XEXP (x, 0) == arg_pointer_rtx)
3490 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3491 return 1;
3492 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
3493 return 1;
3494 if (mode != TImode
3495 && mode != TFmode
3496 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3497 || TARGET_POWERPC64
3498 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
3499 && (TARGET_POWERPC64 || mode != DImode)
3500 && legitimate_indexed_address_p (x, reg_ok_strict))
3501 return 1;
3502 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
3503 return 1;
3504 return 0;
3505 }
3506
3507 /* Go to LABEL if ADDR (a legitimate address expression)
3508 has an effect that depends on the machine mode it is used for.
3509
3510 On the RS/6000 this is true of all integral offsets (since AltiVec
3511 modes don't allow them) or is a pre-increment or decrement.
3512
3513 ??? Except that due to conceptual problems in offsettable_address_p
3514 we can't really report the problems of integral offsets. So leave
3515 this assuming that the adjustable offset must be valid for the
3516 sub-words of a TFmode operand, which is what we had before. */
3517
3518 bool
rs6000_mode_dependent_address(rtx addr)3519 rs6000_mode_dependent_address (rtx addr)
3520 {
3521 switch (GET_CODE (addr))
3522 {
3523 case PLUS:
3524 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3525 {
3526 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3527 return val + 12 + 0x8000 >= 0x10000;
3528 }
3529 break;
3530
3531 case LO_SUM:
3532 return true;
3533
3534 case PRE_INC:
3535 case PRE_DEC:
3536 return TARGET_UPDATE;
3537
3538 default:
3539 break;
3540 }
3541
3542 return false;
3543 }
3544
3545 /* Return number of consecutive hard regs needed starting at reg REGNO
3546 to hold something of mode MODE.
3547 This is ordinarily the length in words of a value of mode MODE
3548 but can be less for certain modes in special long registers.
3549
3550 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3551 scalar instructions. The upper 32 bits are only available to the
3552 SIMD instructions.
3553
3554 POWER and PowerPC GPRs hold 32 bits worth;
3555 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3556
3557 int
rs6000_hard_regno_nregs(int regno,enum machine_mode mode)3558 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3559 {
3560 if (FP_REGNO_P (regno))
3561 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3562
3563 if (TARGET_E500_DOUBLE && mode == DFmode)
3564 return 1;
3565
3566 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3567 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3568
3569 if (ALTIVEC_REGNO_P (regno))
3570 return
3571 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3572
3573 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3574 }
3575
3576 /* Change register usage conditional on target flags. */
3577 void
rs6000_conditional_register_usage(void)3578 rs6000_conditional_register_usage (void)
3579 {
3580 int i;
3581
3582 /* Set MQ register fixed (already call_used) if not POWER
3583 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3584 be allocated. */
3585 if (! TARGET_POWER)
3586 fixed_regs[64] = 1;
3587
3588 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3589 if (TARGET_64BIT)
3590 fixed_regs[13] = call_used_regs[13]
3591 = call_really_used_regs[13] = 1;
3592
3593 /* Conditionally disable FPRs. */
3594 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3595 for (i = 32; i < 64; i++)
3596 fixed_regs[i] = call_used_regs[i]
3597 = call_really_used_regs[i] = 1;
3598
3599 /* The TOC register is not killed across calls in a way that is
3600 visible to the compiler. */
3601 if (DEFAULT_ABI == ABI_AIX)
3602 call_really_used_regs[2] = 0;
3603
3604 if (DEFAULT_ABI == ABI_V4
3605 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3606 && flag_pic == 2)
3607 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3608
3609 if (DEFAULT_ABI == ABI_V4
3610 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3611 && flag_pic == 1)
3612 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3613 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3614 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3615
3616 if (DEFAULT_ABI == ABI_DARWIN
3617 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
3618 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3619 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3620 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3621
3622 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3623 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3624 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3625
3626 if (TARGET_ALTIVEC)
3627 global_regs[VSCR_REGNO] = 1;
3628
3629 if (TARGET_SPE)
3630 {
3631 global_regs[SPEFSCR_REGNO] = 1;
3632 fixed_regs[FIXED_SCRATCH]
3633 = call_used_regs[FIXED_SCRATCH]
3634 = call_really_used_regs[FIXED_SCRATCH] = 1;
3635 }
3636
3637 if (! TARGET_ALTIVEC)
3638 {
3639 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3640 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3641 call_really_used_regs[VRSAVE_REGNO] = 1;
3642 }
3643
3644 if (TARGET_ALTIVEC_ABI)
3645 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3646 call_used_regs[i] = call_really_used_regs[i] = 1;
3647 }
3648
3649 /* Try to output insns to set TARGET equal to the constant C if it can
3650 be done in less than N insns. Do all computations in MODE.
3651 Returns the place where the output has been placed if it can be
3652 done and the insns have been emitted. If it would take more than N
3653 insns, zero is returned and no insns and emitted. */
3654
3655 rtx
rs6000_emit_set_const(rtx dest,enum machine_mode mode,rtx source,int n ATTRIBUTE_UNUSED)3656 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
3657 rtx source, int n ATTRIBUTE_UNUSED)
3658 {
3659 rtx result, insn, set;
3660 HOST_WIDE_INT c0, c1;
3661
3662 switch (mode)
3663 {
3664 case QImode:
3665 case HImode:
3666 if (dest == NULL)
3667 dest = gen_reg_rtx (mode);
3668 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3669 return dest;
3670
3671 case SImode:
3672 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
3673
3674 emit_insn (gen_rtx_SET (VOIDmode, result,
3675 GEN_INT (INTVAL (source)
3676 & (~ (HOST_WIDE_INT) 0xffff))));
3677 emit_insn (gen_rtx_SET (VOIDmode, dest,
3678 gen_rtx_IOR (SImode, result,
3679 GEN_INT (INTVAL (source) & 0xffff))));
3680 result = dest;
3681 break;
3682
3683 case DImode:
3684 switch (GET_CODE (source))
3685 {
3686 case CONST_INT:
3687 c0 = INTVAL (source);
3688 c1 = -(c0 < 0);
3689 break;
3690
3691 case CONST_DOUBLE:
3692 #if HOST_BITS_PER_WIDE_INT >= 64
3693 c0 = CONST_DOUBLE_LOW (source);
3694 c1 = -(c0 < 0);
3695 #else
3696 c0 = CONST_DOUBLE_LOW (source);
3697 c1 = CONST_DOUBLE_HIGH (source);
3698 #endif
3699 break;
3700
3701 default:
3702 gcc_unreachable ();
3703 }
3704
3705 result = rs6000_emit_set_long_const (dest, c0, c1);
3706 break;
3707
3708 default:
3709 gcc_unreachable ();
3710 }
3711
3712 insn = get_last_insn ();
3713 set = single_set (insn);
3714 if (! CONSTANT_P (SET_SRC (set)))
3715 set_unique_reg_note (insn, REG_EQUAL, source);
3716
3717 return result;
3718 }
3719
3720 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3721 fall back to a straight forward decomposition. We do this to avoid
3722 exponential run times encountered when looking for longer sequences
3723 with rs6000_emit_set_const. */
3724 static rtx
rs6000_emit_set_long_const(rtx dest,HOST_WIDE_INT c1,HOST_WIDE_INT c2)3725 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
3726 {
3727 if (!TARGET_POWERPC64)
3728 {
3729 rtx operand1, operand2;
3730
3731 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
3732 DImode);
3733 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
3734 DImode);
3735 emit_move_insn (operand1, GEN_INT (c1));
3736 emit_move_insn (operand2, GEN_INT (c2));
3737 }
3738 else
3739 {
3740 HOST_WIDE_INT ud1, ud2, ud3, ud4;
3741
3742 ud1 = c1 & 0xffff;
3743 ud2 = (c1 & 0xffff0000) >> 16;
3744 #if HOST_BITS_PER_WIDE_INT >= 64
3745 c2 = c1 >> 32;
3746 #endif
3747 ud3 = c2 & 0xffff;
3748 ud4 = (c2 & 0xffff0000) >> 16;
3749
3750 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
3751 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
3752 {
3753 if (ud1 & 0x8000)
3754 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
3755 else
3756 emit_move_insn (dest, GEN_INT (ud1));
3757 }
3758
3759 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
3760 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
3761 {
3762 if (ud2 & 0x8000)
3763 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
3764 - 0x80000000));
3765 else
3766 emit_move_insn (dest, GEN_INT (ud2 << 16));
3767 if (ud1 != 0)
3768 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3769 }
3770 else if ((ud4 == 0xffff && (ud3 & 0x8000))
3771 || (ud4 == 0 && ! (ud3 & 0x8000)))
3772 {
3773 if (ud3 & 0x8000)
3774 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
3775 - 0x80000000));
3776 else
3777 emit_move_insn (dest, GEN_INT (ud3 << 16));
3778
3779 if (ud2 != 0)
3780 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
3781 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
3782 if (ud1 != 0)
3783 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3784 }
3785 else
3786 {
3787 if (ud4 & 0x8000)
3788 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
3789 - 0x80000000));
3790 else
3791 emit_move_insn (dest, GEN_INT (ud4 << 16));
3792
3793 if (ud3 != 0)
3794 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
3795
3796 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
3797 if (ud2 != 0)
3798 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
3799 GEN_INT (ud2 << 16)));
3800 if (ud1 != 0)
3801 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3802 }
3803 }
3804 return dest;
3805 }
3806
3807 /* Helper for the following. Get rid of [r+r] memory refs
3808 in cases where it won't work (TImode, TFmode). */
3809
3810 static void
rs6000_eliminate_indexed_memrefs(rtx operands[2])3811 rs6000_eliminate_indexed_memrefs (rtx operands[2])
3812 {
3813 if (GET_CODE (operands[0]) == MEM
3814 && GET_CODE (XEXP (operands[0], 0)) != REG
3815 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
3816 && ! reload_in_progress)
3817 operands[0]
3818 = replace_equiv_address (operands[0],
3819 copy_addr_to_reg (XEXP (operands[0], 0)));
3820
3821 if (GET_CODE (operands[1]) == MEM
3822 && GET_CODE (XEXP (operands[1], 0)) != REG
3823 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
3824 && ! reload_in_progress)
3825 operands[1]
3826 = replace_equiv_address (operands[1],
3827 copy_addr_to_reg (XEXP (operands[1], 0)));
3828 }
3829
3830 /* Emit a move from SOURCE to DEST in mode MODE. */
3831 void
rs6000_emit_move(rtx dest,rtx source,enum machine_mode mode)3832 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
3833 {
3834 rtx operands[2];
3835 operands[0] = dest;
3836 operands[1] = source;
3837
3838 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3839 if (GET_CODE (operands[1]) == CONST_DOUBLE
3840 && ! FLOAT_MODE_P (mode)
3841 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
3842 {
3843 /* FIXME. This should never happen. */
3844 /* Since it seems that it does, do the safe thing and convert
3845 to a CONST_INT. */
3846 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
3847 }
3848 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
3849 || FLOAT_MODE_P (mode)
3850 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
3851 || CONST_DOUBLE_LOW (operands[1]) < 0)
3852 && (CONST_DOUBLE_HIGH (operands[1]) != -1
3853 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
3854
3855 /* Check if GCC is setting up a block move that will end up using FP
3856 registers as temporaries. We must make sure this is acceptable. */
3857 if (GET_CODE (operands[0]) == MEM
3858 && GET_CODE (operands[1]) == MEM
3859 && mode == DImode
3860 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
3861 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
3862 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
3863 ? 32 : MEM_ALIGN (operands[0])))
3864 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
3865 ? 32
3866 : MEM_ALIGN (operands[1]))))
3867 && ! MEM_VOLATILE_P (operands [0])
3868 && ! MEM_VOLATILE_P (operands [1]))
3869 {
3870 emit_move_insn (adjust_address (operands[0], SImode, 0),
3871 adjust_address (operands[1], SImode, 0));
3872 emit_move_insn (adjust_address (operands[0], SImode, 4),
3873 adjust_address (operands[1], SImode, 4));
3874 return;
3875 }
3876
3877 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
3878 && !gpc_reg_operand (operands[1], mode))
3879 operands[1] = force_reg (mode, operands[1]);
3880
3881 if (mode == SFmode && ! TARGET_POWERPC
3882 && TARGET_HARD_FLOAT && TARGET_FPRS
3883 && GET_CODE (operands[0]) == MEM)
3884 {
3885 int regnum;
3886
3887 if (reload_in_progress || reload_completed)
3888 regnum = true_regnum (operands[1]);
3889 else if (GET_CODE (operands[1]) == REG)
3890 regnum = REGNO (operands[1]);
3891 else
3892 regnum = -1;
3893
3894 /* If operands[1] is a register, on POWER it may have
3895 double-precision data in it, so truncate it to single
3896 precision. */
3897 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
3898 {
3899 rtx newreg;
3900 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
3901 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
3902 operands[1] = newreg;
3903 }
3904 }
3905
3906 /* Recognize the case where operand[1] is a reference to thread-local
3907 data and load its address to a register. */
3908 if (rs6000_tls_referenced_p (operands[1]))
3909 {
3910 enum tls_model model;
3911 rtx tmp = operands[1];
3912 rtx addend = NULL;
3913
3914 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
3915 {
3916 addend = XEXP (XEXP (tmp, 0), 1);
3917 tmp = XEXP (XEXP (tmp, 0), 0);
3918 }
3919
3920 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
3921 model = SYMBOL_REF_TLS_MODEL (tmp);
3922 gcc_assert (model != 0);
3923
3924 tmp = rs6000_legitimize_tls_address (tmp, model);
3925 if (addend)
3926 {
3927 tmp = gen_rtx_PLUS (mode, tmp, addend);
3928 tmp = force_operand (tmp, operands[0]);
3929 }
3930 operands[1] = tmp;
3931 }
3932
3933 /* Handle the case where reload calls us with an invalid address. */
3934 if (reload_in_progress && mode == Pmode
3935 && (! general_operand (operands[1], mode)
3936 || ! nonimmediate_operand (operands[0], mode)))
3937 goto emit_set;
3938
3939 /* 128-bit constant floating-point values on Darwin should really be
3940 loaded as two parts. */
3941 if (!TARGET_IEEEQUAD
3942 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
3943 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
3944 {
3945 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3946 know how to get a DFmode SUBREG of a TFmode. */
3947 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
3948 simplify_gen_subreg (DImode, operands[1], mode, 0),
3949 DImode);
3950 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
3951 GET_MODE_SIZE (DImode)),
3952 simplify_gen_subreg (DImode, operands[1], mode,
3953 GET_MODE_SIZE (DImode)),
3954 DImode);
3955 return;
3956 }
3957
3958 /* FIXME: In the long term, this switch statement should go away
3959 and be replaced by a sequence of tests based on things like
3960 mode == Pmode. */
3961 switch (mode)
3962 {
3963 case HImode:
3964 case QImode:
3965 if (CONSTANT_P (operands[1])
3966 && GET_CODE (operands[1]) != CONST_INT)
3967 operands[1] = force_const_mem (mode, operands[1]);
3968 break;
3969
3970 case TFmode:
3971 rs6000_eliminate_indexed_memrefs (operands);
3972 /* fall through */
3973
3974 case DFmode:
3975 case SFmode:
3976 if (CONSTANT_P (operands[1])
3977 && ! easy_fp_constant (operands[1], mode))
3978 operands[1] = force_const_mem (mode, operands[1]);
3979 break;
3980
3981 case V16QImode:
3982 case V8HImode:
3983 case V4SFmode:
3984 case V4SImode:
3985 case V4HImode:
3986 case V2SFmode:
3987 case V2SImode:
3988 case V1DImode:
3989 if (CONSTANT_P (operands[1])
3990 && !easy_vector_constant (operands[1], mode))
3991 operands[1] = force_const_mem (mode, operands[1]);
3992 break;
3993
3994 case SImode:
3995 case DImode:
3996 /* Use default pattern for address of ELF small data */
3997 if (TARGET_ELF
3998 && mode == Pmode
3999 && DEFAULT_ABI == ABI_V4
4000 && (GET_CODE (operands[1]) == SYMBOL_REF
4001 || GET_CODE (operands[1]) == CONST)
4002 && small_data_operand (operands[1], mode))
4003 {
4004 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4005 return;
4006 }
4007
4008 if (DEFAULT_ABI == ABI_V4
4009 && mode == Pmode && mode == SImode
4010 && flag_pic == 1 && got_operand (operands[1], mode))
4011 {
4012 emit_insn (gen_movsi_got (operands[0], operands[1]));
4013 return;
4014 }
4015
4016 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4017 && TARGET_NO_TOC
4018 && ! flag_pic
4019 && mode == Pmode
4020 && CONSTANT_P (operands[1])
4021 && GET_CODE (operands[1]) != HIGH
4022 && GET_CODE (operands[1]) != CONST_INT)
4023 {
4024 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
4025
4026 /* If this is a function address on -mcall-aixdesc,
4027 convert it to the address of the descriptor. */
4028 if (DEFAULT_ABI == ABI_AIX
4029 && GET_CODE (operands[1]) == SYMBOL_REF
4030 && XSTR (operands[1], 0)[0] == '.')
4031 {
4032 const char *name = XSTR (operands[1], 0);
4033 rtx new_ref;
4034 while (*name == '.')
4035 name++;
4036 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4037 CONSTANT_POOL_ADDRESS_P (new_ref)
4038 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4039 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4040 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4041 SYMBOL_REF_DECL (new_ref) = SYMBOL_REF_DECL (operands[1]);
4042 operands[1] = new_ref;
4043 }
4044
4045 if (DEFAULT_ABI == ABI_DARWIN)
4046 {
4047 #if TARGET_MACHO
4048 if (MACHO_DYNAMIC_NO_PIC_P)
4049 {
4050 /* Take care of any required data indirection. */
4051 operands[1] = rs6000_machopic_legitimize_pic_address (
4052 operands[1], mode, operands[0]);
4053 if (operands[0] != operands[1])
4054 emit_insn (gen_rtx_SET (VOIDmode,
4055 operands[0], operands[1]));
4056 return;
4057 }
4058 #endif
4059 emit_insn (gen_macho_high (target, operands[1]));
4060 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4061 return;
4062 }
4063
4064 emit_insn (gen_elf_high (target, operands[1]));
4065 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4066 return;
4067 }
4068
4069 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4070 and we have put it in the TOC, we just need to make a TOC-relative
4071 reference to it. */
4072 if (TARGET_TOC
4073 && GET_CODE (operands[1]) == SYMBOL_REF
4074 && constant_pool_expr_p (operands[1])
4075 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4076 get_pool_mode (operands[1])))
4077 {
4078 operands[1] = create_TOC_reference (operands[1]);
4079 }
4080 else if (mode == Pmode
4081 && CONSTANT_P (operands[1])
4082 && ((GET_CODE (operands[1]) != CONST_INT
4083 && ! easy_fp_constant (operands[1], mode))
4084 || (GET_CODE (operands[1]) == CONST_INT
4085 && num_insns_constant (operands[1], mode) > 2)
4086 || (GET_CODE (operands[0]) == REG
4087 && FP_REGNO_P (REGNO (operands[0]))))
4088 && GET_CODE (operands[1]) != HIGH
4089 && ! legitimate_constant_pool_address_p (operands[1])
4090 && ! toc_relative_expr_p (operands[1]))
4091 {
4092 /* Emit a USE operation so that the constant isn't deleted if
4093 expensive optimizations are turned on because nobody
4094 references it. This should only be done for operands that
4095 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4096 This should not be done for operands that contain LABEL_REFs.
4097 For now, we just handle the obvious case. */
4098 if (GET_CODE (operands[1]) != LABEL_REF)
4099 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4100
4101 #if TARGET_MACHO
4102 /* Darwin uses a special PIC legitimizer. */
4103 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
4104 {
4105 operands[1] =
4106 rs6000_machopic_legitimize_pic_address (operands[1], mode,
4107 operands[0]);
4108 if (operands[0] != operands[1])
4109 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4110 return;
4111 }
4112 #endif
4113
4114 /* If we are to limit the number of things we put in the TOC and
4115 this is a symbol plus a constant we can add in one insn,
4116 just put the symbol in the TOC and add the constant. Don't do
4117 this if reload is in progress. */
4118 if (GET_CODE (operands[1]) == CONST
4119 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4120 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4121 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
4122 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4123 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4124 && ! side_effects_p (operands[0]))
4125 {
4126 rtx sym =
4127 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
4128 rtx other = XEXP (XEXP (operands[1], 0), 1);
4129
4130 sym = force_reg (mode, sym);
4131 if (mode == SImode)
4132 emit_insn (gen_addsi3 (operands[0], sym, other));
4133 else
4134 emit_insn (gen_adddi3 (operands[0], sym, other));
4135 return;
4136 }
4137
4138 operands[1] = force_const_mem (mode, operands[1]);
4139
4140 if (TARGET_TOC
4141 && constant_pool_expr_p (XEXP (operands[1], 0))
4142 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4143 get_pool_constant (XEXP (operands[1], 0)),
4144 get_pool_mode (XEXP (operands[1], 0))))
4145 {
4146 operands[1]
4147 = gen_const_mem (mode,
4148 create_TOC_reference (XEXP (operands[1], 0)));
4149 set_mem_alias_set (operands[1], get_TOC_alias_set ());
4150 }
4151 }
4152 break;
4153
4154 case TImode:
4155 rs6000_eliminate_indexed_memrefs (operands);
4156
4157 if (TARGET_POWER)
4158 {
4159 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4160 gen_rtvec (2,
4161 gen_rtx_SET (VOIDmode,
4162 operands[0], operands[1]),
4163 gen_rtx_CLOBBER (VOIDmode,
4164 gen_rtx_SCRATCH (SImode)))));
4165 return;
4166 }
4167 break;
4168
4169 default:
4170 gcc_unreachable ();
4171 }
4172
4173 /* Above, we may have called force_const_mem which may have returned
4174 an invalid address. If we can, fix this up; otherwise, reload will
4175 have to deal with it. */
4176 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4177 operands[1] = validize_mem (operands[1]);
4178
4179 emit_set:
4180 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4181 }
4182
4183 /* Nonzero if we can use a floating-point register to pass this arg. */
4184 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4185 (GET_MODE_CLASS (MODE) == MODE_FLOAT \
4186 && (CUM)->fregno <= FP_ARG_MAX_REG \
4187 && TARGET_HARD_FLOAT && TARGET_FPRS)
4188
4189 /* Nonzero if we can use an AltiVec register to pass this arg. */
4190 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4191 (ALTIVEC_VECTOR_MODE (MODE) \
4192 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4193 && TARGET_ALTIVEC_ABI \
4194 && (NAMED))
4195
4196 /* Return a nonzero value to say to return the function value in
4197 memory, just as large structures are always returned. TYPE will be
4198 the data type of the value, and FNTYPE will be the type of the
4199 function doing the returning, or @code{NULL} for libcalls.
4200
4201 The AIX ABI for the RS/6000 specifies that all structures are
4202 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4203 specifies that structures <= 8 bytes are returned in r3/r4, but a
4204 draft put them in memory, and GCC used to implement the draft
4205 instead of the final standard. Therefore, aix_struct_return
4206 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4207 compatibility can change DRAFT_V4_STRUCT_RET to override the
4208 default, and -m switches get the final word. See
4209 rs6000_override_options for more details.
4210
4211 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4212 long double support is enabled. These values are returned in memory.
4213
4214 int_size_in_bytes returns -1 for variable size objects, which go in
4215 memory always. The cast to unsigned makes -1 > 8. */
4216
4217 static bool
rs6000_return_in_memory(tree type,tree fntype ATTRIBUTE_UNUSED)4218 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4219 {
4220 /* In the darwin64 abi, try to use registers for larger structs
4221 if possible. */
4222 if (rs6000_darwin64_abi
4223 && TREE_CODE (type) == RECORD_TYPE
4224 && int_size_in_bytes (type) > 0)
4225 {
4226 CUMULATIVE_ARGS valcum;
4227 rtx valret;
4228
4229 valcum.words = 0;
4230 valcum.fregno = FP_ARG_MIN_REG;
4231 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4232 /* Do a trial code generation as if this were going to be passed
4233 as an argument; if any part goes in memory, we return NULL. */
4234 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4235 if (valret)
4236 return false;
4237 /* Otherwise fall through to more conventional ABI rules. */
4238 }
4239
4240 if (AGGREGATE_TYPE_P (type)
4241 && (aix_struct_return
4242 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4243 return true;
4244
4245 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4246 modes only exist for GCC vector types if -maltivec. */
4247 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4248 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4249 return false;
4250
4251 /* Return synthetic vectors in memory. */
4252 if (TREE_CODE (type) == VECTOR_TYPE
4253 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
4254 {
4255 static bool warned_for_return_big_vectors = false;
4256 if (!warned_for_return_big_vectors)
4257 {
4258 warning (0, "GCC vector returned by reference: "
4259 "non-standard ABI extension with no compatibility guarantee");
4260 warned_for_return_big_vectors = true;
4261 }
4262 return true;
4263 }
4264
4265 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
4266 return true;
4267
4268 return false;
4269 }
4270
4271 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4272 for a call to a function whose data type is FNTYPE.
4273 For a library call, FNTYPE is 0.
4274
4275 For incoming args we set the number of arguments in the prototype large
4276 so we never return a PARALLEL. */
4277
4278 void
init_cumulative_args(CUMULATIVE_ARGS * cum,tree fntype,rtx libname ATTRIBUTE_UNUSED,int incoming,int libcall,int n_named_args)4279 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
4280 rtx libname ATTRIBUTE_UNUSED, int incoming,
4281 int libcall, int n_named_args)
4282 {
4283 static CUMULATIVE_ARGS zero_cumulative;
4284
4285 *cum = zero_cumulative;
4286 cum->words = 0;
4287 cum->fregno = FP_ARG_MIN_REG;
4288 cum->vregno = ALTIVEC_ARG_MIN_REG;
4289 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
4290 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4291 ? CALL_LIBCALL : CALL_NORMAL);
4292 cum->sysv_gregno = GP_ARG_MIN_REG;
4293 cum->stdarg = fntype
4294 && (TYPE_ARG_TYPES (fntype) != 0
4295 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4296 != void_type_node));
4297
4298 cum->nargs_prototype = 0;
4299 if (incoming || cum->prototype)
4300 cum->nargs_prototype = n_named_args;
4301
4302 /* Check for a longcall attribute. */
4303 if ((!fntype && rs6000_default_long_calls)
4304 || (fntype
4305 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4306 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4307 cum->call_cookie |= CALL_LONG;
4308
4309 if (TARGET_DEBUG_ARG)
4310 {
4311 fprintf (stderr, "\ninit_cumulative_args:");
4312 if (fntype)
4313 {
4314 tree ret_type = TREE_TYPE (fntype);
4315 fprintf (stderr, " ret code = %s,",
4316 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4317 }
4318
4319 if (cum->call_cookie & CALL_LONG)
4320 fprintf (stderr, " longcall,");
4321
4322 fprintf (stderr, " proto = %d, nargs = %d\n",
4323 cum->prototype, cum->nargs_prototype);
4324 }
4325
4326 if (fntype
4327 && !TARGET_ALTIVEC
4328 && TARGET_ALTIVEC_ABI
4329 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4330 {
4331 error ("cannot return value in vector register because"
4332 " altivec instructions are disabled, use -maltivec"
4333 " to enable them");
4334 }
4335 }
4336
4337 /* Return true if TYPE must be passed on the stack and not in registers. */
4338
4339 static bool
rs6000_must_pass_in_stack(enum machine_mode mode,tree type)4340 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4341 {
4342 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4343 return must_pass_in_stack_var_size (mode, type);
4344 else
4345 return must_pass_in_stack_var_size_or_pad (mode, type);
4346 }
4347
4348 /* If defined, a C expression which determines whether, and in which
4349 direction, to pad out an argument with extra space. The value
4350 should be of type `enum direction': either `upward' to pad above
4351 the argument, `downward' to pad below, or `none' to inhibit
4352 padding.
4353
4354 For the AIX ABI structs are always stored left shifted in their
4355 argument slot. */
4356
4357 enum direction
function_arg_padding(enum machine_mode mode,tree type)4358 function_arg_padding (enum machine_mode mode, tree type)
4359 {
4360 #ifndef AGGREGATE_PADDING_FIXED
4361 #define AGGREGATE_PADDING_FIXED 0
4362 #endif
4363 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4364 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4365 #endif
4366
4367 if (!AGGREGATE_PADDING_FIXED)
4368 {
4369 /* GCC used to pass structures of the same size as integer types as
4370 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4371 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4372 passed padded downward, except that -mstrict-align further
4373 muddied the water in that multi-component structures of 2 and 4
4374 bytes in size were passed padded upward.
4375
4376 The following arranges for best compatibility with previous
4377 versions of gcc, but removes the -mstrict-align dependency. */
4378 if (BYTES_BIG_ENDIAN)
4379 {
4380 HOST_WIDE_INT size = 0;
4381
4382 if (mode == BLKmode)
4383 {
4384 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4385 size = int_size_in_bytes (type);
4386 }
4387 else
4388 size = GET_MODE_SIZE (mode);
4389
4390 if (size == 1 || size == 2 || size == 4)
4391 return downward;
4392 }
4393 return upward;
4394 }
4395
4396 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4397 {
4398 if (type != 0 && AGGREGATE_TYPE_P (type))
4399 return upward;
4400 }
4401
4402 /* Fall back to the default. */
4403 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
4404 }
4405
4406 /* If defined, a C expression that gives the alignment boundary, in bits,
4407 of an argument with the specified mode and type. If it is not defined,
4408 PARM_BOUNDARY is used for all arguments.
4409
4410 V.4 wants long longs and doubles to be double word aligned. Just
4411 testing the mode size is a boneheaded way to do this as it means
4412 that other types such as complex int are also double word aligned.
4413 However, we're stuck with this because changing the ABI might break
4414 existing library interfaces.
4415
4416 Doubleword align SPE vectors.
4417 Quadword align Altivec vectors.
4418 Quadword align large synthetic vector types. */
4419
4420 int
function_arg_boundary(enum machine_mode mode,tree type)4421 function_arg_boundary (enum machine_mode mode, tree type)
4422 {
4423 if (DEFAULT_ABI == ABI_V4
4424 && (GET_MODE_SIZE (mode) == 8
4425 || (TARGET_HARD_FLOAT
4426 && TARGET_FPRS
4427 && mode == TFmode)))
4428 return 64;
4429 else if (SPE_VECTOR_MODE (mode)
4430 || (type && TREE_CODE (type) == VECTOR_TYPE
4431 && int_size_in_bytes (type) >= 8
4432 && int_size_in_bytes (type) < 16))
4433 return 64;
4434 else if (ALTIVEC_VECTOR_MODE (mode)
4435 || (type && TREE_CODE (type) == VECTOR_TYPE
4436 && int_size_in_bytes (type) >= 16))
4437 return 128;
4438 else if (rs6000_darwin64_abi && mode == BLKmode
4439 && type && TYPE_ALIGN (type) > 64)
4440 return 128;
4441 else
4442 return PARM_BOUNDARY;
4443 }
4444
4445 /* For a function parm of MODE and TYPE, return the starting word in
4446 the parameter area. NWORDS of the parameter area are already used. */
4447
4448 static unsigned int
rs6000_parm_start(enum machine_mode mode,tree type,unsigned int nwords)4449 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4450 {
4451 unsigned int align;
4452 unsigned int parm_offset;
4453
4454 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4455 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4456 return nwords + (-(parm_offset + nwords) & align);
4457 }
4458
4459 /* Compute the size (in words) of a function argument. */
4460
4461 static unsigned long
rs6000_arg_size(enum machine_mode mode,tree type)4462 rs6000_arg_size (enum machine_mode mode, tree type)
4463 {
4464 unsigned long size;
4465
4466 if (mode != BLKmode)
4467 size = GET_MODE_SIZE (mode);
4468 else
4469 size = int_size_in_bytes (type);
4470
4471 if (TARGET_32BIT)
4472 return (size + 3) >> 2;
4473 else
4474 return (size + 7) >> 3;
4475 }
4476
4477 /* Use this to flush pending int fields. */
4478
4479 static void
rs6000_darwin64_record_arg_advance_flush(CUMULATIVE_ARGS * cum,HOST_WIDE_INT bitpos)4480 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4481 HOST_WIDE_INT bitpos)
4482 {
4483 unsigned int startbit, endbit;
4484 int intregs, intoffset;
4485 enum machine_mode mode;
4486
4487 if (cum->intoffset == -1)
4488 return;
4489
4490 intoffset = cum->intoffset;
4491 cum->intoffset = -1;
4492
4493 if (intoffset % BITS_PER_WORD != 0)
4494 {
4495 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4496 MODE_INT, 0);
4497 if (mode == BLKmode)
4498 {
4499 /* We couldn't find an appropriate mode, which happens,
4500 e.g., in packed structs when there are 3 bytes to load.
4501 Back intoffset back to the beginning of the word in this
4502 case. */
4503 intoffset = intoffset & -BITS_PER_WORD;
4504 }
4505 }
4506
4507 startbit = intoffset & -BITS_PER_WORD;
4508 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4509 intregs = (endbit - startbit) / BITS_PER_WORD;
4510 cum->words += intregs;
4511 }
4512
4513 /* The darwin64 ABI calls for us to recurse down through structs,
4514 looking for elements passed in registers. Unfortunately, we have
4515 to track int register count here also because of misalignments
4516 in powerpc alignment mode. */
4517
4518 static void
rs6000_darwin64_record_arg_advance_recurse(CUMULATIVE_ARGS * cum,tree type,HOST_WIDE_INT startbitpos)4519 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4520 tree type,
4521 HOST_WIDE_INT startbitpos)
4522 {
4523 tree f;
4524
4525 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4526 if (TREE_CODE (f) == FIELD_DECL)
4527 {
4528 HOST_WIDE_INT bitpos = startbitpos;
4529 tree ftype = TREE_TYPE (f);
4530 enum machine_mode mode = TYPE_MODE (ftype);
4531
4532 if (DECL_SIZE (f) != 0
4533 && host_integerp (bit_position (f), 1))
4534 bitpos += int_bit_position (f);
4535
4536 /* ??? FIXME: else assume zero offset. */
4537
4538 if (TREE_CODE (ftype) == RECORD_TYPE)
4539 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4540 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4541 {
4542 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4543 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4544 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4545 }
4546 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4547 {
4548 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4549 cum->vregno++;
4550 cum->words += 2;
4551 }
4552 else if (cum->intoffset == -1)
4553 cum->intoffset = bitpos;
4554 }
4555 }
4556
4557 /* Update the data in CUM to advance over an argument
4558 of mode MODE and data type TYPE.
4559 (TYPE is null for libcalls where that information may not be available.)
4560
4561 Note that for args passed by reference, function_arg will be called
4562 with MODE and TYPE set to that of the pointer to the arg, not the arg
4563 itself. */
4564
4565 void
function_arg_advance(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named,int depth)4566 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4567 tree type, int named, int depth)
4568 {
4569 int size;
4570
4571 /* Only tick off an argument if we're not recursing. */
4572 if (depth == 0)
4573 cum->nargs_prototype--;
4574
4575 if (TARGET_ALTIVEC_ABI
4576 && (ALTIVEC_VECTOR_MODE (mode)
4577 || (type && TREE_CODE (type) == VECTOR_TYPE
4578 && int_size_in_bytes (type) == 16)))
4579 {
4580 bool stack = false;
4581
4582 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4583 {
4584 cum->vregno++;
4585 if (!TARGET_ALTIVEC)
4586 error ("cannot pass argument in vector register because"
4587 " altivec instructions are disabled, use -maltivec"
4588 " to enable them");
4589
4590 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4591 even if it is going to be passed in a vector register.
4592 Darwin does the same for variable-argument functions. */
4593 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4594 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4595 stack = true;
4596 }
4597 else
4598 stack = true;
4599
4600 if (stack)
4601 {
4602 int align;
4603
4604 /* Vector parameters must be 16-byte aligned. This places
4605 them at 2 mod 4 in terms of words in 32-bit mode, since
4606 the parameter save area starts at offset 24 from the
4607 stack. In 64-bit mode, they just have to start on an
4608 even word, since the parameter save area is 16-byte
4609 aligned. Space for GPRs is reserved even if the argument
4610 will be passed in memory. */
4611 if (TARGET_32BIT)
4612 align = (2 - cum->words) & 3;
4613 else
4614 align = cum->words & 1;
4615 cum->words += align + rs6000_arg_size (mode, type);
4616
4617 if (TARGET_DEBUG_ARG)
4618 {
4619 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
4620 cum->words, align);
4621 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
4622 cum->nargs_prototype, cum->prototype,
4623 GET_MODE_NAME (mode));
4624 }
4625 }
4626 }
4627 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
4628 && !cum->stdarg
4629 && cum->sysv_gregno <= GP_ARG_MAX_REG)
4630 cum->sysv_gregno++;
4631
4632 else if (rs6000_darwin64_abi
4633 && mode == BLKmode
4634 && TREE_CODE (type) == RECORD_TYPE
4635 && (size = int_size_in_bytes (type)) > 0)
4636 {
4637 /* Variable sized types have size == -1 and are
4638 treated as if consisting entirely of ints.
4639 Pad to 16 byte boundary if needed. */
4640 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4641 && (cum->words % 2) != 0)
4642 cum->words++;
4643 /* For varargs, we can just go up by the size of the struct. */
4644 if (!named)
4645 cum->words += (size + 7) / 8;
4646 else
4647 {
4648 /* It is tempting to say int register count just goes up by
4649 sizeof(type)/8, but this is wrong in a case such as
4650 { int; double; int; } [powerpc alignment]. We have to
4651 grovel through the fields for these too. */
4652 cum->intoffset = 0;
4653 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
4654 rs6000_darwin64_record_arg_advance_flush (cum,
4655 size * BITS_PER_UNIT);
4656 }
4657 }
4658 else if (DEFAULT_ABI == ABI_V4)
4659 {
4660 if (TARGET_HARD_FLOAT && TARGET_FPRS
4661 && (mode == SFmode || mode == DFmode
4662 || (mode == TFmode && !TARGET_IEEEQUAD)))
4663 {
4664 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4665 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4666 else
4667 {
4668 cum->fregno = FP_ARG_V4_MAX_REG + 1;
4669 if (mode == DFmode || mode == TFmode)
4670 cum->words += cum->words & 1;
4671 cum->words += rs6000_arg_size (mode, type);
4672 }
4673 }
4674 else
4675 {
4676 int n_words = rs6000_arg_size (mode, type);
4677 int gregno = cum->sysv_gregno;
4678
4679 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4680 (r7,r8) or (r9,r10). As does any other 2 word item such
4681 as complex int due to a historical mistake. */
4682 if (n_words == 2)
4683 gregno += (1 - gregno) & 1;
4684
4685 /* Multi-reg args are not split between registers and stack. */
4686 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4687 {
4688 /* Long long and SPE vectors are aligned on the stack.
4689 So are other 2 word items such as complex int due to
4690 a historical mistake. */
4691 if (n_words == 2)
4692 cum->words += cum->words & 1;
4693 cum->words += n_words;
4694 }
4695
4696 /* Note: continuing to accumulate gregno past when we've started
4697 spilling to the stack indicates the fact that we've started
4698 spilling to the stack to expand_builtin_saveregs. */
4699 cum->sysv_gregno = gregno + n_words;
4700 }
4701
4702 if (TARGET_DEBUG_ARG)
4703 {
4704 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4705 cum->words, cum->fregno);
4706 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
4707 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
4708 fprintf (stderr, "mode = %4s, named = %d\n",
4709 GET_MODE_NAME (mode), named);
4710 }
4711 }
4712 else
4713 {
4714 int n_words = rs6000_arg_size (mode, type);
4715 int start_words = cum->words;
4716 int align_words = rs6000_parm_start (mode, type, start_words);
4717
4718 cum->words = align_words + n_words;
4719
4720 if (GET_MODE_CLASS (mode) == MODE_FLOAT
4721 && TARGET_HARD_FLOAT && TARGET_FPRS)
4722 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4723
4724 if (TARGET_DEBUG_ARG)
4725 {
4726 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4727 cum->words, cum->fregno);
4728 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
4729 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
4730 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
4731 named, align_words - start_words, depth);
4732 }
4733 }
4734 }
4735
4736 static rtx
spe_build_register_parallel(enum machine_mode mode,int gregno)4737 spe_build_register_parallel (enum machine_mode mode, int gregno)
4738 {
4739 rtx r1, r3;
4740
4741 switch (mode)
4742 {
4743 case DFmode:
4744 r1 = gen_rtx_REG (DImode, gregno);
4745 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4746 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
4747
4748 case DCmode:
4749 r1 = gen_rtx_REG (DImode, gregno);
4750 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4751 r3 = gen_rtx_REG (DImode, gregno + 2);
4752 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
4753 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
4754
4755 default:
4756 gcc_unreachable ();
4757 }
4758 }
4759
4760 /* Determine where to put a SIMD argument on the SPE. */
4761 static rtx
rs6000_spe_function_arg(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type)4762 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4763 tree type)
4764 {
4765 int gregno = cum->sysv_gregno;
4766
4767 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
4768 are passed and returned in a pair of GPRs for ABI compatibility. */
4769 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
4770 {
4771 int n_words = rs6000_arg_size (mode, type);
4772
4773 /* Doubles go in an odd/even register pair (r5/r6, etc). */
4774 if (mode == DFmode)
4775 gregno += (1 - gregno) & 1;
4776
4777 /* Multi-reg args are not split between registers and stack. */
4778 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4779 return NULL_RTX;
4780
4781 return spe_build_register_parallel (mode, gregno);
4782 }
4783 if (cum->stdarg)
4784 {
4785 int n_words = rs6000_arg_size (mode, type);
4786
4787 /* SPE vectors are put in odd registers. */
4788 if (n_words == 2 && (gregno & 1) == 0)
4789 gregno += 1;
4790
4791 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
4792 {
4793 rtx r1, r2;
4794 enum machine_mode m = SImode;
4795
4796 r1 = gen_rtx_REG (m, gregno);
4797 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
4798 r2 = gen_rtx_REG (m, gregno + 1);
4799 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
4800 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
4801 }
4802 else
4803 return NULL_RTX;
4804 }
4805 else
4806 {
4807 if (gregno <= GP_ARG_MAX_REG)
4808 return gen_rtx_REG (mode, gregno);
4809 else
4810 return NULL_RTX;
4811 }
4812 }
4813
4814 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4815 structure between cum->intoffset and bitpos to integer registers. */
4816
4817 static void
rs6000_darwin64_record_arg_flush(CUMULATIVE_ARGS * cum,HOST_WIDE_INT bitpos,rtx rvec[],int * k)4818 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
4819 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
4820 {
4821 enum machine_mode mode;
4822 unsigned int regno;
4823 unsigned int startbit, endbit;
4824 int this_regno, intregs, intoffset;
4825 rtx reg;
4826
4827 if (cum->intoffset == -1)
4828 return;
4829
4830 intoffset = cum->intoffset;
4831 cum->intoffset = -1;
4832
4833 /* If this is the trailing part of a word, try to only load that
4834 much into the register. Otherwise load the whole register. Note
4835 that in the latter case we may pick up unwanted bits. It's not a
4836 problem at the moment but may wish to revisit. */
4837
4838 if (intoffset % BITS_PER_WORD != 0)
4839 {
4840 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4841 MODE_INT, 0);
4842 if (mode == BLKmode)
4843 {
4844 /* We couldn't find an appropriate mode, which happens,
4845 e.g., in packed structs when there are 3 bytes to load.
4846 Back intoffset back to the beginning of the word in this
4847 case. */
4848 intoffset = intoffset & -BITS_PER_WORD;
4849 mode = word_mode;
4850 }
4851 }
4852 else
4853 mode = word_mode;
4854
4855 startbit = intoffset & -BITS_PER_WORD;
4856 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4857 intregs = (endbit - startbit) / BITS_PER_WORD;
4858 this_regno = cum->words + intoffset / BITS_PER_WORD;
4859
4860 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
4861 cum->use_stack = 1;
4862
4863 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
4864 if (intregs <= 0)
4865 return;
4866
4867 intoffset /= BITS_PER_UNIT;
4868 do
4869 {
4870 regno = GP_ARG_MIN_REG + this_regno;
4871 reg = gen_rtx_REG (mode, regno);
4872 rvec[(*k)++] =
4873 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
4874
4875 this_regno += 1;
4876 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
4877 mode = word_mode;
4878 intregs -= 1;
4879 }
4880 while (intregs > 0);
4881 }
4882
4883 /* Recursive workhorse for the following. */
4884
4885 static void
rs6000_darwin64_record_arg_recurse(CUMULATIVE_ARGS * cum,tree type,HOST_WIDE_INT startbitpos,rtx rvec[],int * k)4886 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
4887 HOST_WIDE_INT startbitpos, rtx rvec[],
4888 int *k)
4889 {
4890 tree f;
4891
4892 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4893 if (TREE_CODE (f) == FIELD_DECL)
4894 {
4895 HOST_WIDE_INT bitpos = startbitpos;
4896 tree ftype = TREE_TYPE (f);
4897 enum machine_mode mode = TYPE_MODE (ftype);
4898
4899 if (DECL_SIZE (f) != 0
4900 && host_integerp (bit_position (f), 1))
4901 bitpos += int_bit_position (f);
4902
4903 /* ??? FIXME: else assume zero offset. */
4904
4905 if (TREE_CODE (ftype) == RECORD_TYPE)
4906 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
4907 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
4908 {
4909 #if 0
4910 switch (mode)
4911 {
4912 case SCmode: mode = SFmode; break;
4913 case DCmode: mode = DFmode; break;
4914 case TCmode: mode = TFmode; break;
4915 default: break;
4916 }
4917 #endif
4918 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4919 rvec[(*k)++]
4920 = gen_rtx_EXPR_LIST (VOIDmode,
4921 gen_rtx_REG (mode, cum->fregno++),
4922 GEN_INT (bitpos / BITS_PER_UNIT));
4923 if (mode == TFmode)
4924 cum->fregno++;
4925 }
4926 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
4927 {
4928 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4929 rvec[(*k)++]
4930 = gen_rtx_EXPR_LIST (VOIDmode,
4931 gen_rtx_REG (mode, cum->vregno++),
4932 GEN_INT (bitpos / BITS_PER_UNIT));
4933 }
4934 else if (cum->intoffset == -1)
4935 cum->intoffset = bitpos;
4936 }
4937 }
4938
4939 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4940 the register(s) to be used for each field and subfield of a struct
4941 being passed by value, along with the offset of where the
4942 register's value may be found in the block. FP fields go in FP
4943 register, vector fields go in vector registers, and everything
4944 else goes in int registers, packed as in memory.
4945
4946 This code is also used for function return values. RETVAL indicates
4947 whether this is the case.
4948
4949 Much of this is taken from the SPARC V9 port, which has a similar
4950 calling convention. */
4951
4952 static rtx
rs6000_darwin64_record_arg(CUMULATIVE_ARGS * orig_cum,tree type,int named,bool retval)4953 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
4954 int named, bool retval)
4955 {
4956 rtx rvec[FIRST_PSEUDO_REGISTER];
4957 int k = 1, kbase = 1;
4958 HOST_WIDE_INT typesize = int_size_in_bytes (type);
4959 /* This is a copy; modifications are not visible to our caller. */
4960 CUMULATIVE_ARGS copy_cum = *orig_cum;
4961 CUMULATIVE_ARGS *cum = ©_cum;
4962
4963 /* Pad to 16 byte boundary if needed. */
4964 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4965 && (cum->words % 2) != 0)
4966 cum->words++;
4967
4968 cum->intoffset = 0;
4969 cum->use_stack = 0;
4970 cum->named = named;
4971
4972 /* Put entries into rvec[] for individual FP and vector fields, and
4973 for the chunks of memory that go in int regs. Note we start at
4974 element 1; 0 is reserved for an indication of using memory, and
4975 may or may not be filled in below. */
4976 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
4977 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
4978
4979 /* If any part of the struct went on the stack put all of it there.
4980 This hack is because the generic code for
4981 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4982 parts of the struct are not at the beginning. */
4983 if (cum->use_stack)
4984 {
4985 if (retval)
4986 return NULL_RTX; /* doesn't go in registers at all */
4987 kbase = 0;
4988 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
4989 }
4990 if (k > 1 || cum->use_stack)
4991 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
4992 else
4993 return NULL_RTX;
4994 }
4995
4996 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4997
4998 static rtx
rs6000_mixed_function_arg(enum machine_mode mode,tree type,int align_words)4999 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5000 {
5001 int n_units;
5002 int i, k;
5003 rtx rvec[GP_ARG_NUM_REG + 1];
5004
5005 if (align_words >= GP_ARG_NUM_REG)
5006 return NULL_RTX;
5007
5008 n_units = rs6000_arg_size (mode, type);
5009
5010 /* Optimize the simple case where the arg fits in one gpr, except in
5011 the case of BLKmode due to assign_parms assuming that registers are
5012 BITS_PER_WORD wide. */
5013 if (n_units == 0
5014 || (n_units == 1 && mode != BLKmode))
5015 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5016
5017 k = 0;
5018 if (align_words + n_units > GP_ARG_NUM_REG)
5019 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5020 using a magic NULL_RTX component.
5021 FIXME: This is not strictly correct. Only some of the arg
5022 belongs in memory, not all of it. However, there isn't any way
5023 to do this currently, apart from building rtx descriptions for
5024 the pieces of memory we want stored. Due to bugs in the generic
5025 code we can't use the normal function_arg_partial_nregs scheme
5026 with the PARALLEL arg description we emit here.
5027 In any case, the code to store the whole arg to memory is often
5028 more efficient than code to store pieces, and we know that space
5029 is available in the right place for the whole arg. */
5030 /* FIXME: This should be fixed since the conversion to
5031 TARGET_ARG_PARTIAL_BYTES. */
5032 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5033
5034 i = 0;
5035 do
5036 {
5037 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5038 rtx off = GEN_INT (i++ * 4);
5039 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5040 }
5041 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5042
5043 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5044 }
5045
5046 /* Determine where to put an argument to a function.
5047 Value is zero to push the argument on the stack,
5048 or a hard register in which to store the argument.
5049
5050 MODE is the argument's machine mode.
5051 TYPE is the data type of the argument (as a tree).
5052 This is null for libcalls where that information may
5053 not be available.
5054 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5055 the preceding args and about the function being called. It is
5056 not modified in this routine.
5057 NAMED is nonzero if this argument is a named parameter
5058 (otherwise it is an extra parameter matching an ellipsis).
5059
5060 On RS/6000 the first eight words of non-FP are normally in registers
5061 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5062 Under V.4, the first 8 FP args are in registers.
5063
5064 If this is floating-point and no prototype is specified, we use
5065 both an FP and integer register (or possibly FP reg and stack). Library
5066 functions (when CALL_LIBCALL is set) always have the proper types for args,
5067 so we can pass the FP value just in one register. emit_library_function
5068 doesn't support PARALLEL anyway.
5069
5070 Note that for args passed by reference, function_arg will be called
5071 with MODE and TYPE set to that of the pointer to the arg, not the arg
5072 itself. */
5073
5074 rtx
function_arg(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named)5075 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5076 tree type, int named)
5077 {
5078 enum rs6000_abi abi = DEFAULT_ABI;
5079
5080 /* Return a marker to indicate whether CR1 needs to set or clear the
5081 bit that V.4 uses to say fp args were passed in registers.
5082 Assume that we don't need the marker for software floating point,
5083 or compiler generated library calls. */
5084 if (mode == VOIDmode)
5085 {
5086 if (abi == ABI_V4
5087 && (cum->call_cookie & CALL_LIBCALL) == 0
5088 && (cum->stdarg
5089 || (cum->nargs_prototype < 0
5090 && (cum->prototype || TARGET_NO_PROTOTYPE))))
5091 {
5092 /* For the SPE, we need to crxor CR6 always. */
5093 if (TARGET_SPE_ABI)
5094 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5095 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5096 return GEN_INT (cum->call_cookie
5097 | ((cum->fregno == FP_ARG_MIN_REG)
5098 ? CALL_V4_SET_FP_ARGS
5099 : CALL_V4_CLEAR_FP_ARGS));
5100 }
5101
5102 return GEN_INT (cum->call_cookie);
5103 }
5104
5105 if (rs6000_darwin64_abi && mode == BLKmode
5106 && TREE_CODE (type) == RECORD_TYPE)
5107 {
5108 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
5109 if (rslt != NULL_RTX)
5110 return rslt;
5111 /* Else fall through to usual handling. */
5112 }
5113
5114 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5115 if (TARGET_64BIT && ! cum->prototype)
5116 {
5117 /* Vector parameters get passed in vector register
5118 and also in GPRs or memory, in absence of prototype. */
5119 int align_words;
5120 rtx slot;
5121 align_words = (cum->words + 1) & ~1;
5122
5123 if (align_words >= GP_ARG_NUM_REG)
5124 {
5125 slot = NULL_RTX;
5126 }
5127 else
5128 {
5129 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5130 }
5131 return gen_rtx_PARALLEL (mode,
5132 gen_rtvec (2,
5133 gen_rtx_EXPR_LIST (VOIDmode,
5134 slot, const0_rtx),
5135 gen_rtx_EXPR_LIST (VOIDmode,
5136 gen_rtx_REG (mode, cum->vregno),
5137 const0_rtx)));
5138 }
5139 else
5140 return gen_rtx_REG (mode, cum->vregno);
5141 else if (TARGET_ALTIVEC_ABI
5142 && (ALTIVEC_VECTOR_MODE (mode)
5143 || (type && TREE_CODE (type) == VECTOR_TYPE
5144 && int_size_in_bytes (type) == 16)))
5145 {
5146 if (named || abi == ABI_V4)
5147 return NULL_RTX;
5148 else
5149 {
5150 /* Vector parameters to varargs functions under AIX or Darwin
5151 get passed in memory and possibly also in GPRs. */
5152 int align, align_words, n_words;
5153 enum machine_mode part_mode;
5154
5155 /* Vector parameters must be 16-byte aligned. This places them at
5156 2 mod 4 in terms of words in 32-bit mode, since the parameter
5157 save area starts at offset 24 from the stack. In 64-bit mode,
5158 they just have to start on an even word, since the parameter
5159 save area is 16-byte aligned. */
5160 if (TARGET_32BIT)
5161 align = (2 - cum->words) & 3;
5162 else
5163 align = cum->words & 1;
5164 align_words = cum->words + align;
5165
5166 /* Out of registers? Memory, then. */
5167 if (align_words >= GP_ARG_NUM_REG)
5168 return NULL_RTX;
5169
5170 if (TARGET_32BIT && TARGET_POWERPC64)
5171 return rs6000_mixed_function_arg (mode, type, align_words);
5172
5173 /* The vector value goes in GPRs. Only the part of the
5174 value in GPRs is reported here. */
5175 part_mode = mode;
5176 n_words = rs6000_arg_size (mode, type);
5177 if (align_words + n_words > GP_ARG_NUM_REG)
5178 /* Fortunately, there are only two possibilities, the value
5179 is either wholly in GPRs or half in GPRs and half not. */
5180 part_mode = DImode;
5181
5182 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
5183 }
5184 }
5185 else if (TARGET_SPE_ABI && TARGET_SPE
5186 && (SPE_VECTOR_MODE (mode)
5187 || (TARGET_E500_DOUBLE && (mode == DFmode
5188 || mode == DCmode))))
5189 return rs6000_spe_function_arg (cum, mode, type);
5190
5191 else if (abi == ABI_V4)
5192 {
5193 if (TARGET_HARD_FLOAT && TARGET_FPRS
5194 && (mode == SFmode || mode == DFmode
5195 || (mode == TFmode && !TARGET_IEEEQUAD)))
5196 {
5197 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
5198 return gen_rtx_REG (mode, cum->fregno);
5199 else
5200 return NULL_RTX;
5201 }
5202 else
5203 {
5204 int n_words = rs6000_arg_size (mode, type);
5205 int gregno = cum->sysv_gregno;
5206
5207 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5208 (r7,r8) or (r9,r10). As does any other 2 word item such
5209 as complex int due to a historical mistake. */
5210 if (n_words == 2)
5211 gregno += (1 - gregno) & 1;
5212
5213 /* Multi-reg args are not split between registers and stack. */
5214 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5215 return NULL_RTX;
5216
5217 if (TARGET_32BIT && TARGET_POWERPC64)
5218 return rs6000_mixed_function_arg (mode, type,
5219 gregno - GP_ARG_MIN_REG);
5220 return gen_rtx_REG (mode, gregno);
5221 }
5222 }
5223 else
5224 {
5225 int align_words = rs6000_parm_start (mode, type, cum->words);
5226
5227 if (USE_FP_FOR_ARG_P (cum, mode, type))
5228 {
5229 rtx rvec[GP_ARG_NUM_REG + 1];
5230 rtx r;
5231 int k;
5232 bool needs_psave;
5233 enum machine_mode fmode = mode;
5234 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5235
5236 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5237 {
5238 /* Currently, we only ever need one reg here because complex
5239 doubles are split. */
5240 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
5241
5242 /* Long double split over regs and memory. */
5243 fmode = DFmode;
5244 }
5245
5246 /* Do we also need to pass this arg in the parameter save
5247 area? */
5248 needs_psave = (type
5249 && (cum->nargs_prototype <= 0
5250 || (DEFAULT_ABI == ABI_AIX
5251 && TARGET_XL_COMPAT
5252 && align_words >= GP_ARG_NUM_REG)));
5253
5254 if (!needs_psave && mode == fmode)
5255 return gen_rtx_REG (fmode, cum->fregno);
5256
5257 k = 0;
5258 if (needs_psave)
5259 {
5260 /* Describe the part that goes in gprs or the stack.
5261 This piece must come first, before the fprs. */
5262 if (align_words < GP_ARG_NUM_REG)
5263 {
5264 unsigned long n_words = rs6000_arg_size (mode, type);
5265
5266 if (align_words + n_words > GP_ARG_NUM_REG
5267 || (TARGET_32BIT && TARGET_POWERPC64))
5268 {
5269 /* If this is partially on the stack, then we only
5270 include the portion actually in registers here. */
5271 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5272 rtx off;
5273 int i=0;
5274 if (align_words + n_words > GP_ARG_NUM_REG
5275 && (TARGET_32BIT && TARGET_POWERPC64))
5276 /* Not all of the arg fits in gprs. Say that it
5277 goes in memory too, using a magic NULL_RTX
5278 component. Also see comment in
5279 rs6000_mixed_function_arg for why the normal
5280 function_arg_partial_nregs scheme doesn't work
5281 in this case. */
5282 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5283 const0_rtx);
5284 do
5285 {
5286 r = gen_rtx_REG (rmode,
5287 GP_ARG_MIN_REG + align_words);
5288 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
5289 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5290 }
5291 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5292 }
5293 else
5294 {
5295 /* The whole arg fits in gprs. */
5296 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5297 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5298 }
5299 }
5300 else
5301 /* It's entirely in memory. */
5302 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5303 }
5304
5305 /* Describe where this piece goes in the fprs. */
5306 r = gen_rtx_REG (fmode, cum->fregno);
5307 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5308
5309 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5310 }
5311 else if (align_words < GP_ARG_NUM_REG)
5312 {
5313 if (TARGET_32BIT && TARGET_POWERPC64)
5314 return rs6000_mixed_function_arg (mode, type, align_words);
5315
5316 if (mode == BLKmode)
5317 mode = Pmode;
5318
5319 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5320 }
5321 else
5322 return NULL_RTX;
5323 }
5324 }
5325
5326 /* For an arg passed partly in registers and partly in memory, this is
5327 the number of bytes passed in registers. For args passed entirely in
5328 registers or entirely in memory, zero. When an arg is described by a
5329 PARALLEL, perhaps using more than one register type, this function
5330 returns the number of bytes used by the first element of the PARALLEL. */
5331
5332 static int
rs6000_arg_partial_bytes(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,bool named)5333 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5334 tree type, bool named)
5335 {
5336 int ret = 0;
5337 int align_words;
5338
5339 if (DEFAULT_ABI == ABI_V4)
5340 return 0;
5341
5342 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5343 && cum->nargs_prototype >= 0)
5344 return 0;
5345
5346 /* In this complicated case we just disable the partial_nregs code. */
5347 if (rs6000_darwin64_abi && mode == BLKmode
5348 && TREE_CODE (type) == RECORD_TYPE
5349 && int_size_in_bytes (type) > 0)
5350 return 0;
5351
5352 align_words = rs6000_parm_start (mode, type, cum->words);
5353
5354 if (USE_FP_FOR_ARG_P (cum, mode, type)
5355 /* If we are passing this arg in the fixed parameter save area
5356 (gprs or memory) as well as fprs, then this function should
5357 return the number of bytes passed in the parameter save area
5358 rather than bytes passed in fprs. */
5359 && !(type
5360 && (cum->nargs_prototype <= 0
5361 || (DEFAULT_ABI == ABI_AIX
5362 && TARGET_XL_COMPAT
5363 && align_words >= GP_ARG_NUM_REG))))
5364 {
5365 if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
5366 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
5367 else if (cum->nargs_prototype >= 0)
5368 return 0;
5369 }
5370
5371 if (align_words < GP_ARG_NUM_REG
5372 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
5373 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
5374
5375 if (ret != 0 && TARGET_DEBUG_ARG)
5376 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
5377
5378 return ret;
5379 }
5380
5381 /* A C expression that indicates when an argument must be passed by
5382 reference. If nonzero for an argument, a copy of that argument is
5383 made in memory and a pointer to the argument is passed instead of
5384 the argument itself. The pointer is passed in whatever way is
5385 appropriate for passing a pointer to that type.
5386
5387 Under V.4, aggregates and long double are passed by reference.
5388
5389 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5390 reference unless the AltiVec vector extension ABI is in force.
5391
5392 As an extension to all ABIs, variable sized types are passed by
5393 reference. */
5394
5395 static bool
rs6000_pass_by_reference(CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,enum machine_mode mode,tree type,bool named ATTRIBUTE_UNUSED)5396 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5397 enum machine_mode mode, tree type,
5398 bool named ATTRIBUTE_UNUSED)
5399 {
5400 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
5401 {
5402 if (TARGET_DEBUG_ARG)
5403 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5404 return 1;
5405 }
5406
5407 if (!type)
5408 return 0;
5409
5410 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5411 {
5412 if (TARGET_DEBUG_ARG)
5413 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5414 return 1;
5415 }
5416
5417 if (int_size_in_bytes (type) < 0)
5418 {
5419 if (TARGET_DEBUG_ARG)
5420 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5421 return 1;
5422 }
5423
5424 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5425 modes only exist for GCC vector types if -maltivec. */
5426 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5427 {
5428 if (TARGET_DEBUG_ARG)
5429 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
5430 return 1;
5431 }
5432
5433 /* Pass synthetic vectors in memory. */
5434 if (TREE_CODE (type) == VECTOR_TYPE
5435 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5436 {
5437 static bool warned_for_pass_big_vectors = false;
5438 if (TARGET_DEBUG_ARG)
5439 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5440 if (!warned_for_pass_big_vectors)
5441 {
5442 warning (0, "GCC vector passed by reference: "
5443 "non-standard ABI extension with no compatibility guarantee");
5444 warned_for_pass_big_vectors = true;
5445 }
5446 return 1;
5447 }
5448
5449 return 0;
5450 }
5451
5452 static void
rs6000_move_block_from_reg(int regno,rtx x,int nregs)5453 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5454 {
5455 int i;
5456 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5457
5458 if (nregs == 0)
5459 return;
5460
5461 for (i = 0; i < nregs; i++)
5462 {
5463 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5464 if (reload_completed)
5465 {
5466 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5467 tem = NULL_RTX;
5468 else
5469 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
5470 i * GET_MODE_SIZE (reg_mode));
5471 }
5472 else
5473 tem = replace_equiv_address (tem, XEXP (tem, 0));
5474
5475 gcc_assert (tem);
5476
5477 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5478 }
5479 }
5480
5481 /* Perform any needed actions needed for a function that is receiving a
5482 variable number of arguments.
5483
5484 CUM is as above.
5485
5486 MODE and TYPE are the mode and type of the current parameter.
5487
5488 PRETEND_SIZE is a variable that should be set to the amount of stack
5489 that must be pushed by the prolog to pretend that our caller pushed
5490 it.
5491
5492 Normally, this macro will push all remaining incoming registers on the
5493 stack and set PRETEND_SIZE to the length of the registers pushed. */
5494
5495 static void
setup_incoming_varargs(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int * pretend_size ATTRIBUTE_UNUSED,int no_rtl)5496 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5497 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5498 int no_rtl)
5499 {
5500 CUMULATIVE_ARGS next_cum;
5501 int reg_size = TARGET_32BIT ? 4 : 8;
5502 rtx save_area = NULL_RTX, mem;
5503 int first_reg_offset, set;
5504
5505 /* Skip the last named argument. */
5506 next_cum = *cum;
5507 function_arg_advance (&next_cum, mode, type, 1, 0);
5508
5509 if (DEFAULT_ABI == ABI_V4)
5510 {
5511 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5512
5513 if (! no_rtl)
5514 {
5515 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5516 HOST_WIDE_INT offset = 0;
5517
5518 /* Try to optimize the size of the varargs save area.
5519 The ABI requires that ap.reg_save_area is doubleword
5520 aligned, but we don't need to allocate space for all
5521 the bytes, only those to which we actually will save
5522 anything. */
5523 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5524 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5525 if (TARGET_HARD_FLOAT && TARGET_FPRS
5526 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5527 && cfun->va_list_fpr_size)
5528 {
5529 if (gpr_reg_num)
5530 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5531 * UNITS_PER_FP_WORD;
5532 if (cfun->va_list_fpr_size
5533 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5534 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5535 else
5536 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5537 * UNITS_PER_FP_WORD;
5538 }
5539 if (gpr_reg_num)
5540 {
5541 offset = -((first_reg_offset * reg_size) & ~7);
5542 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5543 {
5544 gpr_reg_num = cfun->va_list_gpr_size;
5545 if (reg_size == 4 && (first_reg_offset & 1))
5546 gpr_reg_num++;
5547 }
5548 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5549 }
5550 else if (fpr_size)
5551 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5552 * UNITS_PER_FP_WORD
5553 - (int) (GP_ARG_NUM_REG * reg_size);
5554
5555 if (gpr_size + fpr_size)
5556 {
5557 rtx reg_save_area
5558 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5559 gcc_assert (GET_CODE (reg_save_area) == MEM);
5560 reg_save_area = XEXP (reg_save_area, 0);
5561 if (GET_CODE (reg_save_area) == PLUS)
5562 {
5563 gcc_assert (XEXP (reg_save_area, 0)
5564 == virtual_stack_vars_rtx);
5565 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5566 offset += INTVAL (XEXP (reg_save_area, 1));
5567 }
5568 else
5569 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5570 }
5571
5572 cfun->machine->varargs_save_offset = offset;
5573 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5574 }
5575 }
5576 else
5577 {
5578 first_reg_offset = next_cum.words;
5579 save_area = virtual_incoming_args_rtx;
5580
5581 if (targetm.calls.must_pass_in_stack (mode, type))
5582 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
5583 }
5584
5585 set = get_varargs_alias_set ();
5586 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5587 && cfun->va_list_gpr_size)
5588 {
5589 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5590
5591 if (va_list_gpr_counter_field)
5592 {
5593 /* V4 va_list_gpr_size counts number of registers needed. */
5594 if (nregs > cfun->va_list_gpr_size)
5595 nregs = cfun->va_list_gpr_size;
5596 }
5597 else
5598 {
5599 /* char * va_list instead counts number of bytes needed. */
5600 if (nregs > cfun->va_list_gpr_size / reg_size)
5601 nregs = cfun->va_list_gpr_size / reg_size;
5602 }
5603
5604 mem = gen_rtx_MEM (BLKmode,
5605 plus_constant (save_area,
5606 first_reg_offset * reg_size));
5607 MEM_NOTRAP_P (mem) = 1;
5608 set_mem_alias_set (mem, set);
5609 set_mem_align (mem, BITS_PER_WORD);
5610
5611 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
5612 nregs);
5613 }
5614
5615 /* Save FP registers if needed. */
5616 if (DEFAULT_ABI == ABI_V4
5617 && TARGET_HARD_FLOAT && TARGET_FPRS
5618 && ! no_rtl
5619 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5620 && cfun->va_list_fpr_size)
5621 {
5622 int fregno = next_cum.fregno, nregs;
5623 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
5624 rtx lab = gen_label_rtx ();
5625 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5626 * UNITS_PER_FP_WORD);
5627
5628 emit_jump_insn
5629 (gen_rtx_SET (VOIDmode,
5630 pc_rtx,
5631 gen_rtx_IF_THEN_ELSE (VOIDmode,
5632 gen_rtx_NE (VOIDmode, cr1,
5633 const0_rtx),
5634 gen_rtx_LABEL_REF (VOIDmode, lab),
5635 pc_rtx)));
5636
5637 for (nregs = 0;
5638 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5639 fregno++, off += UNITS_PER_FP_WORD, nregs++)
5640 {
5641 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
5642 MEM_NOTRAP_P (mem) = 1;
5643 set_mem_alias_set (mem, set);
5644 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
5645 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
5646 }
5647
5648 emit_label (lab);
5649 }
5650 }
5651
5652 /* Create the va_list data type. */
5653
5654 static tree
rs6000_build_builtin_va_list(void)5655 rs6000_build_builtin_va_list (void)
5656 {
5657 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
5658
5659 /* For AIX, prefer 'char *' because that's what the system
5660 header files like. */
5661 if (DEFAULT_ABI != ABI_V4)
5662 return build_pointer_type (char_type_node);
5663
5664 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5665 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5666
5667 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
5668 unsigned_char_type_node);
5669 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
5670 unsigned_char_type_node);
5671 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5672 every user file. */
5673 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
5674 short_unsigned_type_node);
5675 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
5676 ptr_type_node);
5677 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
5678 ptr_type_node);
5679
5680 va_list_gpr_counter_field = f_gpr;
5681 va_list_fpr_counter_field = f_fpr;
5682
5683 DECL_FIELD_CONTEXT (f_gpr) = record;
5684 DECL_FIELD_CONTEXT (f_fpr) = record;
5685 DECL_FIELD_CONTEXT (f_res) = record;
5686 DECL_FIELD_CONTEXT (f_ovf) = record;
5687 DECL_FIELD_CONTEXT (f_sav) = record;
5688
5689 TREE_CHAIN (record) = type_decl;
5690 TYPE_NAME (record) = type_decl;
5691 TYPE_FIELDS (record) = f_gpr;
5692 TREE_CHAIN (f_gpr) = f_fpr;
5693 TREE_CHAIN (f_fpr) = f_res;
5694 TREE_CHAIN (f_res) = f_ovf;
5695 TREE_CHAIN (f_ovf) = f_sav;
5696
5697 layout_type (record);
5698
5699 /* The correct type is an array type of one element. */
5700 return build_array_type (record, build_index_type (size_zero_node));
5701 }
5702
5703 /* Implement va_start. */
5704
5705 void
rs6000_va_start(tree valist,rtx nextarg)5706 rs6000_va_start (tree valist, rtx nextarg)
5707 {
5708 HOST_WIDE_INT words, n_gpr, n_fpr;
5709 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5710 tree gpr, fpr, ovf, sav, t;
5711
5712 /* Only SVR4 needs something special. */
5713 if (DEFAULT_ABI != ABI_V4)
5714 {
5715 std_expand_builtin_va_start (valist, nextarg);
5716 return;
5717 }
5718
5719 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5720 f_fpr = TREE_CHAIN (f_gpr);
5721 f_res = TREE_CHAIN (f_fpr);
5722 f_ovf = TREE_CHAIN (f_res);
5723 f_sav = TREE_CHAIN (f_ovf);
5724
5725 valist = build_va_arg_indirect_ref (valist);
5726 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5727 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5728 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5729 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
5730
5731 /* Count number of gp and fp argument registers used. */
5732 words = current_function_args_info.words;
5733 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
5734 GP_ARG_NUM_REG);
5735 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
5736 FP_ARG_NUM_REG);
5737
5738 if (TARGET_DEBUG_ARG)
5739 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
5740 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
5741 words, n_gpr, n_fpr);
5742
5743 if (cfun->va_list_gpr_size)
5744 {
5745 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
5746 build_int_cst (NULL_TREE, n_gpr));
5747 TREE_SIDE_EFFECTS (t) = 1;
5748 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5749 }
5750
5751 if (cfun->va_list_fpr_size)
5752 {
5753 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
5754 build_int_cst (NULL_TREE, n_fpr));
5755 TREE_SIDE_EFFECTS (t) = 1;
5756 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5757 }
5758
5759 /* Find the overflow area. */
5760 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
5761 if (words != 0)
5762 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
5763 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
5764 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5765 TREE_SIDE_EFFECTS (t) = 1;
5766 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5767
5768 /* If there were no va_arg invocations, don't set up the register
5769 save area. */
5770 if (!cfun->va_list_gpr_size
5771 && !cfun->va_list_fpr_size
5772 && n_gpr < GP_ARG_NUM_REG
5773 && n_fpr < FP_ARG_V4_MAX_REG)
5774 return;
5775
5776 /* Find the register save area. */
5777 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
5778 if (cfun->machine->varargs_save_offset)
5779 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
5780 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
5781 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
5782 TREE_SIDE_EFFECTS (t) = 1;
5783 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5784 }
5785
5786 /* Implement va_arg. */
5787
5788 tree
rs6000_gimplify_va_arg(tree valist,tree type,tree * pre_p,tree * post_p)5789 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5790 {
5791 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5792 tree gpr, fpr, ovf, sav, reg, t, u;
5793 int size, rsize, n_reg, sav_ofs, sav_scale;
5794 tree lab_false, lab_over, addr;
5795 int align;
5796 tree ptrtype = build_pointer_type (type);
5797
5798 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
5799 {
5800 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
5801 return build_va_arg_indirect_ref (t);
5802 }
5803
5804 if (DEFAULT_ABI != ABI_V4)
5805 {
5806 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
5807 {
5808 tree elem_type = TREE_TYPE (type);
5809 enum machine_mode elem_mode = TYPE_MODE (elem_type);
5810 int elem_size = GET_MODE_SIZE (elem_mode);
5811
5812 if (elem_size < UNITS_PER_WORD)
5813 {
5814 tree real_part, imag_part;
5815 tree post = NULL_TREE;
5816
5817 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5818 &post);
5819 /* Copy the value into a temporary, lest the formal temporary
5820 be reused out from under us. */
5821 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
5822 append_to_statement_list (post, pre_p);
5823
5824 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5825 post_p);
5826
5827 return build (COMPLEX_EXPR, type, real_part, imag_part);
5828 }
5829 }
5830
5831 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5832 }
5833
5834 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5835 f_fpr = TREE_CHAIN (f_gpr);
5836 f_res = TREE_CHAIN (f_fpr);
5837 f_ovf = TREE_CHAIN (f_res);
5838 f_sav = TREE_CHAIN (f_ovf);
5839
5840 valist = build_va_arg_indirect_ref (valist);
5841 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5842 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5843 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5844 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
5845
5846 size = int_size_in_bytes (type);
5847 rsize = (size + 3) / 4;
5848 align = 1;
5849
5850 if (TARGET_HARD_FLOAT && TARGET_FPRS
5851 && (TYPE_MODE (type) == SFmode
5852 || TYPE_MODE (type) == DFmode
5853 || TYPE_MODE (type) == TFmode))
5854 {
5855 /* FP args go in FP registers, if present. */
5856 reg = fpr;
5857 n_reg = (size + 7) / 8;
5858 sav_ofs = 8*4;
5859 sav_scale = 8;
5860 if (TYPE_MODE (type) != SFmode)
5861 align = 8;
5862 }
5863 else
5864 {
5865 /* Otherwise into GP registers. */
5866 reg = gpr;
5867 n_reg = rsize;
5868 sav_ofs = 0;
5869 sav_scale = 4;
5870 if (n_reg == 2)
5871 align = 8;
5872 }
5873
5874 /* Pull the value out of the saved registers.... */
5875
5876 lab_over = NULL;
5877 addr = create_tmp_var (ptr_type_node, "addr");
5878 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
5879
5880 /* AltiVec vectors never go in registers when -mabi=altivec. */
5881 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
5882 align = 16;
5883 else
5884 {
5885 lab_false = create_artificial_label ();
5886 lab_over = create_artificial_label ();
5887
5888 /* Long long and SPE vectors are aligned in the registers.
5889 As are any other 2 gpr item such as complex int due to a
5890 historical mistake. */
5891 u = reg;
5892 if (n_reg == 2 && reg == gpr)
5893 {
5894 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
5895 size_int (n_reg - 1));
5896 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
5897 }
5898
5899 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
5900 t = build2 (GE_EXPR, boolean_type_node, u, t);
5901 u = build1 (GOTO_EXPR, void_type_node, lab_false);
5902 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
5903 gimplify_and_add (t, pre_p);
5904
5905 t = sav;
5906 if (sav_ofs)
5907 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
5908
5909 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
5910 u = build1 (CONVERT_EXPR, integer_type_node, u);
5911 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
5912 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
5913
5914 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
5915 gimplify_and_add (t, pre_p);
5916
5917 t = build1 (GOTO_EXPR, void_type_node, lab_over);
5918 gimplify_and_add (t, pre_p);
5919
5920 t = build1 (LABEL_EXPR, void_type_node, lab_false);
5921 append_to_statement_list (t, pre_p);
5922
5923 if ((n_reg == 2 && reg != gpr) || n_reg > 2)
5924 {
5925 /* Ensure that we don't find any more args in regs.
5926 Alignment has taken care of the n_reg == 2 gpr case. */
5927 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
5928 gimplify_and_add (t, pre_p);
5929 }
5930 }
5931
5932 /* ... otherwise out of the overflow area. */
5933
5934 /* Care for on-stack alignment if needed. */
5935 t = ovf;
5936 if (align != 1)
5937 {
5938 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
5939 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
5940 build_int_cst (NULL_TREE, -align));
5941 }
5942 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
5943
5944 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
5945 gimplify_and_add (u, pre_p);
5946
5947 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
5948 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5949 gimplify_and_add (t, pre_p);
5950
5951 if (lab_over)
5952 {
5953 t = build1 (LABEL_EXPR, void_type_node, lab_over);
5954 append_to_statement_list (t, pre_p);
5955 }
5956
5957 addr = fold_convert (ptrtype, addr);
5958 return build_va_arg_indirect_ref (addr);
5959 }
5960
5961 /* Builtins. */
5962
5963 static void
def_builtin(int mask,const char * name,tree type,int code)5964 def_builtin (int mask, const char *name, tree type, int code)
5965 {
5966 if (mask & target_flags)
5967 {
5968 if (rs6000_builtin_decls[code])
5969 abort ();
5970
5971 rs6000_builtin_decls[code] =
5972 lang_hooks.builtin_function (name, type, code, BUILT_IN_MD,
5973 NULL, NULL_TREE);
5974 }
5975 }
5976
5977 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5978
5979 static const struct builtin_description bdesc_3arg[] =
5980 {
5981 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
5982 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
5983 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
5984 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
5985 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
5986 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
5987 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
5988 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
5989 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
5990 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
5991 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
5992 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
5993 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
5994 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
5995 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
5996 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
5997 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
5998 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
5999 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6000 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6001 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6002 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6003 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
6004
6005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
6020 };
6021
6022 /* DST operations: void foo (void *, const int, const char). */
6023
6024 static const struct builtin_description bdesc_dst[] =
6025 {
6026 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6027 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6028 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
6029 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6030
6031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
6035 };
6036
6037 /* Simple binary operations: VECc = foo (VECa, VECb). */
6038
6039 static struct builtin_description bdesc_2arg[] =
6040 {
6041 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6042 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6043 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6044 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
6045 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6046 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6047 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6048 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6049 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6050 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6051 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
6052 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
6053 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
6054 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6055 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6056 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6057 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6058 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6059 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
6060 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6061 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
6062 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6063 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6064 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6065 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6066 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6067 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6068 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6069 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6070 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6071 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6072 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6073 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6074 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
6075 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6076 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
6077 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6078 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
6079 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6080 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6081 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6082 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6083 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
6084 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6085 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6086 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6087 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6088 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6089 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
6090 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6091 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6092 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6093 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6094 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6095 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6096 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
6097 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6098 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6099 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6100 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6101 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6102 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6103 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6104 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
6105 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
6106 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
6107 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6108 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6109 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
6110 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
6111 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6112 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6113 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6114 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6115 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6116 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6117 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6118 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6119 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6120 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6121 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6122 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6123 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
6124 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6125 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6126 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
6127 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6128 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6129 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6130 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6131 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6132 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
6133 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6134 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
6135 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6136 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6137 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6138 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
6139 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6140 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6141 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6142 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6143 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6144 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6145 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6146 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6147 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6148 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6149 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6150 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
6151 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
6152
6153 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6154 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6155 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6156 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6157 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6188 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6189 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6193 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6194 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6258 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6280
6281 /* Place holder, leave as first spe builtin. */
6282 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6283 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6284 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6285 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6286 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6287 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6288 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6289 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6290 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6291 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6292 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6293 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6294 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6295 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6296 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6297 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6298 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6299 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6300 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6301 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6302 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6303 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6304 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6305 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6306 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6307 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6308 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6309 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6310 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6311 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6312 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6313 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6314 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6315 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6316 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6317 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6318 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6319 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6320 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6321 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6322 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6323 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6324 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6325 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6326 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6327 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6328 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6329 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6330 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6331 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6332 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6333 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6334 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6335 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6336 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6337 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6338 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6339 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6340 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6341 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6342 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6343 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6344 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6345 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6346 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6347 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6348 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6349 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6350 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6351 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6352 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6353 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6354 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6355 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
6356 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6357 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
6358 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6359 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6360 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6361 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6362 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6363 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6364 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6365 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6366 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6367 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6368 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6369 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6370 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6371 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6372 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6373 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6374 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6375 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6376 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6377 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6378 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6379 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6380 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6381 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6382 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6383 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6384 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6385 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6386 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6387 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6388 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6389 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6390 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6391
6392 /* SPE binary operations expecting a 5-bit unsigned literal. */
6393 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6394
6395 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6396 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6397 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6398 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6399 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6400 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6401 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6402 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6403 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6404 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6405 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6406 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6407 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6408 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6409 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6410 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6411 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6412 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6413 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6414 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6415 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6416 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6417 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6418 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6419 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6420 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6421
6422 /* Place-holder. Leave as last binary SPE builtin. */
6423 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
6424 };
6425
6426 /* AltiVec predicates. */
6427
6428 struct builtin_description_predicates
6429 {
6430 const unsigned int mask;
6431 const enum insn_code icode;
6432 const char *opcode;
6433 const char *const name;
6434 const enum rs6000_builtins code;
6435 };
6436
6437 static const struct builtin_description_predicates bdesc_altivec_preds[] =
6438 {
6439 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6440 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6441 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6442 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6443 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6444 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6445 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6446 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6447 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6448 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6449 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6450 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
6451 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6452
6453 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6454 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6455 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
6456 };
6457
6458 /* SPE predicates. */
6459 static struct builtin_description bdesc_spe_predicates[] =
6460 {
6461 /* Place-holder. Leave as first. */
6462 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6463 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6464 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6465 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6466 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6467 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6468 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6469 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6470 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6471 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6472 /* Place-holder. Leave as last. */
6473 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6474 };
6475
6476 /* SPE evsel predicates. */
6477 static struct builtin_description bdesc_spe_evsel[] =
6478 {
6479 /* Place-holder. Leave as first. */
6480 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6481 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6482 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6483 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6484 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6485 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6486 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6487 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6488 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6489 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6490 /* Place-holder. Leave as last. */
6491 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6492 };
6493
6494 /* ABS* operations. */
6495
6496 static const struct builtin_description bdesc_abs[] =
6497 {
6498 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6499 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6500 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6501 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6502 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6503 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6504 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6505 };
6506
6507 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6508 foo (VECa). */
6509
6510 static struct builtin_description bdesc_1arg[] =
6511 {
6512 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6513 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6514 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6515 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6516 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6517 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6518 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6519 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
6520 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6521 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6522 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
6523 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6524 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6525 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6526 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6527 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6528 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
6529
6530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6543 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6549
6550 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6551 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6552 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6553 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6554 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6555 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6556 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6557 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6558 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6559 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6560 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6561 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6562 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6563 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6564 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6565 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6566 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6567 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6568 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6569 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6570 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6571 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6572 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6573 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6574 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6575 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
6576 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6577 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6578 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6579 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
6580
6581 /* Place-holder. Leave as last unary SPE builtin. */
6582 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
6583 };
6584
6585 static rtx
rs6000_expand_unop_builtin(enum insn_code icode,tree arglist,rtx target)6586 rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
6587 {
6588 rtx pat;
6589 tree arg0 = TREE_VALUE (arglist);
6590 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6591 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6592 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6593
6594 if (icode == CODE_FOR_nothing)
6595 /* Builtin not supported on this processor. */
6596 return 0;
6597
6598 /* If we got invalid arguments bail out before generating bad rtl. */
6599 if (arg0 == error_mark_node)
6600 return const0_rtx;
6601
6602 if (icode == CODE_FOR_altivec_vspltisb
6603 || icode == CODE_FOR_altivec_vspltish
6604 || icode == CODE_FOR_altivec_vspltisw
6605 || icode == CODE_FOR_spe_evsplatfi
6606 || icode == CODE_FOR_spe_evsplati)
6607 {
6608 /* Only allow 5-bit *signed* literals. */
6609 if (GET_CODE (op0) != CONST_INT
6610 || INTVAL (op0) > 15
6611 || INTVAL (op0) < -16)
6612 {
6613 error ("argument 1 must be a 5-bit signed literal");
6614 return const0_rtx;
6615 }
6616 }
6617
6618 if (target == 0
6619 || GET_MODE (target) != tmode
6620 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6621 target = gen_reg_rtx (tmode);
6622
6623 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6624 op0 = copy_to_mode_reg (mode0, op0);
6625
6626 pat = GEN_FCN (icode) (target, op0);
6627 if (! pat)
6628 return 0;
6629 emit_insn (pat);
6630
6631 return target;
6632 }
6633
6634 static rtx
altivec_expand_abs_builtin(enum insn_code icode,tree arglist,rtx target)6635 altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
6636 {
6637 rtx pat, scratch1, scratch2;
6638 tree arg0 = TREE_VALUE (arglist);
6639 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6640 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6641 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6642
6643 /* If we have invalid arguments, bail out before generating bad rtl. */
6644 if (arg0 == error_mark_node)
6645 return const0_rtx;
6646
6647 if (target == 0
6648 || GET_MODE (target) != tmode
6649 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6650 target = gen_reg_rtx (tmode);
6651
6652 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6653 op0 = copy_to_mode_reg (mode0, op0);
6654
6655 scratch1 = gen_reg_rtx (mode0);
6656 scratch2 = gen_reg_rtx (mode0);
6657
6658 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
6659 if (! pat)
6660 return 0;
6661 emit_insn (pat);
6662
6663 return target;
6664 }
6665
6666 static rtx
rs6000_expand_binop_builtin(enum insn_code icode,tree arglist,rtx target)6667 rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
6668 {
6669 rtx pat;
6670 tree arg0 = TREE_VALUE (arglist);
6671 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6672 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6673 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6674 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6675 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6676 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6677
6678 if (icode == CODE_FOR_nothing)
6679 /* Builtin not supported on this processor. */
6680 return 0;
6681
6682 /* If we got invalid arguments bail out before generating bad rtl. */
6683 if (arg0 == error_mark_node || arg1 == error_mark_node)
6684 return const0_rtx;
6685
6686 if (icode == CODE_FOR_altivec_vcfux
6687 || icode == CODE_FOR_altivec_vcfsx
6688 || icode == CODE_FOR_altivec_vctsxs
6689 || icode == CODE_FOR_altivec_vctuxs
6690 || icode == CODE_FOR_altivec_vspltb
6691 || icode == CODE_FOR_altivec_vsplth
6692 || icode == CODE_FOR_altivec_vspltw
6693 || icode == CODE_FOR_spe_evaddiw
6694 || icode == CODE_FOR_spe_evldd
6695 || icode == CODE_FOR_spe_evldh
6696 || icode == CODE_FOR_spe_evldw
6697 || icode == CODE_FOR_spe_evlhhesplat
6698 || icode == CODE_FOR_spe_evlhhossplat
6699 || icode == CODE_FOR_spe_evlhhousplat
6700 || icode == CODE_FOR_spe_evlwhe
6701 || icode == CODE_FOR_spe_evlwhos
6702 || icode == CODE_FOR_spe_evlwhou
6703 || icode == CODE_FOR_spe_evlwhsplat
6704 || icode == CODE_FOR_spe_evlwwsplat
6705 || icode == CODE_FOR_spe_evrlwi
6706 || icode == CODE_FOR_spe_evslwi
6707 || icode == CODE_FOR_spe_evsrwis
6708 || icode == CODE_FOR_spe_evsubifw
6709 || icode == CODE_FOR_spe_evsrwiu)
6710 {
6711 /* Only allow 5-bit unsigned literals. */
6712 STRIP_NOPS (arg1);
6713 if (TREE_CODE (arg1) != INTEGER_CST
6714 || TREE_INT_CST_LOW (arg1) & ~0x1f)
6715 {
6716 error ("argument 2 must be a 5-bit unsigned literal");
6717 return const0_rtx;
6718 }
6719 }
6720
6721 if (target == 0
6722 || GET_MODE (target) != tmode
6723 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6724 target = gen_reg_rtx (tmode);
6725
6726 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6727 op0 = copy_to_mode_reg (mode0, op0);
6728 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6729 op1 = copy_to_mode_reg (mode1, op1);
6730
6731 pat = GEN_FCN (icode) (target, op0, op1);
6732 if (! pat)
6733 return 0;
6734 emit_insn (pat);
6735
6736 return target;
6737 }
6738
6739 static rtx
altivec_expand_predicate_builtin(enum insn_code icode,const char * opcode,tree arglist,rtx target)6740 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
6741 tree arglist, rtx target)
6742 {
6743 rtx pat, scratch;
6744 tree cr6_form = TREE_VALUE (arglist);
6745 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
6746 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6747 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6748 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6749 enum machine_mode tmode = SImode;
6750 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6751 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6752 int cr6_form_int;
6753
6754 if (TREE_CODE (cr6_form) != INTEGER_CST)
6755 {
6756 error ("argument 1 of __builtin_altivec_predicate must be a constant");
6757 return const0_rtx;
6758 }
6759 else
6760 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
6761
6762 gcc_assert (mode0 == mode1);
6763
6764 /* If we have invalid arguments, bail out before generating bad rtl. */
6765 if (arg0 == error_mark_node || arg1 == error_mark_node)
6766 return const0_rtx;
6767
6768 if (target == 0
6769 || GET_MODE (target) != tmode
6770 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6771 target = gen_reg_rtx (tmode);
6772
6773 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6774 op0 = copy_to_mode_reg (mode0, op0);
6775 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6776 op1 = copy_to_mode_reg (mode1, op1);
6777
6778 scratch = gen_reg_rtx (mode0);
6779
6780 pat = GEN_FCN (icode) (scratch, op0, op1,
6781 gen_rtx_SYMBOL_REF (Pmode, opcode));
6782 if (! pat)
6783 return 0;
6784 emit_insn (pat);
6785
6786 /* The vec_any* and vec_all* predicates use the same opcodes for two
6787 different operations, but the bits in CR6 will be different
6788 depending on what information we want. So we have to play tricks
6789 with CR6 to get the right bits out.
6790
6791 If you think this is disgusting, look at the specs for the
6792 AltiVec predicates. */
6793
6794 switch (cr6_form_int)
6795 {
6796 case 0:
6797 emit_insn (gen_cr6_test_for_zero (target));
6798 break;
6799 case 1:
6800 emit_insn (gen_cr6_test_for_zero_reverse (target));
6801 break;
6802 case 2:
6803 emit_insn (gen_cr6_test_for_lt (target));
6804 break;
6805 case 3:
6806 emit_insn (gen_cr6_test_for_lt_reverse (target));
6807 break;
6808 default:
6809 error ("argument 1 of __builtin_altivec_predicate is out of range");
6810 break;
6811 }
6812
6813 return target;
6814 }
6815
6816 static rtx
altivec_expand_lv_builtin(enum insn_code icode,tree arglist,rtx target)6817 altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
6818 {
6819 rtx pat, addr;
6820 tree arg0 = TREE_VALUE (arglist);
6821 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6822 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6823 enum machine_mode mode0 = Pmode;
6824 enum machine_mode mode1 = Pmode;
6825 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6826 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6827
6828 if (icode == CODE_FOR_nothing)
6829 /* Builtin not supported on this processor. */
6830 return 0;
6831
6832 /* If we got invalid arguments bail out before generating bad rtl. */
6833 if (arg0 == error_mark_node || arg1 == error_mark_node)
6834 return const0_rtx;
6835
6836 if (target == 0
6837 || GET_MODE (target) != tmode
6838 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6839 target = gen_reg_rtx (tmode);
6840
6841 op1 = copy_to_mode_reg (mode1, op1);
6842
6843 if (op0 == const0_rtx)
6844 {
6845 addr = gen_rtx_MEM (tmode, op1);
6846 }
6847 else
6848 {
6849 op0 = copy_to_mode_reg (mode0, op0);
6850 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
6851 }
6852
6853 pat = GEN_FCN (icode) (target, addr);
6854
6855 if (! pat)
6856 return 0;
6857 emit_insn (pat);
6858
6859 return target;
6860 }
6861
6862 static rtx
spe_expand_stv_builtin(enum insn_code icode,tree arglist)6863 spe_expand_stv_builtin (enum insn_code icode, tree arglist)
6864 {
6865 tree arg0 = TREE_VALUE (arglist);
6866 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6867 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6868 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6869 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6870 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6871 rtx pat;
6872 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
6873 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
6874 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
6875
6876 /* Invalid arguments. Bail before doing anything stoopid! */
6877 if (arg0 == error_mark_node
6878 || arg1 == error_mark_node
6879 || arg2 == error_mark_node)
6880 return const0_rtx;
6881
6882 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
6883 op0 = copy_to_mode_reg (mode2, op0);
6884 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
6885 op1 = copy_to_mode_reg (mode0, op1);
6886 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
6887 op2 = copy_to_mode_reg (mode1, op2);
6888
6889 pat = GEN_FCN (icode) (op1, op2, op0);
6890 if (pat)
6891 emit_insn (pat);
6892 return NULL_RTX;
6893 }
6894
6895 static rtx
altivec_expand_stv_builtin(enum insn_code icode,tree arglist)6896 altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
6897 {
6898 tree arg0 = TREE_VALUE (arglist);
6899 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6900 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6901 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6902 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6903 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6904 rtx pat, addr;
6905 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6906 enum machine_mode mode1 = Pmode;
6907 enum machine_mode mode2 = Pmode;
6908
6909 /* Invalid arguments. Bail before doing anything stoopid! */
6910 if (arg0 == error_mark_node
6911 || arg1 == error_mark_node
6912 || arg2 == error_mark_node)
6913 return const0_rtx;
6914
6915 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
6916 op0 = copy_to_mode_reg (tmode, op0);
6917
6918 op2 = copy_to_mode_reg (mode2, op2);
6919
6920 if (op1 == const0_rtx)
6921 {
6922 addr = gen_rtx_MEM (tmode, op2);
6923 }
6924 else
6925 {
6926 op1 = copy_to_mode_reg (mode1, op1);
6927 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
6928 }
6929
6930 pat = GEN_FCN (icode) (addr, op0);
6931 if (pat)
6932 emit_insn (pat);
6933 return NULL_RTX;
6934 }
6935
6936 static rtx
rs6000_expand_ternop_builtin(enum insn_code icode,tree arglist,rtx target)6937 rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
6938 {
6939 rtx pat;
6940 tree arg0 = TREE_VALUE (arglist);
6941 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6942 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6943 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6944 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6945 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6946 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6947 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6948 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6949 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
6950
6951 if (icode == CODE_FOR_nothing)
6952 /* Builtin not supported on this processor. */
6953 return 0;
6954
6955 /* If we got invalid arguments bail out before generating bad rtl. */
6956 if (arg0 == error_mark_node
6957 || arg1 == error_mark_node
6958 || arg2 == error_mark_node)
6959 return const0_rtx;
6960
6961 if (icode == CODE_FOR_altivec_vsldoi_v4sf
6962 || icode == CODE_FOR_altivec_vsldoi_v4si
6963 || icode == CODE_FOR_altivec_vsldoi_v8hi
6964 || icode == CODE_FOR_altivec_vsldoi_v16qi)
6965 {
6966 /* Only allow 4-bit unsigned literals. */
6967 STRIP_NOPS (arg2);
6968 if (TREE_CODE (arg2) != INTEGER_CST
6969 || TREE_INT_CST_LOW (arg2) & ~0xf)
6970 {
6971 error ("argument 3 must be a 4-bit unsigned literal");
6972 return const0_rtx;
6973 }
6974 }
6975
6976 if (target == 0
6977 || GET_MODE (target) != tmode
6978 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6979 target = gen_reg_rtx (tmode);
6980
6981 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6982 op0 = copy_to_mode_reg (mode0, op0);
6983 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6984 op1 = copy_to_mode_reg (mode1, op1);
6985 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
6986 op2 = copy_to_mode_reg (mode2, op2);
6987
6988 pat = GEN_FCN (icode) (target, op0, op1, op2);
6989 if (! pat)
6990 return 0;
6991 emit_insn (pat);
6992
6993 return target;
6994 }
6995
6996 /* Expand the lvx builtins. */
6997 static rtx
altivec_expand_ld_builtin(tree exp,rtx target,bool * expandedp)6998 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
6999 {
7000 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7001 tree arglist = TREE_OPERAND (exp, 1);
7002 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7003 tree arg0;
7004 enum machine_mode tmode, mode0;
7005 rtx pat, op0;
7006 enum insn_code icode;
7007
7008 switch (fcode)
7009 {
7010 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
7011 icode = CODE_FOR_altivec_lvx_v16qi;
7012 break;
7013 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
7014 icode = CODE_FOR_altivec_lvx_v8hi;
7015 break;
7016 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
7017 icode = CODE_FOR_altivec_lvx_v4si;
7018 break;
7019 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
7020 icode = CODE_FOR_altivec_lvx_v4sf;
7021 break;
7022 default:
7023 *expandedp = false;
7024 return NULL_RTX;
7025 }
7026
7027 *expandedp = true;
7028
7029 arg0 = TREE_VALUE (arglist);
7030 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7031 tmode = insn_data[icode].operand[0].mode;
7032 mode0 = insn_data[icode].operand[1].mode;
7033
7034 if (target == 0
7035 || GET_MODE (target) != tmode
7036 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7037 target = gen_reg_rtx (tmode);
7038
7039 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7040 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7041
7042 pat = GEN_FCN (icode) (target, op0);
7043 if (! pat)
7044 return 0;
7045 emit_insn (pat);
7046 return target;
7047 }
7048
7049 /* Expand the stvx builtins. */
7050 static rtx
altivec_expand_st_builtin(tree exp,rtx target ATTRIBUTE_UNUSED,bool * expandedp)7051 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7052 bool *expandedp)
7053 {
7054 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7055 tree arglist = TREE_OPERAND (exp, 1);
7056 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7057 tree arg0, arg1;
7058 enum machine_mode mode0, mode1;
7059 rtx pat, op0, op1;
7060 enum insn_code icode;
7061
7062 switch (fcode)
7063 {
7064 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
7065 icode = CODE_FOR_altivec_stvx_v16qi;
7066 break;
7067 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
7068 icode = CODE_FOR_altivec_stvx_v8hi;
7069 break;
7070 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
7071 icode = CODE_FOR_altivec_stvx_v4si;
7072 break;
7073 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
7074 icode = CODE_FOR_altivec_stvx_v4sf;
7075 break;
7076 default:
7077 *expandedp = false;
7078 return NULL_RTX;
7079 }
7080
7081 arg0 = TREE_VALUE (arglist);
7082 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7083 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7084 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7085 mode0 = insn_data[icode].operand[0].mode;
7086 mode1 = insn_data[icode].operand[1].mode;
7087
7088 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7089 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7090 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7091 op1 = copy_to_mode_reg (mode1, op1);
7092
7093 pat = GEN_FCN (icode) (op0, op1);
7094 if (pat)
7095 emit_insn (pat);
7096
7097 *expandedp = true;
7098 return NULL_RTX;
7099 }
7100
7101 /* Expand the dst builtins. */
7102 static rtx
altivec_expand_dst_builtin(tree exp,rtx target ATTRIBUTE_UNUSED,bool * expandedp)7103 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7104 bool *expandedp)
7105 {
7106 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7107 tree arglist = TREE_OPERAND (exp, 1);
7108 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7109 tree arg0, arg1, arg2;
7110 enum machine_mode mode0, mode1, mode2;
7111 rtx pat, op0, op1, op2;
7112 struct builtin_description *d;
7113 size_t i;
7114
7115 *expandedp = false;
7116
7117 /* Handle DST variants. */
7118 d = (struct builtin_description *) bdesc_dst;
7119 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7120 if (d->code == fcode)
7121 {
7122 arg0 = TREE_VALUE (arglist);
7123 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7124 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7125 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7126 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7127 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
7128 mode0 = insn_data[d->icode].operand[0].mode;
7129 mode1 = insn_data[d->icode].operand[1].mode;
7130 mode2 = insn_data[d->icode].operand[2].mode;
7131
7132 /* Invalid arguments, bail out before generating bad rtl. */
7133 if (arg0 == error_mark_node
7134 || arg1 == error_mark_node
7135 || arg2 == error_mark_node)
7136 return const0_rtx;
7137
7138 *expandedp = true;
7139 STRIP_NOPS (arg2);
7140 if (TREE_CODE (arg2) != INTEGER_CST
7141 || TREE_INT_CST_LOW (arg2) & ~0x3)
7142 {
7143 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
7144 return const0_rtx;
7145 }
7146
7147 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
7148 op0 = copy_to_mode_reg (Pmode, op0);
7149 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7150 op1 = copy_to_mode_reg (mode1, op1);
7151
7152 pat = GEN_FCN (d->icode) (op0, op1, op2);
7153 if (pat != 0)
7154 emit_insn (pat);
7155
7156 return NULL_RTX;
7157 }
7158
7159 return NULL_RTX;
7160 }
7161
7162 /* Expand vec_init builtin. */
7163 static rtx
altivec_expand_vec_init_builtin(tree type,tree arglist,rtx target)7164 altivec_expand_vec_init_builtin (tree type, tree arglist, rtx target)
7165 {
7166 enum machine_mode tmode = TYPE_MODE (type);
7167 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7168 int i, n_elt = GET_MODE_NUNITS (tmode);
7169 rtvec v = rtvec_alloc (n_elt);
7170
7171 gcc_assert (VECTOR_MODE_P (tmode));
7172
7173 for (i = 0; i < n_elt; ++i, arglist = TREE_CHAIN (arglist))
7174 {
7175 rtx x = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
7176 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7177 }
7178
7179 gcc_assert (arglist == NULL);
7180
7181 if (!target || !register_operand (target, tmode))
7182 target = gen_reg_rtx (tmode);
7183
7184 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7185 return target;
7186 }
7187
7188 /* Return the integer constant in ARG. Constrain it to be in the range
7189 of the subparts of VEC_TYPE; issue an error if not. */
7190
7191 static int
get_element_number(tree vec_type,tree arg)7192 get_element_number (tree vec_type, tree arg)
7193 {
7194 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7195
7196 if (!host_integerp (arg, 1)
7197 || (elt = tree_low_cst (arg, 1), elt > max))
7198 {
7199 error ("selector must be an integer constant in the range 0..%wi", max);
7200 return 0;
7201 }
7202
7203 return elt;
7204 }
7205
7206 /* Expand vec_set builtin. */
7207 static rtx
altivec_expand_vec_set_builtin(tree arglist)7208 altivec_expand_vec_set_builtin (tree arglist)
7209 {
7210 enum machine_mode tmode, mode1;
7211 tree arg0, arg1, arg2;
7212 int elt;
7213 rtx op0, op1;
7214
7215 arg0 = TREE_VALUE (arglist);
7216 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7217 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7218
7219 tmode = TYPE_MODE (TREE_TYPE (arg0));
7220 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7221 gcc_assert (VECTOR_MODE_P (tmode));
7222
7223 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7224 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7225 elt = get_element_number (TREE_TYPE (arg0), arg2);
7226
7227 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7228 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7229
7230 op0 = force_reg (tmode, op0);
7231 op1 = force_reg (mode1, op1);
7232
7233 rs6000_expand_vector_set (op0, op1, elt);
7234
7235 return op0;
7236 }
7237
7238 /* Expand vec_ext builtin. */
7239 static rtx
altivec_expand_vec_ext_builtin(tree arglist,rtx target)7240 altivec_expand_vec_ext_builtin (tree arglist, rtx target)
7241 {
7242 enum machine_mode tmode, mode0;
7243 tree arg0, arg1;
7244 int elt;
7245 rtx op0;
7246
7247 arg0 = TREE_VALUE (arglist);
7248 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7249
7250 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7251 elt = get_element_number (TREE_TYPE (arg0), arg1);
7252
7253 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7254 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7255 gcc_assert (VECTOR_MODE_P (mode0));
7256
7257 op0 = force_reg (mode0, op0);
7258
7259 if (optimize || !target || !register_operand (target, tmode))
7260 target = gen_reg_rtx (tmode);
7261
7262 rs6000_expand_vector_extract (target, op0, elt);
7263
7264 return target;
7265 }
7266
7267 /* Expand the builtin in EXP and store the result in TARGET. Store
7268 true in *EXPANDEDP if we found a builtin to expand. */
7269 static rtx
altivec_expand_builtin(tree exp,rtx target,bool * expandedp)7270 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
7271 {
7272 struct builtin_description *d;
7273 struct builtin_description_predicates *dp;
7274 size_t i;
7275 enum insn_code icode;
7276 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7277 tree arglist = TREE_OPERAND (exp, 1);
7278 tree arg0;
7279 rtx op0, pat;
7280 enum machine_mode tmode, mode0;
7281 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7282
7283 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7284 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7285 {
7286 *expandedp = true;
7287 error ("unresolved overload for Altivec builtin %qF", fndecl);
7288 return const0_rtx;
7289 }
7290
7291 target = altivec_expand_ld_builtin (exp, target, expandedp);
7292 if (*expandedp)
7293 return target;
7294
7295 target = altivec_expand_st_builtin (exp, target, expandedp);
7296 if (*expandedp)
7297 return target;
7298
7299 target = altivec_expand_dst_builtin (exp, target, expandedp);
7300 if (*expandedp)
7301 return target;
7302
7303 *expandedp = true;
7304
7305 switch (fcode)
7306 {
7307 case ALTIVEC_BUILTIN_STVX:
7308 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
7309 case ALTIVEC_BUILTIN_STVEBX:
7310 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
7311 case ALTIVEC_BUILTIN_STVEHX:
7312 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
7313 case ALTIVEC_BUILTIN_STVEWX:
7314 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
7315 case ALTIVEC_BUILTIN_STVXL:
7316 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
7317
7318 case ALTIVEC_BUILTIN_MFVSCR:
7319 icode = CODE_FOR_altivec_mfvscr;
7320 tmode = insn_data[icode].operand[0].mode;
7321
7322 if (target == 0
7323 || GET_MODE (target) != tmode
7324 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7325 target = gen_reg_rtx (tmode);
7326
7327 pat = GEN_FCN (icode) (target);
7328 if (! pat)
7329 return 0;
7330 emit_insn (pat);
7331 return target;
7332
7333 case ALTIVEC_BUILTIN_MTVSCR:
7334 icode = CODE_FOR_altivec_mtvscr;
7335 arg0 = TREE_VALUE (arglist);
7336 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7337 mode0 = insn_data[icode].operand[0].mode;
7338
7339 /* If we got invalid arguments bail out before generating bad rtl. */
7340 if (arg0 == error_mark_node)
7341 return const0_rtx;
7342
7343 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7344 op0 = copy_to_mode_reg (mode0, op0);
7345
7346 pat = GEN_FCN (icode) (op0);
7347 if (pat)
7348 emit_insn (pat);
7349 return NULL_RTX;
7350
7351 case ALTIVEC_BUILTIN_DSSALL:
7352 emit_insn (gen_altivec_dssall ());
7353 return NULL_RTX;
7354
7355 case ALTIVEC_BUILTIN_DSS:
7356 icode = CODE_FOR_altivec_dss;
7357 arg0 = TREE_VALUE (arglist);
7358 STRIP_NOPS (arg0);
7359 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7360 mode0 = insn_data[icode].operand[0].mode;
7361
7362 /* If we got invalid arguments bail out before generating bad rtl. */
7363 if (arg0 == error_mark_node)
7364 return const0_rtx;
7365
7366 if (TREE_CODE (arg0) != INTEGER_CST
7367 || TREE_INT_CST_LOW (arg0) & ~0x3)
7368 {
7369 error ("argument to dss must be a 2-bit unsigned literal");
7370 return const0_rtx;
7371 }
7372
7373 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7374 op0 = copy_to_mode_reg (mode0, op0);
7375
7376 emit_insn (gen_altivec_dss (op0));
7377 return NULL_RTX;
7378
7379 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7380 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7381 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7382 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7383 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
7384
7385 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7386 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7387 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7388 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7389 return altivec_expand_vec_set_builtin (arglist);
7390
7391 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7392 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7393 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7394 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7395 return altivec_expand_vec_ext_builtin (arglist, target);
7396
7397 default:
7398 break;
7399 /* Fall through. */
7400 }
7401
7402 /* Expand abs* operations. */
7403 d = (struct builtin_description *) bdesc_abs;
7404 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
7405 if (d->code == fcode)
7406 return altivec_expand_abs_builtin (d->icode, arglist, target);
7407
7408 /* Expand the AltiVec predicates. */
7409 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
7410 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
7411 if (dp->code == fcode)
7412 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7413 arglist, target);
7414
7415 /* LV* are funky. We initialized them differently. */
7416 switch (fcode)
7417 {
7418 case ALTIVEC_BUILTIN_LVSL:
7419 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
7420 arglist, target);
7421 case ALTIVEC_BUILTIN_LVSR:
7422 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
7423 arglist, target);
7424 case ALTIVEC_BUILTIN_LVEBX:
7425 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
7426 arglist, target);
7427 case ALTIVEC_BUILTIN_LVEHX:
7428 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
7429 arglist, target);
7430 case ALTIVEC_BUILTIN_LVEWX:
7431 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
7432 arglist, target);
7433 case ALTIVEC_BUILTIN_LVXL:
7434 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
7435 arglist, target);
7436 case ALTIVEC_BUILTIN_LVX:
7437 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
7438 arglist, target);
7439 default:
7440 break;
7441 /* Fall through. */
7442 }
7443
7444 *expandedp = false;
7445 return NULL_RTX;
7446 }
7447
7448 /* Binops that need to be initialized manually, but can be expanded
7449 automagically by rs6000_expand_binop_builtin. */
7450 static struct builtin_description bdesc_2arg_spe[] =
7451 {
7452 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7453 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7454 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7455 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7456 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7457 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7458 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7459 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7460 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7461 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7462 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7463 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7464 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7465 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7466 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7467 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7468 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7469 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7470 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7471 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7472 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7473 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7474 };
7475
7476 /* Expand the builtin in EXP and store the result in TARGET. Store
7477 true in *EXPANDEDP if we found a builtin to expand.
7478
7479 This expands the SPE builtins that are not simple unary and binary
7480 operations. */
7481 static rtx
spe_expand_builtin(tree exp,rtx target,bool * expandedp)7482 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
7483 {
7484 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7485 tree arglist = TREE_OPERAND (exp, 1);
7486 tree arg1, arg0;
7487 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7488 enum insn_code icode;
7489 enum machine_mode tmode, mode0;
7490 rtx pat, op0;
7491 struct builtin_description *d;
7492 size_t i;
7493
7494 *expandedp = true;
7495
7496 /* Syntax check for a 5-bit unsigned immediate. */
7497 switch (fcode)
7498 {
7499 case SPE_BUILTIN_EVSTDD:
7500 case SPE_BUILTIN_EVSTDH:
7501 case SPE_BUILTIN_EVSTDW:
7502 case SPE_BUILTIN_EVSTWHE:
7503 case SPE_BUILTIN_EVSTWHO:
7504 case SPE_BUILTIN_EVSTWWE:
7505 case SPE_BUILTIN_EVSTWWO:
7506 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7507 if (TREE_CODE (arg1) != INTEGER_CST
7508 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7509 {
7510 error ("argument 2 must be a 5-bit unsigned literal");
7511 return const0_rtx;
7512 }
7513 break;
7514 default:
7515 break;
7516 }
7517
7518 /* The evsplat*i instructions are not quite generic. */
7519 switch (fcode)
7520 {
7521 case SPE_BUILTIN_EVSPLATFI:
7522 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7523 arglist, target);
7524 case SPE_BUILTIN_EVSPLATI:
7525 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7526 arglist, target);
7527 default:
7528 break;
7529 }
7530
7531 d = (struct builtin_description *) bdesc_2arg_spe;
7532 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7533 if (d->code == fcode)
7534 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7535
7536 d = (struct builtin_description *) bdesc_spe_predicates;
7537 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7538 if (d->code == fcode)
7539 return spe_expand_predicate_builtin (d->icode, arglist, target);
7540
7541 d = (struct builtin_description *) bdesc_spe_evsel;
7542 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7543 if (d->code == fcode)
7544 return spe_expand_evsel_builtin (d->icode, arglist, target);
7545
7546 switch (fcode)
7547 {
7548 case SPE_BUILTIN_EVSTDDX:
7549 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
7550 case SPE_BUILTIN_EVSTDHX:
7551 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
7552 case SPE_BUILTIN_EVSTDWX:
7553 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
7554 case SPE_BUILTIN_EVSTWHEX:
7555 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
7556 case SPE_BUILTIN_EVSTWHOX:
7557 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
7558 case SPE_BUILTIN_EVSTWWEX:
7559 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
7560 case SPE_BUILTIN_EVSTWWOX:
7561 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
7562 case SPE_BUILTIN_EVSTDD:
7563 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
7564 case SPE_BUILTIN_EVSTDH:
7565 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
7566 case SPE_BUILTIN_EVSTDW:
7567 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
7568 case SPE_BUILTIN_EVSTWHE:
7569 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
7570 case SPE_BUILTIN_EVSTWHO:
7571 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
7572 case SPE_BUILTIN_EVSTWWE:
7573 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
7574 case SPE_BUILTIN_EVSTWWO:
7575 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
7576 case SPE_BUILTIN_MFSPEFSCR:
7577 icode = CODE_FOR_spe_mfspefscr;
7578 tmode = insn_data[icode].operand[0].mode;
7579
7580 if (target == 0
7581 || GET_MODE (target) != tmode
7582 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7583 target = gen_reg_rtx (tmode);
7584
7585 pat = GEN_FCN (icode) (target);
7586 if (! pat)
7587 return 0;
7588 emit_insn (pat);
7589 return target;
7590 case SPE_BUILTIN_MTSPEFSCR:
7591 icode = CODE_FOR_spe_mtspefscr;
7592 arg0 = TREE_VALUE (arglist);
7593 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7594 mode0 = insn_data[icode].operand[0].mode;
7595
7596 if (arg0 == error_mark_node)
7597 return const0_rtx;
7598
7599 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7600 op0 = copy_to_mode_reg (mode0, op0);
7601
7602 pat = GEN_FCN (icode) (op0);
7603 if (pat)
7604 emit_insn (pat);
7605 return NULL_RTX;
7606 default:
7607 break;
7608 }
7609
7610 *expandedp = false;
7611 return NULL_RTX;
7612 }
7613
7614 static rtx
spe_expand_predicate_builtin(enum insn_code icode,tree arglist,rtx target)7615 spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
7616 {
7617 rtx pat, scratch, tmp;
7618 tree form = TREE_VALUE (arglist);
7619 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7620 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7621 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7622 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7623 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7624 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7625 int form_int;
7626 enum rtx_code code;
7627
7628 if (TREE_CODE (form) != INTEGER_CST)
7629 {
7630 error ("argument 1 of __builtin_spe_predicate must be a constant");
7631 return const0_rtx;
7632 }
7633 else
7634 form_int = TREE_INT_CST_LOW (form);
7635
7636 gcc_assert (mode0 == mode1);
7637
7638 if (arg0 == error_mark_node || arg1 == error_mark_node)
7639 return const0_rtx;
7640
7641 if (target == 0
7642 || GET_MODE (target) != SImode
7643 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7644 target = gen_reg_rtx (SImode);
7645
7646 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7647 op0 = copy_to_mode_reg (mode0, op0);
7648 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7649 op1 = copy_to_mode_reg (mode1, op1);
7650
7651 scratch = gen_reg_rtx (CCmode);
7652
7653 pat = GEN_FCN (icode) (scratch, op0, op1);
7654 if (! pat)
7655 return const0_rtx;
7656 emit_insn (pat);
7657
7658 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7659 _lower_. We use one compare, but look in different bits of the
7660 CR for each variant.
7661
7662 There are 2 elements in each SPE simd type (upper/lower). The CR
7663 bits are set as follows:
7664
7665 BIT0 | BIT 1 | BIT 2 | BIT 3
7666 U | L | (U | L) | (U & L)
7667
7668 So, for an "all" relationship, BIT 3 would be set.
7669 For an "any" relationship, BIT 2 would be set. Etc.
7670
7671 Following traditional nomenclature, these bits map to:
7672
7673 BIT0 | BIT 1 | BIT 2 | BIT 3
7674 LT | GT | EQ | OV
7675
7676 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7677 */
7678
7679 switch (form_int)
7680 {
7681 /* All variant. OV bit. */
7682 case 0:
7683 /* We need to get to the OV bit, which is the ORDERED bit. We
7684 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7685 that's ugly and will make validate_condition_mode die.
7686 So let's just use another pattern. */
7687 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
7688 return target;
7689 /* Any variant. EQ bit. */
7690 case 1:
7691 code = EQ;
7692 break;
7693 /* Upper variant. LT bit. */
7694 case 2:
7695 code = LT;
7696 break;
7697 /* Lower variant. GT bit. */
7698 case 3:
7699 code = GT;
7700 break;
7701 default:
7702 error ("argument 1 of __builtin_spe_predicate is out of range");
7703 return const0_rtx;
7704 }
7705
7706 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
7707 emit_move_insn (target, tmp);
7708
7709 return target;
7710 }
7711
7712 /* The evsel builtins look like this:
7713
7714 e = __builtin_spe_evsel_OP (a, b, c, d);
7715
7716 and work like this:
7717
7718 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7719 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7720 */
7721
7722 static rtx
spe_expand_evsel_builtin(enum insn_code icode,tree arglist,rtx target)7723 spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
7724 {
7725 rtx pat, scratch;
7726 tree arg0 = TREE_VALUE (arglist);
7727 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7728 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7729 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
7730 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7731 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7732 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
7733 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
7734 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7735 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7736
7737 gcc_assert (mode0 == mode1);
7738
7739 if (arg0 == error_mark_node || arg1 == error_mark_node
7740 || arg2 == error_mark_node || arg3 == error_mark_node)
7741 return const0_rtx;
7742
7743 if (target == 0
7744 || GET_MODE (target) != mode0
7745 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
7746 target = gen_reg_rtx (mode0);
7747
7748 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7749 op0 = copy_to_mode_reg (mode0, op0);
7750 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7751 op1 = copy_to_mode_reg (mode0, op1);
7752 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7753 op2 = copy_to_mode_reg (mode0, op2);
7754 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
7755 op3 = copy_to_mode_reg (mode0, op3);
7756
7757 /* Generate the compare. */
7758 scratch = gen_reg_rtx (CCmode);
7759 pat = GEN_FCN (icode) (scratch, op0, op1);
7760 if (! pat)
7761 return const0_rtx;
7762 emit_insn (pat);
7763
7764 if (mode0 == V2SImode)
7765 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
7766 else
7767 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
7768
7769 return target;
7770 }
7771
7772 /* Expand an expression EXP that calls a built-in function,
7773 with result going to TARGET if that's convenient
7774 (and in mode MODE if that's convenient).
7775 SUBTARGET may be used as the target for computing one of EXP's operands.
7776 IGNORE is nonzero if the value is to be ignored. */
7777
7778 static rtx
rs6000_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)7779 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
7780 enum machine_mode mode ATTRIBUTE_UNUSED,
7781 int ignore ATTRIBUTE_UNUSED)
7782 {
7783 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7784 tree arglist = TREE_OPERAND (exp, 1);
7785 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7786 struct builtin_description *d;
7787 size_t i;
7788 rtx ret;
7789 bool success;
7790
7791 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
7792 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7793 {
7794 int icode = (int) CODE_FOR_altivec_lvsr;
7795 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7796 enum machine_mode mode = insn_data[icode].operand[1].mode;
7797 tree arg;
7798 rtx op, addr, pat;
7799
7800 gcc_assert (TARGET_ALTIVEC);
7801
7802 arg = TREE_VALUE (arglist);
7803 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
7804 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
7805 addr = memory_address (mode, op);
7806 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7807 op = addr;
7808 else
7809 {
7810 /* For the load case need to negate the address. */
7811 op = gen_reg_rtx (GET_MODE (addr));
7812 emit_insn (gen_rtx_SET (VOIDmode, op,
7813 gen_rtx_NEG (GET_MODE (addr), addr)));
7814 }
7815 op = gen_rtx_MEM (mode, op);
7816
7817 if (target == 0
7818 || GET_MODE (target) != tmode
7819 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7820 target = gen_reg_rtx (tmode);
7821
7822 /*pat = gen_altivec_lvsr (target, op);*/
7823 pat = GEN_FCN (icode) (target, op);
7824 if (!pat)
7825 return 0;
7826 emit_insn (pat);
7827
7828 return target;
7829 }
7830
7831 if (TARGET_ALTIVEC)
7832 {
7833 ret = altivec_expand_builtin (exp, target, &success);
7834
7835 if (success)
7836 return ret;
7837 }
7838 if (TARGET_SPE)
7839 {
7840 ret = spe_expand_builtin (exp, target, &success);
7841
7842 if (success)
7843 return ret;
7844 }
7845
7846 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
7847
7848 /* Handle simple unary operations. */
7849 d = (struct builtin_description *) bdesc_1arg;
7850 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
7851 if (d->code == fcode)
7852 return rs6000_expand_unop_builtin (d->icode, arglist, target);
7853
7854 /* Handle simple binary operations. */
7855 d = (struct builtin_description *) bdesc_2arg;
7856 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
7857 if (d->code == fcode)
7858 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7859
7860 /* Handle simple ternary operations. */
7861 d = (struct builtin_description *) bdesc_3arg;
7862 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
7863 if (d->code == fcode)
7864 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
7865
7866 gcc_unreachable ();
7867 }
7868
7869 static tree
build_opaque_vector_type(tree node,int nunits)7870 build_opaque_vector_type (tree node, int nunits)
7871 {
7872 node = copy_node (node);
7873 TYPE_MAIN_VARIANT (node) = node;
7874 return build_vector_type (node, nunits);
7875 }
7876
7877 static void
rs6000_init_builtins(void)7878 rs6000_init_builtins (void)
7879 {
7880 V2SI_type_node = build_vector_type (intSI_type_node, 2);
7881 V2SF_type_node = build_vector_type (float_type_node, 2);
7882 V4HI_type_node = build_vector_type (intHI_type_node, 4);
7883 V4SI_type_node = build_vector_type (intSI_type_node, 4);
7884 V4SF_type_node = build_vector_type (float_type_node, 4);
7885 V8HI_type_node = build_vector_type (intHI_type_node, 8);
7886 V16QI_type_node = build_vector_type (intQI_type_node, 16);
7887
7888 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
7889 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
7890 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
7891
7892 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
7893 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
7894 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
7895 opaque_V4SI_type_node = copy_node (V4SI_type_node);
7896
7897 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7898 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7899 'vector unsigned short'. */
7900
7901 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
7902 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
7903 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
7904 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
7905
7906 long_integer_type_internal_node = long_integer_type_node;
7907 long_unsigned_type_internal_node = long_unsigned_type_node;
7908 intQI_type_internal_node = intQI_type_node;
7909 uintQI_type_internal_node = unsigned_intQI_type_node;
7910 intHI_type_internal_node = intHI_type_node;
7911 uintHI_type_internal_node = unsigned_intHI_type_node;
7912 intSI_type_internal_node = intSI_type_node;
7913 uintSI_type_internal_node = unsigned_intSI_type_node;
7914 float_type_internal_node = float_type_node;
7915 void_type_internal_node = void_type_node;
7916
7917 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7918 get_identifier ("__bool char"),
7919 bool_char_type_node));
7920 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7921 get_identifier ("__bool short"),
7922 bool_short_type_node));
7923 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7924 get_identifier ("__bool int"),
7925 bool_int_type_node));
7926 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7927 get_identifier ("__pixel"),
7928 pixel_type_node));
7929
7930 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
7931 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
7932 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
7933 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
7934
7935 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7936 get_identifier ("__vector unsigned char"),
7937 unsigned_V16QI_type_node));
7938 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7939 get_identifier ("__vector signed char"),
7940 V16QI_type_node));
7941 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7942 get_identifier ("__vector __bool char"),
7943 bool_V16QI_type_node));
7944
7945 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7946 get_identifier ("__vector unsigned short"),
7947 unsigned_V8HI_type_node));
7948 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7949 get_identifier ("__vector signed short"),
7950 V8HI_type_node));
7951 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7952 get_identifier ("__vector __bool short"),
7953 bool_V8HI_type_node));
7954
7955 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7956 get_identifier ("__vector unsigned int"),
7957 unsigned_V4SI_type_node));
7958 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7959 get_identifier ("__vector signed int"),
7960 V4SI_type_node));
7961 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7962 get_identifier ("__vector __bool int"),
7963 bool_V4SI_type_node));
7964
7965 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7966 get_identifier ("__vector float"),
7967 V4SF_type_node));
7968 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7969 get_identifier ("__vector __pixel"),
7970 pixel_V8HI_type_node));
7971
7972 if (TARGET_SPE)
7973 spe_init_builtins ();
7974 if (TARGET_ALTIVEC)
7975 altivec_init_builtins ();
7976 if (TARGET_ALTIVEC || TARGET_SPE)
7977 rs6000_common_init_builtins ();
7978
7979 #if TARGET_XCOFF
7980 /* AIX libm provides clog as __clog. */
7981 if (built_in_decls [BUILT_IN_CLOG])
7982 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
7983 #endif
7984 }
7985
7986 /* Search through a set of builtins and enable the mask bits.
7987 DESC is an array of builtins.
7988 SIZE is the total number of builtins.
7989 START is the builtin enum at which to start.
7990 END is the builtin enum at which to end. */
7991 static void
enable_mask_for_builtins(struct builtin_description * desc,int size,enum rs6000_builtins start,enum rs6000_builtins end)7992 enable_mask_for_builtins (struct builtin_description *desc, int size,
7993 enum rs6000_builtins start,
7994 enum rs6000_builtins end)
7995 {
7996 int i;
7997
7998 for (i = 0; i < size; ++i)
7999 if (desc[i].code == start)
8000 break;
8001
8002 if (i == size)
8003 return;
8004
8005 for (; i < size; ++i)
8006 {
8007 /* Flip all the bits on. */
8008 desc[i].mask = target_flags;
8009 if (desc[i].code == end)
8010 break;
8011 }
8012 }
8013
8014 static void
spe_init_builtins(void)8015 spe_init_builtins (void)
8016 {
8017 tree endlink = void_list_node;
8018 tree puint_type_node = build_pointer_type (unsigned_type_node);
8019 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
8020 struct builtin_description *d;
8021 size_t i;
8022
8023 tree v2si_ftype_4_v2si
8024 = build_function_type
8025 (opaque_V2SI_type_node,
8026 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8027 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8028 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8029 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8030 endlink)))));
8031
8032 tree v2sf_ftype_4_v2sf
8033 = build_function_type
8034 (opaque_V2SF_type_node,
8035 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8036 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8037 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8038 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8039 endlink)))));
8040
8041 tree int_ftype_int_v2si_v2si
8042 = build_function_type
8043 (integer_type_node,
8044 tree_cons (NULL_TREE, integer_type_node,
8045 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8046 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8047 endlink))));
8048
8049 tree int_ftype_int_v2sf_v2sf
8050 = build_function_type
8051 (integer_type_node,
8052 tree_cons (NULL_TREE, integer_type_node,
8053 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8054 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8055 endlink))));
8056
8057 tree void_ftype_v2si_puint_int
8058 = build_function_type (void_type_node,
8059 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8060 tree_cons (NULL_TREE, puint_type_node,
8061 tree_cons (NULL_TREE,
8062 integer_type_node,
8063 endlink))));
8064
8065 tree void_ftype_v2si_puint_char
8066 = build_function_type (void_type_node,
8067 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8068 tree_cons (NULL_TREE, puint_type_node,
8069 tree_cons (NULL_TREE,
8070 char_type_node,
8071 endlink))));
8072
8073 tree void_ftype_v2si_pv2si_int
8074 = build_function_type (void_type_node,
8075 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8076 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8077 tree_cons (NULL_TREE,
8078 integer_type_node,
8079 endlink))));
8080
8081 tree void_ftype_v2si_pv2si_char
8082 = build_function_type (void_type_node,
8083 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8084 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8085 tree_cons (NULL_TREE,
8086 char_type_node,
8087 endlink))));
8088
8089 tree void_ftype_int
8090 = build_function_type (void_type_node,
8091 tree_cons (NULL_TREE, integer_type_node, endlink));
8092
8093 tree int_ftype_void
8094 = build_function_type (integer_type_node, endlink);
8095
8096 tree v2si_ftype_pv2si_int
8097 = build_function_type (opaque_V2SI_type_node,
8098 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8099 tree_cons (NULL_TREE, integer_type_node,
8100 endlink)));
8101
8102 tree v2si_ftype_puint_int
8103 = build_function_type (opaque_V2SI_type_node,
8104 tree_cons (NULL_TREE, puint_type_node,
8105 tree_cons (NULL_TREE, integer_type_node,
8106 endlink)));
8107
8108 tree v2si_ftype_pushort_int
8109 = build_function_type (opaque_V2SI_type_node,
8110 tree_cons (NULL_TREE, pushort_type_node,
8111 tree_cons (NULL_TREE, integer_type_node,
8112 endlink)));
8113
8114 tree v2si_ftype_signed_char
8115 = build_function_type (opaque_V2SI_type_node,
8116 tree_cons (NULL_TREE, signed_char_type_node,
8117 endlink));
8118
8119 /* The initialization of the simple binary and unary builtins is
8120 done in rs6000_common_init_builtins, but we have to enable the
8121 mask bits here manually because we have run out of `target_flags'
8122 bits. We really need to redesign this mask business. */
8123
8124 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
8125 ARRAY_SIZE (bdesc_2arg),
8126 SPE_BUILTIN_EVADDW,
8127 SPE_BUILTIN_EVXOR);
8128 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
8129 ARRAY_SIZE (bdesc_1arg),
8130 SPE_BUILTIN_EVABS,
8131 SPE_BUILTIN_EVSUBFUSIAAW);
8132 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
8133 ARRAY_SIZE (bdesc_spe_predicates),
8134 SPE_BUILTIN_EVCMPEQ,
8135 SPE_BUILTIN_EVFSTSTLT);
8136 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
8137 ARRAY_SIZE (bdesc_spe_evsel),
8138 SPE_BUILTIN_EVSEL_CMPGTS,
8139 SPE_BUILTIN_EVSEL_FSTSTEQ);
8140
8141 (*lang_hooks.decls.pushdecl)
8142 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
8143 opaque_V2SI_type_node));
8144
8145 /* Initialize irregular SPE builtins. */
8146
8147 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
8148 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
8149 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
8150 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
8151 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8152 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8153 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8154 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8155 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8156 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8157 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8158 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8159 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8160 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8161 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8162 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
8163 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8164 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
8165
8166 /* Loads. */
8167 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8168 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8169 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8170 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8171 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8172 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8173 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8174 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8175 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8176 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8177 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8178 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8179 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8180 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8181 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8182 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8183 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8184 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8185 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8186 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8187 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8188 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8189
8190 /* Predicates. */
8191 d = (struct builtin_description *) bdesc_spe_predicates;
8192 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8193 {
8194 tree type;
8195
8196 switch (insn_data[d->icode].operand[1].mode)
8197 {
8198 case V2SImode:
8199 type = int_ftype_int_v2si_v2si;
8200 break;
8201 case V2SFmode:
8202 type = int_ftype_int_v2sf_v2sf;
8203 break;
8204 default:
8205 gcc_unreachable ();
8206 }
8207
8208 def_builtin (d->mask, d->name, type, d->code);
8209 }
8210
8211 /* Evsel predicates. */
8212 d = (struct builtin_description *) bdesc_spe_evsel;
8213 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8214 {
8215 tree type;
8216
8217 switch (insn_data[d->icode].operand[1].mode)
8218 {
8219 case V2SImode:
8220 type = v2si_ftype_4_v2si;
8221 break;
8222 case V2SFmode:
8223 type = v2sf_ftype_4_v2sf;
8224 break;
8225 default:
8226 gcc_unreachable ();
8227 }
8228
8229 def_builtin (d->mask, d->name, type, d->code);
8230 }
8231 }
8232
8233 static void
altivec_init_builtins(void)8234 altivec_init_builtins (void)
8235 {
8236 struct builtin_description *d;
8237 struct builtin_description_predicates *dp;
8238 size_t i;
8239 tree ftype;
8240
8241 tree pfloat_type_node = build_pointer_type (float_type_node);
8242 tree pint_type_node = build_pointer_type (integer_type_node);
8243 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8244 tree pchar_type_node = build_pointer_type (char_type_node);
8245
8246 tree pvoid_type_node = build_pointer_type (void_type_node);
8247
8248 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8249 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8250 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8251 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8252
8253 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8254
8255 tree int_ftype_opaque
8256 = build_function_type_list (integer_type_node,
8257 opaque_V4SI_type_node, NULL_TREE);
8258
8259 tree opaque_ftype_opaque_int
8260 = build_function_type_list (opaque_V4SI_type_node,
8261 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8262 tree opaque_ftype_opaque_opaque_int
8263 = build_function_type_list (opaque_V4SI_type_node,
8264 opaque_V4SI_type_node, opaque_V4SI_type_node,
8265 integer_type_node, NULL_TREE);
8266 tree int_ftype_int_opaque_opaque
8267 = build_function_type_list (integer_type_node,
8268 integer_type_node, opaque_V4SI_type_node,
8269 opaque_V4SI_type_node, NULL_TREE);
8270 tree int_ftype_int_v4si_v4si
8271 = build_function_type_list (integer_type_node,
8272 integer_type_node, V4SI_type_node,
8273 V4SI_type_node, NULL_TREE);
8274 tree v4sf_ftype_pcfloat
8275 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
8276 tree void_ftype_pfloat_v4sf
8277 = build_function_type_list (void_type_node,
8278 pfloat_type_node, V4SF_type_node, NULL_TREE);
8279 tree v4si_ftype_pcint
8280 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8281 tree void_ftype_pint_v4si
8282 = build_function_type_list (void_type_node,
8283 pint_type_node, V4SI_type_node, NULL_TREE);
8284 tree v8hi_ftype_pcshort
8285 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
8286 tree void_ftype_pshort_v8hi
8287 = build_function_type_list (void_type_node,
8288 pshort_type_node, V8HI_type_node, NULL_TREE);
8289 tree v16qi_ftype_pcchar
8290 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
8291 tree void_ftype_pchar_v16qi
8292 = build_function_type_list (void_type_node,
8293 pchar_type_node, V16QI_type_node, NULL_TREE);
8294 tree void_ftype_v4si
8295 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
8296 tree v8hi_ftype_void
8297 = build_function_type (V8HI_type_node, void_list_node);
8298 tree void_ftype_void
8299 = build_function_type (void_type_node, void_list_node);
8300 tree void_ftype_int
8301 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
8302
8303 tree opaque_ftype_long_pcvoid
8304 = build_function_type_list (opaque_V4SI_type_node,
8305 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8306 tree v16qi_ftype_long_pcvoid
8307 = build_function_type_list (V16QI_type_node,
8308 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8309 tree v8hi_ftype_long_pcvoid
8310 = build_function_type_list (V8HI_type_node,
8311 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8312 tree v4si_ftype_long_pcvoid
8313 = build_function_type_list (V4SI_type_node,
8314 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8315
8316 tree void_ftype_opaque_long_pvoid
8317 = build_function_type_list (void_type_node,
8318 opaque_V4SI_type_node, long_integer_type_node,
8319 pvoid_type_node, NULL_TREE);
8320 tree void_ftype_v4si_long_pvoid
8321 = build_function_type_list (void_type_node,
8322 V4SI_type_node, long_integer_type_node,
8323 pvoid_type_node, NULL_TREE);
8324 tree void_ftype_v16qi_long_pvoid
8325 = build_function_type_list (void_type_node,
8326 V16QI_type_node, long_integer_type_node,
8327 pvoid_type_node, NULL_TREE);
8328 tree void_ftype_v8hi_long_pvoid
8329 = build_function_type_list (void_type_node,
8330 V8HI_type_node, long_integer_type_node,
8331 pvoid_type_node, NULL_TREE);
8332 tree int_ftype_int_v8hi_v8hi
8333 = build_function_type_list (integer_type_node,
8334 integer_type_node, V8HI_type_node,
8335 V8HI_type_node, NULL_TREE);
8336 tree int_ftype_int_v16qi_v16qi
8337 = build_function_type_list (integer_type_node,
8338 integer_type_node, V16QI_type_node,
8339 V16QI_type_node, NULL_TREE);
8340 tree int_ftype_int_v4sf_v4sf
8341 = build_function_type_list (integer_type_node,
8342 integer_type_node, V4SF_type_node,
8343 V4SF_type_node, NULL_TREE);
8344 tree v4si_ftype_v4si
8345 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8346 tree v8hi_ftype_v8hi
8347 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8348 tree v16qi_ftype_v16qi
8349 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8350 tree v4sf_ftype_v4sf
8351 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8352 tree void_ftype_pcvoid_int_int
8353 = build_function_type_list (void_type_node,
8354 pcvoid_type_node, integer_type_node,
8355 integer_type_node, NULL_TREE);
8356
8357 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8358 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8359 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8360 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8361 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8362 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8363 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8364 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8365 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8366 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8367 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8368 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8369 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8370 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8371 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8372 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
8373 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8374 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8375 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
8376 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
8377 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8378 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8379 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8380 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8381 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8382 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8383 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8384 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8385 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8386 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8387 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8388 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
8389 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8390 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8391 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8392 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8393 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8394 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8395 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8396 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8397 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8398 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8399 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8400 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8401 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8402 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8403
8404 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8405
8406 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8407 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8408 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8409 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8410 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8411 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8412 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8413 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8414 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8415 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8416
8417 /* Add the DST variants. */
8418 d = (struct builtin_description *) bdesc_dst;
8419 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8420 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
8421
8422 /* Initialize the predicates. */
8423 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8424 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8425 {
8426 enum machine_mode mode1;
8427 tree type;
8428 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8429 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8430
8431 if (is_overloaded)
8432 mode1 = VOIDmode;
8433 else
8434 mode1 = insn_data[dp->icode].operand[1].mode;
8435
8436 switch (mode1)
8437 {
8438 case VOIDmode:
8439 type = int_ftype_int_opaque_opaque;
8440 break;
8441 case V4SImode:
8442 type = int_ftype_int_v4si_v4si;
8443 break;
8444 case V8HImode:
8445 type = int_ftype_int_v8hi_v8hi;
8446 break;
8447 case V16QImode:
8448 type = int_ftype_int_v16qi_v16qi;
8449 break;
8450 case V4SFmode:
8451 type = int_ftype_int_v4sf_v4sf;
8452 break;
8453 default:
8454 gcc_unreachable ();
8455 }
8456
8457 def_builtin (dp->mask, dp->name, type, dp->code);
8458 }
8459
8460 /* Initialize the abs* operators. */
8461 d = (struct builtin_description *) bdesc_abs;
8462 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8463 {
8464 enum machine_mode mode0;
8465 tree type;
8466
8467 mode0 = insn_data[d->icode].operand[0].mode;
8468
8469 switch (mode0)
8470 {
8471 case V4SImode:
8472 type = v4si_ftype_v4si;
8473 break;
8474 case V8HImode:
8475 type = v8hi_ftype_v8hi;
8476 break;
8477 case V16QImode:
8478 type = v16qi_ftype_v16qi;
8479 break;
8480 case V4SFmode:
8481 type = v4sf_ftype_v4sf;
8482 break;
8483 default:
8484 gcc_unreachable ();
8485 }
8486
8487 def_builtin (d->mask, d->name, type, d->code);
8488 }
8489
8490 if (TARGET_ALTIVEC)
8491 {
8492 tree decl;
8493
8494 /* Initialize target builtin that implements
8495 targetm.vectorize.builtin_mask_for_load. */
8496
8497 decl = lang_hooks.builtin_function ("__builtin_altivec_mask_for_load",
8498 v16qi_ftype_long_pcvoid,
8499 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8500 BUILT_IN_MD, NULL,
8501 tree_cons (get_identifier ("const"),
8502 NULL_TREE, NULL_TREE));
8503 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8504 altivec_builtin_mask_for_load = decl;
8505 }
8506
8507 /* Access to the vec_init patterns. */
8508 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8509 integer_type_node, integer_type_node,
8510 integer_type_node, NULL_TREE);
8511 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8512 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8513
8514 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8515 short_integer_type_node,
8516 short_integer_type_node,
8517 short_integer_type_node,
8518 short_integer_type_node,
8519 short_integer_type_node,
8520 short_integer_type_node,
8521 short_integer_type_node, NULL_TREE);
8522 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8523 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8524
8525 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8526 char_type_node, char_type_node,
8527 char_type_node, char_type_node,
8528 char_type_node, char_type_node,
8529 char_type_node, char_type_node,
8530 char_type_node, char_type_node,
8531 char_type_node, char_type_node,
8532 char_type_node, char_type_node,
8533 char_type_node, NULL_TREE);
8534 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8535 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8536
8537 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8538 float_type_node, float_type_node,
8539 float_type_node, NULL_TREE);
8540 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8541 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8542
8543 /* Access to the vec_set patterns. */
8544 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8545 intSI_type_node,
8546 integer_type_node, NULL_TREE);
8547 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8548 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8549
8550 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8551 intHI_type_node,
8552 integer_type_node, NULL_TREE);
8553 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8554 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8555
8556 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8557 intQI_type_node,
8558 integer_type_node, NULL_TREE);
8559 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8560 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8561
8562 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8563 float_type_node,
8564 integer_type_node, NULL_TREE);
8565 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8566 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8567
8568 /* Access to the vec_extract patterns. */
8569 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8570 integer_type_node, NULL_TREE);
8571 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8572 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8573
8574 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8575 integer_type_node, NULL_TREE);
8576 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8577 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8578
8579 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8580 integer_type_node, NULL_TREE);
8581 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8582 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8583
8584 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8585 integer_type_node, NULL_TREE);
8586 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8587 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
8588 }
8589
8590 static void
rs6000_common_init_builtins(void)8591 rs6000_common_init_builtins (void)
8592 {
8593 struct builtin_description *d;
8594 size_t i;
8595
8596 tree v4sf_ftype_v4sf_v4sf_v16qi
8597 = build_function_type_list (V4SF_type_node,
8598 V4SF_type_node, V4SF_type_node,
8599 V16QI_type_node, NULL_TREE);
8600 tree v4si_ftype_v4si_v4si_v16qi
8601 = build_function_type_list (V4SI_type_node,
8602 V4SI_type_node, V4SI_type_node,
8603 V16QI_type_node, NULL_TREE);
8604 tree v8hi_ftype_v8hi_v8hi_v16qi
8605 = build_function_type_list (V8HI_type_node,
8606 V8HI_type_node, V8HI_type_node,
8607 V16QI_type_node, NULL_TREE);
8608 tree v16qi_ftype_v16qi_v16qi_v16qi
8609 = build_function_type_list (V16QI_type_node,
8610 V16QI_type_node, V16QI_type_node,
8611 V16QI_type_node, NULL_TREE);
8612 tree v4si_ftype_int
8613 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8614 tree v8hi_ftype_int
8615 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8616 tree v16qi_ftype_int
8617 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
8618 tree v8hi_ftype_v16qi
8619 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8620 tree v4sf_ftype_v4sf
8621 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8622
8623 tree v2si_ftype_v2si_v2si
8624 = build_function_type_list (opaque_V2SI_type_node,
8625 opaque_V2SI_type_node,
8626 opaque_V2SI_type_node, NULL_TREE);
8627
8628 tree v2sf_ftype_v2sf_v2sf
8629 = build_function_type_list (opaque_V2SF_type_node,
8630 opaque_V2SF_type_node,
8631 opaque_V2SF_type_node, NULL_TREE);
8632
8633 tree v2si_ftype_int_int
8634 = build_function_type_list (opaque_V2SI_type_node,
8635 integer_type_node, integer_type_node,
8636 NULL_TREE);
8637
8638 tree opaque_ftype_opaque
8639 = build_function_type_list (opaque_V4SI_type_node,
8640 opaque_V4SI_type_node, NULL_TREE);
8641
8642 tree v2si_ftype_v2si
8643 = build_function_type_list (opaque_V2SI_type_node,
8644 opaque_V2SI_type_node, NULL_TREE);
8645
8646 tree v2sf_ftype_v2sf
8647 = build_function_type_list (opaque_V2SF_type_node,
8648 opaque_V2SF_type_node, NULL_TREE);
8649
8650 tree v2sf_ftype_v2si
8651 = build_function_type_list (opaque_V2SF_type_node,
8652 opaque_V2SI_type_node, NULL_TREE);
8653
8654 tree v2si_ftype_v2sf
8655 = build_function_type_list (opaque_V2SI_type_node,
8656 opaque_V2SF_type_node, NULL_TREE);
8657
8658 tree v2si_ftype_v2si_char
8659 = build_function_type_list (opaque_V2SI_type_node,
8660 opaque_V2SI_type_node,
8661 char_type_node, NULL_TREE);
8662
8663 tree v2si_ftype_int_char
8664 = build_function_type_list (opaque_V2SI_type_node,
8665 integer_type_node, char_type_node, NULL_TREE);
8666
8667 tree v2si_ftype_char
8668 = build_function_type_list (opaque_V2SI_type_node,
8669 char_type_node, NULL_TREE);
8670
8671 tree int_ftype_int_int
8672 = build_function_type_list (integer_type_node,
8673 integer_type_node, integer_type_node,
8674 NULL_TREE);
8675
8676 tree opaque_ftype_opaque_opaque
8677 = build_function_type_list (opaque_V4SI_type_node,
8678 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
8679 tree v4si_ftype_v4si_v4si
8680 = build_function_type_list (V4SI_type_node,
8681 V4SI_type_node, V4SI_type_node, NULL_TREE);
8682 tree v4sf_ftype_v4si_int
8683 = build_function_type_list (V4SF_type_node,
8684 V4SI_type_node, integer_type_node, NULL_TREE);
8685 tree v4si_ftype_v4sf_int
8686 = build_function_type_list (V4SI_type_node,
8687 V4SF_type_node, integer_type_node, NULL_TREE);
8688 tree v4si_ftype_v4si_int
8689 = build_function_type_list (V4SI_type_node,
8690 V4SI_type_node, integer_type_node, NULL_TREE);
8691 tree v8hi_ftype_v8hi_int
8692 = build_function_type_list (V8HI_type_node,
8693 V8HI_type_node, integer_type_node, NULL_TREE);
8694 tree v16qi_ftype_v16qi_int
8695 = build_function_type_list (V16QI_type_node,
8696 V16QI_type_node, integer_type_node, NULL_TREE);
8697 tree v16qi_ftype_v16qi_v16qi_int
8698 = build_function_type_list (V16QI_type_node,
8699 V16QI_type_node, V16QI_type_node,
8700 integer_type_node, NULL_TREE);
8701 tree v8hi_ftype_v8hi_v8hi_int
8702 = build_function_type_list (V8HI_type_node,
8703 V8HI_type_node, V8HI_type_node,
8704 integer_type_node, NULL_TREE);
8705 tree v4si_ftype_v4si_v4si_int
8706 = build_function_type_list (V4SI_type_node,
8707 V4SI_type_node, V4SI_type_node,
8708 integer_type_node, NULL_TREE);
8709 tree v4sf_ftype_v4sf_v4sf_int
8710 = build_function_type_list (V4SF_type_node,
8711 V4SF_type_node, V4SF_type_node,
8712 integer_type_node, NULL_TREE);
8713 tree v4sf_ftype_v4sf_v4sf
8714 = build_function_type_list (V4SF_type_node,
8715 V4SF_type_node, V4SF_type_node, NULL_TREE);
8716 tree opaque_ftype_opaque_opaque_opaque
8717 = build_function_type_list (opaque_V4SI_type_node,
8718 opaque_V4SI_type_node, opaque_V4SI_type_node,
8719 opaque_V4SI_type_node, NULL_TREE);
8720 tree v4sf_ftype_v4sf_v4sf_v4si
8721 = build_function_type_list (V4SF_type_node,
8722 V4SF_type_node, V4SF_type_node,
8723 V4SI_type_node, NULL_TREE);
8724 tree v4sf_ftype_v4sf_v4sf_v4sf
8725 = build_function_type_list (V4SF_type_node,
8726 V4SF_type_node, V4SF_type_node,
8727 V4SF_type_node, NULL_TREE);
8728 tree v4si_ftype_v4si_v4si_v4si
8729 = build_function_type_list (V4SI_type_node,
8730 V4SI_type_node, V4SI_type_node,
8731 V4SI_type_node, NULL_TREE);
8732 tree v8hi_ftype_v8hi_v8hi
8733 = build_function_type_list (V8HI_type_node,
8734 V8HI_type_node, V8HI_type_node, NULL_TREE);
8735 tree v8hi_ftype_v8hi_v8hi_v8hi
8736 = build_function_type_list (V8HI_type_node,
8737 V8HI_type_node, V8HI_type_node,
8738 V8HI_type_node, NULL_TREE);
8739 tree v4si_ftype_v8hi_v8hi_v4si
8740 = build_function_type_list (V4SI_type_node,
8741 V8HI_type_node, V8HI_type_node,
8742 V4SI_type_node, NULL_TREE);
8743 tree v4si_ftype_v16qi_v16qi_v4si
8744 = build_function_type_list (V4SI_type_node,
8745 V16QI_type_node, V16QI_type_node,
8746 V4SI_type_node, NULL_TREE);
8747 tree v16qi_ftype_v16qi_v16qi
8748 = build_function_type_list (V16QI_type_node,
8749 V16QI_type_node, V16QI_type_node, NULL_TREE);
8750 tree v4si_ftype_v4sf_v4sf
8751 = build_function_type_list (V4SI_type_node,
8752 V4SF_type_node, V4SF_type_node, NULL_TREE);
8753 tree v8hi_ftype_v16qi_v16qi
8754 = build_function_type_list (V8HI_type_node,
8755 V16QI_type_node, V16QI_type_node, NULL_TREE);
8756 tree v4si_ftype_v8hi_v8hi
8757 = build_function_type_list (V4SI_type_node,
8758 V8HI_type_node, V8HI_type_node, NULL_TREE);
8759 tree v8hi_ftype_v4si_v4si
8760 = build_function_type_list (V8HI_type_node,
8761 V4SI_type_node, V4SI_type_node, NULL_TREE);
8762 tree v16qi_ftype_v8hi_v8hi
8763 = build_function_type_list (V16QI_type_node,
8764 V8HI_type_node, V8HI_type_node, NULL_TREE);
8765 tree v4si_ftype_v16qi_v4si
8766 = build_function_type_list (V4SI_type_node,
8767 V16QI_type_node, V4SI_type_node, NULL_TREE);
8768 tree v4si_ftype_v16qi_v16qi
8769 = build_function_type_list (V4SI_type_node,
8770 V16QI_type_node, V16QI_type_node, NULL_TREE);
8771 tree v4si_ftype_v8hi_v4si
8772 = build_function_type_list (V4SI_type_node,
8773 V8HI_type_node, V4SI_type_node, NULL_TREE);
8774 tree v4si_ftype_v8hi
8775 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
8776 tree int_ftype_v4si_v4si
8777 = build_function_type_list (integer_type_node,
8778 V4SI_type_node, V4SI_type_node, NULL_TREE);
8779 tree int_ftype_v4sf_v4sf
8780 = build_function_type_list (integer_type_node,
8781 V4SF_type_node, V4SF_type_node, NULL_TREE);
8782 tree int_ftype_v16qi_v16qi
8783 = build_function_type_list (integer_type_node,
8784 V16QI_type_node, V16QI_type_node, NULL_TREE);
8785 tree int_ftype_v8hi_v8hi
8786 = build_function_type_list (integer_type_node,
8787 V8HI_type_node, V8HI_type_node, NULL_TREE);
8788
8789 /* Add the simple ternary operators. */
8790 d = (struct builtin_description *) bdesc_3arg;
8791 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8792 {
8793 enum machine_mode mode0, mode1, mode2, mode3;
8794 tree type;
8795 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8796 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8797
8798 if (is_overloaded)
8799 {
8800 mode0 = VOIDmode;
8801 mode1 = VOIDmode;
8802 mode2 = VOIDmode;
8803 mode3 = VOIDmode;
8804 }
8805 else
8806 {
8807 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8808 continue;
8809
8810 mode0 = insn_data[d->icode].operand[0].mode;
8811 mode1 = insn_data[d->icode].operand[1].mode;
8812 mode2 = insn_data[d->icode].operand[2].mode;
8813 mode3 = insn_data[d->icode].operand[3].mode;
8814 }
8815
8816 /* When all four are of the same mode. */
8817 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
8818 {
8819 switch (mode0)
8820 {
8821 case VOIDmode:
8822 type = opaque_ftype_opaque_opaque_opaque;
8823 break;
8824 case V4SImode:
8825 type = v4si_ftype_v4si_v4si_v4si;
8826 break;
8827 case V4SFmode:
8828 type = v4sf_ftype_v4sf_v4sf_v4sf;
8829 break;
8830 case V8HImode:
8831 type = v8hi_ftype_v8hi_v8hi_v8hi;
8832 break;
8833 case V16QImode:
8834 type = v16qi_ftype_v16qi_v16qi_v16qi;
8835 break;
8836 default:
8837 gcc_unreachable ();
8838 }
8839 }
8840 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
8841 {
8842 switch (mode0)
8843 {
8844 case V4SImode:
8845 type = v4si_ftype_v4si_v4si_v16qi;
8846 break;
8847 case V4SFmode:
8848 type = v4sf_ftype_v4sf_v4sf_v16qi;
8849 break;
8850 case V8HImode:
8851 type = v8hi_ftype_v8hi_v8hi_v16qi;
8852 break;
8853 case V16QImode:
8854 type = v16qi_ftype_v16qi_v16qi_v16qi;
8855 break;
8856 default:
8857 gcc_unreachable ();
8858 }
8859 }
8860 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
8861 && mode3 == V4SImode)
8862 type = v4si_ftype_v16qi_v16qi_v4si;
8863 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
8864 && mode3 == V4SImode)
8865 type = v4si_ftype_v8hi_v8hi_v4si;
8866 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
8867 && mode3 == V4SImode)
8868 type = v4sf_ftype_v4sf_v4sf_v4si;
8869
8870 /* vchar, vchar, vchar, 4 bit literal. */
8871 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
8872 && mode3 == QImode)
8873 type = v16qi_ftype_v16qi_v16qi_int;
8874
8875 /* vshort, vshort, vshort, 4 bit literal. */
8876 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
8877 && mode3 == QImode)
8878 type = v8hi_ftype_v8hi_v8hi_int;
8879
8880 /* vint, vint, vint, 4 bit literal. */
8881 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
8882 && mode3 == QImode)
8883 type = v4si_ftype_v4si_v4si_int;
8884
8885 /* vfloat, vfloat, vfloat, 4 bit literal. */
8886 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
8887 && mode3 == QImode)
8888 type = v4sf_ftype_v4sf_v4sf_int;
8889
8890 else
8891 gcc_unreachable ();
8892
8893 def_builtin (d->mask, d->name, type, d->code);
8894 }
8895
8896 /* Add the simple binary operators. */
8897 d = (struct builtin_description *) bdesc_2arg;
8898 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8899 {
8900 enum machine_mode mode0, mode1, mode2;
8901 tree type;
8902 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8903 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8904
8905 if (is_overloaded)
8906 {
8907 mode0 = VOIDmode;
8908 mode1 = VOIDmode;
8909 mode2 = VOIDmode;
8910 }
8911 else
8912 {
8913 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8914 continue;
8915
8916 mode0 = insn_data[d->icode].operand[0].mode;
8917 mode1 = insn_data[d->icode].operand[1].mode;
8918 mode2 = insn_data[d->icode].operand[2].mode;
8919 }
8920
8921 /* When all three operands are of the same mode. */
8922 if (mode0 == mode1 && mode1 == mode2)
8923 {
8924 switch (mode0)
8925 {
8926 case VOIDmode:
8927 type = opaque_ftype_opaque_opaque;
8928 break;
8929 case V4SFmode:
8930 type = v4sf_ftype_v4sf_v4sf;
8931 break;
8932 case V4SImode:
8933 type = v4si_ftype_v4si_v4si;
8934 break;
8935 case V16QImode:
8936 type = v16qi_ftype_v16qi_v16qi;
8937 break;
8938 case V8HImode:
8939 type = v8hi_ftype_v8hi_v8hi;
8940 break;
8941 case V2SImode:
8942 type = v2si_ftype_v2si_v2si;
8943 break;
8944 case V2SFmode:
8945 type = v2sf_ftype_v2sf_v2sf;
8946 break;
8947 case SImode:
8948 type = int_ftype_int_int;
8949 break;
8950 default:
8951 gcc_unreachable ();
8952 }
8953 }
8954
8955 /* A few other combos we really don't want to do manually. */
8956
8957 /* vint, vfloat, vfloat. */
8958 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
8959 type = v4si_ftype_v4sf_v4sf;
8960
8961 /* vshort, vchar, vchar. */
8962 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
8963 type = v8hi_ftype_v16qi_v16qi;
8964
8965 /* vint, vshort, vshort. */
8966 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
8967 type = v4si_ftype_v8hi_v8hi;
8968
8969 /* vshort, vint, vint. */
8970 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
8971 type = v8hi_ftype_v4si_v4si;
8972
8973 /* vchar, vshort, vshort. */
8974 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
8975 type = v16qi_ftype_v8hi_v8hi;
8976
8977 /* vint, vchar, vint. */
8978 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
8979 type = v4si_ftype_v16qi_v4si;
8980
8981 /* vint, vchar, vchar. */
8982 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
8983 type = v4si_ftype_v16qi_v16qi;
8984
8985 /* vint, vshort, vint. */
8986 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
8987 type = v4si_ftype_v8hi_v4si;
8988
8989 /* vint, vint, 5 bit literal. */
8990 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
8991 type = v4si_ftype_v4si_int;
8992
8993 /* vshort, vshort, 5 bit literal. */
8994 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
8995 type = v8hi_ftype_v8hi_int;
8996
8997 /* vchar, vchar, 5 bit literal. */
8998 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
8999 type = v16qi_ftype_v16qi_int;
9000
9001 /* vfloat, vint, 5 bit literal. */
9002 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
9003 type = v4sf_ftype_v4si_int;
9004
9005 /* vint, vfloat, 5 bit literal. */
9006 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
9007 type = v4si_ftype_v4sf_int;
9008
9009 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
9010 type = v2si_ftype_int_int;
9011
9012 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
9013 type = v2si_ftype_v2si_char;
9014
9015 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
9016 type = v2si_ftype_int_char;
9017
9018 else
9019 {
9020 /* int, x, x. */
9021 gcc_assert (mode0 == SImode);
9022 switch (mode1)
9023 {
9024 case V4SImode:
9025 type = int_ftype_v4si_v4si;
9026 break;
9027 case V4SFmode:
9028 type = int_ftype_v4sf_v4sf;
9029 break;
9030 case V16QImode:
9031 type = int_ftype_v16qi_v16qi;
9032 break;
9033 case V8HImode:
9034 type = int_ftype_v8hi_v8hi;
9035 break;
9036 default:
9037 gcc_unreachable ();
9038 }
9039 }
9040
9041 def_builtin (d->mask, d->name, type, d->code);
9042 }
9043
9044 /* Add the simple unary operators. */
9045 d = (struct builtin_description *) bdesc_1arg;
9046 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9047 {
9048 enum machine_mode mode0, mode1;
9049 tree type;
9050 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9051 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9052
9053 if (is_overloaded)
9054 {
9055 mode0 = VOIDmode;
9056 mode1 = VOIDmode;
9057 }
9058 else
9059 {
9060 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9061 continue;
9062
9063 mode0 = insn_data[d->icode].operand[0].mode;
9064 mode1 = insn_data[d->icode].operand[1].mode;
9065 }
9066
9067 if (mode0 == V4SImode && mode1 == QImode)
9068 type = v4si_ftype_int;
9069 else if (mode0 == V8HImode && mode1 == QImode)
9070 type = v8hi_ftype_int;
9071 else if (mode0 == V16QImode && mode1 == QImode)
9072 type = v16qi_ftype_int;
9073 else if (mode0 == VOIDmode && mode1 == VOIDmode)
9074 type = opaque_ftype_opaque;
9075 else if (mode0 == V4SFmode && mode1 == V4SFmode)
9076 type = v4sf_ftype_v4sf;
9077 else if (mode0 == V8HImode && mode1 == V16QImode)
9078 type = v8hi_ftype_v16qi;
9079 else if (mode0 == V4SImode && mode1 == V8HImode)
9080 type = v4si_ftype_v8hi;
9081 else if (mode0 == V2SImode && mode1 == V2SImode)
9082 type = v2si_ftype_v2si;
9083 else if (mode0 == V2SFmode && mode1 == V2SFmode)
9084 type = v2sf_ftype_v2sf;
9085 else if (mode0 == V2SFmode && mode1 == V2SImode)
9086 type = v2sf_ftype_v2si;
9087 else if (mode0 == V2SImode && mode1 == V2SFmode)
9088 type = v2si_ftype_v2sf;
9089 else if (mode0 == V2SImode && mode1 == QImode)
9090 type = v2si_ftype_char;
9091 else
9092 gcc_unreachable ();
9093
9094 def_builtin (d->mask, d->name, type, d->code);
9095 }
9096 }
9097
9098 static void
rs6000_init_libfuncs(void)9099 rs6000_init_libfuncs (void)
9100 {
9101 if (!TARGET_HARD_FLOAT)
9102 return;
9103
9104 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
9105 && !TARGET_POWER2 && !TARGET_POWERPC)
9106 {
9107 /* AIX library routines for float->int conversion. */
9108 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
9109 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
9110 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
9111 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
9112 }
9113
9114 if (!TARGET_IEEEQUAD)
9115 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9116 if (!TARGET_XL_COMPAT)
9117 {
9118 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
9119 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
9120 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
9121 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
9122 }
9123 else
9124 {
9125 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
9126 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
9127 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
9128 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
9129 }
9130 else
9131 {
9132 /* 32-bit SVR4 quad floating point routines. */
9133
9134 set_optab_libfunc (add_optab, TFmode, "_q_add");
9135 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
9136 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
9137 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
9138 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
9139 if (TARGET_PPC_GPOPT || TARGET_POWER2)
9140 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
9141
9142 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
9143 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
9144 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
9145 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
9146 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
9147 set_optab_libfunc (le_optab, TFmode, "_q_fle");
9148
9149 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
9150 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9151 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9152 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9153 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9154 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9155 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
9156 }
9157 }
9158
9159
9160 /* Expand a block clear operation, and return 1 if successful. Return 0
9161 if we should let the compiler generate normal code.
9162
9163 operands[0] is the destination
9164 operands[1] is the length
9165 operands[3] is the alignment */
9166
9167 int
expand_block_clear(rtx operands[])9168 expand_block_clear (rtx operands[])
9169 {
9170 rtx orig_dest = operands[0];
9171 rtx bytes_rtx = operands[1];
9172 rtx align_rtx = operands[3];
9173 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9174 HOST_WIDE_INT align;
9175 HOST_WIDE_INT bytes;
9176 int offset;
9177 int clear_bytes;
9178 int clear_step;
9179
9180 /* If this is not a fixed size move, just call memcpy */
9181 if (! constp)
9182 return 0;
9183
9184 /* This must be a fixed size alignment */
9185 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9186 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9187
9188 /* Anything to clear? */
9189 bytes = INTVAL (bytes_rtx);
9190 if (bytes <= 0)
9191 return 1;
9192
9193 /* Use the builtin memset after a point, to avoid huge code bloat.
9194 When optimize_size, avoid any significant code bloat; calling
9195 memset is about 4 instructions, so allow for one instruction to
9196 load zero and three to do clearing. */
9197 if (TARGET_ALTIVEC && align >= 128)
9198 clear_step = 16;
9199 else if (TARGET_POWERPC64 && align >= 32)
9200 clear_step = 8;
9201 else
9202 clear_step = 4;
9203
9204 if (optimize_size && bytes > 3 * clear_step)
9205 return 0;
9206 if (! optimize_size && bytes > 8 * clear_step)
9207 return 0;
9208
9209 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9210 {
9211 enum machine_mode mode = BLKmode;
9212 rtx dest;
9213
9214 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9215 {
9216 clear_bytes = 16;
9217 mode = V4SImode;
9218 }
9219 else if (bytes >= 8 && TARGET_POWERPC64
9220 /* 64-bit loads and stores require word-aligned
9221 displacements. */
9222 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9223 {
9224 clear_bytes = 8;
9225 mode = DImode;
9226 }
9227 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9228 { /* move 4 bytes */
9229 clear_bytes = 4;
9230 mode = SImode;
9231 }
9232 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9233 { /* move 2 bytes */
9234 clear_bytes = 2;
9235 mode = HImode;
9236 }
9237 else /* move 1 byte at a time */
9238 {
9239 clear_bytes = 1;
9240 mode = QImode;
9241 }
9242
9243 dest = adjust_address (orig_dest, mode, offset);
9244
9245 emit_move_insn (dest, CONST0_RTX (mode));
9246 }
9247
9248 return 1;
9249 }
9250
9251
9252 /* Expand a block move operation, and return 1 if successful. Return 0
9253 if we should let the compiler generate normal code.
9254
9255 operands[0] is the destination
9256 operands[1] is the source
9257 operands[2] is the length
9258 operands[3] is the alignment */
9259
9260 #define MAX_MOVE_REG 4
9261
9262 int
expand_block_move(rtx operands[])9263 expand_block_move (rtx operands[])
9264 {
9265 rtx orig_dest = operands[0];
9266 rtx orig_src = operands[1];
9267 rtx bytes_rtx = operands[2];
9268 rtx align_rtx = operands[3];
9269 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
9270 int align;
9271 int bytes;
9272 int offset;
9273 int move_bytes;
9274 rtx stores[MAX_MOVE_REG];
9275 int num_reg = 0;
9276
9277 /* If this is not a fixed size move, just call memcpy */
9278 if (! constp)
9279 return 0;
9280
9281 /* This must be a fixed size alignment */
9282 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9283 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9284
9285 /* Anything to move? */
9286 bytes = INTVAL (bytes_rtx);
9287 if (bytes <= 0)
9288 return 1;
9289
9290 /* store_one_arg depends on expand_block_move to handle at least the size of
9291 reg_parm_stack_space. */
9292 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
9293 return 0;
9294
9295 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
9296 {
9297 union {
9298 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
9299 rtx (*mov) (rtx, rtx);
9300 } gen_func;
9301 enum machine_mode mode = BLKmode;
9302 rtx src, dest;
9303
9304 /* Altivec first, since it will be faster than a string move
9305 when it applies, and usually not significantly larger. */
9306 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9307 {
9308 move_bytes = 16;
9309 mode = V4SImode;
9310 gen_func.mov = gen_movv4si;
9311 }
9312 else if (TARGET_STRING
9313 && bytes > 24 /* move up to 32 bytes at a time */
9314 && ! fixed_regs[5]
9315 && ! fixed_regs[6]
9316 && ! fixed_regs[7]
9317 && ! fixed_regs[8]
9318 && ! fixed_regs[9]
9319 && ! fixed_regs[10]
9320 && ! fixed_regs[11]
9321 && ! fixed_regs[12])
9322 {
9323 move_bytes = (bytes > 32) ? 32 : bytes;
9324 gen_func.movmemsi = gen_movmemsi_8reg;
9325 }
9326 else if (TARGET_STRING
9327 && bytes > 16 /* move up to 24 bytes at a time */
9328 && ! fixed_regs[5]
9329 && ! fixed_regs[6]
9330 && ! fixed_regs[7]
9331 && ! fixed_regs[8]
9332 && ! fixed_regs[9]
9333 && ! fixed_regs[10])
9334 {
9335 move_bytes = (bytes > 24) ? 24 : bytes;
9336 gen_func.movmemsi = gen_movmemsi_6reg;
9337 }
9338 else if (TARGET_STRING
9339 && bytes > 8 /* move up to 16 bytes at a time */
9340 && ! fixed_regs[5]
9341 && ! fixed_regs[6]
9342 && ! fixed_regs[7]
9343 && ! fixed_regs[8])
9344 {
9345 move_bytes = (bytes > 16) ? 16 : bytes;
9346 gen_func.movmemsi = gen_movmemsi_4reg;
9347 }
9348 else if (bytes >= 8 && TARGET_POWERPC64
9349 /* 64-bit loads and stores require word-aligned
9350 displacements. */
9351 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9352 {
9353 move_bytes = 8;
9354 mode = DImode;
9355 gen_func.mov = gen_movdi;
9356 }
9357 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9358 { /* move up to 8 bytes at a time */
9359 move_bytes = (bytes > 8) ? 8 : bytes;
9360 gen_func.movmemsi = gen_movmemsi_2reg;
9361 }
9362 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9363 { /* move 4 bytes */
9364 move_bytes = 4;
9365 mode = SImode;
9366 gen_func.mov = gen_movsi;
9367 }
9368 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9369 { /* move 2 bytes */
9370 move_bytes = 2;
9371 mode = HImode;
9372 gen_func.mov = gen_movhi;
9373 }
9374 else if (TARGET_STRING && bytes > 1)
9375 { /* move up to 4 bytes at a time */
9376 move_bytes = (bytes > 4) ? 4 : bytes;
9377 gen_func.movmemsi = gen_movmemsi_1reg;
9378 }
9379 else /* move 1 byte at a time */
9380 {
9381 move_bytes = 1;
9382 mode = QImode;
9383 gen_func.mov = gen_movqi;
9384 }
9385
9386 src = adjust_address (orig_src, mode, offset);
9387 dest = adjust_address (orig_dest, mode, offset);
9388
9389 if (mode != BLKmode)
9390 {
9391 rtx tmp_reg = gen_reg_rtx (mode);
9392
9393 emit_insn ((*gen_func.mov) (tmp_reg, src));
9394 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
9395 }
9396
9397 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9398 {
9399 int i;
9400 for (i = 0; i < num_reg; i++)
9401 emit_insn (stores[i]);
9402 num_reg = 0;
9403 }
9404
9405 if (mode == BLKmode)
9406 {
9407 /* Move the address into scratch registers. The movmemsi
9408 patterns require zero offset. */
9409 if (!REG_P (XEXP (src, 0)))
9410 {
9411 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9412 src = replace_equiv_address (src, src_reg);
9413 }
9414 set_mem_size (src, GEN_INT (move_bytes));
9415
9416 if (!REG_P (XEXP (dest, 0)))
9417 {
9418 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9419 dest = replace_equiv_address (dest, dest_reg);
9420 }
9421 set_mem_size (dest, GEN_INT (move_bytes));
9422
9423 emit_insn ((*gen_func.movmemsi) (dest, src,
9424 GEN_INT (move_bytes & 31),
9425 align_rtx));
9426 }
9427 }
9428
9429 return 1;
9430 }
9431
9432
9433 /* Return a string to perform a load_multiple operation.
9434 operands[0] is the vector.
9435 operands[1] is the source address.
9436 operands[2] is the first destination register. */
9437
9438 const char *
rs6000_output_load_multiple(rtx operands[3])9439 rs6000_output_load_multiple (rtx operands[3])
9440 {
9441 /* We have to handle the case where the pseudo used to contain the address
9442 is assigned to one of the output registers. */
9443 int i, j;
9444 int words = XVECLEN (operands[0], 0);
9445 rtx xop[10];
9446
9447 if (XVECLEN (operands[0], 0) == 1)
9448 return "{l|lwz} %2,0(%1)";
9449
9450 for (i = 0; i < words; i++)
9451 if (refers_to_regno_p (REGNO (operands[2]) + i,
9452 REGNO (operands[2]) + i + 1, operands[1], 0))
9453 {
9454 if (i == words-1)
9455 {
9456 xop[0] = GEN_INT (4 * (words-1));
9457 xop[1] = operands[1];
9458 xop[2] = operands[2];
9459 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9460 return "";
9461 }
9462 else if (i == 0)
9463 {
9464 xop[0] = GEN_INT (4 * (words-1));
9465 xop[1] = operands[1];
9466 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9467 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
9468 return "";
9469 }
9470 else
9471 {
9472 for (j = 0; j < words; j++)
9473 if (j != i)
9474 {
9475 xop[0] = GEN_INT (j * 4);
9476 xop[1] = operands[1];
9477 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9478 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9479 }
9480 xop[0] = GEN_INT (i * 4);
9481 xop[1] = operands[1];
9482 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9483 return "";
9484 }
9485 }
9486
9487 return "{lsi|lswi} %2,%1,%N0";
9488 }
9489
9490
9491 /* A validation routine: say whether CODE, a condition code, and MODE
9492 match. The other alternatives either don't make sense or should
9493 never be generated. */
9494
9495 void
validate_condition_mode(enum rtx_code code,enum machine_mode mode)9496 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
9497 {
9498 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9499 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9500 && GET_MODE_CLASS (mode) == MODE_CC);
9501
9502 /* These don't make sense. */
9503 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9504 || mode != CCUNSmode);
9505
9506 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9507 || mode == CCUNSmode);
9508
9509 gcc_assert (mode == CCFPmode
9510 || (code != ORDERED && code != UNORDERED
9511 && code != UNEQ && code != LTGT
9512 && code != UNGT && code != UNLT
9513 && code != UNGE && code != UNLE));
9514
9515 /* These should never be generated except for
9516 flag_finite_math_only. */
9517 gcc_assert (mode != CCFPmode
9518 || flag_finite_math_only
9519 || (code != LE && code != GE
9520 && code != UNEQ && code != LTGT
9521 && code != UNGT && code != UNLT));
9522
9523 /* These are invalid; the information is not there. */
9524 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
9525 }
9526
9527
9528 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9529 mask required to convert the result of a rotate insn into a shift
9530 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9531
9532 int
includes_lshift_p(rtx shiftop,rtx andop)9533 includes_lshift_p (rtx shiftop, rtx andop)
9534 {
9535 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9536
9537 shift_mask <<= INTVAL (shiftop);
9538
9539 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9540 }
9541
9542 /* Similar, but for right shift. */
9543
9544 int
includes_rshift_p(rtx shiftop,rtx andop)9545 includes_rshift_p (rtx shiftop, rtx andop)
9546 {
9547 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9548
9549 shift_mask >>= INTVAL (shiftop);
9550
9551 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9552 }
9553
9554 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9555 to perform a left shift. It must have exactly SHIFTOP least
9556 significant 0's, then one or more 1's, then zero or more 0's. */
9557
9558 int
includes_rldic_lshift_p(rtx shiftop,rtx andop)9559 includes_rldic_lshift_p (rtx shiftop, rtx andop)
9560 {
9561 if (GET_CODE (andop) == CONST_INT)
9562 {
9563 HOST_WIDE_INT c, lsb, shift_mask;
9564
9565 c = INTVAL (andop);
9566 if (c == 0 || c == ~0)
9567 return 0;
9568
9569 shift_mask = ~0;
9570 shift_mask <<= INTVAL (shiftop);
9571
9572 /* Find the least significant one bit. */
9573 lsb = c & -c;
9574
9575 /* It must coincide with the LSB of the shift mask. */
9576 if (-lsb != shift_mask)
9577 return 0;
9578
9579 /* Invert to look for the next transition (if any). */
9580 c = ~c;
9581
9582 /* Remove the low group of ones (originally low group of zeros). */
9583 c &= -lsb;
9584
9585 /* Again find the lsb, and check we have all 1's above. */
9586 lsb = c & -c;
9587 return c == -lsb;
9588 }
9589 else if (GET_CODE (andop) == CONST_DOUBLE
9590 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9591 {
9592 HOST_WIDE_INT low, high, lsb;
9593 HOST_WIDE_INT shift_mask_low, shift_mask_high;
9594
9595 low = CONST_DOUBLE_LOW (andop);
9596 if (HOST_BITS_PER_WIDE_INT < 64)
9597 high = CONST_DOUBLE_HIGH (andop);
9598
9599 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
9600 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
9601 return 0;
9602
9603 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9604 {
9605 shift_mask_high = ~0;
9606 if (INTVAL (shiftop) > 32)
9607 shift_mask_high <<= INTVAL (shiftop) - 32;
9608
9609 lsb = high & -high;
9610
9611 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9612 return 0;
9613
9614 high = ~high;
9615 high &= -lsb;
9616
9617 lsb = high & -high;
9618 return high == -lsb;
9619 }
9620
9621 shift_mask_low = ~0;
9622 shift_mask_low <<= INTVAL (shiftop);
9623
9624 lsb = low & -low;
9625
9626 if (-lsb != shift_mask_low)
9627 return 0;
9628
9629 if (HOST_BITS_PER_WIDE_INT < 64)
9630 high = ~high;
9631 low = ~low;
9632 low &= -lsb;
9633
9634 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9635 {
9636 lsb = high & -high;
9637 return high == -lsb;
9638 }
9639
9640 lsb = low & -low;
9641 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
9642 }
9643 else
9644 return 0;
9645 }
9646
9647 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9648 to perform a left shift. It must have SHIFTOP or more least
9649 significant 0's, with the remainder of the word 1's. */
9650
9651 int
includes_rldicr_lshift_p(rtx shiftop,rtx andop)9652 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
9653 {
9654 if (GET_CODE (andop) == CONST_INT)
9655 {
9656 HOST_WIDE_INT c, lsb, shift_mask;
9657
9658 shift_mask = ~0;
9659 shift_mask <<= INTVAL (shiftop);
9660 c = INTVAL (andop);
9661
9662 /* Find the least significant one bit. */
9663 lsb = c & -c;
9664
9665 /* It must be covered by the shift mask.
9666 This test also rejects c == 0. */
9667 if ((lsb & shift_mask) == 0)
9668 return 0;
9669
9670 /* Check we have all 1's above the transition, and reject all 1's. */
9671 return c == -lsb && lsb != 1;
9672 }
9673 else if (GET_CODE (andop) == CONST_DOUBLE
9674 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9675 {
9676 HOST_WIDE_INT low, lsb, shift_mask_low;
9677
9678 low = CONST_DOUBLE_LOW (andop);
9679
9680 if (HOST_BITS_PER_WIDE_INT < 64)
9681 {
9682 HOST_WIDE_INT high, shift_mask_high;
9683
9684 high = CONST_DOUBLE_HIGH (andop);
9685
9686 if (low == 0)
9687 {
9688 shift_mask_high = ~0;
9689 if (INTVAL (shiftop) > 32)
9690 shift_mask_high <<= INTVAL (shiftop) - 32;
9691
9692 lsb = high & -high;
9693
9694 if ((lsb & shift_mask_high) == 0)
9695 return 0;
9696
9697 return high == -lsb;
9698 }
9699 if (high != ~0)
9700 return 0;
9701 }
9702
9703 shift_mask_low = ~0;
9704 shift_mask_low <<= INTVAL (shiftop);
9705
9706 lsb = low & -low;
9707
9708 if ((lsb & shift_mask_low) == 0)
9709 return 0;
9710
9711 return low == -lsb && lsb != 1;
9712 }
9713 else
9714 return 0;
9715 }
9716
9717 /* Return 1 if operands will generate a valid arguments to rlwimi
9718 instruction for insert with right shift in 64-bit mode. The mask may
9719 not start on the first bit or stop on the last bit because wrap-around
9720 effects of instruction do not correspond to semantics of RTL insn. */
9721
9722 int
insvdi_rshift_rlwimi_p(rtx sizeop,rtx startop,rtx shiftop)9723 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
9724 {
9725 if (INTVAL (startop) > 32
9726 && INTVAL (startop) < 64
9727 && INTVAL (sizeop) > 1
9728 && INTVAL (sizeop) + INTVAL (startop) < 64
9729 && INTVAL (shiftop) > 0
9730 && INTVAL (sizeop) + INTVAL (shiftop) < 32
9731 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
9732 return 1;
9733
9734 return 0;
9735 }
9736
9737 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
9738 for lfq and stfq insns iff the registers are hard registers. */
9739
9740 int
registers_ok_for_quad_peep(rtx reg1,rtx reg2)9741 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
9742 {
9743 /* We might have been passed a SUBREG. */
9744 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
9745 return 0;
9746
9747 /* We might have been passed non floating point registers. */
9748 if (!FP_REGNO_P (REGNO (reg1))
9749 || !FP_REGNO_P (REGNO (reg2)))
9750 return 0;
9751
9752 return (REGNO (reg1) == REGNO (reg2) - 1);
9753 }
9754
9755 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9756 addr1 and addr2 must be in consecutive memory locations
9757 (addr2 == addr1 + 8). */
9758
9759 int
mems_ok_for_quad_peep(rtx mem1,rtx mem2)9760 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
9761 {
9762 rtx addr1, addr2;
9763 unsigned int reg1, reg2;
9764 int offset1, offset2;
9765
9766 /* The mems cannot be volatile. */
9767 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
9768 return 0;
9769
9770 addr1 = XEXP (mem1, 0);
9771 addr2 = XEXP (mem2, 0);
9772
9773 /* Extract an offset (if used) from the first addr. */
9774 if (GET_CODE (addr1) == PLUS)
9775 {
9776 /* If not a REG, return zero. */
9777 if (GET_CODE (XEXP (addr1, 0)) != REG)
9778 return 0;
9779 else
9780 {
9781 reg1 = REGNO (XEXP (addr1, 0));
9782 /* The offset must be constant! */
9783 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
9784 return 0;
9785 offset1 = INTVAL (XEXP (addr1, 1));
9786 }
9787 }
9788 else if (GET_CODE (addr1) != REG)
9789 return 0;
9790 else
9791 {
9792 reg1 = REGNO (addr1);
9793 /* This was a simple (mem (reg)) expression. Offset is 0. */
9794 offset1 = 0;
9795 }
9796
9797 /* And now for the second addr. */
9798 if (GET_CODE (addr2) == PLUS)
9799 {
9800 /* If not a REG, return zero. */
9801 if (GET_CODE (XEXP (addr2, 0)) != REG)
9802 return 0;
9803 else
9804 {
9805 reg2 = REGNO (XEXP (addr2, 0));
9806 /* The offset must be constant. */
9807 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
9808 return 0;
9809 offset2 = INTVAL (XEXP (addr2, 1));
9810 }
9811 }
9812 else if (GET_CODE (addr2) != REG)
9813 return 0;
9814 else
9815 {
9816 reg2 = REGNO (addr2);
9817 /* This was a simple (mem (reg)) expression. Offset is 0. */
9818 offset2 = 0;
9819 }
9820
9821 /* Both of these must have the same base register. */
9822 if (reg1 != reg2)
9823 return 0;
9824
9825 /* The offset for the second addr must be 8 more than the first addr. */
9826 if (offset2 != offset1 + 8)
9827 return 0;
9828
9829 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9830 instructions. */
9831 return 1;
9832 }
9833
9834 /* Return the register class of a scratch register needed to copy IN into
9835 or out of a register in CLASS in MODE. If it can be done directly,
9836 NO_REGS is returned. */
9837
9838 enum reg_class
secondary_reload_class(enum reg_class class,enum machine_mode mode ATTRIBUTE_UNUSED,rtx in)9839 secondary_reload_class (enum reg_class class,
9840 enum machine_mode mode ATTRIBUTE_UNUSED,
9841 rtx in)
9842 {
9843 int regno;
9844
9845 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
9846 #if TARGET_MACHO
9847 && MACHOPIC_INDIRECT
9848 #endif
9849 ))
9850 {
9851 /* We cannot copy a symbolic operand directly into anything
9852 other than BASE_REGS for TARGET_ELF. So indicate that a
9853 register from BASE_REGS is needed as an intermediate
9854 register.
9855
9856 On Darwin, pic addresses require a load from memory, which
9857 needs a base register. */
9858 if (class != BASE_REGS
9859 && (GET_CODE (in) == SYMBOL_REF
9860 || GET_CODE (in) == HIGH
9861 || GET_CODE (in) == LABEL_REF
9862 || GET_CODE (in) == CONST))
9863 return BASE_REGS;
9864 }
9865
9866 if (GET_CODE (in) == REG)
9867 {
9868 regno = REGNO (in);
9869 if (regno >= FIRST_PSEUDO_REGISTER)
9870 {
9871 regno = true_regnum (in);
9872 if (regno >= FIRST_PSEUDO_REGISTER)
9873 regno = -1;
9874 }
9875 }
9876 else if (GET_CODE (in) == SUBREG)
9877 {
9878 regno = true_regnum (in);
9879 if (regno >= FIRST_PSEUDO_REGISTER)
9880 regno = -1;
9881 }
9882 else
9883 regno = -1;
9884
9885 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9886 into anything. */
9887 if (class == GENERAL_REGS || class == BASE_REGS
9888 || (regno >= 0 && INT_REGNO_P (regno)))
9889 return NO_REGS;
9890
9891 /* Constants, memory, and FP registers can go into FP registers. */
9892 if ((regno == -1 || FP_REGNO_P (regno))
9893 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
9894 return NO_REGS;
9895
9896 /* Memory, and AltiVec registers can go into AltiVec registers. */
9897 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
9898 && class == ALTIVEC_REGS)
9899 return NO_REGS;
9900
9901 /* We can copy among the CR registers. */
9902 if ((class == CR_REGS || class == CR0_REGS)
9903 && regno >= 0 && CR_REGNO_P (regno))
9904 return NO_REGS;
9905
9906 /* Otherwise, we need GENERAL_REGS. */
9907 return GENERAL_REGS;
9908 }
9909
9910 /* Given a comparison operation, return the bit number in CCR to test. We
9911 know this is a valid comparison.
9912
9913 SCC_P is 1 if this is for an scc. That means that %D will have been
9914 used instead of %C, so the bits will be in different places.
9915
9916 Return -1 if OP isn't a valid comparison for some reason. */
9917
9918 int
ccr_bit(rtx op,int scc_p)9919 ccr_bit (rtx op, int scc_p)
9920 {
9921 enum rtx_code code = GET_CODE (op);
9922 enum machine_mode cc_mode;
9923 int cc_regnum;
9924 int base_bit;
9925 rtx reg;
9926
9927 if (!COMPARISON_P (op))
9928 return -1;
9929
9930 reg = XEXP (op, 0);
9931
9932 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
9933
9934 cc_mode = GET_MODE (reg);
9935 cc_regnum = REGNO (reg);
9936 base_bit = 4 * (cc_regnum - CR0_REGNO);
9937
9938 validate_condition_mode (code, cc_mode);
9939
9940 /* When generating a sCOND operation, only positive conditions are
9941 allowed. */
9942 gcc_assert (!scc_p
9943 || code == EQ || code == GT || code == LT || code == UNORDERED
9944 || code == GTU || code == LTU);
9945
9946 switch (code)
9947 {
9948 case NE:
9949 return scc_p ? base_bit + 3 : base_bit + 2;
9950 case EQ:
9951 return base_bit + 2;
9952 case GT: case GTU: case UNLE:
9953 return base_bit + 1;
9954 case LT: case LTU: case UNGE:
9955 return base_bit;
9956 case ORDERED: case UNORDERED:
9957 return base_bit + 3;
9958
9959 case GE: case GEU:
9960 /* If scc, we will have done a cror to put the bit in the
9961 unordered position. So test that bit. For integer, this is ! LT
9962 unless this is an scc insn. */
9963 return scc_p ? base_bit + 3 : base_bit;
9964
9965 case LE: case LEU:
9966 return scc_p ? base_bit + 3 : base_bit + 1;
9967
9968 default:
9969 gcc_unreachable ();
9970 }
9971 }
9972
9973 /* Return the GOT register. */
9974
9975 rtx
rs6000_got_register(rtx value ATTRIBUTE_UNUSED)9976 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
9977 {
9978 /* The second flow pass currently (June 1999) can't update
9979 regs_ever_live without disturbing other parts of the compiler, so
9980 update it here to make the prolog/epilogue code happy. */
9981 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
9982 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
9983
9984 current_function_uses_pic_offset_table = 1;
9985
9986 return pic_offset_table_rtx;
9987 }
9988
9989 /* Function to init struct machine_function.
9990 This will be called, via a pointer variable,
9991 from push_function_context. */
9992
9993 static struct machine_function *
rs6000_init_machine_status(void)9994 rs6000_init_machine_status (void)
9995 {
9996 return ggc_alloc_cleared (sizeof (machine_function));
9997 }
9998
9999 /* These macros test for integers and extract the low-order bits. */
10000 #define INT_P(X) \
10001 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10002 && GET_MODE (X) == VOIDmode)
10003
10004 #define INT_LOWPART(X) \
10005 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10006
10007 int
extract_MB(rtx op)10008 extract_MB (rtx op)
10009 {
10010 int i;
10011 unsigned long val = INT_LOWPART (op);
10012
10013 /* If the high bit is zero, the value is the first 1 bit we find
10014 from the left. */
10015 if ((val & 0x80000000) == 0)
10016 {
10017 gcc_assert (val & 0xffffffff);
10018
10019 i = 1;
10020 while (((val <<= 1) & 0x80000000) == 0)
10021 ++i;
10022 return i;
10023 }
10024
10025 /* If the high bit is set and the low bit is not, or the mask is all
10026 1's, the value is zero. */
10027 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
10028 return 0;
10029
10030 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10031 from the right. */
10032 i = 31;
10033 while (((val >>= 1) & 1) != 0)
10034 --i;
10035
10036 return i;
10037 }
10038
10039 int
extract_ME(rtx op)10040 extract_ME (rtx op)
10041 {
10042 int i;
10043 unsigned long val = INT_LOWPART (op);
10044
10045 /* If the low bit is zero, the value is the first 1 bit we find from
10046 the right. */
10047 if ((val & 1) == 0)
10048 {
10049 gcc_assert (val & 0xffffffff);
10050
10051 i = 30;
10052 while (((val >>= 1) & 1) == 0)
10053 --i;
10054
10055 return i;
10056 }
10057
10058 /* If the low bit is set and the high bit is not, or the mask is all
10059 1's, the value is 31. */
10060 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
10061 return 31;
10062
10063 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10064 from the left. */
10065 i = 0;
10066 while (((val <<= 1) & 0x80000000) != 0)
10067 ++i;
10068
10069 return i;
10070 }
10071
10072 /* Locate some local-dynamic symbol still in use by this function
10073 so that we can print its name in some tls_ld pattern. */
10074
10075 static const char *
rs6000_get_some_local_dynamic_name(void)10076 rs6000_get_some_local_dynamic_name (void)
10077 {
10078 rtx insn;
10079
10080 if (cfun->machine->some_ld_name)
10081 return cfun->machine->some_ld_name;
10082
10083 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
10084 if (INSN_P (insn)
10085 && for_each_rtx (&PATTERN (insn),
10086 rs6000_get_some_local_dynamic_name_1, 0))
10087 return cfun->machine->some_ld_name;
10088
10089 gcc_unreachable ();
10090 }
10091
10092 /* Helper function for rs6000_get_some_local_dynamic_name. */
10093
10094 static int
rs6000_get_some_local_dynamic_name_1(rtx * px,void * data ATTRIBUTE_UNUSED)10095 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
10096 {
10097 rtx x = *px;
10098
10099 if (GET_CODE (x) == SYMBOL_REF)
10100 {
10101 const char *str = XSTR (x, 0);
10102 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
10103 {
10104 cfun->machine->some_ld_name = str;
10105 return 1;
10106 }
10107 }
10108
10109 return 0;
10110 }
10111
10112 /* Write out a function code label. */
10113
10114 void
rs6000_output_function_entry(FILE * file,const char * fname)10115 rs6000_output_function_entry (FILE *file, const char *fname)
10116 {
10117 if (fname[0] != '.')
10118 {
10119 switch (DEFAULT_ABI)
10120 {
10121 default:
10122 gcc_unreachable ();
10123
10124 case ABI_AIX:
10125 if (DOT_SYMBOLS)
10126 putc ('.', file);
10127 else
10128 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
10129 break;
10130
10131 case ABI_V4:
10132 case ABI_DARWIN:
10133 break;
10134 }
10135 }
10136 if (TARGET_AIX)
10137 RS6000_OUTPUT_BASENAME (file, fname);
10138 else
10139 assemble_name (file, fname);
10140 }
10141
10142 /* Print an operand. Recognize special options, documented below. */
10143
10144 #if TARGET_ELF
10145 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10146 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10147 #else
10148 #define SMALL_DATA_RELOC "sda21"
10149 #define SMALL_DATA_REG 0
10150 #endif
10151
10152 void
print_operand(FILE * file,rtx x,int code)10153 print_operand (FILE *file, rtx x, int code)
10154 {
10155 int i;
10156 HOST_WIDE_INT val;
10157 unsigned HOST_WIDE_INT uval;
10158
10159 switch (code)
10160 {
10161 case '.':
10162 /* Write out an instruction after the call which may be replaced
10163 with glue code by the loader. This depends on the AIX version. */
10164 asm_fprintf (file, RS6000_CALL_GLUE);
10165 return;
10166
10167 /* %a is output_address. */
10168
10169 case 'A':
10170 /* If X is a constant integer whose low-order 5 bits are zero,
10171 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10172 in the AIX assembler where "sri" with a zero shift count
10173 writes a trash instruction. */
10174 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
10175 putc ('l', file);
10176 else
10177 putc ('r', file);
10178 return;
10179
10180 case 'b':
10181 /* If constant, low-order 16 bits of constant, unsigned.
10182 Otherwise, write normally. */
10183 if (INT_P (x))
10184 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10185 else
10186 print_operand (file, x, 0);
10187 return;
10188
10189 case 'B':
10190 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10191 for 64-bit mask direction. */
10192 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
10193 return;
10194
10195 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10196 output_operand. */
10197
10198 case 'c':
10199 /* X is a CR register. Print the number of the GT bit of the CR. */
10200 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10201 output_operand_lossage ("invalid %%E value");
10202 else
10203 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10204 return;
10205
10206 case 'D':
10207 /* Like 'J' but get to the EQ bit. */
10208 gcc_assert (GET_CODE (x) == REG);
10209
10210 /* Bit 1 is EQ bit. */
10211 i = 4 * (REGNO (x) - CR0_REGNO) + 2;
10212
10213 fprintf (file, "%d", i);
10214 return;
10215
10216 case 'E':
10217 /* X is a CR register. Print the number of the EQ bit of the CR */
10218 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10219 output_operand_lossage ("invalid %%E value");
10220 else
10221 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
10222 return;
10223
10224 case 'f':
10225 /* X is a CR register. Print the shift count needed to move it
10226 to the high-order four bits. */
10227 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10228 output_operand_lossage ("invalid %%f value");
10229 else
10230 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
10231 return;
10232
10233 case 'F':
10234 /* Similar, but print the count for the rotate in the opposite
10235 direction. */
10236 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10237 output_operand_lossage ("invalid %%F value");
10238 else
10239 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
10240 return;
10241
10242 case 'G':
10243 /* X is a constant integer. If it is negative, print "m",
10244 otherwise print "z". This is to make an aze or ame insn. */
10245 if (GET_CODE (x) != CONST_INT)
10246 output_operand_lossage ("invalid %%G value");
10247 else if (INTVAL (x) >= 0)
10248 putc ('z', file);
10249 else
10250 putc ('m', file);
10251 return;
10252
10253 case 'h':
10254 /* If constant, output low-order five bits. Otherwise, write
10255 normally. */
10256 if (INT_P (x))
10257 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
10258 else
10259 print_operand (file, x, 0);
10260 return;
10261
10262 case 'H':
10263 /* If constant, output low-order six bits. Otherwise, write
10264 normally. */
10265 if (INT_P (x))
10266 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
10267 else
10268 print_operand (file, x, 0);
10269 return;
10270
10271 case 'I':
10272 /* Print `i' if this is a constant, else nothing. */
10273 if (INT_P (x))
10274 putc ('i', file);
10275 return;
10276
10277 case 'j':
10278 /* Write the bit number in CCR for jump. */
10279 i = ccr_bit (x, 0);
10280 if (i == -1)
10281 output_operand_lossage ("invalid %%j code");
10282 else
10283 fprintf (file, "%d", i);
10284 return;
10285
10286 case 'J':
10287 /* Similar, but add one for shift count in rlinm for scc and pass
10288 scc flag to `ccr_bit'. */
10289 i = ccr_bit (x, 1);
10290 if (i == -1)
10291 output_operand_lossage ("invalid %%J code");
10292 else
10293 /* If we want bit 31, write a shift count of zero, not 32. */
10294 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10295 return;
10296
10297 case 'k':
10298 /* X must be a constant. Write the 1's complement of the
10299 constant. */
10300 if (! INT_P (x))
10301 output_operand_lossage ("invalid %%k value");
10302 else
10303 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
10304 return;
10305
10306 case 'K':
10307 /* X must be a symbolic constant on ELF. Write an
10308 expression suitable for an 'addi' that adds in the low 16
10309 bits of the MEM. */
10310 if (GET_CODE (x) != CONST)
10311 {
10312 print_operand_address (file, x);
10313 fputs ("@l", file);
10314 }
10315 else
10316 {
10317 if (GET_CODE (XEXP (x, 0)) != PLUS
10318 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10319 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10320 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
10321 output_operand_lossage ("invalid %%K value");
10322 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10323 fputs ("@l", file);
10324 /* For GNU as, there must be a non-alphanumeric character
10325 between 'l' and the number. The '-' is added by
10326 print_operand() already. */
10327 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10328 fputs ("+", file);
10329 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10330 }
10331 return;
10332
10333 /* %l is output_asm_label. */
10334
10335 case 'L':
10336 /* Write second word of DImode or DFmode reference. Works on register
10337 or non-indexed memory only. */
10338 if (GET_CODE (x) == REG)
10339 fputs (reg_names[REGNO (x) + 1], file);
10340 else if (GET_CODE (x) == MEM)
10341 {
10342 /* Handle possible auto-increment. Since it is pre-increment and
10343 we have already done it, we can just use an offset of word. */
10344 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10345 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10346 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10347 UNITS_PER_WORD));
10348 else
10349 output_address (XEXP (adjust_address_nv (x, SImode,
10350 UNITS_PER_WORD),
10351 0));
10352
10353 if (small_data_operand (x, GET_MODE (x)))
10354 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10355 reg_names[SMALL_DATA_REG]);
10356 }
10357 return;
10358
10359 case 'm':
10360 /* MB value for a mask operand. */
10361 if (! mask_operand (x, SImode))
10362 output_operand_lossage ("invalid %%m value");
10363
10364 fprintf (file, "%d", extract_MB (x));
10365 return;
10366
10367 case 'M':
10368 /* ME value for a mask operand. */
10369 if (! mask_operand (x, SImode))
10370 output_operand_lossage ("invalid %%M value");
10371
10372 fprintf (file, "%d", extract_ME (x));
10373 return;
10374
10375 /* %n outputs the negative of its operand. */
10376
10377 case 'N':
10378 /* Write the number of elements in the vector times 4. */
10379 if (GET_CODE (x) != PARALLEL)
10380 output_operand_lossage ("invalid %%N value");
10381 else
10382 fprintf (file, "%d", XVECLEN (x, 0) * 4);
10383 return;
10384
10385 case 'O':
10386 /* Similar, but subtract 1 first. */
10387 if (GET_CODE (x) != PARALLEL)
10388 output_operand_lossage ("invalid %%O value");
10389 else
10390 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
10391 return;
10392
10393 case 'p':
10394 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10395 if (! INT_P (x)
10396 || INT_LOWPART (x) < 0
10397 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10398 output_operand_lossage ("invalid %%p value");
10399 else
10400 fprintf (file, "%d", i);
10401 return;
10402
10403 case 'P':
10404 /* The operand must be an indirect memory reference. The result
10405 is the register name. */
10406 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10407 || REGNO (XEXP (x, 0)) >= 32)
10408 output_operand_lossage ("invalid %%P value");
10409 else
10410 fputs (reg_names[REGNO (XEXP (x, 0))], file);
10411 return;
10412
10413 case 'q':
10414 /* This outputs the logical code corresponding to a boolean
10415 expression. The expression may have one or both operands
10416 negated (if one, only the first one). For condition register
10417 logical operations, it will also treat the negated
10418 CR codes as NOTs, but not handle NOTs of them. */
10419 {
10420 const char *const *t = 0;
10421 const char *s;
10422 enum rtx_code code = GET_CODE (x);
10423 static const char * const tbl[3][3] = {
10424 { "and", "andc", "nor" },
10425 { "or", "orc", "nand" },
10426 { "xor", "eqv", "xor" } };
10427
10428 if (code == AND)
10429 t = tbl[0];
10430 else if (code == IOR)
10431 t = tbl[1];
10432 else if (code == XOR)
10433 t = tbl[2];
10434 else
10435 output_operand_lossage ("invalid %%q value");
10436
10437 if (GET_CODE (XEXP (x, 0)) != NOT)
10438 s = t[0];
10439 else
10440 {
10441 if (GET_CODE (XEXP (x, 1)) == NOT)
10442 s = t[2];
10443 else
10444 s = t[1];
10445 }
10446
10447 fputs (s, file);
10448 }
10449 return;
10450
10451 case 'Q':
10452 if (TARGET_MFCRF)
10453 fputc (',', file);
10454 /* FALLTHRU */
10455 else
10456 return;
10457
10458 case 'R':
10459 /* X is a CR register. Print the mask for `mtcrf'. */
10460 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10461 output_operand_lossage ("invalid %%R value");
10462 else
10463 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
10464 return;
10465
10466 case 's':
10467 /* Low 5 bits of 32 - value */
10468 if (! INT_P (x))
10469 output_operand_lossage ("invalid %%s value");
10470 else
10471 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
10472 return;
10473
10474 case 'S':
10475 /* PowerPC64 mask position. All 0's is excluded.
10476 CONST_INT 32-bit mask is considered sign-extended so any
10477 transition must occur within the CONST_INT, not on the boundary. */
10478 if (! mask64_operand (x, DImode))
10479 output_operand_lossage ("invalid %%S value");
10480
10481 uval = INT_LOWPART (x);
10482
10483 if (uval & 1) /* Clear Left */
10484 {
10485 #if HOST_BITS_PER_WIDE_INT > 64
10486 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10487 #endif
10488 i = 64;
10489 }
10490 else /* Clear Right */
10491 {
10492 uval = ~uval;
10493 #if HOST_BITS_PER_WIDE_INT > 64
10494 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10495 #endif
10496 i = 63;
10497 }
10498 while (uval != 0)
10499 --i, uval >>= 1;
10500 gcc_assert (i >= 0);
10501 fprintf (file, "%d", i);
10502 return;
10503
10504 case 't':
10505 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10506 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
10507
10508 /* Bit 3 is OV bit. */
10509 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10510
10511 /* If we want bit 31, write a shift count of zero, not 32. */
10512 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10513 return;
10514
10515 case 'T':
10516 /* Print the symbolic name of a branch target register. */
10517 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10518 && REGNO (x) != COUNT_REGISTER_REGNUM))
10519 output_operand_lossage ("invalid %%T value");
10520 else if (REGNO (x) == LINK_REGISTER_REGNUM)
10521 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10522 else
10523 fputs ("ctr", file);
10524 return;
10525
10526 case 'u':
10527 /* High-order 16 bits of constant for use in unsigned operand. */
10528 if (! INT_P (x))
10529 output_operand_lossage ("invalid %%u value");
10530 else
10531 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10532 (INT_LOWPART (x) >> 16) & 0xffff);
10533 return;
10534
10535 case 'v':
10536 /* High-order 16 bits of constant for use in signed operand. */
10537 if (! INT_P (x))
10538 output_operand_lossage ("invalid %%v value");
10539 else
10540 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10541 (INT_LOWPART (x) >> 16) & 0xffff);
10542 return;
10543
10544 case 'U':
10545 /* Print `u' if this has an auto-increment or auto-decrement. */
10546 if (GET_CODE (x) == MEM
10547 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10548 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
10549 putc ('u', file);
10550 return;
10551
10552 case 'V':
10553 /* Print the trap code for this operand. */
10554 switch (GET_CODE (x))
10555 {
10556 case EQ:
10557 fputs ("eq", file); /* 4 */
10558 break;
10559 case NE:
10560 fputs ("ne", file); /* 24 */
10561 break;
10562 case LT:
10563 fputs ("lt", file); /* 16 */
10564 break;
10565 case LE:
10566 fputs ("le", file); /* 20 */
10567 break;
10568 case GT:
10569 fputs ("gt", file); /* 8 */
10570 break;
10571 case GE:
10572 fputs ("ge", file); /* 12 */
10573 break;
10574 case LTU:
10575 fputs ("llt", file); /* 2 */
10576 break;
10577 case LEU:
10578 fputs ("lle", file); /* 6 */
10579 break;
10580 case GTU:
10581 fputs ("lgt", file); /* 1 */
10582 break;
10583 case GEU:
10584 fputs ("lge", file); /* 5 */
10585 break;
10586 default:
10587 gcc_unreachable ();
10588 }
10589 break;
10590
10591 case 'w':
10592 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10593 normally. */
10594 if (INT_P (x))
10595 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
10596 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
10597 else
10598 print_operand (file, x, 0);
10599 return;
10600
10601 case 'W':
10602 /* MB value for a PowerPC64 rldic operand. */
10603 val = (GET_CODE (x) == CONST_INT
10604 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10605
10606 if (val < 0)
10607 i = -1;
10608 else
10609 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10610 if ((val <<= 1) < 0)
10611 break;
10612
10613 #if HOST_BITS_PER_WIDE_INT == 32
10614 if (GET_CODE (x) == CONST_INT && i >= 0)
10615 i += 32; /* zero-extend high-part was all 0's */
10616 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10617 {
10618 val = CONST_DOUBLE_LOW (x);
10619
10620 gcc_assert (val);
10621 if (val < 0)
10622 --i;
10623 else
10624 for ( ; i < 64; i++)
10625 if ((val <<= 1) < 0)
10626 break;
10627 }
10628 #endif
10629
10630 fprintf (file, "%d", i + 1);
10631 return;
10632
10633 case 'X':
10634 if (GET_CODE (x) == MEM
10635 && legitimate_indexed_address_p (XEXP (x, 0), 0))
10636 putc ('x', file);
10637 return;
10638
10639 case 'Y':
10640 /* Like 'L', for third word of TImode */
10641 if (GET_CODE (x) == REG)
10642 fputs (reg_names[REGNO (x) + 2], file);
10643 else if (GET_CODE (x) == MEM)
10644 {
10645 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10646 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10647 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
10648 else
10649 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
10650 if (small_data_operand (x, GET_MODE (x)))
10651 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10652 reg_names[SMALL_DATA_REG]);
10653 }
10654 return;
10655
10656 case 'z':
10657 /* X is a SYMBOL_REF. Write out the name preceded by a
10658 period and without any trailing data in brackets. Used for function
10659 names. If we are configured for System V (or the embedded ABI) on
10660 the PowerPC, do not emit the period, since those systems do not use
10661 TOCs and the like. */
10662 gcc_assert (GET_CODE (x) == SYMBOL_REF);
10663
10664 /* Mark the decl as referenced so that cgraph will output the
10665 function. */
10666 if (SYMBOL_REF_DECL (x))
10667 mark_decl_referenced (SYMBOL_REF_DECL (x));
10668
10669 /* For macho, check to see if we need a stub. */
10670 if (TARGET_MACHO)
10671 {
10672 const char *name = XSTR (x, 0);
10673 #if TARGET_MACHO
10674 if (MACHOPIC_INDIRECT
10675 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
10676 name = machopic_indirection_name (x, /*stub_p=*/true);
10677 #endif
10678 assemble_name (file, name);
10679 }
10680 else if (!DOT_SYMBOLS)
10681 assemble_name (file, XSTR (x, 0));
10682 else
10683 rs6000_output_function_entry (file, XSTR (x, 0));
10684 return;
10685
10686 case 'Z':
10687 /* Like 'L', for last word of TImode. */
10688 if (GET_CODE (x) == REG)
10689 fputs (reg_names[REGNO (x) + 3], file);
10690 else if (GET_CODE (x) == MEM)
10691 {
10692 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10693 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10694 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
10695 else
10696 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
10697 if (small_data_operand (x, GET_MODE (x)))
10698 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10699 reg_names[SMALL_DATA_REG]);
10700 }
10701 return;
10702
10703 /* Print AltiVec or SPE memory operand. */
10704 case 'y':
10705 {
10706 rtx tmp;
10707
10708 gcc_assert (GET_CODE (x) == MEM);
10709
10710 tmp = XEXP (x, 0);
10711
10712 if (TARGET_E500)
10713 {
10714 /* Handle [reg]. */
10715 if (GET_CODE (tmp) == REG)
10716 {
10717 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
10718 break;
10719 }
10720 /* Handle [reg+UIMM]. */
10721 else if (GET_CODE (tmp) == PLUS &&
10722 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
10723 {
10724 int x;
10725
10726 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
10727
10728 x = INTVAL (XEXP (tmp, 1));
10729 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
10730 break;
10731 }
10732
10733 /* Fall through. Must be [reg+reg]. */
10734 }
10735 if (TARGET_ALTIVEC
10736 && GET_CODE (tmp) == AND
10737 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
10738 && INTVAL (XEXP (tmp, 1)) == -16)
10739 tmp = XEXP (tmp, 0);
10740 if (GET_CODE (tmp) == REG)
10741 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
10742 else
10743 {
10744 gcc_assert (GET_CODE (tmp) == PLUS
10745 && REG_P (XEXP (tmp, 0))
10746 && REG_P (XEXP (tmp, 1)));
10747
10748 if (REGNO (XEXP (tmp, 0)) == 0)
10749 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
10750 reg_names[ REGNO (XEXP (tmp, 0)) ]);
10751 else
10752 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
10753 reg_names[ REGNO (XEXP (tmp, 1)) ]);
10754 }
10755 break;
10756 }
10757
10758 case 0:
10759 if (GET_CODE (x) == REG)
10760 fprintf (file, "%s", reg_names[REGNO (x)]);
10761 else if (GET_CODE (x) == MEM)
10762 {
10763 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10764 know the width from the mode. */
10765 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
10766 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
10767 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
10768 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
10769 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
10770 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
10771 else
10772 output_address (XEXP (x, 0));
10773 }
10774 else
10775 output_addr_const (file, x);
10776 return;
10777
10778 case '&':
10779 assemble_name (file, rs6000_get_some_local_dynamic_name ());
10780 return;
10781
10782 default:
10783 output_operand_lossage ("invalid %%xn code");
10784 }
10785 }
10786
10787 /* Print the address of an operand. */
10788
10789 void
print_operand_address(FILE * file,rtx x)10790 print_operand_address (FILE *file, rtx x)
10791 {
10792 if (GET_CODE (x) == REG)
10793 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
10794 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
10795 || GET_CODE (x) == LABEL_REF)
10796 {
10797 output_addr_const (file, x);
10798 if (small_data_operand (x, GET_MODE (x)))
10799 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10800 reg_names[SMALL_DATA_REG]);
10801 else
10802 gcc_assert (!TARGET_TOC);
10803 }
10804 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
10805 {
10806 gcc_assert (REG_P (XEXP (x, 0)));
10807 if (REGNO (XEXP (x, 0)) == 0)
10808 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
10809 reg_names[ REGNO (XEXP (x, 0)) ]);
10810 else
10811 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
10812 reg_names[ REGNO (XEXP (x, 1)) ]);
10813 }
10814 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
10815 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
10816 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
10817 #if TARGET_ELF
10818 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
10819 && CONSTANT_P (XEXP (x, 1)))
10820 {
10821 output_addr_const (file, XEXP (x, 1));
10822 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10823 }
10824 #endif
10825 #if TARGET_MACHO
10826 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
10827 && CONSTANT_P (XEXP (x, 1)))
10828 {
10829 fprintf (file, "lo16(");
10830 output_addr_const (file, XEXP (x, 1));
10831 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10832 }
10833 #endif
10834 else if (legitimate_constant_pool_address_p (x))
10835 {
10836 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
10837 {
10838 rtx contains_minus = XEXP (x, 1);
10839 rtx minus, symref;
10840 const char *name;
10841
10842 /* Find the (minus (sym) (toc)) buried in X, and temporarily
10843 turn it into (sym) for output_addr_const. */
10844 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
10845 contains_minus = XEXP (contains_minus, 0);
10846
10847 minus = XEXP (contains_minus, 0);
10848 symref = XEXP (minus, 0);
10849 XEXP (contains_minus, 0) = symref;
10850 if (TARGET_ELF)
10851 {
10852 char *newname;
10853
10854 name = XSTR (symref, 0);
10855 newname = alloca (strlen (name) + sizeof ("@toc"));
10856 strcpy (newname, name);
10857 strcat (newname, "@toc");
10858 XSTR (symref, 0) = newname;
10859 }
10860 output_addr_const (file, XEXP (x, 1));
10861 if (TARGET_ELF)
10862 XSTR (symref, 0) = name;
10863 XEXP (contains_minus, 0) = minus;
10864 }
10865 else
10866 output_addr_const (file, XEXP (x, 1));
10867
10868 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
10869 }
10870 else
10871 gcc_unreachable ();
10872 }
10873
10874 /* Target hook for assembling integer objects. The PowerPC version has
10875 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10876 is defined. It also needs to handle DI-mode objects on 64-bit
10877 targets. */
10878
10879 static bool
rs6000_assemble_integer(rtx x,unsigned int size,int aligned_p)10880 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
10881 {
10882 #ifdef RELOCATABLE_NEEDS_FIXUP
10883 /* Special handling for SI values. */
10884 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
10885 {
10886 extern int in_toc_section (void);
10887 static int recurse = 0;
10888
10889 /* For -mrelocatable, we mark all addresses that need to be fixed up
10890 in the .fixup section. */
10891 if (TARGET_RELOCATABLE
10892 && !in_toc_section ()
10893 && !in_text_section ()
10894 && !in_unlikely_text_section ()
10895 && !recurse
10896 && GET_CODE (x) != CONST_INT
10897 && GET_CODE (x) != CONST_DOUBLE
10898 && CONSTANT_P (x))
10899 {
10900 char buf[256];
10901
10902 recurse = 1;
10903 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
10904 fixuplabelno++;
10905 ASM_OUTPUT_LABEL (asm_out_file, buf);
10906 fprintf (asm_out_file, "\t.long\t(");
10907 output_addr_const (asm_out_file, x);
10908 fprintf (asm_out_file, ")@fixup\n");
10909 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
10910 ASM_OUTPUT_ALIGN (asm_out_file, 2);
10911 fprintf (asm_out_file, "\t.long\t");
10912 assemble_name (asm_out_file, buf);
10913 fprintf (asm_out_file, "\n\t.previous\n");
10914 recurse = 0;
10915 return true;
10916 }
10917 /* Remove initial .'s to turn a -mcall-aixdesc function
10918 address into the address of the descriptor, not the function
10919 itself. */
10920 else if (GET_CODE (x) == SYMBOL_REF
10921 && XSTR (x, 0)[0] == '.'
10922 && DEFAULT_ABI == ABI_AIX)
10923 {
10924 const char *name = XSTR (x, 0);
10925 while (*name == '.')
10926 name++;
10927
10928 fprintf (asm_out_file, "\t.long\t%s\n", name);
10929 return true;
10930 }
10931 }
10932 #endif /* RELOCATABLE_NEEDS_FIXUP */
10933 return default_assemble_integer (x, size, aligned_p);
10934 }
10935
10936 #ifdef HAVE_GAS_HIDDEN
10937 /* Emit an assembler directive to set symbol visibility for DECL to
10938 VISIBILITY_TYPE. */
10939
10940 static void
rs6000_assemble_visibility(tree decl,int vis)10941 rs6000_assemble_visibility (tree decl, int vis)
10942 {
10943 /* Functions need to have their entry point symbol visibility set as
10944 well as their descriptor symbol visibility. */
10945 if (DEFAULT_ABI == ABI_AIX
10946 && DOT_SYMBOLS
10947 && TREE_CODE (decl) == FUNCTION_DECL)
10948 {
10949 static const char * const visibility_types[] = {
10950 NULL, "internal", "hidden", "protected"
10951 };
10952
10953 const char *name, *type;
10954
10955 name = ((* targetm.strip_name_encoding)
10956 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
10957 type = visibility_types[vis];
10958
10959 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
10960 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
10961 }
10962 else
10963 default_assemble_visibility (decl, vis);
10964 }
10965 #endif
10966
10967 enum rtx_code
rs6000_reverse_condition(enum machine_mode mode,enum rtx_code code)10968 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
10969 {
10970 /* Reversal of FP compares takes care -- an ordered compare
10971 becomes an unordered compare and vice versa. */
10972 if (mode == CCFPmode
10973 && (!flag_finite_math_only
10974 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
10975 || code == UNEQ || code == LTGT))
10976 return reverse_condition_maybe_unordered (code);
10977 else
10978 return reverse_condition (code);
10979 }
10980
10981 /* Generate a compare for CODE. Return a brand-new rtx that
10982 represents the result of the compare. */
10983
10984 static rtx
rs6000_generate_compare(enum rtx_code code)10985 rs6000_generate_compare (enum rtx_code code)
10986 {
10987 enum machine_mode comp_mode;
10988 rtx compare_result;
10989
10990 if (rs6000_compare_fp_p)
10991 comp_mode = CCFPmode;
10992 else if (code == GTU || code == LTU
10993 || code == GEU || code == LEU)
10994 comp_mode = CCUNSmode;
10995 else if ((code == EQ || code == NE)
10996 && GET_CODE (rs6000_compare_op0) == SUBREG
10997 && GET_CODE (rs6000_compare_op1) == SUBREG
10998 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
10999 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
11000 /* These are unsigned values, perhaps there will be a later
11001 ordering compare that can be shared with this one.
11002 Unfortunately we cannot detect the signedness of the operands
11003 for non-subregs. */
11004 comp_mode = CCUNSmode;
11005 else
11006 comp_mode = CCmode;
11007
11008 /* First, the compare. */
11009 compare_result = gen_reg_rtx (comp_mode);
11010
11011 /* SPE FP compare instructions on the GPRs. Yuck! */
11012 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11013 && rs6000_compare_fp_p)
11014 {
11015 rtx cmp, or_result, compare_result2;
11016 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
11017
11018 if (op_mode == VOIDmode)
11019 op_mode = GET_MODE (rs6000_compare_op1);
11020
11021 /* Note: The E500 comparison instructions set the GT bit (x +
11022 1), on success. This explains the mess. */
11023
11024 switch (code)
11025 {
11026 case EQ: case UNEQ: case NE: case LTGT:
11027 switch (op_mode)
11028 {
11029 case SFmode:
11030 cmp = flag_unsafe_math_optimizations
11031 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
11032 rs6000_compare_op1)
11033 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
11034 rs6000_compare_op1);
11035 break;
11036
11037 case DFmode:
11038 cmp = flag_unsafe_math_optimizations
11039 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
11040 rs6000_compare_op1)
11041 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
11042 rs6000_compare_op1);
11043 break;
11044
11045 default:
11046 gcc_unreachable ();
11047 }
11048 break;
11049
11050 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
11051 switch (op_mode)
11052 {
11053 case SFmode:
11054 cmp = flag_unsafe_math_optimizations
11055 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
11056 rs6000_compare_op1)
11057 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
11058 rs6000_compare_op1);
11059 break;
11060
11061 case DFmode:
11062 cmp = flag_unsafe_math_optimizations
11063 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
11064 rs6000_compare_op1)
11065 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
11066 rs6000_compare_op1);
11067 break;
11068
11069 default:
11070 gcc_unreachable ();
11071 }
11072 break;
11073
11074 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
11075 switch (op_mode)
11076 {
11077 case SFmode:
11078 cmp = flag_unsafe_math_optimizations
11079 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
11080 rs6000_compare_op1)
11081 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
11082 rs6000_compare_op1);
11083 break;
11084
11085 case DFmode:
11086 cmp = flag_unsafe_math_optimizations
11087 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
11088 rs6000_compare_op1)
11089 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
11090 rs6000_compare_op1);
11091 break;
11092
11093 default:
11094 gcc_unreachable ();
11095 }
11096 break;
11097 default:
11098 gcc_unreachable ();
11099 }
11100
11101 /* Synthesize LE and GE from LT/GT || EQ. */
11102 if (code == LE || code == GE || code == LEU || code == GEU)
11103 {
11104 emit_insn (cmp);
11105
11106 switch (code)
11107 {
11108 case LE: code = LT; break;
11109 case GE: code = GT; break;
11110 case LEU: code = LT; break;
11111 case GEU: code = GT; break;
11112 default: gcc_unreachable ();
11113 }
11114
11115 compare_result2 = gen_reg_rtx (CCFPmode);
11116
11117 /* Do the EQ. */
11118 switch (op_mode)
11119 {
11120 case SFmode:
11121 cmp = flag_unsafe_math_optimizations
11122 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
11123 rs6000_compare_op1)
11124 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
11125 rs6000_compare_op1);
11126 break;
11127
11128 case DFmode:
11129 cmp = flag_unsafe_math_optimizations
11130 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
11131 rs6000_compare_op1)
11132 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
11133 rs6000_compare_op1);
11134 break;
11135
11136 default:
11137 gcc_unreachable ();
11138 }
11139 emit_insn (cmp);
11140
11141 /* OR them together. */
11142 or_result = gen_reg_rtx (CCFPmode);
11143 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
11144 compare_result2);
11145 compare_result = or_result;
11146 code = EQ;
11147 }
11148 else
11149 {
11150 if (code == NE || code == LTGT)
11151 code = NE;
11152 else
11153 code = EQ;
11154 }
11155
11156 emit_insn (cmp);
11157 }
11158 else
11159 {
11160 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11161 CLOBBERs to match cmptf_internal2 pattern. */
11162 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11163 && GET_MODE (rs6000_compare_op0) == TFmode
11164 && !TARGET_IEEEQUAD
11165 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11166 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11167 gen_rtvec (9,
11168 gen_rtx_SET (VOIDmode,
11169 compare_result,
11170 gen_rtx_COMPARE (comp_mode,
11171 rs6000_compare_op0,
11172 rs6000_compare_op1)),
11173 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11174 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11175 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11176 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11177 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11178 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11179 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11180 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
11181 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11182 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11183 {
11184 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11185 comp_mode = CCEQmode;
11186 compare_result = gen_reg_rtx (CCEQmode);
11187 if (TARGET_64BIT)
11188 emit_insn (gen_stack_protect_testdi (compare_result,
11189 rs6000_compare_op0, op1));
11190 else
11191 emit_insn (gen_stack_protect_testsi (compare_result,
11192 rs6000_compare_op0, op1));
11193 }
11194 else
11195 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11196 gen_rtx_COMPARE (comp_mode,
11197 rs6000_compare_op0,
11198 rs6000_compare_op1)));
11199 }
11200
11201 /* Some kinds of FP comparisons need an OR operation;
11202 under flag_finite_math_only we don't bother. */
11203 if (rs6000_compare_fp_p
11204 && !flag_finite_math_only
11205 && !(TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
11206 && (code == LE || code == GE
11207 || code == UNEQ || code == LTGT
11208 || code == UNGT || code == UNLT))
11209 {
11210 enum rtx_code or1, or2;
11211 rtx or1_rtx, or2_rtx, compare2_rtx;
11212 rtx or_result = gen_reg_rtx (CCEQmode);
11213
11214 switch (code)
11215 {
11216 case LE: or1 = LT; or2 = EQ; break;
11217 case GE: or1 = GT; or2 = EQ; break;
11218 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11219 case LTGT: or1 = LT; or2 = GT; break;
11220 case UNGT: or1 = UNORDERED; or2 = GT; break;
11221 case UNLT: or1 = UNORDERED; or2 = LT; break;
11222 default: gcc_unreachable ();
11223 }
11224 validate_condition_mode (or1, comp_mode);
11225 validate_condition_mode (or2, comp_mode);
11226 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11227 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
11228 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11229 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11230 const_true_rtx);
11231 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11232
11233 compare_result = or_result;
11234 code = EQ;
11235 }
11236
11237 validate_condition_mode (code, GET_MODE (compare_result));
11238
11239 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
11240 }
11241
11242
11243 /* Emit the RTL for an sCOND pattern. */
11244
11245 void
rs6000_emit_sCOND(enum rtx_code code,rtx result)11246 rs6000_emit_sCOND (enum rtx_code code, rtx result)
11247 {
11248 rtx condition_rtx;
11249 enum machine_mode op_mode;
11250 enum rtx_code cond_code;
11251
11252 condition_rtx = rs6000_generate_compare (code);
11253 cond_code = GET_CODE (condition_rtx);
11254
11255 if (TARGET_E500 && rs6000_compare_fp_p
11256 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11257 {
11258 rtx t;
11259
11260 PUT_MODE (condition_rtx, SImode);
11261 t = XEXP (condition_rtx, 0);
11262
11263 gcc_assert (cond_code == NE || cond_code == EQ);
11264
11265 if (cond_code == NE)
11266 emit_insn (gen_e500_flip_gt_bit (t, t));
11267
11268 emit_insn (gen_move_from_CR_gt_bit (result, t));
11269 return;
11270 }
11271
11272 if (cond_code == NE
11273 || cond_code == GE || cond_code == LE
11274 || cond_code == GEU || cond_code == LEU
11275 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11276 {
11277 rtx not_result = gen_reg_rtx (CCEQmode);
11278 rtx not_op, rev_cond_rtx;
11279 enum machine_mode cc_mode;
11280
11281 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11282
11283 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
11284 SImode, XEXP (condition_rtx, 0), const0_rtx);
11285 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11286 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11287 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11288 }
11289
11290 op_mode = GET_MODE (rs6000_compare_op0);
11291 if (op_mode == VOIDmode)
11292 op_mode = GET_MODE (rs6000_compare_op1);
11293
11294 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11295 {
11296 PUT_MODE (condition_rtx, DImode);
11297 convert_move (result, condition_rtx, 0);
11298 }
11299 else
11300 {
11301 PUT_MODE (condition_rtx, SImode);
11302 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11303 }
11304 }
11305
11306 /* Emit a branch of kind CODE to location LOC. */
11307
11308 void
rs6000_emit_cbranch(enum rtx_code code,rtx loc)11309 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
11310 {
11311 rtx condition_rtx, loc_ref;
11312
11313 condition_rtx = rs6000_generate_compare (code);
11314 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11315 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11316 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11317 loc_ref, pc_rtx)));
11318 }
11319
11320 /* Return the string to output a conditional branch to LABEL, which is
11321 the operand number of the label, or -1 if the branch is really a
11322 conditional return.
11323
11324 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11325 condition code register and its mode specifies what kind of
11326 comparison we made.
11327
11328 REVERSED is nonzero if we should reverse the sense of the comparison.
11329
11330 INSN is the insn. */
11331
11332 char *
output_cbranch(rtx op,const char * label,int reversed,rtx insn)11333 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
11334 {
11335 static char string[64];
11336 enum rtx_code code = GET_CODE (op);
11337 rtx cc_reg = XEXP (op, 0);
11338 enum machine_mode mode = GET_MODE (cc_reg);
11339 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
11340 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
11341 int really_reversed = reversed ^ need_longbranch;
11342 char *s = string;
11343 const char *ccode;
11344 const char *pred;
11345 rtx note;
11346
11347 validate_condition_mode (code, mode);
11348
11349 /* Work out which way this really branches. We could use
11350 reverse_condition_maybe_unordered here always but this
11351 makes the resulting assembler clearer. */
11352 if (really_reversed)
11353 {
11354 /* Reversal of FP compares takes care -- an ordered compare
11355 becomes an unordered compare and vice versa. */
11356 if (mode == CCFPmode)
11357 code = reverse_condition_maybe_unordered (code);
11358 else
11359 code = reverse_condition (code);
11360 }
11361
11362 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
11363 {
11364 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11365 to the GT bit. */
11366 switch (code)
11367 {
11368 case EQ:
11369 /* Opposite of GT. */
11370 code = GT;
11371 break;
11372
11373 case NE:
11374 code = UNLE;
11375 break;
11376
11377 default:
11378 gcc_unreachable ();
11379 }
11380 }
11381
11382 switch (code)
11383 {
11384 /* Not all of these are actually distinct opcodes, but
11385 we distinguish them for clarity of the resulting assembler. */
11386 case NE: case LTGT:
11387 ccode = "ne"; break;
11388 case EQ: case UNEQ:
11389 ccode = "eq"; break;
11390 case GE: case GEU:
11391 ccode = "ge"; break;
11392 case GT: case GTU: case UNGT:
11393 ccode = "gt"; break;
11394 case LE: case LEU:
11395 ccode = "le"; break;
11396 case LT: case LTU: case UNLT:
11397 ccode = "lt"; break;
11398 case UNORDERED: ccode = "un"; break;
11399 case ORDERED: ccode = "nu"; break;
11400 case UNGE: ccode = "nl"; break;
11401 case UNLE: ccode = "ng"; break;
11402 default:
11403 gcc_unreachable ();
11404 }
11405
11406 /* Maybe we have a guess as to how likely the branch is.
11407 The old mnemonics don't have a way to specify this information. */
11408 pred = "";
11409 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11410 if (note != NULL_RTX)
11411 {
11412 /* PROB is the difference from 50%. */
11413 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
11414
11415 /* Only hint for highly probable/improbable branches on newer
11416 cpus as static prediction overrides processor dynamic
11417 prediction. For older cpus we may as well always hint, but
11418 assume not taken for branches that are very close to 50% as a
11419 mispredicted taken branch is more expensive than a
11420 mispredicted not-taken branch. */
11421 if (rs6000_always_hint
11422 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
11423 {
11424 if (abs (prob) > REG_BR_PROB_BASE / 20
11425 && ((prob > 0) ^ need_longbranch))
11426 pred = "+";
11427 else
11428 pred = "-";
11429 }
11430 }
11431
11432 if (label == NULL)
11433 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
11434 else
11435 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
11436
11437 /* We need to escape any '%' characters in the reg_names string.
11438 Assume they'd only be the first character.... */
11439 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11440 *s++ = '%';
11441 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
11442
11443 if (label != NULL)
11444 {
11445 /* If the branch distance was too far, we may have to use an
11446 unconditional branch to go the distance. */
11447 if (need_longbranch)
11448 s += sprintf (s, ",$+8\n\tb %s", label);
11449 else
11450 s += sprintf (s, ",%s", label);
11451 }
11452
11453 return string;
11454 }
11455
11456 /* Return the string to flip the GT bit on a CR. */
11457 char *
output_e500_flip_gt_bit(rtx dst,rtx src)11458 output_e500_flip_gt_bit (rtx dst, rtx src)
11459 {
11460 static char string[64];
11461 int a, b;
11462
11463 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11464 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
11465
11466 /* GT bit. */
11467 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11468 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
11469
11470 sprintf (string, "crnot %d,%d", a, b);
11471 return string;
11472 }
11473
11474 /* Return insn index for the vector compare instruction for given CODE,
11475 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11476 not available. */
11477
11478 static int
get_vec_cmp_insn(enum rtx_code code,enum machine_mode dest_mode,enum machine_mode op_mode)11479 get_vec_cmp_insn (enum rtx_code code,
11480 enum machine_mode dest_mode,
11481 enum machine_mode op_mode)
11482 {
11483 if (!TARGET_ALTIVEC)
11484 return INSN_NOT_AVAILABLE;
11485
11486 switch (code)
11487 {
11488 case EQ:
11489 if (dest_mode == V16QImode && op_mode == V16QImode)
11490 return UNSPEC_VCMPEQUB;
11491 if (dest_mode == V8HImode && op_mode == V8HImode)
11492 return UNSPEC_VCMPEQUH;
11493 if (dest_mode == V4SImode && op_mode == V4SImode)
11494 return UNSPEC_VCMPEQUW;
11495 if (dest_mode == V4SImode && op_mode == V4SFmode)
11496 return UNSPEC_VCMPEQFP;
11497 break;
11498 case GE:
11499 if (dest_mode == V4SImode && op_mode == V4SFmode)
11500 return UNSPEC_VCMPGEFP;
11501 case GT:
11502 if (dest_mode == V16QImode && op_mode == V16QImode)
11503 return UNSPEC_VCMPGTSB;
11504 if (dest_mode == V8HImode && op_mode == V8HImode)
11505 return UNSPEC_VCMPGTSH;
11506 if (dest_mode == V4SImode && op_mode == V4SImode)
11507 return UNSPEC_VCMPGTSW;
11508 if (dest_mode == V4SImode && op_mode == V4SFmode)
11509 return UNSPEC_VCMPGTFP;
11510 break;
11511 case GTU:
11512 if (dest_mode == V16QImode && op_mode == V16QImode)
11513 return UNSPEC_VCMPGTUB;
11514 if (dest_mode == V8HImode && op_mode == V8HImode)
11515 return UNSPEC_VCMPGTUH;
11516 if (dest_mode == V4SImode && op_mode == V4SImode)
11517 return UNSPEC_VCMPGTUW;
11518 break;
11519 default:
11520 break;
11521 }
11522 return INSN_NOT_AVAILABLE;
11523 }
11524
11525 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11526 DMODE is expected destination mode. This is a recursive function. */
11527
11528 static rtx
rs6000_emit_vector_compare(enum rtx_code rcode,rtx op0,rtx op1,enum machine_mode dmode)11529 rs6000_emit_vector_compare (enum rtx_code rcode,
11530 rtx op0, rtx op1,
11531 enum machine_mode dmode)
11532 {
11533 int vec_cmp_insn;
11534 rtx mask;
11535 enum machine_mode dest_mode;
11536 enum machine_mode op_mode = GET_MODE (op1);
11537
11538 gcc_assert (TARGET_ALTIVEC);
11539 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
11540
11541 /* Floating point vector compare instructions uses destination V4SImode.
11542 Move destination to appropriate mode later. */
11543 if (dmode == V4SFmode)
11544 dest_mode = V4SImode;
11545 else
11546 dest_mode = dmode;
11547
11548 mask = gen_reg_rtx (dest_mode);
11549 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11550
11551 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11552 {
11553 bool swap_operands = false;
11554 bool try_again = false;
11555 switch (rcode)
11556 {
11557 case LT:
11558 rcode = GT;
11559 swap_operands = true;
11560 try_again = true;
11561 break;
11562 case LTU:
11563 rcode = GTU;
11564 swap_operands = true;
11565 try_again = true;
11566 break;
11567 case NE:
11568 /* Treat A != B as ~(A==B). */
11569 {
11570 enum insn_code nor_code;
11571 rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11572 dest_mode);
11573
11574 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
11575 gcc_assert (nor_code != CODE_FOR_nothing);
11576 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
11577
11578 if (dmode != dest_mode)
11579 {
11580 rtx temp = gen_reg_rtx (dest_mode);
11581 convert_move (temp, mask, 0);
11582 return temp;
11583 }
11584 return mask;
11585 }
11586 break;
11587 case GE:
11588 case GEU:
11589 case LE:
11590 case LEU:
11591 /* Try GT/GTU/LT/LTU OR EQ */
11592 {
11593 rtx c_rtx, eq_rtx;
11594 enum insn_code ior_code;
11595 enum rtx_code new_code;
11596
11597 switch (rcode)
11598 {
11599 case GE:
11600 new_code = GT;
11601 break;
11602
11603 case GEU:
11604 new_code = GTU;
11605 break;
11606
11607 case LE:
11608 new_code = LT;
11609 break;
11610
11611 case LEU:
11612 new_code = LTU;
11613 break;
11614
11615 default:
11616 gcc_unreachable ();
11617 }
11618
11619 c_rtx = rs6000_emit_vector_compare (new_code,
11620 op0, op1, dest_mode);
11621 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11622 dest_mode);
11623
11624 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
11625 gcc_assert (ior_code != CODE_FOR_nothing);
11626 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
11627 if (dmode != dest_mode)
11628 {
11629 rtx temp = gen_reg_rtx (dest_mode);
11630 convert_move (temp, mask, 0);
11631 return temp;
11632 }
11633 return mask;
11634 }
11635 break;
11636 default:
11637 gcc_unreachable ();
11638 }
11639
11640 if (try_again)
11641 {
11642 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11643 /* You only get two chances. */
11644 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
11645 }
11646
11647 if (swap_operands)
11648 {
11649 rtx tmp;
11650 tmp = op0;
11651 op0 = op1;
11652 op1 = tmp;
11653 }
11654 }
11655
11656 emit_insn (gen_rtx_SET (VOIDmode, mask,
11657 gen_rtx_UNSPEC (dest_mode,
11658 gen_rtvec (2, op0, op1),
11659 vec_cmp_insn)));
11660 if (dmode != dest_mode)
11661 {
11662 rtx temp = gen_reg_rtx (dest_mode);
11663 convert_move (temp, mask, 0);
11664 return temp;
11665 }
11666 return mask;
11667 }
11668
11669 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11670 valid insn doesn exist for given mode. */
11671
11672 static int
get_vsel_insn(enum machine_mode mode)11673 get_vsel_insn (enum machine_mode mode)
11674 {
11675 switch (mode)
11676 {
11677 case V4SImode:
11678 return UNSPEC_VSEL4SI;
11679 break;
11680 case V4SFmode:
11681 return UNSPEC_VSEL4SF;
11682 break;
11683 case V8HImode:
11684 return UNSPEC_VSEL8HI;
11685 break;
11686 case V16QImode:
11687 return UNSPEC_VSEL16QI;
11688 break;
11689 default:
11690 return INSN_NOT_AVAILABLE;
11691 break;
11692 }
11693 return INSN_NOT_AVAILABLE;
11694 }
11695
11696 /* Emit vector select insn where DEST is destination using
11697 operands OP1, OP2 and MASK. */
11698
11699 static void
rs6000_emit_vector_select(rtx dest,rtx op1,rtx op2,rtx mask)11700 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
11701 {
11702 rtx t, temp;
11703 enum machine_mode dest_mode = GET_MODE (dest);
11704 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
11705
11706 temp = gen_reg_rtx (dest_mode);
11707
11708 /* For each vector element, select op1 when mask is 1 otherwise
11709 select op2. */
11710 t = gen_rtx_SET (VOIDmode, temp,
11711 gen_rtx_UNSPEC (dest_mode,
11712 gen_rtvec (3, op2, op1, mask),
11713 vsel_insn_index));
11714 emit_insn (t);
11715 emit_move_insn (dest, temp);
11716 return;
11717 }
11718
11719 /* Emit vector conditional expression.
11720 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11721 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11722
11723 int
rs6000_emit_vector_cond_expr(rtx dest,rtx op1,rtx op2,rtx cond,rtx cc_op0,rtx cc_op1)11724 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
11725 rtx cond, rtx cc_op0, rtx cc_op1)
11726 {
11727 enum machine_mode dest_mode = GET_MODE (dest);
11728 enum rtx_code rcode = GET_CODE (cond);
11729 rtx mask;
11730
11731 if (!TARGET_ALTIVEC)
11732 return 0;
11733
11734 /* Get the vector mask for the given relational operations. */
11735 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
11736
11737 rs6000_emit_vector_select (dest, op1, op2, mask);
11738
11739 return 1;
11740 }
11741
11742 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
11743 operands of the last comparison is nonzero/true, FALSE_COND if it
11744 is zero/false. Return 0 if the hardware has no such operation. */
11745
11746 int
rs6000_emit_cmove(rtx dest,rtx op,rtx true_cond,rtx false_cond)11747 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
11748 {
11749 enum rtx_code code = GET_CODE (op);
11750 rtx op0 = rs6000_compare_op0;
11751 rtx op1 = rs6000_compare_op1;
11752 REAL_VALUE_TYPE c1;
11753 enum machine_mode compare_mode = GET_MODE (op0);
11754 enum machine_mode result_mode = GET_MODE (dest);
11755 rtx temp;
11756 bool is_against_zero;
11757
11758 /* These modes should always match. */
11759 if (GET_MODE (op1) != compare_mode
11760 /* In the isel case however, we can use a compare immediate, so
11761 op1 may be a small constant. */
11762 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
11763 return 0;
11764 if (GET_MODE (true_cond) != result_mode)
11765 return 0;
11766 if (GET_MODE (false_cond) != result_mode)
11767 return 0;
11768
11769 /* First, work out if the hardware can do this at all, or
11770 if it's too slow.... */
11771 if (! rs6000_compare_fp_p)
11772 {
11773 if (TARGET_ISEL)
11774 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
11775 return 0;
11776 }
11777 else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
11778 && GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
11779 return 0;
11780
11781 is_against_zero = op1 == CONST0_RTX (compare_mode);
11782
11783 /* A floating-point subtract might overflow, underflow, or produce
11784 an inexact result, thus changing the floating-point flags, so it
11785 can't be generated if we care about that. It's safe if one side
11786 of the construct is zero, since then no subtract will be
11787 generated. */
11788 if (GET_MODE_CLASS (compare_mode) == MODE_FLOAT
11789 && flag_trapping_math && ! is_against_zero)
11790 return 0;
11791
11792 /* Eliminate half of the comparisons by switching operands, this
11793 makes the remaining code simpler. */
11794 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
11795 || code == LTGT || code == LT || code == UNLE)
11796 {
11797 code = reverse_condition_maybe_unordered (code);
11798 temp = true_cond;
11799 true_cond = false_cond;
11800 false_cond = temp;
11801 }
11802
11803 /* UNEQ and LTGT take four instructions for a comparison with zero,
11804 it'll probably be faster to use a branch here too. */
11805 if (code == UNEQ && HONOR_NANS (compare_mode))
11806 return 0;
11807
11808 if (GET_CODE (op1) == CONST_DOUBLE)
11809 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
11810
11811 /* We're going to try to implement comparisons by performing
11812 a subtract, then comparing against zero. Unfortunately,
11813 Inf - Inf is NaN which is not zero, and so if we don't
11814 know that the operand is finite and the comparison
11815 would treat EQ different to UNORDERED, we can't do it. */
11816 if (HONOR_INFINITIES (compare_mode)
11817 && code != GT && code != UNGE
11818 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
11819 /* Constructs of the form (a OP b ? a : b) are safe. */
11820 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
11821 || (! rtx_equal_p (op0, true_cond)
11822 && ! rtx_equal_p (op1, true_cond))))
11823 return 0;
11824
11825 /* At this point we know we can use fsel. */
11826
11827 /* Reduce the comparison to a comparison against zero. */
11828 if (! is_against_zero)
11829 {
11830 temp = gen_reg_rtx (compare_mode);
11831 emit_insn (gen_rtx_SET (VOIDmode, temp,
11832 gen_rtx_MINUS (compare_mode, op0, op1)));
11833 op0 = temp;
11834 op1 = CONST0_RTX (compare_mode);
11835 }
11836
11837 /* If we don't care about NaNs we can reduce some of the comparisons
11838 down to faster ones. */
11839 if (! HONOR_NANS (compare_mode))
11840 switch (code)
11841 {
11842 case GT:
11843 code = LE;
11844 temp = true_cond;
11845 true_cond = false_cond;
11846 false_cond = temp;
11847 break;
11848 case UNGE:
11849 code = GE;
11850 break;
11851 case UNEQ:
11852 code = EQ;
11853 break;
11854 default:
11855 break;
11856 }
11857
11858 /* Now, reduce everything down to a GE. */
11859 switch (code)
11860 {
11861 case GE:
11862 break;
11863
11864 case LE:
11865 temp = gen_reg_rtx (compare_mode);
11866 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11867 op0 = temp;
11868 break;
11869
11870 case ORDERED:
11871 temp = gen_reg_rtx (compare_mode);
11872 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
11873 op0 = temp;
11874 break;
11875
11876 case EQ:
11877 temp = gen_reg_rtx (compare_mode);
11878 emit_insn (gen_rtx_SET (VOIDmode, temp,
11879 gen_rtx_NEG (compare_mode,
11880 gen_rtx_ABS (compare_mode, op0))));
11881 op0 = temp;
11882 break;
11883
11884 case UNGE:
11885 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
11886 temp = gen_reg_rtx (result_mode);
11887 emit_insn (gen_rtx_SET (VOIDmode, temp,
11888 gen_rtx_IF_THEN_ELSE (result_mode,
11889 gen_rtx_GE (VOIDmode,
11890 op0, op1),
11891 true_cond, false_cond)));
11892 false_cond = true_cond;
11893 true_cond = temp;
11894
11895 temp = gen_reg_rtx (compare_mode);
11896 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11897 op0 = temp;
11898 break;
11899
11900 case GT:
11901 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
11902 temp = gen_reg_rtx (result_mode);
11903 emit_insn (gen_rtx_SET (VOIDmode, temp,
11904 gen_rtx_IF_THEN_ELSE (result_mode,
11905 gen_rtx_GE (VOIDmode,
11906 op0, op1),
11907 true_cond, false_cond)));
11908 true_cond = false_cond;
11909 false_cond = temp;
11910
11911 temp = gen_reg_rtx (compare_mode);
11912 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11913 op0 = temp;
11914 break;
11915
11916 default:
11917 gcc_unreachable ();
11918 }
11919
11920 emit_insn (gen_rtx_SET (VOIDmode, dest,
11921 gen_rtx_IF_THEN_ELSE (result_mode,
11922 gen_rtx_GE (VOIDmode,
11923 op0, op1),
11924 true_cond, false_cond)));
11925 return 1;
11926 }
11927
11928 /* Same as above, but for ints (isel). */
11929
11930 static int
rs6000_emit_int_cmove(rtx dest,rtx op,rtx true_cond,rtx false_cond)11931 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
11932 {
11933 rtx condition_rtx, cr;
11934
11935 /* All isel implementations thus far are 32-bits. */
11936 if (GET_MODE (rs6000_compare_op0) != SImode)
11937 return 0;
11938
11939 /* We still have to do the compare, because isel doesn't do a
11940 compare, it just looks at the CRx bits set by a previous compare
11941 instruction. */
11942 condition_rtx = rs6000_generate_compare (GET_CODE (op));
11943 cr = XEXP (condition_rtx, 0);
11944
11945 if (GET_MODE (cr) == CCmode)
11946 emit_insn (gen_isel_signed (dest, condition_rtx,
11947 true_cond, false_cond, cr));
11948 else
11949 emit_insn (gen_isel_unsigned (dest, condition_rtx,
11950 true_cond, false_cond, cr));
11951
11952 return 1;
11953 }
11954
11955 const char *
output_isel(rtx * operands)11956 output_isel (rtx *operands)
11957 {
11958 enum rtx_code code;
11959
11960 code = GET_CODE (operands[1]);
11961 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
11962 {
11963 PUT_CODE (operands[1], reverse_condition (code));
11964 return "isel %0,%3,%2,%j1";
11965 }
11966 else
11967 return "isel %0,%2,%3,%j1";
11968 }
11969
11970 void
rs6000_emit_minmax(rtx dest,enum rtx_code code,rtx op0,rtx op1)11971 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
11972 {
11973 enum machine_mode mode = GET_MODE (op0);
11974 enum rtx_code c;
11975 rtx target;
11976
11977 if (code == SMAX || code == SMIN)
11978 c = GE;
11979 else
11980 c = GEU;
11981
11982 if (code == SMAX || code == UMAX)
11983 target = emit_conditional_move (dest, c, op0, op1, mode,
11984 op0, op1, mode, 0);
11985 else
11986 target = emit_conditional_move (dest, c, op0, op1, mode,
11987 op1, op0, mode, 0);
11988 gcc_assert (target);
11989 if (target != dest)
11990 emit_move_insn (dest, target);
11991 }
11992
11993 /* Emit instructions to perform a load-reserved/store-conditional operation.
11994 The operation performed is an atomic
11995 (set M (CODE:MODE M OP))
11996 If not NULL, BEFORE is atomically set to M before the operation, and
11997 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
11998 If SYNC_P then a memory barrier is emitted before the operation.
11999 Either OP or M may be wrapped in a NOT operation. */
12000
12001 void
rs6000_emit_sync(enum rtx_code code,enum machine_mode mode,rtx m,rtx op,rtx before_param,rtx after_param,bool sync_p)12002 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
12003 rtx m, rtx op, rtx before_param, rtx after_param,
12004 bool sync_p)
12005 {
12006 enum machine_mode used_mode;
12007 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
12008 rtx used_m;
12009 rtvec vec;
12010 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12011 rtx shift = NULL_RTX;
12012
12013 if (sync_p)
12014 emit_insn (gen_memory_barrier ());
12015
12016 if (GET_CODE (m) == NOT)
12017 used_m = XEXP (m, 0);
12018 else
12019 used_m = m;
12020
12021 /* If this is smaller than SImode, we'll have to use SImode with
12022 adjustments. */
12023 if (mode == QImode || mode == HImode)
12024 {
12025 rtx newop, oldop;
12026
12027 if (MEM_ALIGN (used_m) >= 32)
12028 {
12029 int ishift = 0;
12030 if (BYTES_BIG_ENDIAN)
12031 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
12032
12033 shift = GEN_INT (ishift);
12034 }
12035 else
12036 {
12037 rtx addrSI, aligned_addr;
12038 int shift_mask = mode == QImode ? 0x18 : 0x10;
12039
12040 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
12041 XEXP (used_m, 0)));
12042 shift = gen_reg_rtx (SImode);
12043
12044 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12045 GEN_INT (shift_mask)));
12046 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12047
12048 aligned_addr = expand_binop (Pmode, and_optab,
12049 XEXP (used_m, 0),
12050 GEN_INT (-4), NULL_RTX,
12051 1, OPTAB_LIB_WIDEN);
12052 used_m = change_address (used_m, SImode, aligned_addr);
12053 set_mem_align (used_m, 32);
12054 /* It's safe to keep the old alias set of USED_M, because
12055 the operation is atomic and only affects the original
12056 USED_M. */
12057 if (GET_CODE (m) == NOT)
12058 m = gen_rtx_NOT (SImode, used_m);
12059 else
12060 m = used_m;
12061 }
12062
12063 if (GET_CODE (op) == NOT)
12064 {
12065 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
12066 oldop = gen_rtx_NOT (SImode, oldop);
12067 }
12068 else
12069 oldop = lowpart_subreg (SImode, op, mode);
12070
12071 switch (code)
12072 {
12073 case IOR:
12074 case XOR:
12075 newop = expand_binop (SImode, and_optab,
12076 oldop, GEN_INT (imask), NULL_RTX,
12077 1, OPTAB_LIB_WIDEN);
12078 emit_insn (gen_ashlsi3 (newop, newop, shift));
12079 break;
12080
12081 case AND:
12082 newop = expand_binop (SImode, ior_optab,
12083 oldop, GEN_INT (~imask), NULL_RTX,
12084 1, OPTAB_LIB_WIDEN);
12085 emit_insn (gen_rotlsi3 (newop, newop, shift));
12086 break;
12087
12088 case PLUS:
12089 case MINUS:
12090 {
12091 rtx mask;
12092
12093 newop = expand_binop (SImode, and_optab,
12094 oldop, GEN_INT (imask), NULL_RTX,
12095 1, OPTAB_LIB_WIDEN);
12096 emit_insn (gen_ashlsi3 (newop, newop, shift));
12097
12098 mask = gen_reg_rtx (SImode);
12099 emit_move_insn (mask, GEN_INT (imask));
12100 emit_insn (gen_ashlsi3 (mask, mask, shift));
12101
12102 if (code == PLUS)
12103 newop = gen_rtx_PLUS (SImode, m, newop);
12104 else
12105 newop = gen_rtx_MINUS (SImode, m, newop);
12106 newop = gen_rtx_AND (SImode, newop, mask);
12107 newop = gen_rtx_IOR (SImode, newop,
12108 gen_rtx_AND (SImode,
12109 gen_rtx_NOT (SImode, mask),
12110 m));
12111 break;
12112 }
12113
12114 default:
12115 gcc_unreachable ();
12116 }
12117
12118 if (GET_CODE (m) == NOT)
12119 {
12120 rtx mask, xorm;
12121
12122 mask = gen_reg_rtx (SImode);
12123 emit_move_insn (mask, GEN_INT (imask));
12124 emit_insn (gen_ashlsi3 (mask, mask, shift));
12125
12126 xorm = gen_rtx_XOR (SImode, used_m, mask);
12127 /* Depending on the value of 'op', the XOR or the operation might
12128 be able to be simplified away. */
12129 newop = simplify_gen_binary (code, SImode, xorm, newop);
12130 }
12131 op = newop;
12132 used_mode = SImode;
12133 before = gen_reg_rtx (used_mode);
12134 after = gen_reg_rtx (used_mode);
12135 }
12136 else
12137 {
12138 used_mode = mode;
12139 before = before_param;
12140 after = after_param;
12141
12142 if (before == NULL_RTX)
12143 before = gen_reg_rtx (used_mode);
12144 if (after == NULL_RTX)
12145 after = gen_reg_rtx (used_mode);
12146 }
12147
12148 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
12149 && used_mode != mode)
12150 the_op = op; /* Computed above. */
12151 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
12152 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12153 else
12154 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12155
12156 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12157 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12158 set_atomic = gen_rtx_SET (VOIDmode, used_m,
12159 gen_rtx_UNSPEC (used_mode,
12160 gen_rtvec (1, the_op),
12161 UNSPEC_SYNC_OP));
12162 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12163
12164 if ((code == PLUS || code == MINUS) && used_mode != mode)
12165 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12166 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12167 else
12168 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12169 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12170
12171 /* Shift and mask the return values properly. */
12172 if (used_mode != mode && before_param)
12173 {
12174 emit_insn (gen_lshrsi3 (before, before, shift));
12175 convert_move (before_param, before, 1);
12176 }
12177
12178 if (used_mode != mode && after_param)
12179 {
12180 emit_insn (gen_lshrsi3 (after, after, shift));
12181 convert_move (after_param, after, 1);
12182 }
12183
12184 /* The previous sequence will end with a branch that's dependent on
12185 the conditional store, so placing an isync will ensure that no
12186 other instructions (especially, no load or store instructions)
12187 can start before the atomic operation completes. */
12188 if (sync_p)
12189 emit_insn (gen_isync ());
12190 }
12191
12192 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12193 COND is true. Mark the jump as unlikely to be taken. */
12194
12195 static void
emit_unlikely_jump(rtx cond,rtx label)12196 emit_unlikely_jump (rtx cond, rtx label)
12197 {
12198 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12199 rtx x;
12200
12201 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12202 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12203 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12204 }
12205
12206 /* A subroutine of the atomic operation splitters. Emit a load-locked
12207 instruction in MODE. */
12208
12209 static void
emit_load_locked(enum machine_mode mode,rtx reg,rtx mem)12210 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12211 {
12212 rtx (*fn) (rtx, rtx) = NULL;
12213 if (mode == SImode)
12214 fn = gen_load_locked_si;
12215 else if (mode == DImode)
12216 fn = gen_load_locked_di;
12217 emit_insn (fn (reg, mem));
12218 }
12219
12220 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12221 instruction in MODE. */
12222
12223 static void
emit_store_conditional(enum machine_mode mode,rtx res,rtx mem,rtx val)12224 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12225 {
12226 rtx (*fn) (rtx, rtx, rtx) = NULL;
12227 if (mode == SImode)
12228 fn = gen_store_conditional_si;
12229 else if (mode == DImode)
12230 fn = gen_store_conditional_di;
12231
12232 /* Emit sync before stwcx. to address PPC405 Erratum. */
12233 if (PPC405_ERRATUM77)
12234 emit_insn (gen_memory_barrier ());
12235
12236 emit_insn (fn (res, mem, val));
12237 }
12238
12239 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12240 to perform. MEM is the memory on which to operate. VAL is the second
12241 operand of the binary operator. BEFORE and AFTER are optional locations to
12242 return the value of MEM either before of after the operation. SCRATCH is
12243 a scratch register. */
12244
12245 void
rs6000_split_atomic_op(enum rtx_code code,rtx mem,rtx val,rtx before,rtx after,rtx scratch)12246 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12247 rtx before, rtx after, rtx scratch)
12248 {
12249 enum machine_mode mode = GET_MODE (mem);
12250 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12251
12252 emit_insn (gen_memory_barrier ());
12253
12254 label = gen_label_rtx ();
12255 emit_label (label);
12256 label = gen_rtx_LABEL_REF (VOIDmode, label);
12257
12258 if (before == NULL_RTX)
12259 before = scratch;
12260 emit_load_locked (mode, before, mem);
12261
12262 if (code == NOT)
12263 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12264 else if (code == AND)
12265 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12266 else
12267 x = gen_rtx_fmt_ee (code, mode, before, val);
12268
12269 if (after != NULL_RTX)
12270 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12271 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12272
12273 emit_store_conditional (mode, cond, mem, scratch);
12274
12275 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12276 emit_unlikely_jump (x, label);
12277
12278 emit_insn (gen_isync ());
12279 }
12280
12281 /* Expand an atomic compare and swap operation. MEM is the memory on which
12282 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12283 value to be stored. SCRATCH is a scratch GPR. */
12284
12285 void
rs6000_split_compare_and_swap(rtx retval,rtx mem,rtx oldval,rtx newval,rtx scratch)12286 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12287 rtx scratch)
12288 {
12289 enum machine_mode mode = GET_MODE (mem);
12290 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12291
12292 emit_insn (gen_memory_barrier ());
12293
12294 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12295 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12296 emit_label (XEXP (label1, 0));
12297
12298 emit_load_locked (mode, retval, mem);
12299
12300 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12301 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12302
12303 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12304 emit_unlikely_jump (x, label2);
12305
12306 emit_move_insn (scratch, newval);
12307 emit_store_conditional (mode, cond, mem, scratch);
12308
12309 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12310 emit_unlikely_jump (x, label1);
12311
12312 emit_insn (gen_isync ());
12313 emit_label (XEXP (label2, 0));
12314 }
12315
12316 /* Expand an atomic test and set operation. MEM is the memory on which
12317 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12318
12319 void
rs6000_split_lock_test_and_set(rtx retval,rtx mem,rtx val,rtx scratch)12320 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12321 {
12322 enum machine_mode mode = GET_MODE (mem);
12323 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12324
12325 emit_insn (gen_memory_barrier ());
12326
12327 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12328 emit_label (XEXP (label, 0));
12329
12330 emit_load_locked (mode, retval, mem);
12331 emit_move_insn (scratch, val);
12332 emit_store_conditional (mode, cond, mem, scratch);
12333
12334 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12335 emit_unlikely_jump (x, label);
12336
12337 emit_insn (gen_isync ());
12338 }
12339
12340 /* Emit instructions to move SRC to DST. Called by splitters for
12341 multi-register moves. It will emit at most one instruction for
12342 each register that is accessed; that is, it won't emit li/lis pairs
12343 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12344 register. */
12345
12346 void
rs6000_split_multireg_move(rtx dst,rtx src)12347 rs6000_split_multireg_move (rtx dst, rtx src)
12348 {
12349 /* The register number of the first register being moved. */
12350 int reg;
12351 /* The mode that is to be moved. */
12352 enum machine_mode mode;
12353 /* The mode that the move is being done in, and its size. */
12354 enum machine_mode reg_mode;
12355 int reg_mode_size;
12356 /* The number of registers that will be moved. */
12357 int nregs;
12358
12359 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12360 mode = GET_MODE (dst);
12361 nregs = hard_regno_nregs[reg][mode];
12362 if (FP_REGNO_P (reg))
12363 reg_mode = DFmode;
12364 else if (ALTIVEC_REGNO_P (reg))
12365 reg_mode = V16QImode;
12366 else
12367 reg_mode = word_mode;
12368 reg_mode_size = GET_MODE_SIZE (reg_mode);
12369
12370 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
12371
12372 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12373 {
12374 /* Move register range backwards, if we might have destructive
12375 overlap. */
12376 int i;
12377 for (i = nregs - 1; i >= 0; i--)
12378 emit_insn (gen_rtx_SET (VOIDmode,
12379 simplify_gen_subreg (reg_mode, dst, mode,
12380 i * reg_mode_size),
12381 simplify_gen_subreg (reg_mode, src, mode,
12382 i * reg_mode_size)));
12383 }
12384 else
12385 {
12386 int i;
12387 int j = -1;
12388 bool used_update = false;
12389
12390 if (MEM_P (src) && INT_REGNO_P (reg))
12391 {
12392 rtx breg;
12393
12394 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12395 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
12396 {
12397 rtx delta_rtx;
12398 breg = XEXP (XEXP (src, 0), 0);
12399 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12400 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12401 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
12402 emit_insn (TARGET_32BIT
12403 ? gen_addsi3 (breg, breg, delta_rtx)
12404 : gen_adddi3 (breg, breg, delta_rtx));
12405 src = replace_equiv_address (src, breg);
12406 }
12407 else if (! offsettable_memref_p (src))
12408 {
12409 rtx basereg;
12410 basereg = gen_rtx_REG (Pmode, reg);
12411 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
12412 src = replace_equiv_address (src, basereg);
12413 }
12414
12415 breg = XEXP (src, 0);
12416 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12417 breg = XEXP (breg, 0);
12418
12419 /* If the base register we are using to address memory is
12420 also a destination reg, then change that register last. */
12421 if (REG_P (breg)
12422 && REGNO (breg) >= REGNO (dst)
12423 && REGNO (breg) < REGNO (dst) + nregs)
12424 j = REGNO (breg) - REGNO (dst);
12425 }
12426
12427 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
12428 {
12429 rtx breg;
12430
12431 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12432 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
12433 {
12434 rtx delta_rtx;
12435 breg = XEXP (XEXP (dst, 0), 0);
12436 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12437 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12438 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
12439
12440 /* We have to update the breg before doing the store.
12441 Use store with update, if available. */
12442
12443 if (TARGET_UPDATE)
12444 {
12445 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
12446 emit_insn (TARGET_32BIT
12447 ? (TARGET_POWERPC64
12448 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12449 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12450 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
12451 used_update = true;
12452 }
12453 else
12454 emit_insn (TARGET_32BIT
12455 ? gen_addsi3 (breg, breg, delta_rtx)
12456 : gen_adddi3 (breg, breg, delta_rtx));
12457 dst = replace_equiv_address (dst, breg);
12458 }
12459 else
12460 gcc_assert (offsettable_memref_p (dst));
12461 }
12462
12463 for (i = 0; i < nregs; i++)
12464 {
12465 /* Calculate index to next subword. */
12466 ++j;
12467 if (j == nregs)
12468 j = 0;
12469
12470 /* If compiler already emitted move of first word by
12471 store with update, no need to do anything. */
12472 if (j == 0 && used_update)
12473 continue;
12474
12475 emit_insn (gen_rtx_SET (VOIDmode,
12476 simplify_gen_subreg (reg_mode, dst, mode,
12477 j * reg_mode_size),
12478 simplify_gen_subreg (reg_mode, src, mode,
12479 j * reg_mode_size)));
12480 }
12481 }
12482 }
12483
12484
12485 /* This page contains routines that are used to determine what the
12486 function prologue and epilogue code will do and write them out. */
12487
12488 /* Return the first fixed-point register that is required to be
12489 saved. 32 if none. */
12490
12491 int
first_reg_to_save(void)12492 first_reg_to_save (void)
12493 {
12494 int first_reg;
12495
12496 /* Find lowest numbered live register. */
12497 for (first_reg = 13; first_reg <= 31; first_reg++)
12498 if (regs_ever_live[first_reg]
12499 && (! call_used_regs[first_reg]
12500 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
12501 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
12502 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
12503 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
12504 break;
12505
12506 #if TARGET_MACHO
12507 if (flag_pic
12508 && current_function_uses_pic_offset_table
12509 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
12510 return RS6000_PIC_OFFSET_TABLE_REGNUM;
12511 #endif
12512
12513 return first_reg;
12514 }
12515
12516 /* Similar, for FP regs. */
12517
12518 int
first_fp_reg_to_save(void)12519 first_fp_reg_to_save (void)
12520 {
12521 int first_reg;
12522
12523 /* Find lowest numbered live register. */
12524 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
12525 if (regs_ever_live[first_reg])
12526 break;
12527
12528 return first_reg;
12529 }
12530
12531 /* Similar, for AltiVec regs. */
12532
12533 static int
first_altivec_reg_to_save(void)12534 first_altivec_reg_to_save (void)
12535 {
12536 int i;
12537
12538 /* Stack frame remains as is unless we are in AltiVec ABI. */
12539 if (! TARGET_ALTIVEC_ABI)
12540 return LAST_ALTIVEC_REGNO + 1;
12541
12542 /* Find lowest numbered live register. */
12543 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
12544 if (regs_ever_live[i])
12545 break;
12546
12547 return i;
12548 }
12549
12550 /* Return a 32-bit mask of the AltiVec registers we need to set in
12551 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12552 the 32-bit word is 0. */
12553
12554 static unsigned int
compute_vrsave_mask(void)12555 compute_vrsave_mask (void)
12556 {
12557 unsigned int i, mask = 0;
12558
12559 /* First, find out if we use _any_ altivec registers. */
12560 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
12561 if (regs_ever_live[i])
12562 mask |= ALTIVEC_REG_BIT (i);
12563
12564 if (mask == 0)
12565 return mask;
12566
12567 /* Next, remove the argument registers from the set. These must
12568 be in the VRSAVE mask set by the caller, so we don't need to add
12569 them in again. More importantly, the mask we compute here is
12570 used to generate CLOBBERs in the set_vrsave insn, and we do not
12571 wish the argument registers to die. */
12572 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
12573 mask &= ~ALTIVEC_REG_BIT (i);
12574
12575 /* Similarly, remove the return value from the set. */
12576 {
12577 bool yes = false;
12578 diddle_return_value (is_altivec_return_reg, &yes);
12579 if (yes)
12580 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
12581 }
12582
12583 return mask;
12584 }
12585
12586 /* For a very restricted set of circumstances, we can cut down the
12587 size of prologues/epilogues by calling our own save/restore-the-world
12588 routines. */
12589
12590 static void
compute_save_world_info(rs6000_stack_t * info_ptr)12591 compute_save_world_info (rs6000_stack_t *info_ptr)
12592 {
12593 info_ptr->world_save_p = 1;
12594 info_ptr->world_save_p
12595 = (WORLD_SAVE_P (info_ptr)
12596 && DEFAULT_ABI == ABI_DARWIN
12597 && ! (current_function_calls_setjmp && flag_exceptions)
12598 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
12599 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
12600 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
12601 && info_ptr->cr_save_p);
12602
12603 /* This will not work in conjunction with sibcalls. Make sure there
12604 are none. (This check is expensive, but seldom executed.) */
12605 if (WORLD_SAVE_P (info_ptr))
12606 {
12607 rtx insn;
12608 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
12609 if ( GET_CODE (insn) == CALL_INSN
12610 && SIBLING_CALL_P (insn))
12611 {
12612 info_ptr->world_save_p = 0;
12613 break;
12614 }
12615 }
12616
12617 if (WORLD_SAVE_P (info_ptr))
12618 {
12619 /* Even if we're not touching VRsave, make sure there's room on the
12620 stack for it, if it looks like we're calling SAVE_WORLD, which
12621 will attempt to save it. */
12622 info_ptr->vrsave_size = 4;
12623
12624 /* "Save" the VRsave register too if we're saving the world. */
12625 if (info_ptr->vrsave_mask == 0)
12626 info_ptr->vrsave_mask = compute_vrsave_mask ();
12627
12628 /* Because the Darwin register save/restore routines only handle
12629 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
12630 check. */
12631 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
12632 && (info_ptr->first_altivec_reg_save
12633 >= FIRST_SAVED_ALTIVEC_REGNO));
12634 }
12635 return;
12636 }
12637
12638
12639 static void
is_altivec_return_reg(rtx reg,void * xyes)12640 is_altivec_return_reg (rtx reg, void *xyes)
12641 {
12642 bool *yes = (bool *) xyes;
12643 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
12644 *yes = true;
12645 }
12646
12647
12648 /* Calculate the stack information for the current function. This is
12649 complicated by having two separate calling sequences, the AIX calling
12650 sequence and the V.4 calling sequence.
12651
12652 AIX (and Darwin/Mac OS X) stack frames look like:
12653 32-bit 64-bit
12654 SP----> +---------------------------------------+
12655 | back chain to caller | 0 0
12656 +---------------------------------------+
12657 | saved CR | 4 8 (8-11)
12658 +---------------------------------------+
12659 | saved LR | 8 16
12660 +---------------------------------------+
12661 | reserved for compilers | 12 24
12662 +---------------------------------------+
12663 | reserved for binders | 16 32
12664 +---------------------------------------+
12665 | saved TOC pointer | 20 40
12666 +---------------------------------------+
12667 | Parameter save area (P) | 24 48
12668 +---------------------------------------+
12669 | Alloca space (A) | 24+P etc.
12670 +---------------------------------------+
12671 | Local variable space (L) | 24+P+A
12672 +---------------------------------------+
12673 | Float/int conversion temporary (X) | 24+P+A+L
12674 +---------------------------------------+
12675 | Save area for AltiVec registers (W) | 24+P+A+L+X
12676 +---------------------------------------+
12677 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
12678 +---------------------------------------+
12679 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
12680 +---------------------------------------+
12681 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
12682 +---------------------------------------+
12683 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
12684 +---------------------------------------+
12685 old SP->| back chain to caller's caller |
12686 +---------------------------------------+
12687
12688 The required alignment for AIX configurations is two words (i.e., 8
12689 or 16 bytes).
12690
12691
12692 V.4 stack frames look like:
12693
12694 SP----> +---------------------------------------+
12695 | back chain to caller | 0
12696 +---------------------------------------+
12697 | caller's saved LR | 4
12698 +---------------------------------------+
12699 | Parameter save area (P) | 8
12700 +---------------------------------------+
12701 | Alloca space (A) | 8+P
12702 +---------------------------------------+
12703 | Varargs save area (V) | 8+P+A
12704 +---------------------------------------+
12705 | Local variable space (L) | 8+P+A+V
12706 +---------------------------------------+
12707 | Float/int conversion temporary (X) | 8+P+A+V+L
12708 +---------------------------------------+
12709 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
12710 +---------------------------------------+
12711 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
12712 +---------------------------------------+
12713 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
12714 +---------------------------------------+
12715 | SPE: area for 64-bit GP registers |
12716 +---------------------------------------+
12717 | SPE alignment padding |
12718 +---------------------------------------+
12719 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
12720 +---------------------------------------+
12721 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
12722 +---------------------------------------+
12723 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
12724 +---------------------------------------+
12725 old SP->| back chain to caller's caller |
12726 +---------------------------------------+
12727
12728 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
12729 given. (But note below and in sysv4.h that we require only 8 and
12730 may round up the size of our stack frame anyways. The historical
12731 reason is early versions of powerpc-linux which didn't properly
12732 align the stack at program startup. A happy side-effect is that
12733 -mno-eabi libraries can be used with -meabi programs.)
12734
12735 The EABI configuration defaults to the V.4 layout. However,
12736 the stack alignment requirements may differ. If -mno-eabi is not
12737 given, the required stack alignment is 8 bytes; if -mno-eabi is
12738 given, the required alignment is 16 bytes. (But see V.4 comment
12739 above.) */
12740
12741 #ifndef ABI_STACK_BOUNDARY
12742 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
12743 #endif
12744
12745 static rs6000_stack_t *
rs6000_stack_info(void)12746 rs6000_stack_info (void)
12747 {
12748 static rs6000_stack_t info, zero_info;
12749 rs6000_stack_t *info_ptr = &info;
12750 int reg_size = TARGET_32BIT ? 4 : 8;
12751 int ehrd_size;
12752 int save_align;
12753 HOST_WIDE_INT non_fixed_size;
12754
12755 /* Zero all fields portably. */
12756 info = zero_info;
12757
12758 if (TARGET_SPE)
12759 {
12760 /* Cache value so we don't rescan instruction chain over and over. */
12761 if (cfun->machine->insn_chain_scanned_p == 0)
12762 cfun->machine->insn_chain_scanned_p
12763 = spe_func_has_64bit_regs_p () + 1;
12764 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
12765 }
12766
12767 /* Select which calling sequence. */
12768 info_ptr->abi = DEFAULT_ABI;
12769
12770 /* Calculate which registers need to be saved & save area size. */
12771 info_ptr->first_gp_reg_save = first_reg_to_save ();
12772 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
12773 even if it currently looks like we won't. */
12774 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
12775 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
12776 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
12777 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
12778 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
12779 else
12780 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
12781
12782 /* For the SPE, we have an additional upper 32-bits on each GPR.
12783 Ideally we should save the entire 64-bits only when the upper
12784 half is used in SIMD instructions. Since we only record
12785 registers live (not the size they are used in), this proves
12786 difficult because we'd have to traverse the instruction chain at
12787 the right time, taking reload into account. This is a real pain,
12788 so we opt to save the GPRs in 64-bits always if but one register
12789 gets used in 64-bits. Otherwise, all the registers in the frame
12790 get saved in 32-bits.
12791
12792 So... since when we save all GPRs (except the SP) in 64-bits, the
12793 traditional GP save area will be empty. */
12794 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12795 info_ptr->gp_size = 0;
12796
12797 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
12798 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
12799
12800 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
12801 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
12802 - info_ptr->first_altivec_reg_save);
12803
12804 /* Does this function call anything? */
12805 info_ptr->calls_p = (! current_function_is_leaf
12806 || cfun->machine->ra_needs_full_frame);
12807
12808 /* Determine if we need to save the link register. */
12809 if (rs6000_ra_ever_killed ()
12810 || (DEFAULT_ABI == ABI_AIX
12811 && current_function_profile
12812 && !TARGET_PROFILE_KERNEL)
12813 #ifdef TARGET_RELOCATABLE
12814 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
12815 #endif
12816 || (info_ptr->first_fp_reg_save != 64
12817 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
12818 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
12819 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
12820 || info_ptr->calls_p)
12821 {
12822 info_ptr->lr_save_p = 1;
12823 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
12824 }
12825
12826 /* Determine if we need to save the condition code registers. */
12827 if (regs_ever_live[CR2_REGNO]
12828 || regs_ever_live[CR3_REGNO]
12829 || regs_ever_live[CR4_REGNO])
12830 {
12831 info_ptr->cr_save_p = 1;
12832 if (DEFAULT_ABI == ABI_V4)
12833 info_ptr->cr_size = reg_size;
12834 }
12835
12836 /* If the current function calls __builtin_eh_return, then we need
12837 to allocate stack space for registers that will hold data for
12838 the exception handler. */
12839 if (current_function_calls_eh_return)
12840 {
12841 unsigned int i;
12842 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
12843 continue;
12844
12845 /* SPE saves EH registers in 64-bits. */
12846 ehrd_size = i * (TARGET_SPE_ABI
12847 && info_ptr->spe_64bit_regs_used != 0
12848 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
12849 }
12850 else
12851 ehrd_size = 0;
12852
12853 /* Determine various sizes. */
12854 info_ptr->reg_size = reg_size;
12855 info_ptr->fixed_size = RS6000_SAVE_AREA;
12856 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
12857 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
12858 TARGET_ALTIVEC ? 16 : 8);
12859 if (FRAME_GROWS_DOWNWARD)
12860 info_ptr->vars_size
12861 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
12862 + info_ptr->parm_size,
12863 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
12864 - (info_ptr->fixed_size + info_ptr->vars_size
12865 + info_ptr->parm_size);
12866
12867 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12868 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
12869 else
12870 info_ptr->spe_gp_size = 0;
12871
12872 if (TARGET_ALTIVEC_ABI)
12873 info_ptr->vrsave_mask = compute_vrsave_mask ();
12874 else
12875 info_ptr->vrsave_mask = 0;
12876
12877 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
12878 info_ptr->vrsave_size = 4;
12879 else
12880 info_ptr->vrsave_size = 0;
12881
12882 compute_save_world_info (info_ptr);
12883
12884 /* Calculate the offsets. */
12885 switch (DEFAULT_ABI)
12886 {
12887 case ABI_NONE:
12888 default:
12889 gcc_unreachable ();
12890
12891 case ABI_AIX:
12892 case ABI_DARWIN:
12893 info_ptr->fp_save_offset = - info_ptr->fp_size;
12894 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
12895
12896 if (TARGET_ALTIVEC_ABI)
12897 {
12898 info_ptr->vrsave_save_offset
12899 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
12900
12901 /* Align stack so vector save area is on a quadword boundary. */
12902 if (info_ptr->altivec_size != 0)
12903 info_ptr->altivec_padding_size
12904 = 16 - (-info_ptr->vrsave_save_offset % 16);
12905 else
12906 info_ptr->altivec_padding_size = 0;
12907
12908 info_ptr->altivec_save_offset
12909 = info_ptr->vrsave_save_offset
12910 - info_ptr->altivec_padding_size
12911 - info_ptr->altivec_size;
12912
12913 /* Adjust for AltiVec case. */
12914 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
12915 }
12916 else
12917 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
12918 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
12919 info_ptr->lr_save_offset = 2*reg_size;
12920 break;
12921
12922 case ABI_V4:
12923 info_ptr->fp_save_offset = - info_ptr->fp_size;
12924 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
12925 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
12926
12927 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12928 {
12929 /* Align stack so SPE GPR save area is aligned on a
12930 double-word boundary. */
12931 if (info_ptr->spe_gp_size != 0)
12932 info_ptr->spe_padding_size
12933 = 8 - (-info_ptr->cr_save_offset % 8);
12934 else
12935 info_ptr->spe_padding_size = 0;
12936
12937 info_ptr->spe_gp_save_offset
12938 = info_ptr->cr_save_offset
12939 - info_ptr->spe_padding_size
12940 - info_ptr->spe_gp_size;
12941
12942 /* Adjust for SPE case. */
12943 info_ptr->toc_save_offset
12944 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
12945 }
12946 else if (TARGET_ALTIVEC_ABI)
12947 {
12948 info_ptr->vrsave_save_offset
12949 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
12950
12951 /* Align stack so vector save area is on a quadword boundary. */
12952 if (info_ptr->altivec_size != 0)
12953 info_ptr->altivec_padding_size
12954 = 16 - (-info_ptr->vrsave_save_offset % 16);
12955 else
12956 info_ptr->altivec_padding_size = 0;
12957
12958 info_ptr->altivec_save_offset
12959 = info_ptr->vrsave_save_offset
12960 - info_ptr->altivec_padding_size
12961 - info_ptr->altivec_size;
12962
12963 /* Adjust for AltiVec case. */
12964 info_ptr->toc_save_offset
12965 = info_ptr->altivec_save_offset - info_ptr->toc_size;
12966 }
12967 else
12968 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
12969 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
12970 info_ptr->lr_save_offset = reg_size;
12971 break;
12972 }
12973
12974 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
12975 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
12976 + info_ptr->gp_size
12977 + info_ptr->altivec_size
12978 + info_ptr->altivec_padding_size
12979 + info_ptr->spe_gp_size
12980 + info_ptr->spe_padding_size
12981 + ehrd_size
12982 + info_ptr->cr_size
12983 + info_ptr->lr_size
12984 + info_ptr->vrsave_size
12985 + info_ptr->toc_size,
12986 save_align);
12987
12988 non_fixed_size = (info_ptr->vars_size
12989 + info_ptr->parm_size
12990 + info_ptr->save_size);
12991
12992 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
12993 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
12994
12995 /* Determine if we need to allocate any stack frame:
12996
12997 For AIX we need to push the stack if a frame pointer is needed
12998 (because the stack might be dynamically adjusted), if we are
12999 debugging, if we make calls, or if the sum of fp_save, gp_save,
13000 and local variables are more than the space needed to save all
13001 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13002 + 18*8 = 288 (GPR13 reserved).
13003
13004 For V.4 we don't have the stack cushion that AIX uses, but assume
13005 that the debugger can handle stackless frames. */
13006
13007 if (info_ptr->calls_p)
13008 info_ptr->push_p = 1;
13009
13010 else if (DEFAULT_ABI == ABI_V4)
13011 info_ptr->push_p = non_fixed_size != 0;
13012
13013 else if (frame_pointer_needed)
13014 info_ptr->push_p = 1;
13015
13016 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
13017 info_ptr->push_p = 1;
13018
13019 else
13020 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
13021
13022 /* Zero offsets if we're not saving those registers. */
13023 if (info_ptr->fp_size == 0)
13024 info_ptr->fp_save_offset = 0;
13025
13026 if (info_ptr->gp_size == 0)
13027 info_ptr->gp_save_offset = 0;
13028
13029 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
13030 info_ptr->altivec_save_offset = 0;
13031
13032 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
13033 info_ptr->vrsave_save_offset = 0;
13034
13035 if (! TARGET_SPE_ABI
13036 || info_ptr->spe_64bit_regs_used == 0
13037 || info_ptr->spe_gp_size == 0)
13038 info_ptr->spe_gp_save_offset = 0;
13039
13040 if (! info_ptr->lr_save_p)
13041 info_ptr->lr_save_offset = 0;
13042
13043 if (! info_ptr->cr_save_p)
13044 info_ptr->cr_save_offset = 0;
13045
13046 if (! info_ptr->toc_save_p)
13047 info_ptr->toc_save_offset = 0;
13048
13049 return info_ptr;
13050 }
13051
13052 /* Return true if the current function uses any GPRs in 64-bit SIMD
13053 mode. */
13054
13055 static bool
spe_func_has_64bit_regs_p(void)13056 spe_func_has_64bit_regs_p (void)
13057 {
13058 rtx insns, insn;
13059
13060 /* Functions that save and restore all the call-saved registers will
13061 need to save/restore the registers in 64-bits. */
13062 if (current_function_calls_eh_return
13063 || current_function_calls_setjmp
13064 || current_function_has_nonlocal_goto)
13065 return true;
13066
13067 insns = get_insns ();
13068
13069 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
13070 {
13071 if (INSN_P (insn))
13072 {
13073 rtx i;
13074
13075 /* FIXME: This should be implemented with attributes...
13076
13077 (set_attr "spe64" "true")....then,
13078 if (get_spe64(insn)) return true;
13079
13080 It's the only reliable way to do the stuff below. */
13081
13082 i = PATTERN (insn);
13083 if (GET_CODE (i) == SET)
13084 {
13085 enum machine_mode mode = GET_MODE (SET_SRC (i));
13086
13087 if (SPE_VECTOR_MODE (mode))
13088 return true;
13089 if (TARGET_E500_DOUBLE && mode == DFmode)
13090 return true;
13091 }
13092 }
13093 }
13094
13095 return false;
13096 }
13097
13098 static void
debug_stack_info(rs6000_stack_t * info)13099 debug_stack_info (rs6000_stack_t *info)
13100 {
13101 const char *abi_string;
13102
13103 if (! info)
13104 info = rs6000_stack_info ();
13105
13106 fprintf (stderr, "\nStack information for function %s:\n",
13107 ((current_function_decl && DECL_NAME (current_function_decl))
13108 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
13109 : "<unknown>"));
13110
13111 switch (info->abi)
13112 {
13113 default: abi_string = "Unknown"; break;
13114 case ABI_NONE: abi_string = "NONE"; break;
13115 case ABI_AIX: abi_string = "AIX"; break;
13116 case ABI_DARWIN: abi_string = "Darwin"; break;
13117 case ABI_V4: abi_string = "V.4"; break;
13118 }
13119
13120 fprintf (stderr, "\tABI = %5s\n", abi_string);
13121
13122 if (TARGET_ALTIVEC_ABI)
13123 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
13124
13125 if (TARGET_SPE_ABI)
13126 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
13127
13128 if (info->first_gp_reg_save != 32)
13129 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
13130
13131 if (info->first_fp_reg_save != 64)
13132 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
13133
13134 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
13135 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
13136 info->first_altivec_reg_save);
13137
13138 if (info->lr_save_p)
13139 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
13140
13141 if (info->cr_save_p)
13142 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
13143
13144 if (info->toc_save_p)
13145 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
13146
13147 if (info->vrsave_mask)
13148 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
13149
13150 if (info->push_p)
13151 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13152
13153 if (info->calls_p)
13154 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13155
13156 if (info->gp_save_offset)
13157 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13158
13159 if (info->fp_save_offset)
13160 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13161
13162 if (info->altivec_save_offset)
13163 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13164 info->altivec_save_offset);
13165
13166 if (info->spe_gp_save_offset)
13167 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13168 info->spe_gp_save_offset);
13169
13170 if (info->vrsave_save_offset)
13171 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13172 info->vrsave_save_offset);
13173
13174 if (info->lr_save_offset)
13175 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13176
13177 if (info->cr_save_offset)
13178 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13179
13180 if (info->toc_save_offset)
13181 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
13182
13183 if (info->varargs_save_offset)
13184 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13185
13186 if (info->total_size)
13187 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13188 info->total_size);
13189
13190 if (info->vars_size)
13191 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13192 info->vars_size);
13193
13194 if (info->parm_size)
13195 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13196
13197 if (info->fixed_size)
13198 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13199
13200 if (info->gp_size)
13201 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13202
13203 if (info->spe_gp_size)
13204 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13205
13206 if (info->fp_size)
13207 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13208
13209 if (info->altivec_size)
13210 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13211
13212 if (info->vrsave_size)
13213 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13214
13215 if (info->altivec_padding_size)
13216 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13217 info->altivec_padding_size);
13218
13219 if (info->spe_padding_size)
13220 fprintf (stderr, "\tspe_padding_size = %5d\n",
13221 info->spe_padding_size);
13222
13223 if (info->lr_size)
13224 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
13225
13226 if (info->cr_size)
13227 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13228
13229 if (info->toc_size)
13230 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
13231
13232 if (info->save_size)
13233 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13234
13235 if (info->reg_size != 4)
13236 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13237
13238 fprintf (stderr, "\n");
13239 }
13240
13241 rtx
rs6000_return_addr(int count,rtx frame)13242 rs6000_return_addr (int count, rtx frame)
13243 {
13244 /* Currently we don't optimize very well between prolog and body
13245 code and for PIC code the code can be actually quite bad, so
13246 don't try to be too clever here. */
13247 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
13248 {
13249 cfun->machine->ra_needs_full_frame = 1;
13250
13251 return
13252 gen_rtx_MEM
13253 (Pmode,
13254 memory_address
13255 (Pmode,
13256 plus_constant (copy_to_reg
13257 (gen_rtx_MEM (Pmode,
13258 memory_address (Pmode, frame))),
13259 RETURN_ADDRESS_OFFSET)));
13260 }
13261
13262 cfun->machine->ra_need_lr = 1;
13263 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
13264 }
13265
13266 /* Say whether a function is a candidate for sibcall handling or not.
13267 We do not allow indirect calls to be optimized into sibling calls.
13268 Also, we can't do it if there are any vector parameters; there's
13269 nowhere to put the VRsave code so it works; note that functions with
13270 vector parameters are required to have a prototype, so the argument
13271 type info must be available here. (The tail recursion case can work
13272 with vector parameters, but there's no way to distinguish here.) */
13273 static bool
rs6000_function_ok_for_sibcall(tree decl,tree exp ATTRIBUTE_UNUSED)13274 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
13275 {
13276 tree type;
13277 if (decl)
13278 {
13279 if (TARGET_ALTIVEC_VRSAVE)
13280 {
13281 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
13282 type; type = TREE_CHAIN (type))
13283 {
13284 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
13285 return false;
13286 }
13287 }
13288 if (DEFAULT_ABI == ABI_DARWIN
13289 || (*targetm.binds_local_p) (decl))
13290 {
13291 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
13292
13293 if (!lookup_attribute ("longcall", attr_list)
13294 || lookup_attribute ("shortcall", attr_list))
13295 return true;
13296 }
13297 }
13298 return false;
13299 }
13300
13301 /* NULL if INSN insn is valid within a low-overhead loop.
13302 Otherwise return why doloop cannot be applied.
13303 PowerPC uses the COUNT register for branch on table instructions. */
13304
13305 static const char *
rs6000_invalid_within_doloop(rtx insn)13306 rs6000_invalid_within_doloop (rtx insn)
13307 {
13308 if (CALL_P (insn))
13309 return "Function call in the loop.";
13310
13311 if (JUMP_P (insn)
13312 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13313 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
13314 return "Computed branch in the loop.";
13315
13316 return NULL;
13317 }
13318
13319 static int
rs6000_ra_ever_killed(void)13320 rs6000_ra_ever_killed (void)
13321 {
13322 rtx top;
13323 rtx reg;
13324 rtx insn;
13325
13326 if (current_function_is_thunk)
13327 return 0;
13328
13329 /* regs_ever_live has LR marked as used if any sibcalls are present,
13330 but this should not force saving and restoring in the
13331 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13332 clobbers LR, so that is inappropriate. */
13333
13334 /* Also, the prologue can generate a store into LR that
13335 doesn't really count, like this:
13336
13337 move LR->R0
13338 bcl to set PIC register
13339 move LR->R31
13340 move R0->LR
13341
13342 When we're called from the epilogue, we need to avoid counting
13343 this as a store. */
13344
13345 push_topmost_sequence ();
13346 top = get_insns ();
13347 pop_topmost_sequence ();
13348 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
13349
13350 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13351 {
13352 if (INSN_P (insn))
13353 {
13354 if (FIND_REG_INC_NOTE (insn, reg))
13355 return 1;
13356 else if (GET_CODE (insn) == CALL_INSN
13357 && !SIBLING_CALL_P (insn))
13358 return 1;
13359 else if (set_of (reg, insn) != NULL_RTX
13360 && !prologue_epilogue_contains (insn))
13361 return 1;
13362 }
13363 }
13364 return 0;
13365 }
13366
13367 /* Add a REG_MAYBE_DEAD note to the insn. */
13368 static void
rs6000_maybe_dead(rtx insn)13369 rs6000_maybe_dead (rtx insn)
13370 {
13371 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13372 const0_rtx,
13373 REG_NOTES (insn));
13374 }
13375
13376 /* Emit instructions needed to load the TOC register.
13377 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13378 a constant pool; or for SVR4 -fpic. */
13379
13380 void
rs6000_emit_load_toc_table(int fromprolog)13381 rs6000_emit_load_toc_table (int fromprolog)
13382 {
13383 rtx dest, insn;
13384 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
13385
13386 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
13387 {
13388 char buf[30];
13389 rtx lab, tmp1, tmp2, got, tempLR;
13390
13391 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13392 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13393 if (flag_pic == 2)
13394 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13395 else
13396 got = rs6000_got_sym ();
13397 tmp1 = tmp2 = dest;
13398 if (!fromprolog)
13399 {
13400 tmp1 = gen_reg_rtx (Pmode);
13401 tmp2 = gen_reg_rtx (Pmode);
13402 }
13403 tempLR = (fromprolog
13404 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13405 : gen_reg_rtx (Pmode));
13406 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13407 if (fromprolog)
13408 rs6000_maybe_dead (insn);
13409 insn = emit_move_insn (tmp1, tempLR);
13410 if (fromprolog)
13411 rs6000_maybe_dead (insn);
13412 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13413 if (fromprolog)
13414 rs6000_maybe_dead (insn);
13415 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13416 if (fromprolog)
13417 rs6000_maybe_dead (insn);
13418 }
13419 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13420 {
13421 rtx tempLR = (fromprolog
13422 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13423 : gen_reg_rtx (Pmode));
13424
13425 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
13426 if (fromprolog)
13427 rs6000_maybe_dead (insn);
13428 insn = emit_move_insn (dest, tempLR);
13429 if (fromprolog)
13430 rs6000_maybe_dead (insn);
13431 }
13432 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13433 {
13434 char buf[30];
13435 rtx tempLR = (fromprolog
13436 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13437 : gen_reg_rtx (Pmode));
13438 rtx temp0 = (fromprolog
13439 ? gen_rtx_REG (Pmode, 0)
13440 : gen_reg_rtx (Pmode));
13441
13442 if (fromprolog)
13443 {
13444 rtx symF, symL;
13445
13446 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13447 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13448
13449 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13450 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13451
13452 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13453 symF)));
13454 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13455 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13456 symL,
13457 symF)));
13458 }
13459 else
13460 {
13461 rtx tocsym;
13462
13463 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13464 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
13465 emit_move_insn (dest, tempLR);
13466 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
13467 }
13468 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13469 if (fromprolog)
13470 rs6000_maybe_dead (insn);
13471 }
13472 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13473 {
13474 /* This is for AIX code running in non-PIC ELF32. */
13475 char buf[30];
13476 rtx realsym;
13477 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13478 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13479
13480 insn = emit_insn (gen_elf_high (dest, realsym));
13481 if (fromprolog)
13482 rs6000_maybe_dead (insn);
13483 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13484 if (fromprolog)
13485 rs6000_maybe_dead (insn);
13486 }
13487 else
13488 {
13489 gcc_assert (DEFAULT_ABI == ABI_AIX);
13490
13491 if (TARGET_32BIT)
13492 insn = emit_insn (gen_load_toc_aix_si (dest));
13493 else
13494 insn = emit_insn (gen_load_toc_aix_di (dest));
13495 if (fromprolog)
13496 rs6000_maybe_dead (insn);
13497 }
13498 }
13499
13500 /* Emit instructions to restore the link register after determining where
13501 its value has been stored. */
13502
13503 void
rs6000_emit_eh_reg_restore(rtx source,rtx scratch)13504 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
13505 {
13506 rs6000_stack_t *info = rs6000_stack_info ();
13507 rtx operands[2];
13508
13509 operands[0] = source;
13510 operands[1] = scratch;
13511
13512 if (info->lr_save_p)
13513 {
13514 rtx frame_rtx = stack_pointer_rtx;
13515 HOST_WIDE_INT sp_offset = 0;
13516 rtx tmp;
13517
13518 if (frame_pointer_needed
13519 || current_function_calls_alloca
13520 || info->total_size > 32767)
13521 {
13522 tmp = gen_rtx_MEM (Pmode, frame_rtx);
13523 MEM_NOTRAP_P (tmp) = 1;
13524 set_mem_alias_set (tmp, rs6000_sr_alias_set);
13525 emit_move_insn (operands[1], tmp);
13526 frame_rtx = operands[1];
13527 }
13528 else if (info->push_p)
13529 sp_offset = info->total_size;
13530
13531 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
13532 tmp = gen_rtx_MEM (Pmode, tmp);
13533 MEM_NOTRAP_P (tmp) = 1;
13534 set_mem_alias_set (tmp, rs6000_sr_alias_set);
13535 emit_move_insn (tmp, operands[0]);
13536 }
13537 else
13538 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
13539 }
13540
13541 static GTY(()) int set = -1;
13542
13543 int
get_TOC_alias_set(void)13544 get_TOC_alias_set (void)
13545 {
13546 if (set == -1)
13547 set = new_alias_set ();
13548 return set;
13549 }
13550
13551 /* This returns nonzero if the current function uses the TOC. This is
13552 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13553 is generated by the ABI_V4 load_toc_* patterns. */
13554 #if TARGET_ELF
13555 static int
uses_TOC(void)13556 uses_TOC (void)
13557 {
13558 rtx insn;
13559
13560 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13561 if (INSN_P (insn))
13562 {
13563 rtx pat = PATTERN (insn);
13564 int i;
13565
13566 if (GET_CODE (pat) == PARALLEL)
13567 for (i = 0; i < XVECLEN (pat, 0); i++)
13568 {
13569 rtx sub = XVECEXP (pat, 0, i);
13570 if (GET_CODE (sub) == USE)
13571 {
13572 sub = XEXP (sub, 0);
13573 if (GET_CODE (sub) == UNSPEC
13574 && XINT (sub, 1) == UNSPEC_TOC)
13575 return 1;
13576 }
13577 }
13578 }
13579 return 0;
13580 }
13581 #endif
13582
13583 rtx
create_TOC_reference(rtx symbol)13584 create_TOC_reference (rtx symbol)
13585 {
13586 if (no_new_pseudos)
13587 regs_ever_live[TOC_REGISTER] = 1;
13588 return gen_rtx_PLUS (Pmode,
13589 gen_rtx_REG (Pmode, TOC_REGISTER),
13590 gen_rtx_CONST (Pmode,
13591 gen_rtx_MINUS (Pmode, symbol,
13592 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
13593 }
13594
13595 /* If _Unwind_* has been called from within the same module,
13596 toc register is not guaranteed to be saved to 40(1) on function
13597 entry. Save it there in that case. */
13598
13599 void
rs6000_aix_emit_builtin_unwind_init(void)13600 rs6000_aix_emit_builtin_unwind_init (void)
13601 {
13602 rtx mem;
13603 rtx stack_top = gen_reg_rtx (Pmode);
13604 rtx opcode_addr = gen_reg_rtx (Pmode);
13605 rtx opcode = gen_reg_rtx (SImode);
13606 rtx tocompare = gen_reg_rtx (SImode);
13607 rtx no_toc_save_needed = gen_label_rtx ();
13608
13609 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
13610 emit_move_insn (stack_top, mem);
13611
13612 mem = gen_frame_mem (Pmode,
13613 gen_rtx_PLUS (Pmode, stack_top,
13614 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
13615 emit_move_insn (opcode_addr, mem);
13616 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
13617 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
13618 : 0xE8410028, SImode));
13619
13620 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
13621 SImode, NULL_RTX, NULL_RTX,
13622 no_toc_save_needed);
13623
13624 mem = gen_frame_mem (Pmode,
13625 gen_rtx_PLUS (Pmode, stack_top,
13626 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
13627 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
13628 emit_label (no_toc_save_needed);
13629 }
13630
13631 /* This ties together stack memory (MEM with an alias set of
13632 rs6000_sr_alias_set) and the change to the stack pointer. */
13633
13634 static void
rs6000_emit_stack_tie(void)13635 rs6000_emit_stack_tie (void)
13636 {
13637 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
13638
13639 set_mem_alias_set (mem, rs6000_sr_alias_set);
13640 emit_insn (gen_stack_tie (mem));
13641 }
13642
13643 /* Emit the correct code for allocating stack space, as insns.
13644 If COPY_R12, make sure a copy of the old frame is left in r12.
13645 The generated code may use hard register 0 as a temporary. */
13646
13647 static void
rs6000_emit_allocate_stack(HOST_WIDE_INT size,int copy_r12)13648 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
13649 {
13650 rtx insn;
13651 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
13652 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
13653 rtx todec = gen_int_mode (-size, Pmode);
13654
13655 if (INTVAL (todec) != -size)
13656 {
13657 warning (0, "stack frame too large");
13658 emit_insn (gen_trap ());
13659 return;
13660 }
13661
13662 if (current_function_limit_stack)
13663 {
13664 if (REG_P (stack_limit_rtx)
13665 && REGNO (stack_limit_rtx) > 1
13666 && REGNO (stack_limit_rtx) <= 31)
13667 {
13668 emit_insn (TARGET_32BIT
13669 ? gen_addsi3 (tmp_reg,
13670 stack_limit_rtx,
13671 GEN_INT (size))
13672 : gen_adddi3 (tmp_reg,
13673 stack_limit_rtx,
13674 GEN_INT (size)));
13675
13676 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13677 const0_rtx));
13678 }
13679 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
13680 && TARGET_32BIT
13681 && DEFAULT_ABI == ABI_V4)
13682 {
13683 rtx toload = gen_rtx_CONST (VOIDmode,
13684 gen_rtx_PLUS (Pmode,
13685 stack_limit_rtx,
13686 GEN_INT (size)));
13687
13688 emit_insn (gen_elf_high (tmp_reg, toload));
13689 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
13690 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13691 const0_rtx));
13692 }
13693 else
13694 warning (0, "stack limit expression is not supported");
13695 }
13696
13697 if (copy_r12 || ! TARGET_UPDATE)
13698 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
13699
13700 if (TARGET_UPDATE)
13701 {
13702 if (size > 32767)
13703 {
13704 /* Need a note here so that try_split doesn't get confused. */
13705 if (get_last_insn () == NULL_RTX)
13706 emit_note (NOTE_INSN_DELETED);
13707 insn = emit_move_insn (tmp_reg, todec);
13708 try_split (PATTERN (insn), insn, 0);
13709 todec = tmp_reg;
13710 }
13711
13712 insn = emit_insn (TARGET_32BIT
13713 ? gen_movsi_update (stack_reg, stack_reg,
13714 todec, stack_reg)
13715 : gen_movdi_di_update (stack_reg, stack_reg,
13716 todec, stack_reg));
13717 }
13718 else
13719 {
13720 insn = emit_insn (TARGET_32BIT
13721 ? gen_addsi3 (stack_reg, stack_reg, todec)
13722 : gen_adddi3 (stack_reg, stack_reg, todec));
13723 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
13724 gen_rtx_REG (Pmode, 12));
13725 }
13726
13727 RTX_FRAME_RELATED_P (insn) = 1;
13728 REG_NOTES (insn) =
13729 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13730 gen_rtx_SET (VOIDmode, stack_reg,
13731 gen_rtx_PLUS (Pmode, stack_reg,
13732 GEN_INT (-size))),
13733 REG_NOTES (insn));
13734 }
13735
13736 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
13737 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
13738 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
13739 deduce these equivalences by itself so it wasn't necessary to hold
13740 its hand so much. */
13741
13742 static void
rs6000_frame_related(rtx insn,rtx reg,HOST_WIDE_INT val,rtx reg2,rtx rreg)13743 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
13744 rtx reg2, rtx rreg)
13745 {
13746 rtx real, temp;
13747
13748 /* copy_rtx will not make unique copies of registers, so we need to
13749 ensure we don't have unwanted sharing here. */
13750 if (reg == reg2)
13751 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13752
13753 if (reg == rreg)
13754 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13755
13756 real = copy_rtx (PATTERN (insn));
13757
13758 if (reg2 != NULL_RTX)
13759 real = replace_rtx (real, reg2, rreg);
13760
13761 real = replace_rtx (real, reg,
13762 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
13763 STACK_POINTER_REGNUM),
13764 GEN_INT (val)));
13765
13766 /* We expect that 'real' is either a SET or a PARALLEL containing
13767 SETs (and possibly other stuff). In a PARALLEL, all the SETs
13768 are important so they all have to be marked RTX_FRAME_RELATED_P. */
13769
13770 if (GET_CODE (real) == SET)
13771 {
13772 rtx set = real;
13773
13774 temp = simplify_rtx (SET_SRC (set));
13775 if (temp)
13776 SET_SRC (set) = temp;
13777 temp = simplify_rtx (SET_DEST (set));
13778 if (temp)
13779 SET_DEST (set) = temp;
13780 if (GET_CODE (SET_DEST (set)) == MEM)
13781 {
13782 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13783 if (temp)
13784 XEXP (SET_DEST (set), 0) = temp;
13785 }
13786 }
13787 else
13788 {
13789 int i;
13790
13791 gcc_assert (GET_CODE (real) == PARALLEL);
13792 for (i = 0; i < XVECLEN (real, 0); i++)
13793 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
13794 {
13795 rtx set = XVECEXP (real, 0, i);
13796
13797 temp = simplify_rtx (SET_SRC (set));
13798 if (temp)
13799 SET_SRC (set) = temp;
13800 temp = simplify_rtx (SET_DEST (set));
13801 if (temp)
13802 SET_DEST (set) = temp;
13803 if (GET_CODE (SET_DEST (set)) == MEM)
13804 {
13805 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13806 if (temp)
13807 XEXP (SET_DEST (set), 0) = temp;
13808 }
13809 RTX_FRAME_RELATED_P (set) = 1;
13810 }
13811 }
13812
13813 if (TARGET_SPE)
13814 real = spe_synthesize_frame_save (real);
13815
13816 RTX_FRAME_RELATED_P (insn) = 1;
13817 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13818 real,
13819 REG_NOTES (insn));
13820 }
13821
13822 /* Given an SPE frame note, return a PARALLEL of SETs with the
13823 original note, plus a synthetic register save. */
13824
13825 static rtx
spe_synthesize_frame_save(rtx real)13826 spe_synthesize_frame_save (rtx real)
13827 {
13828 rtx synth, offset, reg, real2;
13829
13830 if (GET_CODE (real) != SET
13831 || GET_MODE (SET_SRC (real)) != V2SImode)
13832 return real;
13833
13834 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13835 frame related note. The parallel contains a set of the register
13836 being saved, and another set to a synthetic register (n+1200).
13837 This is so we can differentiate between 64-bit and 32-bit saves.
13838 Words cannot describe this nastiness. */
13839
13840 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
13841 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
13842 && GET_CODE (SET_SRC (real)) == REG);
13843
13844 /* Transform:
13845 (set (mem (plus (reg x) (const y)))
13846 (reg z))
13847 into:
13848 (set (mem (plus (reg x) (const y+4)))
13849 (reg z+1200))
13850 */
13851
13852 real2 = copy_rtx (real);
13853 PUT_MODE (SET_DEST (real2), SImode);
13854 reg = SET_SRC (real2);
13855 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
13856 synth = copy_rtx (real2);
13857
13858 if (BYTES_BIG_ENDIAN)
13859 {
13860 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
13861 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
13862 }
13863
13864 reg = SET_SRC (synth);
13865
13866 synth = replace_rtx (synth, reg,
13867 gen_rtx_REG (SImode, REGNO (reg) + 1200));
13868
13869 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
13870 synth = replace_rtx (synth, offset,
13871 GEN_INT (INTVAL (offset)
13872 + (BYTES_BIG_ENDIAN ? 0 : 4)));
13873
13874 RTX_FRAME_RELATED_P (synth) = 1;
13875 RTX_FRAME_RELATED_P (real2) = 1;
13876 if (BYTES_BIG_ENDIAN)
13877 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
13878 else
13879 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
13880
13881 return real;
13882 }
13883
13884 /* Returns an insn that has a vrsave set operation with the
13885 appropriate CLOBBERs. */
13886
13887 static rtx
generate_set_vrsave(rtx reg,rs6000_stack_t * info,int epiloguep)13888 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
13889 {
13890 int nclobs, i;
13891 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
13892 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
13893
13894 clobs[0]
13895 = gen_rtx_SET (VOIDmode,
13896 vrsave,
13897 gen_rtx_UNSPEC_VOLATILE (SImode,
13898 gen_rtvec (2, reg, vrsave),
13899 UNSPECV_SET_VRSAVE));
13900
13901 nclobs = 1;
13902
13903 /* We need to clobber the registers in the mask so the scheduler
13904 does not move sets to VRSAVE before sets of AltiVec registers.
13905
13906 However, if the function receives nonlocal gotos, reload will set
13907 all call saved registers live. We will end up with:
13908
13909 (set (reg 999) (mem))
13910 (parallel [ (set (reg vrsave) (unspec blah))
13911 (clobber (reg 999))])
13912
13913 The clobber will cause the store into reg 999 to be dead, and
13914 flow will attempt to delete an epilogue insn. In this case, we
13915 need an unspec use/set of the register. */
13916
13917 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
13918 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
13919 {
13920 if (!epiloguep || call_used_regs [i])
13921 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
13922 gen_rtx_REG (V4SImode, i));
13923 else
13924 {
13925 rtx reg = gen_rtx_REG (V4SImode, i);
13926
13927 clobs[nclobs++]
13928 = gen_rtx_SET (VOIDmode,
13929 reg,
13930 gen_rtx_UNSPEC (V4SImode,
13931 gen_rtvec (1, reg), 27));
13932 }
13933 }
13934
13935 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
13936
13937 for (i = 0; i < nclobs; ++i)
13938 XVECEXP (insn, 0, i) = clobs[i];
13939
13940 return insn;
13941 }
13942
13943 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13944 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13945
13946 static void
emit_frame_save(rtx frame_reg,rtx frame_ptr,enum machine_mode mode,unsigned int regno,int offset,HOST_WIDE_INT total_size)13947 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
13948 unsigned int regno, int offset, HOST_WIDE_INT total_size)
13949 {
13950 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
13951 rtx replacea, replaceb;
13952
13953 int_rtx = GEN_INT (offset);
13954
13955 /* Some cases that need register indexed addressing. */
13956 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
13957 || (TARGET_E500_DOUBLE && mode == DFmode)
13958 || (TARGET_SPE_ABI
13959 && SPE_VECTOR_MODE (mode)
13960 && !SPE_CONST_OFFSET_OK (offset)))
13961 {
13962 /* Whomever calls us must make sure r11 is available in the
13963 flow path of instructions in the prologue. */
13964 offset_rtx = gen_rtx_REG (Pmode, 11);
13965 emit_move_insn (offset_rtx, int_rtx);
13966
13967 replacea = offset_rtx;
13968 replaceb = int_rtx;
13969 }
13970 else
13971 {
13972 offset_rtx = int_rtx;
13973 replacea = NULL_RTX;
13974 replaceb = NULL_RTX;
13975 }
13976
13977 reg = gen_rtx_REG (mode, regno);
13978 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
13979 mem = gen_rtx_MEM (mode, addr);
13980 set_mem_alias_set (mem, rs6000_sr_alias_set);
13981
13982 insn = emit_move_insn (mem, reg);
13983
13984 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
13985 }
13986
13987 /* Emit an offset memory reference suitable for a frame store, while
13988 converting to a valid addressing mode. */
13989
13990 static rtx
gen_frame_mem_offset(enum machine_mode mode,rtx reg,int offset)13991 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
13992 {
13993 rtx int_rtx, offset_rtx;
13994
13995 int_rtx = GEN_INT (offset);
13996
13997 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
13998 || (TARGET_E500_DOUBLE && mode == DFmode))
13999 {
14000 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14001 emit_move_insn (offset_rtx, int_rtx);
14002 }
14003 else
14004 offset_rtx = int_rtx;
14005
14006 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
14007 }
14008
14009 /* Look for user-defined global regs. We should not save and restore these,
14010 and cannot use stmw/lmw if there are any in its range. */
14011
14012 static bool
no_global_regs_above(int first_greg)14013 no_global_regs_above (int first_greg)
14014 {
14015 int i;
14016 for (i = 0; i < 32 - first_greg; i++)
14017 if (global_regs[first_greg + i])
14018 return false;
14019 return true;
14020 }
14021
14022 #ifndef TARGET_FIX_AND_CONTINUE
14023 #define TARGET_FIX_AND_CONTINUE 0
14024 #endif
14025
14026 /* Emit function prologue as insns. */
14027
14028 void
rs6000_emit_prologue(void)14029 rs6000_emit_prologue (void)
14030 {
14031 rs6000_stack_t *info = rs6000_stack_info ();
14032 enum machine_mode reg_mode = Pmode;
14033 int reg_size = TARGET_32BIT ? 4 : 8;
14034 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14035 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
14036 rtx frame_reg_rtx = sp_reg_rtx;
14037 rtx cr_save_rtx = NULL_RTX;
14038 rtx insn;
14039 int saving_FPRs_inline;
14040 int using_store_multiple;
14041 HOST_WIDE_INT sp_offset = 0;
14042
14043 if (TARGET_FIX_AND_CONTINUE)
14044 {
14045 /* gdb on darwin arranges to forward a function from the old
14046 address by modifying the first 5 instructions of the function
14047 to branch to the overriding function. This is necessary to
14048 permit function pointers that point to the old function to
14049 actually forward to the new function. */
14050 emit_insn (gen_nop ());
14051 emit_insn (gen_nop ());
14052 emit_insn (gen_nop ());
14053 emit_insn (gen_nop ());
14054 emit_insn (gen_nop ());
14055 }
14056
14057 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14058 {
14059 reg_mode = V2SImode;
14060 reg_size = 8;
14061 }
14062
14063 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14064 && (!TARGET_SPE_ABI
14065 || info->spe_64bit_regs_used == 0)
14066 && info->first_gp_reg_save < 31
14067 && no_global_regs_above (info->first_gp_reg_save));
14068 saving_FPRs_inline = (info->first_fp_reg_save == 64
14069 || FP_SAVE_INLINE (info->first_fp_reg_save)
14070 || current_function_calls_eh_return
14071 || cfun->machine->ra_need_lr);
14072
14073 /* For V.4, update stack before we do any saving and set back pointer. */
14074 if (info->push_p
14075 && (DEFAULT_ABI == ABI_V4
14076 || current_function_calls_eh_return))
14077 {
14078 if (info->total_size < 32767)
14079 sp_offset = info->total_size;
14080 else
14081 frame_reg_rtx = frame_ptr_rtx;
14082 rs6000_emit_allocate_stack (info->total_size,
14083 (frame_reg_rtx != sp_reg_rtx
14084 && (info->cr_save_p
14085 || info->lr_save_p
14086 || info->first_fp_reg_save < 64
14087 || info->first_gp_reg_save < 32
14088 )));
14089 if (frame_reg_rtx != sp_reg_rtx)
14090 rs6000_emit_stack_tie ();
14091 }
14092
14093 /* Handle world saves specially here. */
14094 if (WORLD_SAVE_P (info))
14095 {
14096 int i, j, sz;
14097 rtx treg;
14098 rtvec p;
14099
14100 /* save_world expects lr in r0. */
14101 if (info->lr_save_p)
14102 {
14103 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14104 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14105 RTX_FRAME_RELATED_P (insn) = 1;
14106 }
14107
14108 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14109 assumptions about the offsets of various bits of the stack
14110 frame. */
14111 gcc_assert (info->gp_save_offset == -220
14112 && info->fp_save_offset == -144
14113 && info->lr_save_offset == 8
14114 && info->cr_save_offset == 4
14115 && info->push_p
14116 && info->lr_save_p
14117 && (!current_function_calls_eh_return
14118 || info->ehrd_offset == -432)
14119 && info->vrsave_save_offset == -224
14120 && info->altivec_save_offset == (-224 -16 -192));
14121
14122 treg = gen_rtx_REG (SImode, 11);
14123 emit_move_insn (treg, GEN_INT (-info->total_size));
14124
14125 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14126 in R11. It also clobbers R12, so beware! */
14127
14128 /* Preserve CR2 for save_world prologues */
14129 sz = 6;
14130 sz += 32 - info->first_gp_reg_save;
14131 sz += 64 - info->first_fp_reg_save;
14132 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
14133 p = rtvec_alloc (sz);
14134 j = 0;
14135 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
14136 gen_rtx_REG (Pmode,
14137 LINK_REGISTER_REGNUM));
14138 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14139 gen_rtx_SYMBOL_REF (Pmode,
14140 "*save_world"));
14141 /* We do floats first so that the instruction pattern matches
14142 properly. */
14143 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14144 {
14145 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14146 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14147 GEN_INT (info->fp_save_offset
14148 + sp_offset + 8 * i));
14149 rtx mem = gen_rtx_MEM (DFmode, addr);
14150 set_mem_alias_set (mem, rs6000_sr_alias_set);
14151
14152 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14153 }
14154 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14155 {
14156 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14157 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14158 GEN_INT (info->altivec_save_offset
14159 + sp_offset + 16 * i));
14160 rtx mem = gen_rtx_MEM (V4SImode, addr);
14161 set_mem_alias_set (mem, rs6000_sr_alias_set);
14162
14163 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14164 }
14165 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14166 {
14167 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14168 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14169 GEN_INT (info->gp_save_offset
14170 + sp_offset + reg_size * i));
14171 rtx mem = gen_rtx_MEM (reg_mode, addr);
14172 set_mem_alias_set (mem, rs6000_sr_alias_set);
14173
14174 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14175 }
14176
14177 {
14178 /* CR register traditionally saved as CR2. */
14179 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14180 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14181 GEN_INT (info->cr_save_offset
14182 + sp_offset));
14183 rtx mem = gen_rtx_MEM (reg_mode, addr);
14184 set_mem_alias_set (mem, rs6000_sr_alias_set);
14185
14186 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14187 }
14188 /* Prevent any attempt to delete the setting of r0 and treg! */
14189 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
14190 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, treg);
14191 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, sp_reg_rtx);
14192
14193 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14194 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14195 NULL_RTX, NULL_RTX);
14196
14197 if (current_function_calls_eh_return)
14198 {
14199 unsigned int i;
14200 for (i = 0; ; ++i)
14201 {
14202 unsigned int regno = EH_RETURN_DATA_REGNO (i);
14203 if (regno == INVALID_REGNUM)
14204 break;
14205 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14206 info->ehrd_offset + sp_offset
14207 + reg_size * (int) i,
14208 info->total_size);
14209 }
14210 }
14211 }
14212
14213 /* Save AltiVec registers if needed. */
14214 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14215 {
14216 int i;
14217
14218 /* There should be a non inline version of this, for when we
14219 are saving lots of vector registers. */
14220 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14221 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14222 {
14223 rtx areg, savereg, mem;
14224 int offset;
14225
14226 offset = info->altivec_save_offset + sp_offset
14227 + 16 * (i - info->first_altivec_reg_save);
14228
14229 savereg = gen_rtx_REG (V4SImode, i);
14230
14231 areg = gen_rtx_REG (Pmode, 0);
14232 emit_move_insn (areg, GEN_INT (offset));
14233
14234 /* AltiVec addressing mode is [reg+reg]. */
14235 mem = gen_rtx_MEM (V4SImode,
14236 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14237
14238 set_mem_alias_set (mem, rs6000_sr_alias_set);
14239
14240 insn = emit_move_insn (mem, savereg);
14241
14242 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14243 areg, GEN_INT (offset));
14244 }
14245 }
14246
14247 /* VRSAVE is a bit vector representing which AltiVec registers
14248 are used. The OS uses this to determine which vector
14249 registers to save on a context switch. We need to save
14250 VRSAVE on the stack frame, add whatever AltiVec registers we
14251 used in this function, and do the corresponding magic in the
14252 epilogue. */
14253
14254 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14255 && info->vrsave_mask != 0)
14256 {
14257 rtx reg, mem, vrsave;
14258 int offset;
14259
14260 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14261 as frame_reg_rtx and r11 as the static chain pointer for
14262 nested functions. */
14263 reg = gen_rtx_REG (SImode, 0);
14264 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14265 if (TARGET_MACHO)
14266 emit_insn (gen_get_vrsave_internal (reg));
14267 else
14268 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14269
14270 if (!WORLD_SAVE_P (info))
14271 {
14272 /* Save VRSAVE. */
14273 offset = info->vrsave_save_offset + sp_offset;
14274 mem
14275 = gen_rtx_MEM (SImode,
14276 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
14277 set_mem_alias_set (mem, rs6000_sr_alias_set);
14278 insn = emit_move_insn (mem, reg);
14279 }
14280
14281 /* Include the registers in the mask. */
14282 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14283
14284 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14285 }
14286
14287 /* If we use the link register, get it into r0. */
14288 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14289 {
14290 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14291 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14292 RTX_FRAME_RELATED_P (insn) = 1;
14293 }
14294
14295 /* If we need to save CR, put it into r12. */
14296 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
14297 {
14298 rtx set;
14299
14300 cr_save_rtx = gen_rtx_REG (SImode, 12);
14301 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14302 RTX_FRAME_RELATED_P (insn) = 1;
14303 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14304 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14305 But that's OK. All we have to do is specify that _one_ condition
14306 code register is saved in this stack slot. The thrower's epilogue
14307 will then restore all the call-saved registers.
14308 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14309 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14310 gen_rtx_REG (SImode, CR2_REGNO));
14311 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14312 set,
14313 REG_NOTES (insn));
14314 }
14315
14316 /* Do any required saving of fpr's. If only one or two to save, do
14317 it ourselves. Otherwise, call function. */
14318 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
14319 {
14320 int i;
14321 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14322 if ((regs_ever_live[info->first_fp_reg_save+i]
14323 && ! call_used_regs[info->first_fp_reg_save+i]))
14324 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14325 info->first_fp_reg_save + i,
14326 info->fp_save_offset + sp_offset + 8 * i,
14327 info->total_size);
14328 }
14329 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
14330 {
14331 int i;
14332 char rname[30];
14333 const char *alloc_rname;
14334 rtvec p;
14335 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
14336
14337 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14338 gen_rtx_REG (Pmode,
14339 LINK_REGISTER_REGNUM));
14340 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14341 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
14342 alloc_rname = ggc_strdup (rname);
14343 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14344 gen_rtx_SYMBOL_REF (Pmode,
14345 alloc_rname));
14346 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14347 {
14348 rtx addr, reg, mem;
14349 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14350 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14351 GEN_INT (info->fp_save_offset
14352 + sp_offset + 8*i));
14353 mem = gen_rtx_MEM (DFmode, addr);
14354 set_mem_alias_set (mem, rs6000_sr_alias_set);
14355
14356 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14357 }
14358 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14359 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14360 NULL_RTX, NULL_RTX);
14361 }
14362
14363 /* Save GPRs. This is done as a PARALLEL if we are using
14364 the store-multiple instructions. */
14365 if (!WORLD_SAVE_P (info) && using_store_multiple)
14366 {
14367 rtvec p;
14368 int i;
14369 p = rtvec_alloc (32 - info->first_gp_reg_save);
14370 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14371 {
14372 rtx addr, reg, mem;
14373 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14374 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14375 GEN_INT (info->gp_save_offset
14376 + sp_offset
14377 + reg_size * i));
14378 mem = gen_rtx_MEM (reg_mode, addr);
14379 set_mem_alias_set (mem, rs6000_sr_alias_set);
14380
14381 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14382 }
14383 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14384 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14385 NULL_RTX, NULL_RTX);
14386 }
14387 else if (!WORLD_SAVE_P (info))
14388 {
14389 int i;
14390 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14391 if ((regs_ever_live[info->first_gp_reg_save + i]
14392 && (!call_used_regs[info->first_gp_reg_save + i]
14393 || (i + info->first_gp_reg_save
14394 == RS6000_PIC_OFFSET_TABLE_REGNUM
14395 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14396 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14397 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14398 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14399 {
14400 rtx addr, reg, mem;
14401 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14402
14403 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14404 {
14405 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14406 rtx b;
14407
14408 if (!SPE_CONST_OFFSET_OK (offset))
14409 {
14410 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14411 emit_move_insn (b, GEN_INT (offset));
14412 }
14413 else
14414 b = GEN_INT (offset);
14415
14416 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14417 mem = gen_rtx_MEM (V2SImode, addr);
14418 set_mem_alias_set (mem, rs6000_sr_alias_set);
14419 insn = emit_move_insn (mem, reg);
14420
14421 if (GET_CODE (b) == CONST_INT)
14422 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14423 NULL_RTX, NULL_RTX);
14424 else
14425 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14426 b, GEN_INT (offset));
14427 }
14428 else
14429 {
14430 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14431 GEN_INT (info->gp_save_offset
14432 + sp_offset
14433 + reg_size * i));
14434 mem = gen_rtx_MEM (reg_mode, addr);
14435 set_mem_alias_set (mem, rs6000_sr_alias_set);
14436
14437 insn = emit_move_insn (mem, reg);
14438 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14439 NULL_RTX, NULL_RTX);
14440 }
14441 }
14442 }
14443
14444 /* ??? There's no need to emit actual instructions here, but it's the
14445 easiest way to get the frame unwind information emitted. */
14446 if (!WORLD_SAVE_P (info) && current_function_calls_eh_return)
14447 {
14448 unsigned int i, regno;
14449
14450 /* In AIX ABI we need to pretend we save r2 here. */
14451 if (TARGET_AIX)
14452 {
14453 rtx addr, reg, mem;
14454
14455 reg = gen_rtx_REG (reg_mode, 2);
14456 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14457 GEN_INT (sp_offset + 5 * reg_size));
14458 mem = gen_rtx_MEM (reg_mode, addr);
14459 set_mem_alias_set (mem, rs6000_sr_alias_set);
14460
14461 insn = emit_move_insn (mem, reg);
14462 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14463 NULL_RTX, NULL_RTX);
14464 PATTERN (insn) = gen_blockage ();
14465 }
14466
14467 for (i = 0; ; ++i)
14468 {
14469 regno = EH_RETURN_DATA_REGNO (i);
14470 if (regno == INVALID_REGNUM)
14471 break;
14472
14473 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14474 info->ehrd_offset + sp_offset
14475 + reg_size * (int) i,
14476 info->total_size);
14477 }
14478 }
14479
14480 /* Save lr if we used it. */
14481 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14482 {
14483 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14484 GEN_INT (info->lr_save_offset + sp_offset));
14485 rtx reg = gen_rtx_REG (Pmode, 0);
14486 rtx mem = gen_rtx_MEM (Pmode, addr);
14487 /* This should not be of rs6000_sr_alias_set, because of
14488 __builtin_return_address. */
14489
14490 insn = emit_move_insn (mem, reg);
14491 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14492 NULL_RTX, NULL_RTX);
14493 }
14494
14495 /* Save CR if we use any that must be preserved. */
14496 if (!WORLD_SAVE_P (info) && info->cr_save_p)
14497 {
14498 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14499 GEN_INT (info->cr_save_offset + sp_offset));
14500 rtx mem = gen_rtx_MEM (SImode, addr);
14501 /* See the large comment above about why CR2_REGNO is used. */
14502 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
14503
14504 set_mem_alias_set (mem, rs6000_sr_alias_set);
14505
14506 /* If r12 was used to hold the original sp, copy cr into r0 now
14507 that it's free. */
14508 if (REGNO (frame_reg_rtx) == 12)
14509 {
14510 rtx set;
14511
14512 cr_save_rtx = gen_rtx_REG (SImode, 0);
14513 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14514 RTX_FRAME_RELATED_P (insn) = 1;
14515 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
14516 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14517 set,
14518 REG_NOTES (insn));
14519
14520 }
14521 insn = emit_move_insn (mem, cr_save_rtx);
14522
14523 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14524 NULL_RTX, NULL_RTX);
14525 }
14526
14527 /* Update stack and set back pointer unless this is V.4,
14528 for which it was done previously. */
14529 if (!WORLD_SAVE_P (info) && info->push_p
14530 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14531 rs6000_emit_allocate_stack (info->total_size, FALSE);
14532
14533 /* Set frame pointer, if needed. */
14534 if (frame_pointer_needed)
14535 {
14536 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14537 sp_reg_rtx);
14538 RTX_FRAME_RELATED_P (insn) = 1;
14539 }
14540
14541 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14542 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
14543 || (DEFAULT_ABI == ABI_V4
14544 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
14545 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
14546 {
14547 /* If emit_load_toc_table will use the link register, we need to save
14548 it. We use R12 for this purpose because emit_load_toc_table
14549 can use register 0. This allows us to use a plain 'blr' to return
14550 from the procedure more often. */
14551 int save_LR_around_toc_setup = (TARGET_ELF
14552 && DEFAULT_ABI != ABI_AIX
14553 && flag_pic
14554 && ! info->lr_save_p
14555 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
14556 if (save_LR_around_toc_setup)
14557 {
14558 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14559
14560 insn = emit_move_insn (frame_ptr_rtx, lr);
14561 rs6000_maybe_dead (insn);
14562 RTX_FRAME_RELATED_P (insn) = 1;
14563
14564 rs6000_emit_load_toc_table (TRUE);
14565
14566 insn = emit_move_insn (lr, frame_ptr_rtx);
14567 rs6000_maybe_dead (insn);
14568 RTX_FRAME_RELATED_P (insn) = 1;
14569 }
14570 else
14571 rs6000_emit_load_toc_table (TRUE);
14572 }
14573
14574 #if TARGET_MACHO
14575 if (DEFAULT_ABI == ABI_DARWIN
14576 && flag_pic && current_function_uses_pic_offset_table)
14577 {
14578 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14579 rtx src = machopic_function_base_sym ();
14580
14581 /* Save and restore LR locally around this call (in R0). */
14582 if (!info->lr_save_p)
14583 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
14584
14585 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
14586
14587 insn = emit_move_insn (gen_rtx_REG (Pmode,
14588 RS6000_PIC_OFFSET_TABLE_REGNUM),
14589 lr);
14590 rs6000_maybe_dead (insn);
14591
14592 if (!info->lr_save_p)
14593 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
14594 }
14595 #endif
14596 }
14597
14598 /* Write function prologue. */
14599
14600 static void
rs6000_output_function_prologue(FILE * file,HOST_WIDE_INT size ATTRIBUTE_UNUSED)14601 rs6000_output_function_prologue (FILE *file,
14602 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
14603 {
14604 rs6000_stack_t *info = rs6000_stack_info ();
14605
14606 if (TARGET_DEBUG_STACK)
14607 debug_stack_info (info);
14608
14609 /* Write .extern for any function we will call to save and restore
14610 fp values. */
14611 if (info->first_fp_reg_save < 64
14612 && !FP_SAVE_INLINE (info->first_fp_reg_save))
14613 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
14614 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
14615 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
14616 RESTORE_FP_SUFFIX);
14617
14618 /* Write .extern for AIX common mode routines, if needed. */
14619 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
14620 {
14621 fputs ("\t.extern __mulh\n", file);
14622 fputs ("\t.extern __mull\n", file);
14623 fputs ("\t.extern __divss\n", file);
14624 fputs ("\t.extern __divus\n", file);
14625 fputs ("\t.extern __quoss\n", file);
14626 fputs ("\t.extern __quous\n", file);
14627 common_mode_defined = 1;
14628 }
14629
14630 if (! HAVE_prologue)
14631 {
14632 start_sequence ();
14633
14634 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14635 the "toplevel" insn chain. */
14636 emit_note (NOTE_INSN_DELETED);
14637 rs6000_emit_prologue ();
14638 emit_note (NOTE_INSN_DELETED);
14639
14640 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14641 {
14642 rtx insn;
14643 unsigned addr = 0;
14644 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
14645 {
14646 INSN_ADDRESSES_NEW (insn, addr);
14647 addr += 4;
14648 }
14649 }
14650
14651 if (TARGET_DEBUG_STACK)
14652 debug_rtx_list (get_insns (), 100);
14653 final (get_insns (), file, FALSE);
14654 end_sequence ();
14655 }
14656
14657 rs6000_pic_labelno++;
14658 }
14659
14660 /* Emit function epilogue as insns.
14661
14662 At present, dwarf2out_frame_debug_expr doesn't understand
14663 register restores, so we don't bother setting RTX_FRAME_RELATED_P
14664 anywhere in the epilogue. Most of the insns below would in any case
14665 need special notes to explain where r11 is in relation to the stack. */
14666
14667 void
rs6000_emit_epilogue(int sibcall)14668 rs6000_emit_epilogue (int sibcall)
14669 {
14670 rs6000_stack_t *info;
14671 int restoring_FPRs_inline;
14672 int using_load_multiple;
14673 int using_mfcr_multiple;
14674 int use_backchain_to_restore_sp;
14675 int sp_offset = 0;
14676 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
14677 rtx frame_reg_rtx = sp_reg_rtx;
14678 enum machine_mode reg_mode = Pmode;
14679 int reg_size = TARGET_32BIT ? 4 : 8;
14680 int i;
14681
14682 info = rs6000_stack_info ();
14683
14684 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14685 {
14686 reg_mode = V2SImode;
14687 reg_size = 8;
14688 }
14689
14690 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14691 && (!TARGET_SPE_ABI
14692 || info->spe_64bit_regs_used == 0)
14693 && info->first_gp_reg_save < 31
14694 && no_global_regs_above (info->first_gp_reg_save));
14695 restoring_FPRs_inline = (sibcall
14696 || current_function_calls_eh_return
14697 || info->first_fp_reg_save == 64
14698 || FP_SAVE_INLINE (info->first_fp_reg_save));
14699 use_backchain_to_restore_sp = (frame_pointer_needed
14700 || current_function_calls_alloca
14701 || info->total_size > 32767);
14702 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
14703 || rs6000_cpu == PROCESSOR_PPC603
14704 || rs6000_cpu == PROCESSOR_PPC750
14705 || optimize_size);
14706
14707 if (WORLD_SAVE_P (info))
14708 {
14709 int i, j;
14710 char rname[30];
14711 const char *alloc_rname;
14712 rtvec p;
14713
14714 /* eh_rest_world_r10 will return to the location saved in the LR
14715 stack slot (which is not likely to be our caller.)
14716 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
14717 rest_world is similar, except any R10 parameter is ignored.
14718 The exception-handling stuff that was here in 2.95 is no
14719 longer necessary. */
14720
14721 p = rtvec_alloc (9
14722 + 1
14723 + 32 - info->first_gp_reg_save
14724 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
14725 + 63 + 1 - info->first_fp_reg_save);
14726
14727 strcpy (rname, ((current_function_calls_eh_return) ?
14728 "*eh_rest_world_r10" : "*rest_world"));
14729 alloc_rname = ggc_strdup (rname);
14730
14731 j = 0;
14732 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
14733 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14734 gen_rtx_REG (Pmode,
14735 LINK_REGISTER_REGNUM));
14736 RTVEC_ELT (p, j++)
14737 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
14738 /* The instruction pattern requires a clobber here;
14739 it is shared with the restVEC helper. */
14740 RTVEC_ELT (p, j++)
14741 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
14742
14743 {
14744 /* CR register traditionally saved as CR2. */
14745 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14746 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14747 GEN_INT (info->cr_save_offset));
14748 rtx mem = gen_rtx_MEM (reg_mode, addr);
14749 set_mem_alias_set (mem, rs6000_sr_alias_set);
14750
14751 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14752 }
14753
14754 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14755 {
14756 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14757 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14758 GEN_INT (info->gp_save_offset
14759 + reg_size * i));
14760 rtx mem = gen_rtx_MEM (reg_mode, addr);
14761 set_mem_alias_set (mem, rs6000_sr_alias_set);
14762
14763 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14764 }
14765 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14766 {
14767 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14768 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14769 GEN_INT (info->altivec_save_offset
14770 + 16 * i));
14771 rtx mem = gen_rtx_MEM (V4SImode, addr);
14772 set_mem_alias_set (mem, rs6000_sr_alias_set);
14773
14774 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14775 }
14776 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
14777 {
14778 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14779 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14780 GEN_INT (info->fp_save_offset
14781 + 8 * i));
14782 rtx mem = gen_rtx_MEM (DFmode, addr);
14783 set_mem_alias_set (mem, rs6000_sr_alias_set);
14784
14785 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14786 }
14787 RTVEC_ELT (p, j++)
14788 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
14789 RTVEC_ELT (p, j++)
14790 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
14791 RTVEC_ELT (p, j++)
14792 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
14793 RTVEC_ELT (p, j++)
14794 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
14795 RTVEC_ELT (p, j++)
14796 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
14797 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
14798
14799 return;
14800 }
14801
14802 /* If we have a frame pointer, a call to alloca, or a large stack
14803 frame, restore the old stack pointer using the backchain. Otherwise,
14804 we know what size to update it with. */
14805 if (use_backchain_to_restore_sp)
14806 {
14807 /* Under V.4, don't reset the stack pointer until after we're done
14808 loading the saved registers. */
14809 if (DEFAULT_ABI == ABI_V4)
14810 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
14811
14812 emit_move_insn (frame_reg_rtx,
14813 gen_rtx_MEM (Pmode, sp_reg_rtx));
14814
14815 }
14816 else if (info->push_p)
14817 {
14818 if (DEFAULT_ABI == ABI_V4
14819 || current_function_calls_eh_return)
14820 sp_offset = info->total_size;
14821 else
14822 {
14823 emit_insn (TARGET_32BIT
14824 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
14825 GEN_INT (info->total_size))
14826 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
14827 GEN_INT (info->total_size)));
14828 }
14829 }
14830
14831 /* Restore AltiVec registers if needed. */
14832 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14833 {
14834 int i;
14835
14836 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14837 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14838 {
14839 rtx addr, areg, mem;
14840
14841 areg = gen_rtx_REG (Pmode, 0);
14842 emit_move_insn
14843 (areg, GEN_INT (info->altivec_save_offset
14844 + sp_offset
14845 + 16 * (i - info->first_altivec_reg_save)));
14846
14847 /* AltiVec addressing mode is [reg+reg]. */
14848 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
14849 mem = gen_rtx_MEM (V4SImode, addr);
14850 set_mem_alias_set (mem, rs6000_sr_alias_set);
14851
14852 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
14853 }
14854 }
14855
14856 /* Restore VRSAVE if needed. */
14857 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14858 && info->vrsave_mask != 0)
14859 {
14860 rtx addr, mem, reg;
14861
14862 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14863 GEN_INT (info->vrsave_save_offset + sp_offset));
14864 mem = gen_rtx_MEM (SImode, addr);
14865 set_mem_alias_set (mem, rs6000_sr_alias_set);
14866 reg = gen_rtx_REG (SImode, 12);
14867 emit_move_insn (reg, mem);
14868
14869 emit_insn (generate_set_vrsave (reg, info, 1));
14870 }
14871
14872 /* Get the old lr if we saved it. */
14873 if (info->lr_save_p)
14874 {
14875 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
14876 info->lr_save_offset + sp_offset);
14877
14878 set_mem_alias_set (mem, rs6000_sr_alias_set);
14879
14880 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
14881 }
14882
14883 /* Get the old cr if we saved it. */
14884 if (info->cr_save_p)
14885 {
14886 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14887 GEN_INT (info->cr_save_offset + sp_offset));
14888 rtx mem = gen_rtx_MEM (SImode, addr);
14889
14890 set_mem_alias_set (mem, rs6000_sr_alias_set);
14891
14892 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
14893 }
14894
14895 /* Set LR here to try to overlap restores below. */
14896 if (info->lr_save_p)
14897 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
14898 gen_rtx_REG (Pmode, 0));
14899
14900 /* Load exception handler data registers, if needed. */
14901 if (current_function_calls_eh_return)
14902 {
14903 unsigned int i, regno;
14904
14905 if (TARGET_AIX)
14906 {
14907 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14908 GEN_INT (sp_offset + 5 * reg_size));
14909 rtx mem = gen_rtx_MEM (reg_mode, addr);
14910
14911 set_mem_alias_set (mem, rs6000_sr_alias_set);
14912
14913 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
14914 }
14915
14916 for (i = 0; ; ++i)
14917 {
14918 rtx mem;
14919
14920 regno = EH_RETURN_DATA_REGNO (i);
14921 if (regno == INVALID_REGNUM)
14922 break;
14923
14924 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
14925 info->ehrd_offset + sp_offset
14926 + reg_size * (int) i);
14927 set_mem_alias_set (mem, rs6000_sr_alias_set);
14928
14929 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
14930 }
14931 }
14932
14933 /* Restore GPRs. This is done as a PARALLEL if we are using
14934 the load-multiple instructions. */
14935 if (using_load_multiple)
14936 {
14937 rtvec p;
14938 p = rtvec_alloc (32 - info->first_gp_reg_save);
14939 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14940 {
14941 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14942 GEN_INT (info->gp_save_offset
14943 + sp_offset
14944 + reg_size * i));
14945 rtx mem = gen_rtx_MEM (reg_mode, addr);
14946
14947 set_mem_alias_set (mem, rs6000_sr_alias_set);
14948
14949 RTVEC_ELT (p, i) =
14950 gen_rtx_SET (VOIDmode,
14951 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
14952 mem);
14953 }
14954 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14955 }
14956 else
14957 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14958 if ((regs_ever_live[info->first_gp_reg_save + i]
14959 && (!call_used_regs[info->first_gp_reg_save + i]
14960 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14961 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14962 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14963 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14964 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14965 {
14966 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14967 GEN_INT (info->gp_save_offset
14968 + sp_offset
14969 + reg_size * i));
14970 rtx mem = gen_rtx_MEM (reg_mode, addr);
14971
14972 /* Restore 64-bit quantities for SPE. */
14973 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14974 {
14975 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14976 rtx b;
14977
14978 if (!SPE_CONST_OFFSET_OK (offset))
14979 {
14980 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14981 emit_move_insn (b, GEN_INT (offset));
14982 }
14983 else
14984 b = GEN_INT (offset);
14985
14986 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14987 mem = gen_rtx_MEM (V2SImode, addr);
14988 }
14989
14990 set_mem_alias_set (mem, rs6000_sr_alias_set);
14991
14992 emit_move_insn (gen_rtx_REG (reg_mode,
14993 info->first_gp_reg_save + i), mem);
14994 }
14995
14996 /* Restore fpr's if we need to do it without calling a function. */
14997 if (restoring_FPRs_inline)
14998 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14999 if ((regs_ever_live[info->first_fp_reg_save+i]
15000 && ! call_used_regs[info->first_fp_reg_save+i]))
15001 {
15002 rtx addr, mem;
15003 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15004 GEN_INT (info->fp_save_offset
15005 + sp_offset
15006 + 8 * i));
15007 mem = gen_rtx_MEM (DFmode, addr);
15008 set_mem_alias_set (mem, rs6000_sr_alias_set);
15009
15010 emit_move_insn (gen_rtx_REG (DFmode,
15011 info->first_fp_reg_save + i),
15012 mem);
15013 }
15014
15015 /* If we saved cr, restore it here. Just those that were used. */
15016 if (info->cr_save_p)
15017 {
15018 rtx r12_rtx = gen_rtx_REG (SImode, 12);
15019 int count = 0;
15020
15021 if (using_mfcr_multiple)
15022 {
15023 for (i = 0; i < 8; i++)
15024 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15025 count++;
15026 gcc_assert (count);
15027 }
15028
15029 if (using_mfcr_multiple && count > 1)
15030 {
15031 rtvec p;
15032 int ndx;
15033
15034 p = rtvec_alloc (count);
15035
15036 ndx = 0;
15037 for (i = 0; i < 8; i++)
15038 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15039 {
15040 rtvec r = rtvec_alloc (2);
15041 RTVEC_ELT (r, 0) = r12_rtx;
15042 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
15043 RTVEC_ELT (p, ndx) =
15044 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
15045 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
15046 ndx++;
15047 }
15048 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15049 gcc_assert (ndx == count);
15050 }
15051 else
15052 for (i = 0; i < 8; i++)
15053 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15054 {
15055 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
15056 CR0_REGNO+i),
15057 r12_rtx));
15058 }
15059 }
15060
15061 /* If this is V.4, unwind the stack pointer after all of the loads
15062 have been done. We need to emit a block here so that sched
15063 doesn't decide to move the sp change before the register restores
15064 (which may not have any obvious dependency on the stack). This
15065 doesn't hurt performance, because there is no scheduling that can
15066 be done after this point. */
15067 if (DEFAULT_ABI == ABI_V4
15068 || current_function_calls_eh_return)
15069 {
15070 if (frame_reg_rtx != sp_reg_rtx)
15071 rs6000_emit_stack_tie ();
15072
15073 if (use_backchain_to_restore_sp)
15074 {
15075 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
15076 }
15077 else if (sp_offset != 0)
15078 {
15079 emit_insn (TARGET_32BIT
15080 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15081 GEN_INT (sp_offset))
15082 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15083 GEN_INT (sp_offset)));
15084 }
15085 }
15086
15087 if (current_function_calls_eh_return)
15088 {
15089 rtx sa = EH_RETURN_STACKADJ_RTX;
15090 emit_insn (TARGET_32BIT
15091 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
15092 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
15093 }
15094
15095 if (!sibcall)
15096 {
15097 rtvec p;
15098 if (! restoring_FPRs_inline)
15099 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
15100 else
15101 p = rtvec_alloc (2);
15102
15103 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
15104 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15105 gen_rtx_REG (Pmode,
15106 LINK_REGISTER_REGNUM));
15107
15108 /* If we have to restore more than two FP registers, branch to the
15109 restore function. It will return to our caller. */
15110 if (! restoring_FPRs_inline)
15111 {
15112 int i;
15113 char rname[30];
15114 const char *alloc_rname;
15115
15116 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
15117 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
15118 alloc_rname = ggc_strdup (rname);
15119 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
15120 gen_rtx_SYMBOL_REF (Pmode,
15121 alloc_rname));
15122
15123 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15124 {
15125 rtx addr, mem;
15126 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
15127 GEN_INT (info->fp_save_offset + 8*i));
15128 mem = gen_rtx_MEM (DFmode, addr);
15129 set_mem_alias_set (mem, rs6000_sr_alias_set);
15130
15131 RTVEC_ELT (p, i+3) =
15132 gen_rtx_SET (VOIDmode,
15133 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
15134 mem);
15135 }
15136 }
15137
15138 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15139 }
15140 }
15141
15142 /* Write function epilogue. */
15143
15144 static void
rs6000_output_function_epilogue(FILE * file,HOST_WIDE_INT size ATTRIBUTE_UNUSED)15145 rs6000_output_function_epilogue (FILE *file,
15146 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15147 {
15148 if (! HAVE_epilogue)
15149 {
15150 rtx insn = get_last_insn ();
15151 /* If the last insn was a BARRIER, we don't have to write anything except
15152 the trace table. */
15153 if (GET_CODE (insn) == NOTE)
15154 insn = prev_nonnote_insn (insn);
15155 if (insn == 0 || GET_CODE (insn) != BARRIER)
15156 {
15157 /* This is slightly ugly, but at least we don't have two
15158 copies of the epilogue-emitting code. */
15159 start_sequence ();
15160
15161 /* A NOTE_INSN_DELETED is supposed to be at the start
15162 and end of the "toplevel" insn chain. */
15163 emit_note (NOTE_INSN_DELETED);
15164 rs6000_emit_epilogue (FALSE);
15165 emit_note (NOTE_INSN_DELETED);
15166
15167 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15168 {
15169 rtx insn;
15170 unsigned addr = 0;
15171 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15172 {
15173 INSN_ADDRESSES_NEW (insn, addr);
15174 addr += 4;
15175 }
15176 }
15177
15178 if (TARGET_DEBUG_STACK)
15179 debug_rtx_list (get_insns (), 100);
15180 final (get_insns (), file, FALSE);
15181 end_sequence ();
15182 }
15183 }
15184
15185 #if TARGET_MACHO
15186 macho_branch_islands ();
15187 /* Mach-O doesn't support labels at the end of objects, so if
15188 it looks like we might want one, insert a NOP. */
15189 {
15190 rtx insn = get_last_insn ();
15191 while (insn
15192 && NOTE_P (insn)
15193 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15194 insn = PREV_INSN (insn);
15195 if (insn
15196 && (LABEL_P (insn)
15197 || (NOTE_P (insn)
15198 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15199 fputs ("\tnop\n", file);
15200 }
15201 #endif
15202
15203 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15204 on its format.
15205
15206 We don't output a traceback table if -finhibit-size-directive was
15207 used. The documentation for -finhibit-size-directive reads
15208 ``don't output a @code{.size} assembler directive, or anything
15209 else that would cause trouble if the function is split in the
15210 middle, and the two halves are placed at locations far apart in
15211 memory.'' The traceback table has this property, since it
15212 includes the offset from the start of the function to the
15213 traceback table itself.
15214
15215 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15216 different traceback table. */
15217 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
15218 && rs6000_traceback != traceback_none && !current_function_is_thunk)
15219 {
15220 const char *fname = NULL;
15221 const char *language_string = lang_hooks.name;
15222 int fixed_parms = 0, float_parms = 0, parm_info = 0;
15223 int i;
15224 int optional_tbtab;
15225 rs6000_stack_t *info = rs6000_stack_info ();
15226
15227 if (rs6000_traceback == traceback_full)
15228 optional_tbtab = 1;
15229 else if (rs6000_traceback == traceback_part)
15230 optional_tbtab = 0;
15231 else
15232 optional_tbtab = !optimize_size && !TARGET_ELF;
15233
15234 if (optional_tbtab)
15235 {
15236 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15237 while (*fname == '.') /* V.4 encodes . in the name */
15238 fname++;
15239
15240 /* Need label immediately before tbtab, so we can compute
15241 its offset from the function start. */
15242 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15243 ASM_OUTPUT_LABEL (file, fname);
15244 }
15245
15246 /* The .tbtab pseudo-op can only be used for the first eight
15247 expressions, since it can't handle the possibly variable
15248 length fields that follow. However, if you omit the optional
15249 fields, the assembler outputs zeros for all optional fields
15250 anyways, giving each variable length field is minimum length
15251 (as defined in sys/debug.h). Thus we can not use the .tbtab
15252 pseudo-op at all. */
15253
15254 /* An all-zero word flags the start of the tbtab, for debuggers
15255 that have to find it by searching forward from the entry
15256 point or from the current pc. */
15257 fputs ("\t.long 0\n", file);
15258
15259 /* Tbtab format type. Use format type 0. */
15260 fputs ("\t.byte 0,", file);
15261
15262 /* Language type. Unfortunately, there does not seem to be any
15263 official way to discover the language being compiled, so we
15264 use language_string.
15265 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15266 Java is 13. Objective-C is 14. */
15267 if (! strcmp (language_string, "GNU C"))
15268 i = 0;
15269 else if (! strcmp (language_string, "GNU F77")
15270 || ! strcmp (language_string, "GNU F95"))
15271 i = 1;
15272 else if (! strcmp (language_string, "GNU Pascal"))
15273 i = 2;
15274 else if (! strcmp (language_string, "GNU Ada"))
15275 i = 3;
15276 else if (! strcmp (language_string, "GNU C++"))
15277 i = 9;
15278 else if (! strcmp (language_string, "GNU Java"))
15279 i = 13;
15280 else if (! strcmp (language_string, "GNU Objective-C"))
15281 i = 14;
15282 else
15283 gcc_unreachable ();
15284 fprintf (file, "%d,", i);
15285
15286 /* 8 single bit fields: global linkage (not set for C extern linkage,
15287 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15288 from start of procedure stored in tbtab, internal function, function
15289 has controlled storage, function has no toc, function uses fp,
15290 function logs/aborts fp operations. */
15291 /* Assume that fp operations are used if any fp reg must be saved. */
15292 fprintf (file, "%d,",
15293 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
15294
15295 /* 6 bitfields: function is interrupt handler, name present in
15296 proc table, function calls alloca, on condition directives
15297 (controls stack walks, 3 bits), saves condition reg, saves
15298 link reg. */
15299 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15300 set up as a frame pointer, even when there is no alloca call. */
15301 fprintf (file, "%d,",
15302 ((optional_tbtab << 6)
15303 | ((optional_tbtab & frame_pointer_needed) << 5)
15304 | (info->cr_save_p << 1)
15305 | (info->lr_save_p)));
15306
15307 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15308 (6 bits). */
15309 fprintf (file, "%d,",
15310 (info->push_p << 7) | (64 - info->first_fp_reg_save));
15311
15312 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15313 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15314
15315 if (optional_tbtab)
15316 {
15317 /* Compute the parameter info from the function decl argument
15318 list. */
15319 tree decl;
15320 int next_parm_info_bit = 31;
15321
15322 for (decl = DECL_ARGUMENTS (current_function_decl);
15323 decl; decl = TREE_CHAIN (decl))
15324 {
15325 rtx parameter = DECL_INCOMING_RTL (decl);
15326 enum machine_mode mode = GET_MODE (parameter);
15327
15328 if (GET_CODE (parameter) == REG)
15329 {
15330 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
15331 {
15332 int bits;
15333
15334 float_parms++;
15335
15336 switch (mode)
15337 {
15338 case SFmode:
15339 bits = 0x2;
15340 break;
15341
15342 case DFmode:
15343 case TFmode:
15344 bits = 0x3;
15345 break;
15346
15347 default:
15348 gcc_unreachable ();
15349 }
15350
15351 /* If only one bit will fit, don't or in this entry. */
15352 if (next_parm_info_bit > 0)
15353 parm_info |= (bits << (next_parm_info_bit - 1));
15354 next_parm_info_bit -= 2;
15355 }
15356 else
15357 {
15358 fixed_parms += ((GET_MODE_SIZE (mode)
15359 + (UNITS_PER_WORD - 1))
15360 / UNITS_PER_WORD);
15361 next_parm_info_bit -= 1;
15362 }
15363 }
15364 }
15365 }
15366
15367 /* Number of fixed point parameters. */
15368 /* This is actually the number of words of fixed point parameters; thus
15369 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15370 fprintf (file, "%d,", fixed_parms);
15371
15372 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15373 all on stack. */
15374 /* This is actually the number of fp registers that hold parameters;
15375 and thus the maximum value is 13. */
15376 /* Set parameters on stack bit if parameters are not in their original
15377 registers, regardless of whether they are on the stack? Xlc
15378 seems to set the bit when not optimizing. */
15379 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15380
15381 if (! optional_tbtab)
15382 return;
15383
15384 /* Optional fields follow. Some are variable length. */
15385
15386 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15387 11 double float. */
15388 /* There is an entry for each parameter in a register, in the order that
15389 they occur in the parameter list. Any intervening arguments on the
15390 stack are ignored. If the list overflows a long (max possible length
15391 34 bits) then completely leave off all elements that don't fit. */
15392 /* Only emit this long if there was at least one parameter. */
15393 if (fixed_parms || float_parms)
15394 fprintf (file, "\t.long %d\n", parm_info);
15395
15396 /* Offset from start of code to tb table. */
15397 fputs ("\t.long ", file);
15398 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15399 if (TARGET_AIX)
15400 RS6000_OUTPUT_BASENAME (file, fname);
15401 else
15402 assemble_name (file, fname);
15403 putc ('-', file);
15404 rs6000_output_function_entry (file, fname);
15405 putc ('\n', file);
15406
15407 /* Interrupt handler mask. */
15408 /* Omit this long, since we never set the interrupt handler bit
15409 above. */
15410
15411 /* Number of CTL (controlled storage) anchors. */
15412 /* Omit this long, since the has_ctl bit is never set above. */
15413
15414 /* Displacement into stack of each CTL anchor. */
15415 /* Omit this list of longs, because there are no CTL anchors. */
15416
15417 /* Length of function name. */
15418 if (*fname == '*')
15419 ++fname;
15420 fprintf (file, "\t.short %d\n", (int) strlen (fname));
15421
15422 /* Function name. */
15423 assemble_string (fname, strlen (fname));
15424
15425 /* Register for alloca automatic storage; this is always reg 31.
15426 Only emit this if the alloca bit was set above. */
15427 if (frame_pointer_needed)
15428 fputs ("\t.byte 31\n", file);
15429
15430 fputs ("\t.align 2\n", file);
15431 }
15432 }
15433
15434 /* A C compound statement that outputs the assembler code for a thunk
15435 function, used to implement C++ virtual function calls with
15436 multiple inheritance. The thunk acts as a wrapper around a virtual
15437 function, adjusting the implicit object parameter before handing
15438 control off to the real function.
15439
15440 First, emit code to add the integer DELTA to the location that
15441 contains the incoming first argument. Assume that this argument
15442 contains a pointer, and is the one used to pass the `this' pointer
15443 in C++. This is the incoming argument *before* the function
15444 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15445 values of all other incoming arguments.
15446
15447 After the addition, emit code to jump to FUNCTION, which is a
15448 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15449 not touch the return address. Hence returning from FUNCTION will
15450 return to whoever called the current `thunk'.
15451
15452 The effect must be as if FUNCTION had been called directly with the
15453 adjusted first argument. This macro is responsible for emitting
15454 all of the code for a thunk function; output_function_prologue()
15455 and output_function_epilogue() are not invoked.
15456
15457 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15458 been extracted from it.) It might possibly be useful on some
15459 targets, but probably not.
15460
15461 If you do not define this macro, the target-independent code in the
15462 C++ frontend will generate a less efficient heavyweight thunk that
15463 calls FUNCTION instead of jumping to it. The generic approach does
15464 not support varargs. */
15465
15466 static void
rs6000_output_mi_thunk(FILE * file,tree thunk_fndecl ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset,tree function)15467 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15468 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
15469 tree function)
15470 {
15471 rtx this, insn, funexp;
15472
15473 reload_completed = 1;
15474 epilogue_completed = 1;
15475 no_new_pseudos = 1;
15476 reset_block_changes ();
15477
15478 /* Mark the end of the (empty) prologue. */
15479 emit_note (NOTE_INSN_PROLOGUE_END);
15480
15481 /* Find the "this" pointer. If the function returns a structure,
15482 the structure return pointer is in r3. */
15483 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
15484 this = gen_rtx_REG (Pmode, 4);
15485 else
15486 this = gen_rtx_REG (Pmode, 3);
15487
15488 /* Apply the constant offset, if required. */
15489 if (delta)
15490 {
15491 rtx delta_rtx = GEN_INT (delta);
15492 emit_insn (TARGET_32BIT
15493 ? gen_addsi3 (this, this, delta_rtx)
15494 : gen_adddi3 (this, this, delta_rtx));
15495 }
15496
15497 /* Apply the offset from the vtable, if required. */
15498 if (vcall_offset)
15499 {
15500 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15501 rtx tmp = gen_rtx_REG (Pmode, 12);
15502
15503 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
15504 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15505 {
15506 emit_insn (TARGET_32BIT
15507 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15508 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15509 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15510 }
15511 else
15512 {
15513 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15514
15515 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15516 }
15517 emit_insn (TARGET_32BIT
15518 ? gen_addsi3 (this, this, tmp)
15519 : gen_adddi3 (this, this, tmp));
15520 }
15521
15522 /* Generate a tail call to the target function. */
15523 if (!TREE_USED (function))
15524 {
15525 assemble_external (function);
15526 TREE_USED (function) = 1;
15527 }
15528 funexp = XEXP (DECL_RTL (function), 0);
15529 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
15530
15531 #if TARGET_MACHO
15532 if (MACHOPIC_INDIRECT)
15533 funexp = machopic_indirect_call_target (funexp);
15534 #endif
15535
15536 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15537 generate sibcall RTL explicitly. */
15538 insn = emit_call_insn (
15539 gen_rtx_PARALLEL (VOIDmode,
15540 gen_rtvec (4,
15541 gen_rtx_CALL (VOIDmode,
15542 funexp, const0_rtx),
15543 gen_rtx_USE (VOIDmode, const0_rtx),
15544 gen_rtx_USE (VOIDmode,
15545 gen_rtx_REG (SImode,
15546 LINK_REGISTER_REGNUM)),
15547 gen_rtx_RETURN (VOIDmode))));
15548 SIBLING_CALL_P (insn) = 1;
15549 emit_barrier ();
15550
15551 /* Run just enough of rest_of_compilation to get the insns emitted.
15552 There's not really enough bulk here to make other passes such as
15553 instruction scheduling worth while. Note that use_thunk calls
15554 assemble_start_function and assemble_end_function. */
15555 insn = get_insns ();
15556 insn_locators_initialize ();
15557 shorten_branches (insn);
15558 final_start_function (insn, file, 1);
15559 final (insn, file, 1);
15560 final_end_function ();
15561
15562 reload_completed = 0;
15563 epilogue_completed = 0;
15564 no_new_pseudos = 0;
15565 }
15566
15567 /* A quick summary of the various types of 'constant-pool tables'
15568 under PowerPC:
15569
15570 Target Flags Name One table per
15571 AIX (none) AIX TOC object file
15572 AIX -mfull-toc AIX TOC object file
15573 AIX -mminimal-toc AIX minimal TOC translation unit
15574 SVR4/EABI (none) SVR4 SDATA object file
15575 SVR4/EABI -fpic SVR4 pic object file
15576 SVR4/EABI -fPIC SVR4 PIC translation unit
15577 SVR4/EABI -mrelocatable EABI TOC function
15578 SVR4/EABI -maix AIX TOC object file
15579 SVR4/EABI -maix -mminimal-toc
15580 AIX minimal TOC translation unit
15581
15582 Name Reg. Set by entries contains:
15583 made by addrs? fp? sum?
15584
15585 AIX TOC 2 crt0 as Y option option
15586 AIX minimal TOC 30 prolog gcc Y Y option
15587 SVR4 SDATA 13 crt0 gcc N Y N
15588 SVR4 pic 30 prolog ld Y not yet N
15589 SVR4 PIC 30 prolog gcc Y option option
15590 EABI TOC 30 prolog gcc Y option option
15591
15592 */
15593
15594 /* Hash functions for the hash table. */
15595
15596 static unsigned
rs6000_hash_constant(rtx k)15597 rs6000_hash_constant (rtx k)
15598 {
15599 enum rtx_code code = GET_CODE (k);
15600 enum machine_mode mode = GET_MODE (k);
15601 unsigned result = (code << 3) ^ mode;
15602 const char *format;
15603 int flen, fidx;
15604
15605 format = GET_RTX_FORMAT (code);
15606 flen = strlen (format);
15607 fidx = 0;
15608
15609 switch (code)
15610 {
15611 case LABEL_REF:
15612 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
15613
15614 case CONST_DOUBLE:
15615 if (mode != VOIDmode)
15616 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
15617 flen = 2;
15618 break;
15619
15620 case CODE_LABEL:
15621 fidx = 3;
15622 break;
15623
15624 default:
15625 break;
15626 }
15627
15628 for (; fidx < flen; fidx++)
15629 switch (format[fidx])
15630 {
15631 case 's':
15632 {
15633 unsigned i, len;
15634 const char *str = XSTR (k, fidx);
15635 len = strlen (str);
15636 result = result * 613 + len;
15637 for (i = 0; i < len; i++)
15638 result = result * 613 + (unsigned) str[i];
15639 break;
15640 }
15641 case 'u':
15642 case 'e':
15643 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
15644 break;
15645 case 'i':
15646 case 'n':
15647 result = result * 613 + (unsigned) XINT (k, fidx);
15648 break;
15649 case 'w':
15650 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
15651 result = result * 613 + (unsigned) XWINT (k, fidx);
15652 else
15653 {
15654 size_t i;
15655 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
15656 result = result * 613 + (unsigned) (XWINT (k, fidx)
15657 >> CHAR_BIT * i);
15658 }
15659 break;
15660 case '0':
15661 break;
15662 default:
15663 gcc_unreachable ();
15664 }
15665
15666 return result;
15667 }
15668
15669 static unsigned
toc_hash_function(const void * hash_entry)15670 toc_hash_function (const void *hash_entry)
15671 {
15672 const struct toc_hash_struct *thc =
15673 (const struct toc_hash_struct *) hash_entry;
15674 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
15675 }
15676
15677 /* Compare H1 and H2 for equivalence. */
15678
15679 static int
toc_hash_eq(const void * h1,const void * h2)15680 toc_hash_eq (const void *h1, const void *h2)
15681 {
15682 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
15683 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
15684
15685 if (((const struct toc_hash_struct *) h1)->key_mode
15686 != ((const struct toc_hash_struct *) h2)->key_mode)
15687 return 0;
15688
15689 return rtx_equal_p (r1, r2);
15690 }
15691
15692 /* These are the names given by the C++ front-end to vtables, and
15693 vtable-like objects. Ideally, this logic should not be here;
15694 instead, there should be some programmatic way of inquiring as
15695 to whether or not an object is a vtable. */
15696
15697 #define VTABLE_NAME_P(NAME) \
15698 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
15699 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
15700 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
15701 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
15702 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
15703
15704 void
rs6000_output_symbol_ref(FILE * file,rtx x)15705 rs6000_output_symbol_ref (FILE *file, rtx x)
15706 {
15707 /* Currently C++ toc references to vtables can be emitted before it
15708 is decided whether the vtable is public or private. If this is
15709 the case, then the linker will eventually complain that there is
15710 a reference to an unknown section. Thus, for vtables only,
15711 we emit the TOC reference to reference the symbol and not the
15712 section. */
15713 const char *name = XSTR (x, 0);
15714
15715 if (VTABLE_NAME_P (name))
15716 {
15717 RS6000_OUTPUT_BASENAME (file, name);
15718 }
15719 else
15720 assemble_name (file, name);
15721 }
15722
15723 /* Output a TOC entry. We derive the entry name from what is being
15724 written. */
15725
15726 void
output_toc(FILE * file,rtx x,int labelno,enum machine_mode mode)15727 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
15728 {
15729 char buf[256];
15730 const char *name = buf;
15731 const char *real_name;
15732 rtx base = x;
15733 HOST_WIDE_INT offset = 0;
15734
15735 gcc_assert (!TARGET_NO_TOC);
15736
15737 /* When the linker won't eliminate them, don't output duplicate
15738 TOC entries (this happens on AIX if there is any kind of TOC,
15739 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
15740 CODE_LABELs. */
15741 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
15742 {
15743 struct toc_hash_struct *h;
15744 void * * found;
15745
15746 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
15747 time because GGC is not initialized at that point. */
15748 if (toc_hash_table == NULL)
15749 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
15750 toc_hash_eq, NULL);
15751
15752 h = ggc_alloc (sizeof (*h));
15753 h->key = x;
15754 h->key_mode = mode;
15755 h->labelno = labelno;
15756
15757 found = htab_find_slot (toc_hash_table, h, 1);
15758 if (*found == NULL)
15759 *found = h;
15760 else /* This is indeed a duplicate.
15761 Set this label equal to that label. */
15762 {
15763 fputs ("\t.set ", file);
15764 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
15765 fprintf (file, "%d,", labelno);
15766 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
15767 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
15768 found)->labelno));
15769 return;
15770 }
15771 }
15772
15773 /* If we're going to put a double constant in the TOC, make sure it's
15774 aligned properly when strict alignment is on. */
15775 if (GET_CODE (x) == CONST_DOUBLE
15776 && STRICT_ALIGNMENT
15777 && GET_MODE_BITSIZE (mode) >= 64
15778 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
15779 ASM_OUTPUT_ALIGN (file, 3);
15780 }
15781
15782 (*targetm.asm_out.internal_label) (file, "LC", labelno);
15783
15784 /* Handle FP constants specially. Note that if we have a minimal
15785 TOC, things we put here aren't actually in the TOC, so we can allow
15786 FP constants. */
15787 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
15788 {
15789 REAL_VALUE_TYPE rv;
15790 long k[4];
15791
15792 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15793 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
15794
15795 if (TARGET_64BIT)
15796 {
15797 if (TARGET_MINIMAL_TOC)
15798 fputs (DOUBLE_INT_ASM_OP, file);
15799 else
15800 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15801 k[0] & 0xffffffff, k[1] & 0xffffffff,
15802 k[2] & 0xffffffff, k[3] & 0xffffffff);
15803 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
15804 k[0] & 0xffffffff, k[1] & 0xffffffff,
15805 k[2] & 0xffffffff, k[3] & 0xffffffff);
15806 return;
15807 }
15808 else
15809 {
15810 if (TARGET_MINIMAL_TOC)
15811 fputs ("\t.long ", file);
15812 else
15813 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15814 k[0] & 0xffffffff, k[1] & 0xffffffff,
15815 k[2] & 0xffffffff, k[3] & 0xffffffff);
15816 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
15817 k[0] & 0xffffffff, k[1] & 0xffffffff,
15818 k[2] & 0xffffffff, k[3] & 0xffffffff);
15819 return;
15820 }
15821 }
15822 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
15823 {
15824 REAL_VALUE_TYPE rv;
15825 long k[2];
15826
15827 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15828 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
15829
15830 if (TARGET_64BIT)
15831 {
15832 if (TARGET_MINIMAL_TOC)
15833 fputs (DOUBLE_INT_ASM_OP, file);
15834 else
15835 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15836 k[0] & 0xffffffff, k[1] & 0xffffffff);
15837 fprintf (file, "0x%lx%08lx\n",
15838 k[0] & 0xffffffff, k[1] & 0xffffffff);
15839 return;
15840 }
15841 else
15842 {
15843 if (TARGET_MINIMAL_TOC)
15844 fputs ("\t.long ", file);
15845 else
15846 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15847 k[0] & 0xffffffff, k[1] & 0xffffffff);
15848 fprintf (file, "0x%lx,0x%lx\n",
15849 k[0] & 0xffffffff, k[1] & 0xffffffff);
15850 return;
15851 }
15852 }
15853 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
15854 {
15855 REAL_VALUE_TYPE rv;
15856 long l;
15857
15858 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15859 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
15860
15861 if (TARGET_64BIT)
15862 {
15863 if (TARGET_MINIMAL_TOC)
15864 fputs (DOUBLE_INT_ASM_OP, file);
15865 else
15866 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15867 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
15868 return;
15869 }
15870 else
15871 {
15872 if (TARGET_MINIMAL_TOC)
15873 fputs ("\t.long ", file);
15874 else
15875 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15876 fprintf (file, "0x%lx\n", l & 0xffffffff);
15877 return;
15878 }
15879 }
15880 else if (GET_MODE (x) == VOIDmode
15881 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
15882 {
15883 unsigned HOST_WIDE_INT low;
15884 HOST_WIDE_INT high;
15885
15886 if (GET_CODE (x) == CONST_DOUBLE)
15887 {
15888 low = CONST_DOUBLE_LOW (x);
15889 high = CONST_DOUBLE_HIGH (x);
15890 }
15891 else
15892 #if HOST_BITS_PER_WIDE_INT == 32
15893 {
15894 low = INTVAL (x);
15895 high = (low & 0x80000000) ? ~0 : 0;
15896 }
15897 #else
15898 {
15899 low = INTVAL (x) & 0xffffffff;
15900 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
15901 }
15902 #endif
15903
15904 /* TOC entries are always Pmode-sized, but since this
15905 is a bigendian machine then if we're putting smaller
15906 integer constants in the TOC we have to pad them.
15907 (This is still a win over putting the constants in
15908 a separate constant pool, because then we'd have
15909 to have both a TOC entry _and_ the actual constant.)
15910
15911 For a 32-bit target, CONST_INT values are loaded and shifted
15912 entirely within `low' and can be stored in one TOC entry. */
15913
15914 /* It would be easy to make this work, but it doesn't now. */
15915 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
15916
15917 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
15918 {
15919 #if HOST_BITS_PER_WIDE_INT == 32
15920 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
15921 POINTER_SIZE, &low, &high, 0);
15922 #else
15923 low |= high << 32;
15924 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
15925 high = (HOST_WIDE_INT) low >> 32;
15926 low &= 0xffffffff;
15927 #endif
15928 }
15929
15930 if (TARGET_64BIT)
15931 {
15932 if (TARGET_MINIMAL_TOC)
15933 fputs (DOUBLE_INT_ASM_OP, file);
15934 else
15935 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
15936 (long) high & 0xffffffff, (long) low & 0xffffffff);
15937 fprintf (file, "0x%lx%08lx\n",
15938 (long) high & 0xffffffff, (long) low & 0xffffffff);
15939 return;
15940 }
15941 else
15942 {
15943 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
15944 {
15945 if (TARGET_MINIMAL_TOC)
15946 fputs ("\t.long ", file);
15947 else
15948 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
15949 (long) high & 0xffffffff, (long) low & 0xffffffff);
15950 fprintf (file, "0x%lx,0x%lx\n",
15951 (long) high & 0xffffffff, (long) low & 0xffffffff);
15952 }
15953 else
15954 {
15955 if (TARGET_MINIMAL_TOC)
15956 fputs ("\t.long ", file);
15957 else
15958 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
15959 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
15960 }
15961 return;
15962 }
15963 }
15964
15965 if (GET_CODE (x) == CONST)
15966 {
15967 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
15968
15969 base = XEXP (XEXP (x, 0), 0);
15970 offset = INTVAL (XEXP (XEXP (x, 0), 1));
15971 }
15972
15973 switch (GET_CODE (base))
15974 {
15975 case SYMBOL_REF:
15976 name = XSTR (base, 0);
15977 break;
15978
15979 case LABEL_REF:
15980 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
15981 CODE_LABEL_NUMBER (XEXP (base, 0)));
15982 break;
15983
15984 case CODE_LABEL:
15985 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
15986 break;
15987
15988 default:
15989 gcc_unreachable ();
15990 }
15991
15992 real_name = (*targetm.strip_name_encoding) (name);
15993 if (TARGET_MINIMAL_TOC)
15994 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
15995 else
15996 {
15997 fprintf (file, "\t.tc %s", real_name);
15998
15999 if (offset < 0)
16000 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
16001 else if (offset)
16002 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
16003
16004 fputs ("[TC],", file);
16005 }
16006
16007 /* Currently C++ toc references to vtables can be emitted before it
16008 is decided whether the vtable is public or private. If this is
16009 the case, then the linker will eventually complain that there is
16010 a TOC reference to an unknown section. Thus, for vtables only,
16011 we emit the TOC reference to reference the symbol and not the
16012 section. */
16013 if (VTABLE_NAME_P (name))
16014 {
16015 RS6000_OUTPUT_BASENAME (file, name);
16016 if (offset < 0)
16017 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
16018 else if (offset > 0)
16019 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
16020 }
16021 else
16022 output_addr_const (file, x);
16023 putc ('\n', file);
16024 }
16025
16026 /* Output an assembler pseudo-op to write an ASCII string of N characters
16027 starting at P to FILE.
16028
16029 On the RS/6000, we have to do this using the .byte operation and
16030 write out special characters outside the quoted string.
16031 Also, the assembler is broken; very long strings are truncated,
16032 so we must artificially break them up early. */
16033
16034 void
output_ascii(FILE * file,const char * p,int n)16035 output_ascii (FILE *file, const char *p, int n)
16036 {
16037 char c;
16038 int i, count_string;
16039 const char *for_string = "\t.byte \"";
16040 const char *for_decimal = "\t.byte ";
16041 const char *to_close = NULL;
16042
16043 count_string = 0;
16044 for (i = 0; i < n; i++)
16045 {
16046 c = *p++;
16047 if (c >= ' ' && c < 0177)
16048 {
16049 if (for_string)
16050 fputs (for_string, file);
16051 putc (c, file);
16052
16053 /* Write two quotes to get one. */
16054 if (c == '"')
16055 {
16056 putc (c, file);
16057 ++count_string;
16058 }
16059
16060 for_string = NULL;
16061 for_decimal = "\"\n\t.byte ";
16062 to_close = "\"\n";
16063 ++count_string;
16064
16065 if (count_string >= 512)
16066 {
16067 fputs (to_close, file);
16068
16069 for_string = "\t.byte \"";
16070 for_decimal = "\t.byte ";
16071 to_close = NULL;
16072 count_string = 0;
16073 }
16074 }
16075 else
16076 {
16077 if (for_decimal)
16078 fputs (for_decimal, file);
16079 fprintf (file, "%d", c);
16080
16081 for_string = "\n\t.byte \"";
16082 for_decimal = ", ";
16083 to_close = "\n";
16084 count_string = 0;
16085 }
16086 }
16087
16088 /* Now close the string if we have written one. Then end the line. */
16089 if (to_close)
16090 fputs (to_close, file);
16091 }
16092
16093 /* Generate a unique section name for FILENAME for a section type
16094 represented by SECTION_DESC. Output goes into BUF.
16095
16096 SECTION_DESC can be any string, as long as it is different for each
16097 possible section type.
16098
16099 We name the section in the same manner as xlc. The name begins with an
16100 underscore followed by the filename (after stripping any leading directory
16101 names) with the last period replaced by the string SECTION_DESC. If
16102 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16103 the name. */
16104
16105 void
rs6000_gen_section_name(char ** buf,const char * filename,const char * section_desc)16106 rs6000_gen_section_name (char **buf, const char *filename,
16107 const char *section_desc)
16108 {
16109 const char *q, *after_last_slash, *last_period = 0;
16110 char *p;
16111 int len;
16112
16113 after_last_slash = filename;
16114 for (q = filename; *q; q++)
16115 {
16116 if (*q == '/')
16117 after_last_slash = q + 1;
16118 else if (*q == '.')
16119 last_period = q;
16120 }
16121
16122 len = strlen (after_last_slash) + strlen (section_desc) + 2;
16123 *buf = (char *) xmalloc (len);
16124
16125 p = *buf;
16126 *p++ = '_';
16127
16128 for (q = after_last_slash; *q; q++)
16129 {
16130 if (q == last_period)
16131 {
16132 strcpy (p, section_desc);
16133 p += strlen (section_desc);
16134 break;
16135 }
16136
16137 else if (ISALNUM (*q))
16138 *p++ = *q;
16139 }
16140
16141 if (last_period == 0)
16142 strcpy (p, section_desc);
16143 else
16144 *p = '\0';
16145 }
16146
16147 /* Emit profile function. */
16148
16149 void
output_profile_hook(int labelno ATTRIBUTE_UNUSED)16150 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
16151 {
16152 /* Non-standard profiling for kernels, which just saves LR then calls
16153 _mcount without worrying about arg saves. The idea is to change
16154 the function prologue as little as possible as it isn't easy to
16155 account for arg save/restore code added just for _mcount. */
16156 if (TARGET_PROFILE_KERNEL)
16157 return;
16158
16159 if (DEFAULT_ABI == ABI_AIX)
16160 {
16161 #ifndef NO_PROFILE_COUNTERS
16162 # define NO_PROFILE_COUNTERS 0
16163 #endif
16164 if (NO_PROFILE_COUNTERS)
16165 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16166 else
16167 {
16168 char buf[30];
16169 const char *label_name;
16170 rtx fun;
16171
16172 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16173 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16174 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
16175
16176 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16177 fun, Pmode);
16178 }
16179 }
16180 else if (DEFAULT_ABI == ABI_DARWIN)
16181 {
16182 const char *mcount_name = RS6000_MCOUNT;
16183 int caller_addr_regno = LINK_REGISTER_REGNUM;
16184
16185 /* Be conservative and always set this, at least for now. */
16186 current_function_uses_pic_offset_table = 1;
16187
16188 #if TARGET_MACHO
16189 /* For PIC code, set up a stub and collect the caller's address
16190 from r0, which is where the prologue puts it. */
16191 if (MACHOPIC_INDIRECT
16192 && current_function_uses_pic_offset_table)
16193 caller_addr_regno = 0;
16194 #endif
16195 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16196 0, VOIDmode, 1,
16197 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16198 }
16199 }
16200
16201 /* Write function profiler code. */
16202
16203 void
output_function_profiler(FILE * file,int labelno)16204 output_function_profiler (FILE *file, int labelno)
16205 {
16206 char buf[100];
16207
16208 switch (DEFAULT_ABI)
16209 {
16210 default:
16211 gcc_unreachable ();
16212
16213 case ABI_V4:
16214 if (!TARGET_32BIT)
16215 {
16216 warning (0, "no profiling of 64-bit code for this ABI");
16217 return;
16218 }
16219 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16220 fprintf (file, "\tmflr %s\n", reg_names[0]);
16221 if (NO_PROFILE_COUNTERS)
16222 {
16223 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16224 reg_names[0], reg_names[1]);
16225 }
16226 else if (TARGET_SECURE_PLT && flag_pic)
16227 {
16228 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16229 reg_names[0], reg_names[1]);
16230 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16231 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16232 reg_names[12], reg_names[12]);
16233 assemble_name (file, buf);
16234 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16235 assemble_name (file, buf);
16236 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16237 }
16238 else if (flag_pic == 1)
16239 {
16240 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
16241 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16242 reg_names[0], reg_names[1]);
16243 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16244 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
16245 assemble_name (file, buf);
16246 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
16247 }
16248 else if (flag_pic > 1)
16249 {
16250 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16251 reg_names[0], reg_names[1]);
16252 /* Now, we need to get the address of the label. */
16253 fputs ("\tbcl 20,31,1f\n\t.long ", file);
16254 assemble_name (file, buf);
16255 fputs ("-.\n1:", file);
16256 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
16257 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
16258 reg_names[0], reg_names[11]);
16259 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16260 reg_names[0], reg_names[0], reg_names[11]);
16261 }
16262 else
16263 {
16264 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
16265 assemble_name (file, buf);
16266 fputs ("@ha\n", file);
16267 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16268 reg_names[0], reg_names[1]);
16269 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
16270 assemble_name (file, buf);
16271 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
16272 }
16273
16274 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16275 fprintf (file, "\tbl %s%s\n",
16276 RS6000_MCOUNT, flag_pic ? "@plt" : "");
16277 break;
16278
16279 case ABI_AIX:
16280 case ABI_DARWIN:
16281 if (!TARGET_PROFILE_KERNEL)
16282 {
16283 /* Don't do anything, done in output_profile_hook (). */
16284 }
16285 else
16286 {
16287 gcc_assert (!TARGET_32BIT);
16288
16289 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16290 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16291
16292 if (cfun->static_chain_decl != NULL)
16293 {
16294 asm_fprintf (file, "\tstd %s,24(%s)\n",
16295 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16296 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16297 asm_fprintf (file, "\tld %s,24(%s)\n",
16298 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16299 }
16300 else
16301 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16302 }
16303 break;
16304 }
16305 }
16306
16307
16308 /* Power4 load update and store update instructions are cracked into a
16309 load or store and an integer insn which are executed in the same cycle.
16310 Branches have their own dispatch slot which does not count against the
16311 GCC issue rate, but it changes the program flow so there are no other
16312 instructions to issue in this cycle. */
16313
16314 static int
rs6000_variable_issue(FILE * stream ATTRIBUTE_UNUSED,int verbose ATTRIBUTE_UNUSED,rtx insn,int more)16315 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16316 int verbose ATTRIBUTE_UNUSED,
16317 rtx insn, int more)
16318 {
16319 if (GET_CODE (PATTERN (insn)) == USE
16320 || GET_CODE (PATTERN (insn)) == CLOBBER)
16321 return more;
16322
16323 if (rs6000_sched_groups)
16324 {
16325 if (is_microcoded_insn (insn))
16326 return 0;
16327 else if (is_cracked_insn (insn))
16328 return more > 2 ? more - 2 : 0;
16329 }
16330
16331 return more - 1;
16332 }
16333
16334 /* Adjust the cost of a scheduling dependency. Return the new cost of
16335 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16336
16337 static int
rs6000_adjust_cost(rtx insn,rtx link,rtx dep_insn,int cost)16338 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
16339 {
16340 if (! recog_memoized (insn))
16341 return 0;
16342
16343 if (REG_NOTE_KIND (link) != 0)
16344 return 0;
16345
16346 if (REG_NOTE_KIND (link) == 0)
16347 {
16348 /* Data dependency; DEP_INSN writes a register that INSN reads
16349 some cycles later. */
16350
16351 /* Separate a load from a narrower, dependent store. */
16352 if (rs6000_sched_groups
16353 && GET_CODE (PATTERN (insn)) == SET
16354 && GET_CODE (PATTERN (dep_insn)) == SET
16355 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16356 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16357 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16358 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16359 return cost + 14;
16360
16361 switch (get_attr_type (insn))
16362 {
16363 case TYPE_JMPREG:
16364 /* Tell the first scheduling pass about the latency between
16365 a mtctr and bctr (and mtlr and br/blr). The first
16366 scheduling pass will not know about this latency since
16367 the mtctr instruction, which has the latency associated
16368 to it, will be generated by reload. */
16369 return TARGET_POWER ? 5 : 4;
16370 case TYPE_BRANCH:
16371 /* Leave some extra cycles between a compare and its
16372 dependent branch, to inhibit expensive mispredicts. */
16373 if ((rs6000_cpu_attr == CPU_PPC603
16374 || rs6000_cpu_attr == CPU_PPC604
16375 || rs6000_cpu_attr == CPU_PPC604E
16376 || rs6000_cpu_attr == CPU_PPC620
16377 || rs6000_cpu_attr == CPU_PPC630
16378 || rs6000_cpu_attr == CPU_PPC750
16379 || rs6000_cpu_attr == CPU_PPC7400
16380 || rs6000_cpu_attr == CPU_PPC7450
16381 || rs6000_cpu_attr == CPU_POWER4
16382 || rs6000_cpu_attr == CPU_POWER5)
16383 && recog_memoized (dep_insn)
16384 && (INSN_CODE (dep_insn) >= 0)
16385 && (get_attr_type (dep_insn) == TYPE_CMP
16386 || get_attr_type (dep_insn) == TYPE_COMPARE
16387 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
16388 || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
16389 || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
16390 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
16391 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
16392 || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
16393 return cost + 2;
16394 default:
16395 break;
16396 }
16397 /* Fall out to return default cost. */
16398 }
16399
16400 return cost;
16401 }
16402
16403 /* The function returns a true if INSN is microcoded.
16404 Return false otherwise. */
16405
16406 static bool
is_microcoded_insn(rtx insn)16407 is_microcoded_insn (rtx insn)
16408 {
16409 if (!insn || !INSN_P (insn)
16410 || GET_CODE (PATTERN (insn)) == USE
16411 || GET_CODE (PATTERN (insn)) == CLOBBER)
16412 return false;
16413
16414 if (rs6000_sched_groups)
16415 {
16416 enum attr_type type = get_attr_type (insn);
16417 if (type == TYPE_LOAD_EXT_U
16418 || type == TYPE_LOAD_EXT_UX
16419 || type == TYPE_LOAD_UX
16420 || type == TYPE_STORE_UX
16421 || type == TYPE_MFCR)
16422 return true;
16423 }
16424
16425 return false;
16426 }
16427
16428 /* The function returns a nonzero value if INSN can be scheduled only
16429 as the first insn in a dispatch group ("dispatch-slot restricted").
16430 In this case, the returned value indicates how many dispatch slots
16431 the insn occupies (at the beginning of the group).
16432 Return 0 otherwise. */
16433
16434 static int
is_dispatch_slot_restricted(rtx insn)16435 is_dispatch_slot_restricted (rtx insn)
16436 {
16437 enum attr_type type;
16438
16439 if (!rs6000_sched_groups)
16440 return 0;
16441
16442 if (!insn
16443 || insn == NULL_RTX
16444 || GET_CODE (insn) == NOTE
16445 || GET_CODE (PATTERN (insn)) == USE
16446 || GET_CODE (PATTERN (insn)) == CLOBBER)
16447 return 0;
16448
16449 type = get_attr_type (insn);
16450
16451 switch (type)
16452 {
16453 case TYPE_MFCR:
16454 case TYPE_MFCRF:
16455 case TYPE_MTCR:
16456 case TYPE_DELAYED_CR:
16457 case TYPE_CR_LOGICAL:
16458 case TYPE_MTJMPR:
16459 case TYPE_MFJMPR:
16460 return 1;
16461 case TYPE_IDIV:
16462 case TYPE_LDIV:
16463 return 2;
16464 case TYPE_LOAD_L:
16465 case TYPE_STORE_C:
16466 case TYPE_ISYNC:
16467 case TYPE_SYNC:
16468 return 4;
16469 default:
16470 if (rs6000_cpu == PROCESSOR_POWER5
16471 && is_cracked_insn (insn))
16472 return 2;
16473 return 0;
16474 }
16475 }
16476
16477 /* The function returns true if INSN is cracked into 2 instructions
16478 by the processor (and therefore occupies 2 issue slots). */
16479
16480 static bool
is_cracked_insn(rtx insn)16481 is_cracked_insn (rtx insn)
16482 {
16483 if (!insn || !INSN_P (insn)
16484 || GET_CODE (PATTERN (insn)) == USE
16485 || GET_CODE (PATTERN (insn)) == CLOBBER)
16486 return false;
16487
16488 if (rs6000_sched_groups)
16489 {
16490 enum attr_type type = get_attr_type (insn);
16491 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
16492 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
16493 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
16494 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
16495 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
16496 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
16497 || type == TYPE_IDIV || type == TYPE_LDIV
16498 || type == TYPE_INSERT_WORD)
16499 return true;
16500 }
16501
16502 return false;
16503 }
16504
16505 /* The function returns true if INSN can be issued only from
16506 the branch slot. */
16507
16508 static bool
is_branch_slot_insn(rtx insn)16509 is_branch_slot_insn (rtx insn)
16510 {
16511 if (!insn || !INSN_P (insn)
16512 || GET_CODE (PATTERN (insn)) == USE
16513 || GET_CODE (PATTERN (insn)) == CLOBBER)
16514 return false;
16515
16516 if (rs6000_sched_groups)
16517 {
16518 enum attr_type type = get_attr_type (insn);
16519 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
16520 return true;
16521 return false;
16522 }
16523
16524 return false;
16525 }
16526
16527 /* A C statement (sans semicolon) to update the integer scheduling
16528 priority INSN_PRIORITY (INSN). Increase the priority to execute the
16529 INSN earlier, reduce the priority to execute INSN later. Do not
16530 define this macro if you do not need to adjust the scheduling
16531 priorities of insns. */
16532
16533 static int
rs6000_adjust_priority(rtx insn ATTRIBUTE_UNUSED,int priority)16534 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
16535 {
16536 /* On machines (like the 750) which have asymmetric integer units,
16537 where one integer unit can do multiply and divides and the other
16538 can't, reduce the priority of multiply/divide so it is scheduled
16539 before other integer operations. */
16540
16541 #if 0
16542 if (! INSN_P (insn))
16543 return priority;
16544
16545 if (GET_CODE (PATTERN (insn)) == USE)
16546 return priority;
16547
16548 switch (rs6000_cpu_attr) {
16549 case CPU_PPC750:
16550 switch (get_attr_type (insn))
16551 {
16552 default:
16553 break;
16554
16555 case TYPE_IMUL:
16556 case TYPE_IDIV:
16557 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
16558 priority, priority);
16559 if (priority >= 0 && priority < 0x01000000)
16560 priority >>= 3;
16561 break;
16562 }
16563 }
16564 #endif
16565
16566 if (is_dispatch_slot_restricted (insn)
16567 && reload_completed
16568 && current_sched_info->sched_max_insns_priority
16569 && rs6000_sched_restricted_insns_priority)
16570 {
16571
16572 /* Prioritize insns that can be dispatched only in the first
16573 dispatch slot. */
16574 if (rs6000_sched_restricted_insns_priority == 1)
16575 /* Attach highest priority to insn. This means that in
16576 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
16577 precede 'priority' (critical path) considerations. */
16578 return current_sched_info->sched_max_insns_priority;
16579 else if (rs6000_sched_restricted_insns_priority == 2)
16580 /* Increase priority of insn by a minimal amount. This means that in
16581 haifa-sched.c:ready_sort(), only 'priority' (critical path)
16582 considerations precede dispatch-slot restriction considerations. */
16583 return (priority + 1);
16584 }
16585
16586 return priority;
16587 }
16588
16589 /* Return how many instructions the machine can issue per cycle. */
16590
16591 static int
rs6000_issue_rate(void)16592 rs6000_issue_rate (void)
16593 {
16594 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
16595 if (!reload_completed)
16596 return 1;
16597
16598 switch (rs6000_cpu_attr) {
16599 case CPU_RIOS1: /* ? */
16600 case CPU_RS64A:
16601 case CPU_PPC601: /* ? */
16602 case CPU_PPC7450:
16603 return 3;
16604 case CPU_PPC440:
16605 case CPU_PPC603:
16606 case CPU_PPC750:
16607 case CPU_PPC7400:
16608 case CPU_PPC8540:
16609 return 2;
16610 case CPU_RIOS2:
16611 case CPU_PPC604:
16612 case CPU_PPC604E:
16613 case CPU_PPC620:
16614 case CPU_PPC630:
16615 return 4;
16616 case CPU_POWER4:
16617 case CPU_POWER5:
16618 return 5;
16619 default:
16620 return 1;
16621 }
16622 }
16623
16624 /* Return how many instructions to look ahead for better insn
16625 scheduling. */
16626
16627 static int
rs6000_use_sched_lookahead(void)16628 rs6000_use_sched_lookahead (void)
16629 {
16630 if (rs6000_cpu_attr == CPU_PPC8540)
16631 return 4;
16632 return 0;
16633 }
16634
16635 /* Determine is PAT refers to memory. */
16636
16637 static bool
is_mem_ref(rtx pat)16638 is_mem_ref (rtx pat)
16639 {
16640 const char * fmt;
16641 int i, j;
16642 bool ret = false;
16643
16644 if (GET_CODE (pat) == MEM)
16645 return true;
16646
16647 /* Recursively process the pattern. */
16648 fmt = GET_RTX_FORMAT (GET_CODE (pat));
16649
16650 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
16651 {
16652 if (fmt[i] == 'e')
16653 ret |= is_mem_ref (XEXP (pat, i));
16654 else if (fmt[i] == 'E')
16655 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
16656 ret |= is_mem_ref (XVECEXP (pat, i, j));
16657 }
16658
16659 return ret;
16660 }
16661
16662 /* Determine if PAT is a PATTERN of a load insn. */
16663
16664 static bool
is_load_insn1(rtx pat)16665 is_load_insn1 (rtx pat)
16666 {
16667 if (!pat || pat == NULL_RTX)
16668 return false;
16669
16670 if (GET_CODE (pat) == SET)
16671 return is_mem_ref (SET_SRC (pat));
16672
16673 if (GET_CODE (pat) == PARALLEL)
16674 {
16675 int i;
16676
16677 for (i = 0; i < XVECLEN (pat, 0); i++)
16678 if (is_load_insn1 (XVECEXP (pat, 0, i)))
16679 return true;
16680 }
16681
16682 return false;
16683 }
16684
16685 /* Determine if INSN loads from memory. */
16686
16687 static bool
is_load_insn(rtx insn)16688 is_load_insn (rtx insn)
16689 {
16690 if (!insn || !INSN_P (insn))
16691 return false;
16692
16693 if (GET_CODE (insn) == CALL_INSN)
16694 return false;
16695
16696 return is_load_insn1 (PATTERN (insn));
16697 }
16698
16699 /* Determine if PAT is a PATTERN of a store insn. */
16700
16701 static bool
is_store_insn1(rtx pat)16702 is_store_insn1 (rtx pat)
16703 {
16704 if (!pat || pat == NULL_RTX)
16705 return false;
16706
16707 if (GET_CODE (pat) == SET)
16708 return is_mem_ref (SET_DEST (pat));
16709
16710 if (GET_CODE (pat) == PARALLEL)
16711 {
16712 int i;
16713
16714 for (i = 0; i < XVECLEN (pat, 0); i++)
16715 if (is_store_insn1 (XVECEXP (pat, 0, i)))
16716 return true;
16717 }
16718
16719 return false;
16720 }
16721
16722 /* Determine if INSN stores to memory. */
16723
16724 static bool
is_store_insn(rtx insn)16725 is_store_insn (rtx insn)
16726 {
16727 if (!insn || !INSN_P (insn))
16728 return false;
16729
16730 return is_store_insn1 (PATTERN (insn));
16731 }
16732
16733 /* Returns whether the dependence between INSN and NEXT is considered
16734 costly by the given target. */
16735
16736 static bool
rs6000_is_costly_dependence(rtx insn,rtx next,rtx link,int cost,int distance)16737 rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
16738 int distance)
16739 {
16740 /* If the flag is not enabled - no dependence is considered costly;
16741 allow all dependent insns in the same group.
16742 This is the most aggressive option. */
16743 if (rs6000_sched_costly_dep == no_dep_costly)
16744 return false;
16745
16746 /* If the flag is set to 1 - a dependence is always considered costly;
16747 do not allow dependent instructions in the same group.
16748 This is the most conservative option. */
16749 if (rs6000_sched_costly_dep == all_deps_costly)
16750 return true;
16751
16752 if (rs6000_sched_costly_dep == store_to_load_dep_costly
16753 && is_load_insn (next)
16754 && is_store_insn (insn))
16755 /* Prevent load after store in the same group. */
16756 return true;
16757
16758 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
16759 && is_load_insn (next)
16760 && is_store_insn (insn)
16761 && (!link || (int) REG_NOTE_KIND (link) == 0))
16762 /* Prevent load after store in the same group if it is a true
16763 dependence. */
16764 return true;
16765
16766 /* The flag is set to X; dependences with latency >= X are considered costly,
16767 and will not be scheduled in the same group. */
16768 if (rs6000_sched_costly_dep <= max_dep_latency
16769 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
16770 return true;
16771
16772 return false;
16773 }
16774
16775 /* Return the next insn after INSN that is found before TAIL is reached,
16776 skipping any "non-active" insns - insns that will not actually occupy
16777 an issue slot. Return NULL_RTX if such an insn is not found. */
16778
16779 static rtx
get_next_active_insn(rtx insn,rtx tail)16780 get_next_active_insn (rtx insn, rtx tail)
16781 {
16782 if (insn == NULL_RTX || insn == tail)
16783 return NULL_RTX;
16784
16785 while (1)
16786 {
16787 insn = NEXT_INSN (insn);
16788 if (insn == NULL_RTX || insn == tail)
16789 return NULL_RTX;
16790
16791 if (CALL_P (insn)
16792 || JUMP_P (insn)
16793 || (NONJUMP_INSN_P (insn)
16794 && GET_CODE (PATTERN (insn)) != USE
16795 && GET_CODE (PATTERN (insn)) != CLOBBER
16796 && INSN_CODE (insn) != CODE_FOR_stack_tie))
16797 break;
16798 }
16799 return insn;
16800 }
16801
16802 /* Return whether the presence of INSN causes a dispatch group termination
16803 of group WHICH_GROUP.
16804
16805 If WHICH_GROUP == current_group, this function will return true if INSN
16806 causes the termination of the current group (i.e, the dispatch group to
16807 which INSN belongs). This means that INSN will be the last insn in the
16808 group it belongs to.
16809
16810 If WHICH_GROUP == previous_group, this function will return true if INSN
16811 causes the termination of the previous group (i.e, the dispatch group that
16812 precedes the group to which INSN belongs). This means that INSN will be
16813 the first insn in the group it belongs to). */
16814
16815 static bool
insn_terminates_group_p(rtx insn,enum group_termination which_group)16816 insn_terminates_group_p (rtx insn, enum group_termination which_group)
16817 {
16818 enum attr_type type;
16819
16820 if (! insn)
16821 return false;
16822
16823 type = get_attr_type (insn);
16824
16825 if (is_microcoded_insn (insn))
16826 return true;
16827
16828 if (which_group == current_group)
16829 {
16830 if (is_branch_slot_insn (insn))
16831 return true;
16832 return false;
16833 }
16834 else if (which_group == previous_group)
16835 {
16836 if (is_dispatch_slot_restricted (insn))
16837 return true;
16838 return false;
16839 }
16840
16841 return false;
16842 }
16843
16844 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
16845 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
16846
16847 static bool
is_costly_group(rtx * group_insns,rtx next_insn)16848 is_costly_group (rtx *group_insns, rtx next_insn)
16849 {
16850 int i;
16851 rtx link;
16852 int cost;
16853 int issue_rate = rs6000_issue_rate ();
16854
16855 for (i = 0; i < issue_rate; i++)
16856 {
16857 rtx insn = group_insns[i];
16858 if (!insn)
16859 continue;
16860 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
16861 {
16862 rtx next = XEXP (link, 0);
16863 if (next == next_insn)
16864 {
16865 cost = insn_cost (insn, link, next_insn);
16866 if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
16867 return true;
16868 }
16869 }
16870 }
16871
16872 return false;
16873 }
16874
16875 /* Utility of the function redefine_groups.
16876 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16877 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16878 to keep it "far" (in a separate group) from GROUP_INSNS, following
16879 one of the following schemes, depending on the value of the flag
16880 -minsert_sched_nops = X:
16881 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
16882 in order to force NEXT_INSN into a separate group.
16883 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16884 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
16885 insertion (has a group just ended, how many vacant issue slots remain in the
16886 last group, and how many dispatch groups were encountered so far). */
16887
16888 static int
force_new_group(int sched_verbose,FILE * dump,rtx * group_insns,rtx next_insn,bool * group_end,int can_issue_more,int * group_count)16889 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
16890 rtx next_insn, bool *group_end, int can_issue_more,
16891 int *group_count)
16892 {
16893 rtx nop;
16894 bool force;
16895 int issue_rate = rs6000_issue_rate ();
16896 bool end = *group_end;
16897 int i;
16898
16899 if (next_insn == NULL_RTX)
16900 return can_issue_more;
16901
16902 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
16903 return can_issue_more;
16904
16905 force = is_costly_group (group_insns, next_insn);
16906 if (!force)
16907 return can_issue_more;
16908
16909 if (sched_verbose > 6)
16910 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
16911 *group_count ,can_issue_more);
16912
16913 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
16914 {
16915 if (*group_end)
16916 can_issue_more = 0;
16917
16918 /* Since only a branch can be issued in the last issue_slot, it is
16919 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16920 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16921 in this case the last nop will start a new group and the branch
16922 will be forced to the new group. */
16923 if (can_issue_more && !is_branch_slot_insn (next_insn))
16924 can_issue_more--;
16925
16926 while (can_issue_more > 0)
16927 {
16928 nop = gen_nop ();
16929 emit_insn_before (nop, next_insn);
16930 can_issue_more--;
16931 }
16932
16933 *group_end = true;
16934 return 0;
16935 }
16936
16937 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
16938 {
16939 int n_nops = rs6000_sched_insert_nops;
16940
16941 /* Nops can't be issued from the branch slot, so the effective
16942 issue_rate for nops is 'issue_rate - 1'. */
16943 if (can_issue_more == 0)
16944 can_issue_more = issue_rate;
16945 can_issue_more--;
16946 if (can_issue_more == 0)
16947 {
16948 can_issue_more = issue_rate - 1;
16949 (*group_count)++;
16950 end = true;
16951 for (i = 0; i < issue_rate; i++)
16952 {
16953 group_insns[i] = 0;
16954 }
16955 }
16956
16957 while (n_nops > 0)
16958 {
16959 nop = gen_nop ();
16960 emit_insn_before (nop, next_insn);
16961 if (can_issue_more == issue_rate - 1) /* new group begins */
16962 end = false;
16963 can_issue_more--;
16964 if (can_issue_more == 0)
16965 {
16966 can_issue_more = issue_rate - 1;
16967 (*group_count)++;
16968 end = true;
16969 for (i = 0; i < issue_rate; i++)
16970 {
16971 group_insns[i] = 0;
16972 }
16973 }
16974 n_nops--;
16975 }
16976
16977 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16978 can_issue_more++;
16979
16980 /* Is next_insn going to start a new group? */
16981 *group_end
16982 = (end
16983 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
16984 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
16985 || (can_issue_more < issue_rate &&
16986 insn_terminates_group_p (next_insn, previous_group)));
16987 if (*group_end && end)
16988 (*group_count)--;
16989
16990 if (sched_verbose > 6)
16991 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
16992 *group_count, can_issue_more);
16993 return can_issue_more;
16994 }
16995
16996 return can_issue_more;
16997 }
16998
16999 /* This function tries to synch the dispatch groups that the compiler "sees"
17000 with the dispatch groups that the processor dispatcher is expected to
17001 form in practice. It tries to achieve this synchronization by forcing the
17002 estimated processor grouping on the compiler (as opposed to the function
17003 'pad_goups' which tries to force the scheduler's grouping on the processor).
17004
17005 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
17006 examines the (estimated) dispatch groups that will be formed by the processor
17007 dispatcher. It marks these group boundaries to reflect the estimated
17008 processor grouping, overriding the grouping that the scheduler had marked.
17009 Depending on the value of the flag '-minsert-sched-nops' this function can
17010 force certain insns into separate groups or force a certain distance between
17011 them by inserting nops, for example, if there exists a "costly dependence"
17012 between the insns.
17013
17014 The function estimates the group boundaries that the processor will form as
17015 follows: It keeps track of how many vacant issue slots are available after
17016 each insn. A subsequent insn will start a new group if one of the following
17017 4 cases applies:
17018 - no more vacant issue slots remain in the current dispatch group.
17019 - only the last issue slot, which is the branch slot, is vacant, but the next
17020 insn is not a branch.
17021 - only the last 2 or less issue slots, including the branch slot, are vacant,
17022 which means that a cracked insn (which occupies two issue slots) can't be
17023 issued in this group.
17024 - less than 'issue_rate' slots are vacant, and the next insn always needs to
17025 start a new group. */
17026
17027 static int
redefine_groups(FILE * dump,int sched_verbose,rtx prev_head_insn,rtx tail)17028 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
17029 {
17030 rtx insn, next_insn;
17031 int issue_rate;
17032 int can_issue_more;
17033 int slot, i;
17034 bool group_end;
17035 int group_count = 0;
17036 rtx *group_insns;
17037
17038 /* Initialize. */
17039 issue_rate = rs6000_issue_rate ();
17040 group_insns = alloca (issue_rate * sizeof (rtx));
17041 for (i = 0; i < issue_rate; i++)
17042 {
17043 group_insns[i] = 0;
17044 }
17045 can_issue_more = issue_rate;
17046 slot = 0;
17047 insn = get_next_active_insn (prev_head_insn, tail);
17048 group_end = false;
17049
17050 while (insn != NULL_RTX)
17051 {
17052 slot = (issue_rate - can_issue_more);
17053 group_insns[slot] = insn;
17054 can_issue_more =
17055 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
17056 if (insn_terminates_group_p (insn, current_group))
17057 can_issue_more = 0;
17058
17059 next_insn = get_next_active_insn (insn, tail);
17060 if (next_insn == NULL_RTX)
17061 return group_count + 1;
17062
17063 /* Is next_insn going to start a new group? */
17064 group_end
17065 = (can_issue_more == 0
17066 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
17067 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
17068 || (can_issue_more < issue_rate &&
17069 insn_terminates_group_p (next_insn, previous_group)));
17070
17071 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
17072 next_insn, &group_end, can_issue_more,
17073 &group_count);
17074
17075 if (group_end)
17076 {
17077 group_count++;
17078 can_issue_more = 0;
17079 for (i = 0; i < issue_rate; i++)
17080 {
17081 group_insns[i] = 0;
17082 }
17083 }
17084
17085 if (GET_MODE (next_insn) == TImode && can_issue_more)
17086 PUT_MODE (next_insn, VOIDmode);
17087 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
17088 PUT_MODE (next_insn, TImode);
17089
17090 insn = next_insn;
17091 if (can_issue_more == 0)
17092 can_issue_more = issue_rate;
17093 } /* while */
17094
17095 return group_count;
17096 }
17097
17098 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
17099 dispatch group boundaries that the scheduler had marked. Pad with nops
17100 any dispatch groups which have vacant issue slots, in order to force the
17101 scheduler's grouping on the processor dispatcher. The function
17102 returns the number of dispatch groups found. */
17103
17104 static int
pad_groups(FILE * dump,int sched_verbose,rtx prev_head_insn,rtx tail)17105 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
17106 {
17107 rtx insn, next_insn;
17108 rtx nop;
17109 int issue_rate;
17110 int can_issue_more;
17111 int group_end;
17112 int group_count = 0;
17113
17114 /* Initialize issue_rate. */
17115 issue_rate = rs6000_issue_rate ();
17116 can_issue_more = issue_rate;
17117
17118 insn = get_next_active_insn (prev_head_insn, tail);
17119 next_insn = get_next_active_insn (insn, tail);
17120
17121 while (insn != NULL_RTX)
17122 {
17123 can_issue_more =
17124 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
17125
17126 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
17127
17128 if (next_insn == NULL_RTX)
17129 break;
17130
17131 if (group_end)
17132 {
17133 /* If the scheduler had marked group termination at this location
17134 (between insn and next_indn), and neither insn nor next_insn will
17135 force group termination, pad the group with nops to force group
17136 termination. */
17137 if (can_issue_more
17138 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
17139 && !insn_terminates_group_p (insn, current_group)
17140 && !insn_terminates_group_p (next_insn, previous_group))
17141 {
17142 if (!is_branch_slot_insn (next_insn))
17143 can_issue_more--;
17144
17145 while (can_issue_more)
17146 {
17147 nop = gen_nop ();
17148 emit_insn_before (nop, next_insn);
17149 can_issue_more--;
17150 }
17151 }
17152
17153 can_issue_more = issue_rate;
17154 group_count++;
17155 }
17156
17157 insn = next_insn;
17158 next_insn = get_next_active_insn (insn, tail);
17159 }
17160
17161 return group_count;
17162 }
17163
17164 /* The following function is called at the end of scheduling BB.
17165 After reload, it inserts nops at insn group bundling. */
17166
17167 static void
rs6000_sched_finish(FILE * dump,int sched_verbose)17168 rs6000_sched_finish (FILE *dump, int sched_verbose)
17169 {
17170 int n_groups;
17171
17172 if (sched_verbose)
17173 fprintf (dump, "=== Finishing schedule.\n");
17174
17175 if (reload_completed && rs6000_sched_groups)
17176 {
17177 if (rs6000_sched_insert_nops == sched_finish_none)
17178 return;
17179
17180 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
17181 n_groups = pad_groups (dump, sched_verbose,
17182 current_sched_info->prev_head,
17183 current_sched_info->next_tail);
17184 else
17185 n_groups = redefine_groups (dump, sched_verbose,
17186 current_sched_info->prev_head,
17187 current_sched_info->next_tail);
17188
17189 if (sched_verbose >= 6)
17190 {
17191 fprintf (dump, "ngroups = %d\n", n_groups);
17192 print_rtl (dump, current_sched_info->prev_head);
17193 fprintf (dump, "Done finish_sched\n");
17194 }
17195 }
17196 }
17197
17198 /* Length in units of the trampoline for entering a nested function. */
17199
17200 int
rs6000_trampoline_size(void)17201 rs6000_trampoline_size (void)
17202 {
17203 int ret = 0;
17204
17205 switch (DEFAULT_ABI)
17206 {
17207 default:
17208 gcc_unreachable ();
17209
17210 case ABI_AIX:
17211 ret = (TARGET_32BIT) ? 12 : 24;
17212 break;
17213
17214 case ABI_DARWIN:
17215 case ABI_V4:
17216 ret = (TARGET_32BIT) ? 40 : 48;
17217 break;
17218 }
17219
17220 return ret;
17221 }
17222
17223 /* Emit RTL insns to initialize the variable parts of a trampoline.
17224 FNADDR is an RTX for the address of the function's pure code.
17225 CXT is an RTX for the static chain value for the function. */
17226
17227 void
rs6000_initialize_trampoline(rtx addr,rtx fnaddr,rtx cxt)17228 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
17229 {
17230 enum machine_mode pmode = Pmode;
17231 int regsize = (TARGET_32BIT) ? 4 : 8;
17232 rtx ctx_reg = force_reg (pmode, cxt);
17233
17234 switch (DEFAULT_ABI)
17235 {
17236 default:
17237 gcc_unreachable ();
17238
17239 /* Macros to shorten the code expansions below. */
17240 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
17241 #define MEM_PLUS(addr,offset) \
17242 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
17243
17244 /* Under AIX, just build the 3 word function descriptor */
17245 case ABI_AIX:
17246 {
17247 rtx fn_reg = gen_reg_rtx (pmode);
17248 rtx toc_reg = gen_reg_rtx (pmode);
17249 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
17250 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
17251 emit_move_insn (MEM_DEREF (addr), fn_reg);
17252 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
17253 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
17254 }
17255 break;
17256
17257 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
17258 case ABI_DARWIN:
17259 case ABI_V4:
17260 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
17261 FALSE, VOIDmode, 4,
17262 addr, pmode,
17263 GEN_INT (rs6000_trampoline_size ()), SImode,
17264 fnaddr, pmode,
17265 ctx_reg, pmode);
17266 break;
17267 }
17268
17269 return;
17270 }
17271
17272
17273 /* Table of valid machine attributes. */
17274
17275 const struct attribute_spec rs6000_attribute_table[] =
17276 {
17277 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
17278 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
17279 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
17280 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
17281 #ifdef SUBTARGET_ATTRIBUTE_TABLE
17282 SUBTARGET_ATTRIBUTE_TABLE,
17283 #endif
17284 { NULL, 0, 0, false, false, false, NULL }
17285 };
17286
17287 /* Handle the "altivec" attribute. The attribute may have
17288 arguments as follows:
17289
17290 __attribute__((altivec(vector__)))
17291 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
17292 __attribute__((altivec(bool__))) (always followed by 'unsigned')
17293
17294 and may appear more than once (e.g., 'vector bool char') in a
17295 given declaration. */
17296
17297 static tree
rs6000_handle_altivec_attribute(tree * node,tree name ATTRIBUTE_UNUSED,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)17298 rs6000_handle_altivec_attribute (tree *node,
17299 tree name ATTRIBUTE_UNUSED,
17300 tree args,
17301 int flags ATTRIBUTE_UNUSED,
17302 bool *no_add_attrs)
17303 {
17304 tree type = *node, result = NULL_TREE;
17305 enum machine_mode mode;
17306 int unsigned_p;
17307 char altivec_type
17308 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
17309 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
17310 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
17311 : '?');
17312
17313 while (POINTER_TYPE_P (type)
17314 || TREE_CODE (type) == FUNCTION_TYPE
17315 || TREE_CODE (type) == METHOD_TYPE
17316 || TREE_CODE (type) == ARRAY_TYPE)
17317 type = TREE_TYPE (type);
17318
17319 mode = TYPE_MODE (type);
17320
17321 /* Check for invalid AltiVec type qualifiers. */
17322 if (type == long_unsigned_type_node || type == long_integer_type_node)
17323 {
17324 if (TARGET_64BIT)
17325 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
17326 else if (rs6000_warn_altivec_long)
17327 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
17328 }
17329 else if (type == long_long_unsigned_type_node
17330 || type == long_long_integer_type_node)
17331 error ("use of %<long long%> in AltiVec types is invalid");
17332 else if (type == double_type_node)
17333 error ("use of %<double%> in AltiVec types is invalid");
17334 else if (type == long_double_type_node)
17335 error ("use of %<long double%> in AltiVec types is invalid");
17336 else if (type == boolean_type_node)
17337 error ("use of boolean types in AltiVec types is invalid");
17338 else if (TREE_CODE (type) == COMPLEX_TYPE)
17339 error ("use of %<complex%> in AltiVec types is invalid");
17340
17341 switch (altivec_type)
17342 {
17343 case 'v':
17344 unsigned_p = TYPE_UNSIGNED (type);
17345 switch (mode)
17346 {
17347 case SImode:
17348 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
17349 break;
17350 case HImode:
17351 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
17352 break;
17353 case QImode:
17354 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
17355 break;
17356 case SFmode: result = V4SF_type_node; break;
17357 /* If the user says 'vector int bool', we may be handed the 'bool'
17358 attribute _before_ the 'vector' attribute, and so select the
17359 proper type in the 'b' case below. */
17360 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
17361 result = type;
17362 default: break;
17363 }
17364 break;
17365 case 'b':
17366 switch (mode)
17367 {
17368 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
17369 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
17370 case QImode: case V16QImode: result = bool_V16QI_type_node;
17371 default: break;
17372 }
17373 break;
17374 case 'p':
17375 switch (mode)
17376 {
17377 case V8HImode: result = pixel_V8HI_type_node;
17378 default: break;
17379 }
17380 default: break;
17381 }
17382
17383 if (result && result != type && TYPE_READONLY (type))
17384 result = build_qualified_type (result, TYPE_QUAL_CONST);
17385
17386 *no_add_attrs = true; /* No need to hang on to the attribute. */
17387
17388 if (result)
17389 *node = reconstruct_complex_type (*node, result);
17390
17391 return NULL_TREE;
17392 }
17393
17394 /* AltiVec defines four built-in scalar types that serve as vector
17395 elements; we must teach the compiler how to mangle them. */
17396
17397 static const char *
rs6000_mangle_fundamental_type(tree type)17398 rs6000_mangle_fundamental_type (tree type)
17399 {
17400 if (type == bool_char_type_node) return "U6__boolc";
17401 if (type == bool_short_type_node) return "U6__bools";
17402 if (type == pixel_type_node) return "u7__pixel";
17403 if (type == bool_int_type_node) return "U6__booli";
17404
17405 /* Mangle IBM extended float long double as `g' (__float128) on
17406 powerpc*-linux where long-double-64 previously was the default. */
17407 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
17408 && TARGET_ELF
17409 && TARGET_LONG_DOUBLE_128
17410 && !TARGET_IEEEQUAD)
17411 return "g";
17412
17413 /* For all other types, use normal C++ mangling. */
17414 return NULL;
17415 }
17416
17417 /* Handle a "longcall" or "shortcall" attribute; arguments as in
17418 struct attribute_spec.handler. */
17419
17420 static tree
rs6000_handle_longcall_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)17421 rs6000_handle_longcall_attribute (tree *node, tree name,
17422 tree args ATTRIBUTE_UNUSED,
17423 int flags ATTRIBUTE_UNUSED,
17424 bool *no_add_attrs)
17425 {
17426 if (TREE_CODE (*node) != FUNCTION_TYPE
17427 && TREE_CODE (*node) != FIELD_DECL
17428 && TREE_CODE (*node) != TYPE_DECL)
17429 {
17430 warning (OPT_Wattributes, "%qs attribute only applies to functions",
17431 IDENTIFIER_POINTER (name));
17432 *no_add_attrs = true;
17433 }
17434
17435 return NULL_TREE;
17436 }
17437
17438 /* Set longcall attributes on all functions declared when
17439 rs6000_default_long_calls is true. */
17440 static void
rs6000_set_default_type_attributes(tree type)17441 rs6000_set_default_type_attributes (tree type)
17442 {
17443 if (rs6000_default_long_calls
17444 && (TREE_CODE (type) == FUNCTION_TYPE
17445 || TREE_CODE (type) == METHOD_TYPE))
17446 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
17447 NULL_TREE,
17448 TYPE_ATTRIBUTES (type));
17449 }
17450
17451 /* Return a reference suitable for calling a function with the
17452 longcall attribute. */
17453
17454 rtx
rs6000_longcall_ref(rtx call_ref)17455 rs6000_longcall_ref (rtx call_ref)
17456 {
17457 const char *call_name;
17458 tree node;
17459
17460 if (GET_CODE (call_ref) != SYMBOL_REF)
17461 return call_ref;
17462
17463 /* System V adds '.' to the internal name, so skip them. */
17464 call_name = XSTR (call_ref, 0);
17465 if (*call_name == '.')
17466 {
17467 while (*call_name == '.')
17468 call_name++;
17469
17470 node = get_identifier (call_name);
17471 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
17472 }
17473
17474 return force_reg (Pmode, call_ref);
17475 }
17476
17477 #ifdef USING_ELFOS_H
17478
17479 /* A C statement or statements to switch to the appropriate section
17480 for output of RTX in mode MODE. You can assume that RTX is some
17481 kind of constant in RTL. The argument MODE is redundant except in
17482 the case of a `const_int' rtx. Select the section by calling
17483 `text_section' or one of the alternatives for other sections.
17484
17485 Do not define this macro if you put all constants in the read-only
17486 data section. */
17487
17488 static void
rs6000_elf_select_rtx_section(enum machine_mode mode,rtx x,unsigned HOST_WIDE_INT align)17489 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
17490 unsigned HOST_WIDE_INT align)
17491 {
17492 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
17493 toc_section ();
17494 else
17495 default_elf_select_rtx_section (mode, x, align);
17496 }
17497
17498 /* A C statement or statements to switch to the appropriate
17499 section for output of DECL. DECL is either a `VAR_DECL' node
17500 or a constant of some sort. RELOC indicates whether forming
17501 the initial value of DECL requires link-time relocations. */
17502
17503 static void
rs6000_elf_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align)17504 rs6000_elf_select_section (tree decl, int reloc,
17505 unsigned HOST_WIDE_INT align)
17506 {
17507 /* Pretend that we're always building for a shared library when
17508 ABI_AIX, because otherwise we end up with dynamic relocations
17509 in read-only sections. This happens for function pointers,
17510 references to vtables in typeinfo, and probably other cases. */
17511 default_elf_select_section_1 (decl, reloc, align,
17512 flag_pic || DEFAULT_ABI == ABI_AIX);
17513 }
17514
17515 /* A C statement to build up a unique section name, expressed as a
17516 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
17517 RELOC indicates whether the initial value of EXP requires
17518 link-time relocations. If you do not define this macro, GCC will use
17519 the symbol name prefixed by `.' as the section name. Note - this
17520 macro can now be called for uninitialized data items as well as
17521 initialized data and functions. */
17522
17523 static void
rs6000_elf_unique_section(tree decl,int reloc)17524 rs6000_elf_unique_section (tree decl, int reloc)
17525 {
17526 /* As above, pretend that we're always building for a shared library
17527 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
17528 default_unique_section_1 (decl, reloc,
17529 flag_pic || DEFAULT_ABI == ABI_AIX);
17530 }
17531
17532 /* For a SYMBOL_REF, set generic flags and then perform some
17533 target-specific processing.
17534
17535 When the AIX ABI is requested on a non-AIX system, replace the
17536 function name with the real name (with a leading .) rather than the
17537 function descriptor name. This saves a lot of overriding code to
17538 read the prefixes. */
17539
17540 static void
rs6000_elf_encode_section_info(tree decl,rtx rtl,int first)17541 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
17542 {
17543 default_encode_section_info (decl, rtl, first);
17544
17545 if (first
17546 && TREE_CODE (decl) == FUNCTION_DECL
17547 && !TARGET_AIX
17548 && DEFAULT_ABI == ABI_AIX)
17549 {
17550 rtx sym_ref = XEXP (rtl, 0);
17551 size_t len = strlen (XSTR (sym_ref, 0));
17552 char *str = alloca (len + 2);
17553 str[0] = '.';
17554 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
17555 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
17556 }
17557 }
17558
17559 static bool
rs6000_elf_in_small_data_p(tree decl)17560 rs6000_elf_in_small_data_p (tree decl)
17561 {
17562 if (rs6000_sdata == SDATA_NONE)
17563 return false;
17564
17565 /* We want to merge strings, so we never consider them small data. */
17566 if (TREE_CODE (decl) == STRING_CST)
17567 return false;
17568
17569 /* Functions are never in the small data area. */
17570 if (TREE_CODE (decl) == FUNCTION_DECL)
17571 return false;
17572
17573 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
17574 {
17575 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
17576 if (strcmp (section, ".sdata") == 0
17577 || strcmp (section, ".sdata2") == 0
17578 || strcmp (section, ".sbss") == 0
17579 || strcmp (section, ".sbss2") == 0
17580 || strcmp (section, ".PPC.EMB.sdata0") == 0
17581 || strcmp (section, ".PPC.EMB.sbss0") == 0)
17582 return true;
17583 }
17584 else
17585 {
17586 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
17587
17588 if (size > 0
17589 && (unsigned HOST_WIDE_INT) size <= g_switch_value
17590 /* If it's not public, and we're not going to reference it there,
17591 there's no need to put it in the small data section. */
17592 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
17593 return true;
17594 }
17595
17596 return false;
17597 }
17598
17599 #endif /* USING_ELFOS_H */
17600
17601
17602 /* Return a REG that occurs in ADDR with coefficient 1.
17603 ADDR can be effectively incremented by incrementing REG.
17604
17605 r0 is special and we must not select it as an address
17606 register by this routine since our caller will try to
17607 increment the returned register via an "la" instruction. */
17608
17609 rtx
find_addr_reg(rtx addr)17610 find_addr_reg (rtx addr)
17611 {
17612 while (GET_CODE (addr) == PLUS)
17613 {
17614 if (GET_CODE (XEXP (addr, 0)) == REG
17615 && REGNO (XEXP (addr, 0)) != 0)
17616 addr = XEXP (addr, 0);
17617 else if (GET_CODE (XEXP (addr, 1)) == REG
17618 && REGNO (XEXP (addr, 1)) != 0)
17619 addr = XEXP (addr, 1);
17620 else if (CONSTANT_P (XEXP (addr, 0)))
17621 addr = XEXP (addr, 1);
17622 else if (CONSTANT_P (XEXP (addr, 1)))
17623 addr = XEXP (addr, 0);
17624 else
17625 gcc_unreachable ();
17626 }
17627 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
17628 return addr;
17629 }
17630
17631 void
rs6000_fatal_bad_address(rtx op)17632 rs6000_fatal_bad_address (rtx op)
17633 {
17634 fatal_insn ("bad address", op);
17635 }
17636
17637 #if TARGET_MACHO
17638
17639 static tree branch_island_list = 0;
17640
17641 /* Remember to generate a branch island for far calls to the given
17642 function. */
17643
17644 static void
add_compiler_branch_island(tree label_name,tree function_name,int line_number)17645 add_compiler_branch_island (tree label_name, tree function_name,
17646 int line_number)
17647 {
17648 tree branch_island = build_tree_list (function_name, label_name);
17649 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
17650 TREE_CHAIN (branch_island) = branch_island_list;
17651 branch_island_list = branch_island;
17652 }
17653
17654 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
17655 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
17656 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
17657 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
17658
17659 /* Generate far-jump branch islands for everything on the
17660 branch_island_list. Invoked immediately after the last instruction
17661 of the epilogue has been emitted; the branch-islands must be
17662 appended to, and contiguous with, the function body. Mach-O stubs
17663 are generated in machopic_output_stub(). */
17664
17665 static void
macho_branch_islands(void)17666 macho_branch_islands (void)
17667 {
17668 char tmp_buf[512];
17669 tree branch_island;
17670
17671 for (branch_island = branch_island_list;
17672 branch_island;
17673 branch_island = TREE_CHAIN (branch_island))
17674 {
17675 const char *label =
17676 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
17677 const char *name =
17678 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
17679 char name_buf[512];
17680 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
17681 if (name[0] == '*' || name[0] == '&')
17682 strcpy (name_buf, name+1);
17683 else
17684 {
17685 name_buf[0] = '_';
17686 strcpy (name_buf+1, name);
17687 }
17688 strcpy (tmp_buf, "\n");
17689 strcat (tmp_buf, label);
17690 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17691 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
17692 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
17693 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17694 if (flag_pic)
17695 {
17696 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
17697 strcat (tmp_buf, label);
17698 strcat (tmp_buf, "_pic\n");
17699 strcat (tmp_buf, label);
17700 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
17701
17702 strcat (tmp_buf, "\taddis r11,r11,ha16(");
17703 strcat (tmp_buf, name_buf);
17704 strcat (tmp_buf, " - ");
17705 strcat (tmp_buf, label);
17706 strcat (tmp_buf, "_pic)\n");
17707
17708 strcat (tmp_buf, "\tmtlr r0\n");
17709
17710 strcat (tmp_buf, "\taddi r12,r11,lo16(");
17711 strcat (tmp_buf, name_buf);
17712 strcat (tmp_buf, " - ");
17713 strcat (tmp_buf, label);
17714 strcat (tmp_buf, "_pic)\n");
17715
17716 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
17717 }
17718 else
17719 {
17720 strcat (tmp_buf, ":\nlis r12,hi16(");
17721 strcat (tmp_buf, name_buf);
17722 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
17723 strcat (tmp_buf, name_buf);
17724 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
17725 }
17726 output_asm_insn (tmp_buf, 0);
17727 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17728 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
17729 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
17730 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17731 }
17732
17733 branch_island_list = 0;
17734 }
17735
17736 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
17737 already there or not. */
17738
17739 static int
no_previous_def(tree function_name)17740 no_previous_def (tree function_name)
17741 {
17742 tree branch_island;
17743 for (branch_island = branch_island_list;
17744 branch_island;
17745 branch_island = TREE_CHAIN (branch_island))
17746 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
17747 return 0;
17748 return 1;
17749 }
17750
17751 /* GET_PREV_LABEL gets the label name from the previous definition of
17752 the function. */
17753
17754 static tree
get_prev_label(tree function_name)17755 get_prev_label (tree function_name)
17756 {
17757 tree branch_island;
17758 for (branch_island = branch_island_list;
17759 branch_island;
17760 branch_island = TREE_CHAIN (branch_island))
17761 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
17762 return BRANCH_ISLAND_LABEL_NAME (branch_island);
17763 return 0;
17764 }
17765
17766 /* INSN is either a function call or a millicode call. It may have an
17767 unconditional jump in its delay slot.
17768
17769 CALL_DEST is the routine we are calling. */
17770
17771 char *
output_call(rtx insn,rtx * operands,int dest_operand_number,int cookie_operand_number)17772 output_call (rtx insn, rtx *operands, int dest_operand_number,
17773 int cookie_operand_number)
17774 {
17775 static char buf[256];
17776 if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
17777 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
17778 {
17779 tree labelname;
17780 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
17781
17782 if (no_previous_def (funname))
17783 {
17784 int line_number = 0;
17785 rtx label_rtx = gen_label_rtx ();
17786 char *label_buf, temp_buf[256];
17787 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
17788 CODE_LABEL_NUMBER (label_rtx));
17789 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
17790 labelname = get_identifier (label_buf);
17791 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
17792 if (insn)
17793 line_number = NOTE_LINE_NUMBER (insn);
17794 add_compiler_branch_island (labelname, funname, line_number);
17795 }
17796 else
17797 labelname = get_prev_label (funname);
17798
17799 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
17800 instruction will reach 'foo', otherwise link as 'bl L42'".
17801 "L42" should be a 'branch island', that will do a far jump to
17802 'foo'. Branch islands are generated in
17803 macho_branch_islands(). */
17804 sprintf (buf, "jbsr %%z%d,%.246s",
17805 dest_operand_number, IDENTIFIER_POINTER (labelname));
17806 }
17807 else
17808 sprintf (buf, "bl %%z%d", dest_operand_number);
17809 return buf;
17810 }
17811
17812 /* Generate PIC and indirect symbol stubs. */
17813
17814 void
machopic_output_stub(FILE * file,const char * symb,const char * stub)17815 machopic_output_stub (FILE *file, const char *symb, const char *stub)
17816 {
17817 unsigned int length;
17818 char *symbol_name, *lazy_ptr_name;
17819 char *local_label_0;
17820 static int label = 0;
17821
17822 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
17823 symb = (*targetm.strip_name_encoding) (symb);
17824
17825
17826 length = strlen (symb);
17827 symbol_name = alloca (length + 32);
17828 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
17829
17830 lazy_ptr_name = alloca (length + 32);
17831 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
17832
17833 if (flag_pic == 2)
17834 machopic_picsymbol_stub1_section ();
17835 else
17836 machopic_symbol_stub1_section ();
17837
17838 if (flag_pic == 2)
17839 {
17840 fprintf (file, "\t.align 5\n");
17841
17842 fprintf (file, "%s:\n", stub);
17843 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17844
17845 label++;
17846 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
17847 sprintf (local_label_0, "\"L%011d$spb\"", label);
17848
17849 fprintf (file, "\tmflr r0\n");
17850 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
17851 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
17852 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
17853 lazy_ptr_name, local_label_0);
17854 fprintf (file, "\tmtlr r0\n");
17855 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
17856 (TARGET_64BIT ? "ldu" : "lwzu"),
17857 lazy_ptr_name, local_label_0);
17858 fprintf (file, "\tmtctr r12\n");
17859 fprintf (file, "\tbctr\n");
17860 }
17861 else
17862 {
17863 fprintf (file, "\t.align 4\n");
17864
17865 fprintf (file, "%s:\n", stub);
17866 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17867
17868 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
17869 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
17870 (TARGET_64BIT ? "ldu" : "lwzu"),
17871 lazy_ptr_name);
17872 fprintf (file, "\tmtctr r12\n");
17873 fprintf (file, "\tbctr\n");
17874 }
17875
17876 machopic_lazy_symbol_ptr_section ();
17877 fprintf (file, "%s:\n", lazy_ptr_name);
17878 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17879 fprintf (file, "%sdyld_stub_binding_helper\n",
17880 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
17881 }
17882
17883 /* Legitimize PIC addresses. If the address is already
17884 position-independent, we return ORIG. Newly generated
17885 position-independent addresses go into a reg. This is REG if non
17886 zero, otherwise we allocate register(s) as necessary. */
17887
17888 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
17889
17890 rtx
rs6000_machopic_legitimize_pic_address(rtx orig,enum machine_mode mode,rtx reg)17891 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
17892 rtx reg)
17893 {
17894 rtx base, offset;
17895
17896 if (reg == NULL && ! reload_in_progress && ! reload_completed)
17897 reg = gen_reg_rtx (Pmode);
17898
17899 if (GET_CODE (orig) == CONST)
17900 {
17901 rtx reg_temp;
17902
17903 if (GET_CODE (XEXP (orig, 0)) == PLUS
17904 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
17905 return orig;
17906
17907 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
17908
17909 /* Use a different reg for the intermediate value, as
17910 it will be marked UNCHANGING. */
17911 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
17912 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
17913 Pmode, reg_temp);
17914 offset =
17915 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
17916 Pmode, reg);
17917
17918 if (GET_CODE (offset) == CONST_INT)
17919 {
17920 if (SMALL_INT (offset))
17921 return plus_constant (base, INTVAL (offset));
17922 else if (! reload_in_progress && ! reload_completed)
17923 offset = force_reg (Pmode, offset);
17924 else
17925 {
17926 rtx mem = force_const_mem (Pmode, orig);
17927 return machopic_legitimize_pic_address (mem, Pmode, reg);
17928 }
17929 }
17930 return gen_rtx_PLUS (Pmode, base, offset);
17931 }
17932
17933 /* Fall back on generic machopic code. */
17934 return machopic_legitimize_pic_address (orig, mode, reg);
17935 }
17936
17937 /* This is just a placeholder to make linking work without having to
17938 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
17939 ever needed for Darwin (not too likely!) this would have to get a
17940 real definition. */
17941
17942 void
toc_section(void)17943 toc_section (void)
17944 {
17945 }
17946
17947 /* Output a .machine directive for the Darwin assembler, and call
17948 the generic start_file routine. */
17949
17950 static void
rs6000_darwin_file_start(void)17951 rs6000_darwin_file_start (void)
17952 {
17953 static const struct
17954 {
17955 const char *arg;
17956 const char *name;
17957 int if_set;
17958 } mapping[] = {
17959 { "ppc64", "ppc64", MASK_64BIT },
17960 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
17961 { "power4", "ppc970", 0 },
17962 { "G5", "ppc970", 0 },
17963 { "7450", "ppc7450", 0 },
17964 { "7400", "ppc7400", MASK_ALTIVEC },
17965 { "G4", "ppc7400", 0 },
17966 { "750", "ppc750", 0 },
17967 { "740", "ppc750", 0 },
17968 { "G3", "ppc750", 0 },
17969 { "604e", "ppc604e", 0 },
17970 { "604", "ppc604", 0 },
17971 { "603e", "ppc603", 0 },
17972 { "603", "ppc603", 0 },
17973 { "601", "ppc601", 0 },
17974 { NULL, "ppc", 0 } };
17975 const char *cpu_id = "";
17976 size_t i;
17977
17978 rs6000_file_start ();
17979
17980 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
17981 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
17982 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
17983 && rs6000_select[i].string[0] != '\0')
17984 cpu_id = rs6000_select[i].string;
17985
17986 /* Look through the mapping array. Pick the first name that either
17987 matches the argument, has a bit set in IF_SET that is also set
17988 in the target flags, or has a NULL name. */
17989
17990 i = 0;
17991 while (mapping[i].arg != NULL
17992 && strcmp (mapping[i].arg, cpu_id) != 0
17993 && (mapping[i].if_set & target_flags) == 0)
17994 i++;
17995
17996 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
17997 }
17998
17999 #endif /* TARGET_MACHO */
18000
18001 #if TARGET_ELF
18002 static unsigned int
rs6000_elf_section_type_flags(tree decl,const char * name,int reloc)18003 rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
18004 {
18005 return default_section_type_flags_1 (decl, name, reloc,
18006 flag_pic || DEFAULT_ABI == ABI_AIX);
18007 }
18008
18009 /* Record an element in the table of global constructors. SYMBOL is
18010 a SYMBOL_REF of the function to be called; PRIORITY is a number
18011 between 0 and MAX_INIT_PRIORITY.
18012
18013 This differs from default_named_section_asm_out_constructor in
18014 that we have special handling for -mrelocatable. */
18015
18016 static void
rs6000_elf_asm_out_constructor(rtx symbol,int priority)18017 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
18018 {
18019 const char *section = ".ctors";
18020 char buf[16];
18021
18022 if (priority != DEFAULT_INIT_PRIORITY)
18023 {
18024 sprintf (buf, ".ctors.%.5u",
18025 /* Invert the numbering so the linker puts us in the proper
18026 order; constructors are run from right to left, and the
18027 linker sorts in increasing order. */
18028 MAX_INIT_PRIORITY - priority);
18029 section = buf;
18030 }
18031
18032 named_section_flags (section, SECTION_WRITE);
18033 assemble_align (POINTER_SIZE);
18034
18035 if (TARGET_RELOCATABLE)
18036 {
18037 fputs ("\t.long (", asm_out_file);
18038 output_addr_const (asm_out_file, symbol);
18039 fputs (")@fixup\n", asm_out_file);
18040 }
18041 else
18042 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
18043 }
18044
18045 static void
rs6000_elf_asm_out_destructor(rtx symbol,int priority)18046 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
18047 {
18048 const char *section = ".dtors";
18049 char buf[16];
18050
18051 if (priority != DEFAULT_INIT_PRIORITY)
18052 {
18053 sprintf (buf, ".dtors.%.5u",
18054 /* Invert the numbering so the linker puts us in the proper
18055 order; constructors are run from right to left, and the
18056 linker sorts in increasing order. */
18057 MAX_INIT_PRIORITY - priority);
18058 section = buf;
18059 }
18060
18061 named_section_flags (section, SECTION_WRITE);
18062 assemble_align (POINTER_SIZE);
18063
18064 if (TARGET_RELOCATABLE)
18065 {
18066 fputs ("\t.long (", asm_out_file);
18067 output_addr_const (asm_out_file, symbol);
18068 fputs (")@fixup\n", asm_out_file);
18069 }
18070 else
18071 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
18072 }
18073
18074 void
rs6000_elf_declare_function_name(FILE * file,const char * name,tree decl)18075 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
18076 {
18077 if (TARGET_64BIT)
18078 {
18079 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
18080 ASM_OUTPUT_LABEL (file, name);
18081 fputs (DOUBLE_INT_ASM_OP, file);
18082 rs6000_output_function_entry (file, name);
18083 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
18084 if (DOT_SYMBOLS)
18085 {
18086 fputs ("\t.size\t", file);
18087 assemble_name (file, name);
18088 fputs (",24\n\t.type\t.", file);
18089 assemble_name (file, name);
18090 fputs (",@function\n", file);
18091 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
18092 {
18093 fputs ("\t.globl\t.", file);
18094 assemble_name (file, name);
18095 putc ('\n', file);
18096 }
18097 }
18098 else
18099 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
18100 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
18101 rs6000_output_function_entry (file, name);
18102 fputs (":\n", file);
18103 return;
18104 }
18105
18106 if (TARGET_RELOCATABLE
18107 && !TARGET_SECURE_PLT
18108 && (get_pool_size () != 0 || current_function_profile)
18109 && uses_TOC ())
18110 {
18111 char buf[256];
18112
18113 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
18114
18115 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18116 fprintf (file, "\t.long ");
18117 assemble_name (file, buf);
18118 putc ('-', file);
18119 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18120 assemble_name (file, buf);
18121 putc ('\n', file);
18122 }
18123
18124 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
18125 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
18126
18127 if (DEFAULT_ABI == ABI_AIX)
18128 {
18129 const char *desc_name, *orig_name;
18130
18131 orig_name = (*targetm.strip_name_encoding) (name);
18132 desc_name = orig_name;
18133 while (*desc_name == '.')
18134 desc_name++;
18135
18136 if (TREE_PUBLIC (decl))
18137 fprintf (file, "\t.globl %s\n", desc_name);
18138
18139 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18140 fprintf (file, "%s:\n", desc_name);
18141 fprintf (file, "\t.long %s\n", orig_name);
18142 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
18143 if (DEFAULT_ABI == ABI_AIX)
18144 fputs ("\t.long 0\n", file);
18145 fprintf (file, "\t.previous\n");
18146 }
18147 ASM_OUTPUT_LABEL (file, name);
18148 }
18149
18150 static void
rs6000_elf_end_indicate_exec_stack(void)18151 rs6000_elf_end_indicate_exec_stack (void)
18152 {
18153 if (TARGET_32BIT)
18154 file_end_indicate_exec_stack ();
18155 }
18156 #endif
18157
18158 #if TARGET_XCOFF
18159 static void
rs6000_xcoff_asm_globalize_label(FILE * stream,const char * name)18160 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
18161 {
18162 fputs (GLOBAL_ASM_OP, stream);
18163 RS6000_OUTPUT_BASENAME (stream, name);
18164 putc ('\n', stream);
18165 }
18166
18167 static void
rs6000_xcoff_asm_named_section(const char * name,unsigned int flags,tree decl ATTRIBUTE_UNUSED)18168 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
18169 tree decl ATTRIBUTE_UNUSED)
18170 {
18171 int smclass;
18172 static const char * const suffix[3] = { "PR", "RO", "RW" };
18173
18174 if (flags & SECTION_CODE)
18175 smclass = 0;
18176 else if (flags & SECTION_WRITE)
18177 smclass = 2;
18178 else
18179 smclass = 1;
18180
18181 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
18182 (flags & SECTION_CODE) ? "." : "",
18183 name, suffix[smclass], flags & SECTION_ENTSIZE);
18184 }
18185
18186 static void
rs6000_xcoff_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)18187 rs6000_xcoff_select_section (tree decl, int reloc,
18188 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
18189 {
18190 if (decl_readonly_section_1 (decl, reloc, 1))
18191 {
18192 if (TREE_PUBLIC (decl))
18193 read_only_data_section ();
18194 else
18195 read_only_private_data_section ();
18196 }
18197 else
18198 {
18199 if (TREE_PUBLIC (decl))
18200 data_section ();
18201 else
18202 private_data_section ();
18203 }
18204 }
18205
18206 static void
rs6000_xcoff_unique_section(tree decl,int reloc ATTRIBUTE_UNUSED)18207 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
18208 {
18209 const char *name;
18210
18211 /* Use select_section for private and uninitialized data. */
18212 if (!TREE_PUBLIC (decl)
18213 || DECL_COMMON (decl)
18214 || DECL_INITIAL (decl) == NULL_TREE
18215 || DECL_INITIAL (decl) == error_mark_node
18216 || (flag_zero_initialized_in_bss
18217 && initializer_zerop (DECL_INITIAL (decl))))
18218 return;
18219
18220 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
18221 name = (*targetm.strip_name_encoding) (name);
18222 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
18223 }
18224
18225 /* Select section for constant in constant pool.
18226
18227 On RS/6000, all constants are in the private read-only data area.
18228 However, if this is being placed in the TOC it must be output as a
18229 toc entry. */
18230
18231 static void
rs6000_xcoff_select_rtx_section(enum machine_mode mode,rtx x,unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)18232 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
18233 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
18234 {
18235 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
18236 toc_section ();
18237 else
18238 read_only_private_data_section ();
18239 }
18240
18241 /* Remove any trailing [DS] or the like from the symbol name. */
18242
18243 static const char *
rs6000_xcoff_strip_name_encoding(const char * name)18244 rs6000_xcoff_strip_name_encoding (const char *name)
18245 {
18246 size_t len;
18247 if (*name == '*')
18248 name++;
18249 len = strlen (name);
18250 if (name[len - 1] == ']')
18251 return ggc_alloc_string (name, len - 4);
18252 else
18253 return name;
18254 }
18255
18256 /* Section attributes. AIX is always PIC. */
18257
18258 static unsigned int
rs6000_xcoff_section_type_flags(tree decl,const char * name,int reloc)18259 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
18260 {
18261 unsigned int align;
18262 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
18263
18264 /* Align to at least UNIT size. */
18265 if (flags & SECTION_CODE)
18266 align = MIN_UNITS_PER_WORD;
18267 else
18268 /* Increase alignment of large objects if not already stricter. */
18269 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
18270 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
18271 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
18272
18273 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
18274 }
18275
18276 /* Output at beginning of assembler file.
18277
18278 Initialize the section names for the RS/6000 at this point.
18279
18280 Specify filename, including full path, to assembler.
18281
18282 We want to go into the TOC section so at least one .toc will be emitted.
18283 Also, in order to output proper .bs/.es pairs, we need at least one static
18284 [RW] section emitted.
18285
18286 Finally, declare mcount when profiling to make the assembler happy. */
18287
18288 static void
rs6000_xcoff_file_start(void)18289 rs6000_xcoff_file_start (void)
18290 {
18291 rs6000_gen_section_name (&xcoff_bss_section_name,
18292 main_input_filename, ".bss_");
18293 rs6000_gen_section_name (&xcoff_private_data_section_name,
18294 main_input_filename, ".rw_");
18295 rs6000_gen_section_name (&xcoff_read_only_section_name,
18296 main_input_filename, ".ro_");
18297
18298 fputs ("\t.file\t", asm_out_file);
18299 output_quoted_string (asm_out_file, main_input_filename);
18300 fputc ('\n', asm_out_file);
18301 if (write_symbols != NO_DEBUG)
18302 private_data_section ();
18303 text_section ();
18304 if (profile_flag)
18305 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
18306 rs6000_file_start ();
18307 }
18308
18309 /* Output at end of assembler file.
18310 On the RS/6000, referencing data should automatically pull in text. */
18311
18312 static void
rs6000_xcoff_file_end(void)18313 rs6000_xcoff_file_end (void)
18314 {
18315 text_section ();
18316 fputs ("_section_.text:\n", asm_out_file);
18317 data_section ();
18318 fputs (TARGET_32BIT
18319 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
18320 asm_out_file);
18321 }
18322 #endif /* TARGET_XCOFF */
18323
18324 /* Compute a (partial) cost for rtx X. Return true if the complete
18325 cost has been computed, and false if subexpressions should be
18326 scanned. In either case, *TOTAL contains the cost result. */
18327
18328 static bool
rs6000_rtx_costs(rtx x,int code,int outer_code,int * total)18329 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
18330 {
18331 enum machine_mode mode = GET_MODE (x);
18332
18333 switch (code)
18334 {
18335 /* On the RS/6000, if it is valid in the insn, it is free. */
18336 case CONST_INT:
18337 if (((outer_code == SET
18338 || outer_code == PLUS
18339 || outer_code == MINUS)
18340 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18341 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')))
18342 || (outer_code == AND
18343 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18344 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18345 mode == SImode ? 'L' : 'J'))
18346 || mask_operand (x, mode)
18347 || (mode == DImode
18348 && mask64_operand (x, DImode))))
18349 || ((outer_code == IOR || outer_code == XOR)
18350 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18351 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18352 mode == SImode ? 'L' : 'J'))))
18353 || outer_code == ASHIFT
18354 || outer_code == ASHIFTRT
18355 || outer_code == LSHIFTRT
18356 || outer_code == ROTATE
18357 || outer_code == ROTATERT
18358 || outer_code == ZERO_EXTRACT
18359 || (outer_code == MULT
18360 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
18361 || ((outer_code == DIV || outer_code == UDIV
18362 || outer_code == MOD || outer_code == UMOD)
18363 && exact_log2 (INTVAL (x)) >= 0)
18364 || (outer_code == COMPARE
18365 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18366 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')))
18367 || (outer_code == EQ
18368 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18369 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18370 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18371 mode == SImode ? 'L' : 'J'))))
18372 || (outer_code == GTU
18373 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
18374 || (outer_code == LTU
18375 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'P')))
18376 {
18377 *total = 0;
18378 return true;
18379 }
18380 else if ((outer_code == PLUS
18381 && reg_or_add_cint_operand (x, VOIDmode))
18382 || (outer_code == MINUS
18383 && reg_or_sub_cint_operand (x, VOIDmode))
18384 || ((outer_code == SET
18385 || outer_code == IOR
18386 || outer_code == XOR)
18387 && (INTVAL (x)
18388 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
18389 {
18390 *total = COSTS_N_INSNS (1);
18391 return true;
18392 }
18393 /* FALLTHRU */
18394
18395 case CONST_DOUBLE:
18396 if (mode == DImode
18397 && ((outer_code == AND
18398 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18399 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')
18400 || mask_operand (x, DImode)
18401 || mask64_operand (x, DImode)))
18402 || ((outer_code == IOR || outer_code == XOR)
18403 && CONST_DOUBLE_HIGH (x) == 0
18404 && (CONST_DOUBLE_LOW (x)
18405 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)))
18406 {
18407 *total = 0;
18408 return true;
18409 }
18410 else if (mode == DImode
18411 && (outer_code == SET
18412 || outer_code == IOR
18413 || outer_code == XOR)
18414 && CONST_DOUBLE_HIGH (x) == 0)
18415 {
18416 *total = COSTS_N_INSNS (1);
18417 return true;
18418 }
18419 /* FALLTHRU */
18420
18421 case CONST:
18422 case HIGH:
18423 case SYMBOL_REF:
18424 case MEM:
18425 /* When optimizing for size, MEM should be slightly more expensive
18426 than generating address, e.g., (plus (reg) (const)).
18427 L1 cache latency is about two instructions. */
18428 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
18429 return true;
18430
18431 case LABEL_REF:
18432 *total = 0;
18433 return true;
18434
18435 case PLUS:
18436 if (mode == DFmode)
18437 {
18438 if (GET_CODE (XEXP (x, 0)) == MULT)
18439 {
18440 /* FNMA accounted in outer NEG. */
18441 if (outer_code == NEG)
18442 *total = rs6000_cost->dmul - rs6000_cost->fp;
18443 else
18444 *total = rs6000_cost->dmul;
18445 }
18446 else
18447 *total = rs6000_cost->fp;
18448 }
18449 else if (mode == SFmode)
18450 {
18451 /* FNMA accounted in outer NEG. */
18452 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18453 *total = 0;
18454 else
18455 *total = rs6000_cost->fp;
18456 }
18457 else
18458 *total = COSTS_N_INSNS (1);
18459 return false;
18460
18461 case MINUS:
18462 if (mode == DFmode)
18463 {
18464 if (GET_CODE (XEXP (x, 0)) == MULT)
18465 {
18466 /* FNMA accounted in outer NEG. */
18467 if (outer_code == NEG)
18468 *total = 0;
18469 else
18470 *total = rs6000_cost->dmul;
18471 }
18472 else
18473 *total = rs6000_cost->fp;
18474 }
18475 else if (mode == SFmode)
18476 {
18477 /* FNMA accounted in outer NEG. */
18478 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18479 *total = 0;
18480 else
18481 *total = rs6000_cost->fp;
18482 }
18483 else
18484 *total = COSTS_N_INSNS (1);
18485 return false;
18486
18487 case MULT:
18488 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18489 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
18490 {
18491 if (INTVAL (XEXP (x, 1)) >= -256
18492 && INTVAL (XEXP (x, 1)) <= 255)
18493 *total = rs6000_cost->mulsi_const9;
18494 else
18495 *total = rs6000_cost->mulsi_const;
18496 }
18497 /* FMA accounted in outer PLUS/MINUS. */
18498 else if ((mode == DFmode || mode == SFmode)
18499 && (outer_code == PLUS || outer_code == MINUS))
18500 *total = 0;
18501 else if (mode == DFmode)
18502 *total = rs6000_cost->dmul;
18503 else if (mode == SFmode)
18504 *total = rs6000_cost->fp;
18505 else if (mode == DImode)
18506 *total = rs6000_cost->muldi;
18507 else
18508 *total = rs6000_cost->mulsi;
18509 return false;
18510
18511 case DIV:
18512 case MOD:
18513 if (FLOAT_MODE_P (mode))
18514 {
18515 *total = mode == DFmode ? rs6000_cost->ddiv
18516 : rs6000_cost->sdiv;
18517 return false;
18518 }
18519 /* FALLTHRU */
18520
18521 case UDIV:
18522 case UMOD:
18523 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18524 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
18525 {
18526 if (code == DIV || code == MOD)
18527 /* Shift, addze */
18528 *total = COSTS_N_INSNS (2);
18529 else
18530 /* Shift */
18531 *total = COSTS_N_INSNS (1);
18532 }
18533 else
18534 {
18535 if (GET_MODE (XEXP (x, 1)) == DImode)
18536 *total = rs6000_cost->divdi;
18537 else
18538 *total = rs6000_cost->divsi;
18539 }
18540 /* Add in shift and subtract for MOD. */
18541 if (code == MOD || code == UMOD)
18542 *total += COSTS_N_INSNS (2);
18543 return false;
18544
18545 case FFS:
18546 *total = COSTS_N_INSNS (4);
18547 return false;
18548
18549 case NOT:
18550 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
18551 {
18552 *total = 0;
18553 return false;
18554 }
18555 /* FALLTHRU */
18556
18557 case AND:
18558 case IOR:
18559 case XOR:
18560 case ZERO_EXTRACT:
18561 *total = COSTS_N_INSNS (1);
18562 return false;
18563
18564 case ASHIFT:
18565 case ASHIFTRT:
18566 case LSHIFTRT:
18567 case ROTATE:
18568 case ROTATERT:
18569 /* Handle mul_highpart. */
18570 if (outer_code == TRUNCATE
18571 && GET_CODE (XEXP (x, 0)) == MULT)
18572 {
18573 if (mode == DImode)
18574 *total = rs6000_cost->muldi;
18575 else
18576 *total = rs6000_cost->mulsi;
18577 return true;
18578 }
18579 else if (outer_code == AND)
18580 *total = 0;
18581 else
18582 *total = COSTS_N_INSNS (1);
18583 return false;
18584
18585 case SIGN_EXTEND:
18586 case ZERO_EXTEND:
18587 if (GET_CODE (XEXP (x, 0)) == MEM)
18588 *total = 0;
18589 else
18590 *total = COSTS_N_INSNS (1);
18591 return false;
18592
18593 case COMPARE:
18594 case NEG:
18595 case ABS:
18596 if (!FLOAT_MODE_P (mode))
18597 {
18598 *total = COSTS_N_INSNS (1);
18599 return false;
18600 }
18601 /* FALLTHRU */
18602
18603 case FLOAT:
18604 case UNSIGNED_FLOAT:
18605 case FIX:
18606 case UNSIGNED_FIX:
18607 case FLOAT_TRUNCATE:
18608 *total = rs6000_cost->fp;
18609 return false;
18610
18611 case FLOAT_EXTEND:
18612 if (mode == DFmode)
18613 *total = 0;
18614 else
18615 *total = rs6000_cost->fp;
18616 return false;
18617
18618 case UNSPEC:
18619 switch (XINT (x, 1))
18620 {
18621 case UNSPEC_FRSP:
18622 *total = rs6000_cost->fp;
18623 return true;
18624
18625 default:
18626 break;
18627 }
18628 break;
18629
18630 case CALL:
18631 case IF_THEN_ELSE:
18632 if (optimize_size)
18633 {
18634 *total = COSTS_N_INSNS (1);
18635 return true;
18636 }
18637 else if (FLOAT_MODE_P (mode)
18638 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
18639 {
18640 *total = rs6000_cost->fp;
18641 return false;
18642 }
18643 break;
18644
18645 case EQ:
18646 case GTU:
18647 case LTU:
18648 /* Carry bit requires mode == Pmode.
18649 NEG or PLUS already counted so only add one. */
18650 if (mode == Pmode
18651 && (outer_code == NEG || outer_code == PLUS))
18652 {
18653 *total = COSTS_N_INSNS (1);
18654 return true;
18655 }
18656 if (outer_code == SET)
18657 {
18658 if (XEXP (x, 1) == const0_rtx)
18659 {
18660 *total = COSTS_N_INSNS (2);
18661 return true;
18662 }
18663 else if (mode == Pmode)
18664 {
18665 *total = COSTS_N_INSNS (3);
18666 return false;
18667 }
18668 }
18669 /* FALLTHRU */
18670
18671 case GT:
18672 case LT:
18673 case UNORDERED:
18674 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
18675 {
18676 *total = COSTS_N_INSNS (2);
18677 return true;
18678 }
18679 /* CC COMPARE. */
18680 if (outer_code == COMPARE)
18681 {
18682 *total = 0;
18683 return true;
18684 }
18685 break;
18686
18687 default:
18688 break;
18689 }
18690
18691 return false;
18692 }
18693
18694 /* A C expression returning the cost of moving data from a register of class
18695 CLASS1 to one of CLASS2. */
18696
18697 int
rs6000_register_move_cost(enum machine_mode mode,enum reg_class from,enum reg_class to)18698 rs6000_register_move_cost (enum machine_mode mode,
18699 enum reg_class from, enum reg_class to)
18700 {
18701 /* Moves from/to GENERAL_REGS. */
18702 if (reg_classes_intersect_p (to, GENERAL_REGS)
18703 || reg_classes_intersect_p (from, GENERAL_REGS))
18704 {
18705 if (! reg_classes_intersect_p (to, GENERAL_REGS))
18706 from = to;
18707
18708 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
18709 return (rs6000_memory_move_cost (mode, from, 0)
18710 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
18711
18712 /* It's more expensive to move CR_REGS than CR0_REGS because of the
18713 shift. */
18714 else if (from == CR_REGS)
18715 return 4;
18716
18717 else
18718 /* A move will cost one instruction per GPR moved. */
18719 return 2 * hard_regno_nregs[0][mode];
18720 }
18721
18722 /* Moving between two similar registers is just one instruction. */
18723 else if (reg_classes_intersect_p (to, from))
18724 return mode == TFmode ? 4 : 2;
18725
18726 /* Everything else has to go through GENERAL_REGS. */
18727 else
18728 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
18729 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
18730 }
18731
18732 /* A C expressions returning the cost of moving data of MODE from a register to
18733 or from memory. */
18734
18735 int
rs6000_memory_move_cost(enum machine_mode mode,enum reg_class class,int in ATTRIBUTE_UNUSED)18736 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
18737 int in ATTRIBUTE_UNUSED)
18738 {
18739 if (reg_classes_intersect_p (class, GENERAL_REGS))
18740 return 4 * hard_regno_nregs[0][mode];
18741 else if (reg_classes_intersect_p (class, FLOAT_REGS))
18742 return 4 * hard_regno_nregs[32][mode];
18743 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
18744 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
18745 else
18746 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
18747 }
18748
18749 /* Newton-Raphson approximation of single-precision floating point divide n/d.
18750 Assumes no trapping math and finite arguments. */
18751
18752 void
rs6000_emit_swdivsf(rtx res,rtx n,rtx d)18753 rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
18754 {
18755 rtx x0, e0, e1, y1, u0, v0, one;
18756
18757 x0 = gen_reg_rtx (SFmode);
18758 e0 = gen_reg_rtx (SFmode);
18759 e1 = gen_reg_rtx (SFmode);
18760 y1 = gen_reg_rtx (SFmode);
18761 u0 = gen_reg_rtx (SFmode);
18762 v0 = gen_reg_rtx (SFmode);
18763 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
18764
18765 /* x0 = 1./d estimate */
18766 emit_insn (gen_rtx_SET (VOIDmode, x0,
18767 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
18768 UNSPEC_FRES)));
18769 /* e0 = 1. - d * x0 */
18770 emit_insn (gen_rtx_SET (VOIDmode, e0,
18771 gen_rtx_MINUS (SFmode, one,
18772 gen_rtx_MULT (SFmode, d, x0))));
18773 /* e1 = e0 + e0 * e0 */
18774 emit_insn (gen_rtx_SET (VOIDmode, e1,
18775 gen_rtx_PLUS (SFmode,
18776 gen_rtx_MULT (SFmode, e0, e0), e0)));
18777 /* y1 = x0 + e1 * x0 */
18778 emit_insn (gen_rtx_SET (VOIDmode, y1,
18779 gen_rtx_PLUS (SFmode,
18780 gen_rtx_MULT (SFmode, e1, x0), x0)));
18781 /* u0 = n * y1 */
18782 emit_insn (gen_rtx_SET (VOIDmode, u0,
18783 gen_rtx_MULT (SFmode, n, y1)));
18784 /* v0 = n - d * u0 */
18785 emit_insn (gen_rtx_SET (VOIDmode, v0,
18786 gen_rtx_MINUS (SFmode, n,
18787 gen_rtx_MULT (SFmode, d, u0))));
18788 /* res = u0 + v0 * y1 */
18789 emit_insn (gen_rtx_SET (VOIDmode, res,
18790 gen_rtx_PLUS (SFmode,
18791 gen_rtx_MULT (SFmode, v0, y1), u0)));
18792 }
18793
18794 /* Newton-Raphson approximation of double-precision floating point divide n/d.
18795 Assumes no trapping math and finite arguments. */
18796
18797 void
rs6000_emit_swdivdf(rtx res,rtx n,rtx d)18798 rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
18799 {
18800 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
18801
18802 x0 = gen_reg_rtx (DFmode);
18803 e0 = gen_reg_rtx (DFmode);
18804 e1 = gen_reg_rtx (DFmode);
18805 e2 = gen_reg_rtx (DFmode);
18806 y1 = gen_reg_rtx (DFmode);
18807 y2 = gen_reg_rtx (DFmode);
18808 y3 = gen_reg_rtx (DFmode);
18809 u0 = gen_reg_rtx (DFmode);
18810 v0 = gen_reg_rtx (DFmode);
18811 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
18812
18813 /* x0 = 1./d estimate */
18814 emit_insn (gen_rtx_SET (VOIDmode, x0,
18815 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
18816 UNSPEC_FRES)));
18817 /* e0 = 1. - d * x0 */
18818 emit_insn (gen_rtx_SET (VOIDmode, e0,
18819 gen_rtx_MINUS (DFmode, one,
18820 gen_rtx_MULT (SFmode, d, x0))));
18821 /* y1 = x0 + e0 * x0 */
18822 emit_insn (gen_rtx_SET (VOIDmode, y1,
18823 gen_rtx_PLUS (DFmode,
18824 gen_rtx_MULT (DFmode, e0, x0), x0)));
18825 /* e1 = e0 * e0 */
18826 emit_insn (gen_rtx_SET (VOIDmode, e1,
18827 gen_rtx_MULT (DFmode, e0, e0)));
18828 /* y2 = y1 + e1 * y1 */
18829 emit_insn (gen_rtx_SET (VOIDmode, y2,
18830 gen_rtx_PLUS (DFmode,
18831 gen_rtx_MULT (DFmode, e1, y1), y1)));
18832 /* e2 = e1 * e1 */
18833 emit_insn (gen_rtx_SET (VOIDmode, e2,
18834 gen_rtx_MULT (DFmode, e1, e1)));
18835 /* y3 = y2 + e2 * y2 */
18836 emit_insn (gen_rtx_SET (VOIDmode, y3,
18837 gen_rtx_PLUS (DFmode,
18838 gen_rtx_MULT (DFmode, e2, y2), y2)));
18839 /* u0 = n * y3 */
18840 emit_insn (gen_rtx_SET (VOIDmode, u0,
18841 gen_rtx_MULT (DFmode, n, y3)));
18842 /* v0 = n - d * u0 */
18843 emit_insn (gen_rtx_SET (VOIDmode, v0,
18844 gen_rtx_MINUS (DFmode, n,
18845 gen_rtx_MULT (DFmode, d, u0))));
18846 /* res = u0 + v0 * y3 */
18847 emit_insn (gen_rtx_SET (VOIDmode, res,
18848 gen_rtx_PLUS (DFmode,
18849 gen_rtx_MULT (DFmode, v0, y3), u0)));
18850 }
18851
18852 /* Return an RTX representing where to find the function value of a
18853 function returning MODE. */
18854 static rtx
rs6000_complex_function_value(enum machine_mode mode)18855 rs6000_complex_function_value (enum machine_mode mode)
18856 {
18857 unsigned int regno;
18858 rtx r1, r2;
18859 enum machine_mode inner = GET_MODE_INNER (mode);
18860 unsigned int inner_bytes = GET_MODE_SIZE (inner);
18861
18862 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
18863 regno = FP_ARG_RETURN;
18864 else
18865 {
18866 regno = GP_ARG_RETURN;
18867
18868 /* 32-bit is OK since it'll go in r3/r4. */
18869 if (TARGET_32BIT && inner_bytes >= 4)
18870 return gen_rtx_REG (mode, regno);
18871 }
18872
18873 if (inner_bytes >= 8)
18874 return gen_rtx_REG (mode, regno);
18875
18876 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
18877 const0_rtx);
18878 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
18879 GEN_INT (inner_bytes));
18880 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
18881 }
18882
18883 /* Define how to find the value returned by a function.
18884 VALTYPE is the data type of the value (as a tree).
18885 If the precise function being called is known, FUNC is its FUNCTION_DECL;
18886 otherwise, FUNC is 0.
18887
18888 On the SPE, both FPs and vectors are returned in r3.
18889
18890 On RS/6000 an integer value is in r3 and a floating-point value is in
18891 fp1, unless -msoft-float. */
18892
18893 rtx
rs6000_function_value(tree valtype,tree func ATTRIBUTE_UNUSED)18894 rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
18895 {
18896 enum machine_mode mode;
18897 unsigned int regno;
18898
18899 /* Special handling for structs in darwin64. */
18900 if (rs6000_darwin64_abi
18901 && TYPE_MODE (valtype) == BLKmode
18902 && TREE_CODE (valtype) == RECORD_TYPE
18903 && int_size_in_bytes (valtype) > 0)
18904 {
18905 CUMULATIVE_ARGS valcum;
18906 rtx valret;
18907
18908 valcum.words = 0;
18909 valcum.fregno = FP_ARG_MIN_REG;
18910 valcum.vregno = ALTIVEC_ARG_MIN_REG;
18911 /* Do a trial code generation as if this were going to be passed as
18912 an argument; if any part goes in memory, we return NULL. */
18913 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
18914 if (valret)
18915 return valret;
18916 /* Otherwise fall through to standard ABI rules. */
18917 }
18918
18919 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
18920 {
18921 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18922 return gen_rtx_PARALLEL (DImode,
18923 gen_rtvec (2,
18924 gen_rtx_EXPR_LIST (VOIDmode,
18925 gen_rtx_REG (SImode, GP_ARG_RETURN),
18926 const0_rtx),
18927 gen_rtx_EXPR_LIST (VOIDmode,
18928 gen_rtx_REG (SImode,
18929 GP_ARG_RETURN + 1),
18930 GEN_INT (4))));
18931 }
18932 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
18933 {
18934 return gen_rtx_PARALLEL (DCmode,
18935 gen_rtvec (4,
18936 gen_rtx_EXPR_LIST (VOIDmode,
18937 gen_rtx_REG (SImode, GP_ARG_RETURN),
18938 const0_rtx),
18939 gen_rtx_EXPR_LIST (VOIDmode,
18940 gen_rtx_REG (SImode,
18941 GP_ARG_RETURN + 1),
18942 GEN_INT (4)),
18943 gen_rtx_EXPR_LIST (VOIDmode,
18944 gen_rtx_REG (SImode,
18945 GP_ARG_RETURN + 2),
18946 GEN_INT (8)),
18947 gen_rtx_EXPR_LIST (VOIDmode,
18948 gen_rtx_REG (SImode,
18949 GP_ARG_RETURN + 3),
18950 GEN_INT (12))));
18951 }
18952 if ((INTEGRAL_TYPE_P (valtype)
18953 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
18954 || POINTER_TYPE_P (valtype))
18955 mode = TARGET_32BIT ? SImode : DImode;
18956 else
18957 mode = TYPE_MODE (valtype);
18958
18959 if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
18960 regno = FP_ARG_RETURN;
18961 else if (TREE_CODE (valtype) == COMPLEX_TYPE
18962 && targetm.calls.split_complex_arg)
18963 return rs6000_complex_function_value (mode);
18964 else if (TREE_CODE (valtype) == VECTOR_TYPE
18965 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
18966 && ALTIVEC_VECTOR_MODE (mode))
18967 regno = ALTIVEC_ARG_RETURN;
18968 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
18969 && (mode == DFmode || mode == DCmode))
18970 return spe_build_register_parallel (mode, GP_ARG_RETURN);
18971 else
18972 regno = GP_ARG_RETURN;
18973
18974 return gen_rtx_REG (mode, regno);
18975 }
18976
18977 /* Define how to find the value returned by a library function
18978 assuming the value has mode MODE. */
18979 rtx
rs6000_libcall_value(enum machine_mode mode)18980 rs6000_libcall_value (enum machine_mode mode)
18981 {
18982 unsigned int regno;
18983
18984 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
18985 {
18986 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18987 return gen_rtx_PARALLEL (DImode,
18988 gen_rtvec (2,
18989 gen_rtx_EXPR_LIST (VOIDmode,
18990 gen_rtx_REG (SImode, GP_ARG_RETURN),
18991 const0_rtx),
18992 gen_rtx_EXPR_LIST (VOIDmode,
18993 gen_rtx_REG (SImode,
18994 GP_ARG_RETURN + 1),
18995 GEN_INT (4))));
18996 }
18997
18998 if (GET_MODE_CLASS (mode) == MODE_FLOAT
18999 && TARGET_HARD_FLOAT && TARGET_FPRS)
19000 regno = FP_ARG_RETURN;
19001 else if (ALTIVEC_VECTOR_MODE (mode)
19002 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
19003 regno = ALTIVEC_ARG_RETURN;
19004 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
19005 return rs6000_complex_function_value (mode);
19006 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
19007 && (mode == DFmode || mode == DCmode))
19008 return spe_build_register_parallel (mode, GP_ARG_RETURN);
19009 else
19010 regno = GP_ARG_RETURN;
19011
19012 return gen_rtx_REG (mode, regno);
19013 }
19014
19015 /* Define the offset between two registers, FROM to be eliminated and its
19016 replacement TO, at the start of a routine. */
19017 HOST_WIDE_INT
rs6000_initial_elimination_offset(int from,int to)19018 rs6000_initial_elimination_offset (int from, int to)
19019 {
19020 rs6000_stack_t *info = rs6000_stack_info ();
19021 HOST_WIDE_INT offset;
19022
19023 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
19024 offset = info->push_p ? 0 : -info->total_size;
19025 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
19026 {
19027 offset = info->push_p ? 0 : -info->total_size;
19028 if (FRAME_GROWS_DOWNWARD)
19029 offset += info->fixed_size + info->vars_size + info->parm_size;
19030 }
19031 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
19032 offset = FRAME_GROWS_DOWNWARD
19033 ? info->fixed_size + info->vars_size + info->parm_size
19034 : 0;
19035 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
19036 offset = info->total_size;
19037 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
19038 offset = info->push_p ? info->total_size : 0;
19039 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
19040 offset = 0;
19041 else
19042 gcc_unreachable ();
19043
19044 return offset;
19045 }
19046
19047 /* Return true if TYPE is a SPE or AltiVec opaque type. */
19048
19049 static bool
rs6000_is_opaque_type(tree type)19050 rs6000_is_opaque_type (tree type)
19051 {
19052 return (type == opaque_V2SI_type_node
19053 || type == opaque_V2SF_type_node
19054 || type == opaque_p_V2SI_type_node
19055 || type == opaque_V4SI_type_node);
19056 }
19057
19058 static rtx
rs6000_dwarf_register_span(rtx reg)19059 rs6000_dwarf_register_span (rtx reg)
19060 {
19061 unsigned regno;
19062
19063 if (TARGET_SPE
19064 && (SPE_VECTOR_MODE (GET_MODE (reg))
19065 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
19066 ;
19067 else
19068 return NULL_RTX;
19069
19070 regno = REGNO (reg);
19071
19072 /* The duality of the SPE register size wreaks all kinds of havoc.
19073 This is a way of distinguishing r0 in 32-bits from r0 in
19074 64-bits. */
19075 return
19076 gen_rtx_PARALLEL (VOIDmode,
19077 BYTES_BIG_ENDIAN
19078 ? gen_rtvec (2,
19079 gen_rtx_REG (SImode, regno + 1200),
19080 gen_rtx_REG (SImode, regno))
19081 : gen_rtvec (2,
19082 gen_rtx_REG (SImode, regno),
19083 gen_rtx_REG (SImode, regno + 1200)));
19084 }
19085
19086 /* Map internal gcc register numbers to DWARF2 register numbers. */
19087
19088 unsigned int
rs6000_dbx_register_number(unsigned int regno)19089 rs6000_dbx_register_number (unsigned int regno)
19090 {
19091 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
19092 return regno;
19093 if (regno == MQ_REGNO)
19094 return 100;
19095 if (regno == LINK_REGISTER_REGNUM)
19096 return 108;
19097 if (regno == COUNT_REGISTER_REGNUM)
19098 return 109;
19099 if (CR_REGNO_P (regno))
19100 return regno - CR0_REGNO + 86;
19101 if (regno == XER_REGNO)
19102 return 101;
19103 if (ALTIVEC_REGNO_P (regno))
19104 return regno - FIRST_ALTIVEC_REGNO + 1124;
19105 if (regno == VRSAVE_REGNO)
19106 return 356;
19107 if (regno == VSCR_REGNO)
19108 return 67;
19109 if (regno == SPE_ACC_REGNO)
19110 return 99;
19111 if (regno == SPEFSCR_REGNO)
19112 return 612;
19113 /* SPE high reg number. We get these values of regno from
19114 rs6000_dwarf_register_span. */
19115 gcc_assert (regno >= 1200 && regno < 1232);
19116 return regno;
19117 }
19118
19119 /* target hook eh_return_filter_mode */
19120 static enum machine_mode
rs6000_eh_return_filter_mode(void)19121 rs6000_eh_return_filter_mode (void)
19122 {
19123 return TARGET_32BIT ? SImode : word_mode;
19124 }
19125
19126 /* Target hook for vector_mode_supported_p. */
19127 static bool
rs6000_vector_mode_supported_p(enum machine_mode mode)19128 rs6000_vector_mode_supported_p (enum machine_mode mode)
19129 {
19130
19131 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
19132 return true;
19133
19134 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
19135 return true;
19136
19137 else
19138 return false;
19139 }
19140
19141 /* Target hook for invalid_arg_for_unprototyped_fn. */
19142 static const char *
invalid_arg_for_unprototyped_fn(tree typelist,tree funcdecl,tree val)19143 invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
19144 {
19145 return (!rs6000_darwin64_abi
19146 && typelist == 0
19147 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
19148 && (funcdecl == NULL_TREE
19149 || (TREE_CODE (funcdecl) == FUNCTION_DECL
19150 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
19151 ? N_("AltiVec argument passed to unprototyped function")
19152 : NULL;
19153 }
19154
19155 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
19156 setup by using __stack_chk_fail_local hidden function instead of
19157 calling __stack_chk_fail directly. Otherwise it is better to call
19158 __stack_chk_fail directly. */
19159
19160 static tree
rs6000_stack_protect_fail(void)19161 rs6000_stack_protect_fail (void)
19162 {
19163 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
19164 ? default_hidden_stack_protect_fail ()
19165 : default_external_stack_protect_fail ();
19166 }
19167
19168 #include "gt-rs6000.h"
19169