1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 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 Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 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 "tree.h"
30 #include "tm_p.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "except.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "expr.h"
43 #include "reload.h"
44 #include "toplev.h"
45 #include "basic-block.h"
46 #include "integrate.h"
47 #include "ggc.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "debug.h"
51 #include "langhooks.h"
52 #include "optabs.h"
53 #include "tree-gimple.h"
54
55
56 /* Define the specific costs for a given cpu. */
57
58 struct processor_costs
59 {
60 /* multiplication */
61 const int m; /* cost of an M instruction. */
62 const int mghi; /* cost of an MGHI instruction. */
63 const int mh; /* cost of an MH instruction. */
64 const int mhi; /* cost of an MHI instruction. */
65 const int ml; /* cost of an ML instruction. */
66 const int mr; /* cost of an MR instruction. */
67 const int ms; /* cost of an MS instruction. */
68 const int msg; /* cost of an MSG instruction. */
69 const int msgf; /* cost of an MSGF instruction. */
70 const int msgfr; /* cost of an MSGFR instruction. */
71 const int msgr; /* cost of an MSGR instruction. */
72 const int msr; /* cost of an MSR instruction. */
73 const int mult_df; /* cost of multiplication in DFmode. */
74 const int mxbr;
75 /* square root */
76 const int sqxbr; /* cost of square root in TFmode. */
77 const int sqdbr; /* cost of square root in DFmode. */
78 const int sqebr; /* cost of square root in SFmode. */
79 /* multiply and add */
80 const int madbr; /* cost of multiply and add in DFmode. */
81 const int maebr; /* cost of multiply and add in SFmode. */
82 /* division */
83 const int dxbr;
84 const int dxr;
85 const int ddbr;
86 const int ddr;
87 const int debr;
88 const int der;
89 const int dlgr;
90 const int dlr;
91 const int dr;
92 const int dsgfr;
93 const int dsgr;
94 };
95
96 const struct processor_costs *s390_cost;
97
98 static const
99 struct processor_costs z900_cost =
100 {
101 COSTS_N_INSNS (5), /* M */
102 COSTS_N_INSNS (10), /* MGHI */
103 COSTS_N_INSNS (5), /* MH */
104 COSTS_N_INSNS (4), /* MHI */
105 COSTS_N_INSNS (5), /* ML */
106 COSTS_N_INSNS (5), /* MR */
107 COSTS_N_INSNS (4), /* MS */
108 COSTS_N_INSNS (15), /* MSG */
109 COSTS_N_INSNS (7), /* MSGF */
110 COSTS_N_INSNS (7), /* MSGFR */
111 COSTS_N_INSNS (10), /* MSGR */
112 COSTS_N_INSNS (4), /* MSR */
113 COSTS_N_INSNS (7), /* multiplication in DFmode */
114 COSTS_N_INSNS (13), /* MXBR */
115 COSTS_N_INSNS (136), /* SQXBR */
116 COSTS_N_INSNS (44), /* SQDBR */
117 COSTS_N_INSNS (35), /* SQEBR */
118 COSTS_N_INSNS (18), /* MADBR */
119 COSTS_N_INSNS (13), /* MAEBR */
120 COSTS_N_INSNS (134), /* DXBR */
121 COSTS_N_INSNS (135), /* DXR */
122 COSTS_N_INSNS (30), /* DDBR */
123 COSTS_N_INSNS (30), /* DDR */
124 COSTS_N_INSNS (27), /* DEBR */
125 COSTS_N_INSNS (26), /* DER */
126 COSTS_N_INSNS (220), /* DLGR */
127 COSTS_N_INSNS (34), /* DLR */
128 COSTS_N_INSNS (34), /* DR */
129 COSTS_N_INSNS (32), /* DSGFR */
130 COSTS_N_INSNS (32), /* DSGR */
131 };
132
133 static const
134 struct processor_costs z990_cost =
135 {
136 COSTS_N_INSNS (4), /* M */
137 COSTS_N_INSNS (2), /* MGHI */
138 COSTS_N_INSNS (2), /* MH */
139 COSTS_N_INSNS (2), /* MHI */
140 COSTS_N_INSNS (4), /* ML */
141 COSTS_N_INSNS (4), /* MR */
142 COSTS_N_INSNS (5), /* MS */
143 COSTS_N_INSNS (6), /* MSG */
144 COSTS_N_INSNS (4), /* MSGF */
145 COSTS_N_INSNS (4), /* MSGFR */
146 COSTS_N_INSNS (4), /* MSGR */
147 COSTS_N_INSNS (4), /* MSR */
148 COSTS_N_INSNS (1), /* multiplication in DFmode */
149 COSTS_N_INSNS (28), /* MXBR */
150 COSTS_N_INSNS (130), /* SQXBR */
151 COSTS_N_INSNS (66), /* SQDBR */
152 COSTS_N_INSNS (38), /* SQEBR */
153 COSTS_N_INSNS (1), /* MADBR */
154 COSTS_N_INSNS (1), /* MAEBR */
155 COSTS_N_INSNS (60), /* DXBR */
156 COSTS_N_INSNS (72), /* DXR */
157 COSTS_N_INSNS (40), /* DDBR */
158 COSTS_N_INSNS (44), /* DDR */
159 COSTS_N_INSNS (26), /* DDBR */
160 COSTS_N_INSNS (28), /* DER */
161 COSTS_N_INSNS (176), /* DLGR */
162 COSTS_N_INSNS (31), /* DLR */
163 COSTS_N_INSNS (31), /* DR */
164 COSTS_N_INSNS (31), /* DSGFR */
165 COSTS_N_INSNS (31), /* DSGR */
166 };
167
168 static const
169 struct processor_costs z9_109_cost =
170 {
171 COSTS_N_INSNS (4), /* M */
172 COSTS_N_INSNS (2), /* MGHI */
173 COSTS_N_INSNS (2), /* MH */
174 COSTS_N_INSNS (2), /* MHI */
175 COSTS_N_INSNS (4), /* ML */
176 COSTS_N_INSNS (4), /* MR */
177 COSTS_N_INSNS (5), /* MS */
178 COSTS_N_INSNS (6), /* MSG */
179 COSTS_N_INSNS (4), /* MSGF */
180 COSTS_N_INSNS (4), /* MSGFR */
181 COSTS_N_INSNS (4), /* MSGR */
182 COSTS_N_INSNS (4), /* MSR */
183 COSTS_N_INSNS (1), /* multiplication in DFmode */
184 COSTS_N_INSNS (28), /* MXBR */
185 COSTS_N_INSNS (130), /* SQXBR */
186 COSTS_N_INSNS (66), /* SQDBR */
187 COSTS_N_INSNS (38), /* SQEBR */
188 COSTS_N_INSNS (1), /* MADBR */
189 COSTS_N_INSNS (1), /* MAEBR */
190 COSTS_N_INSNS (60), /* DXBR */
191 COSTS_N_INSNS (72), /* DXR */
192 COSTS_N_INSNS (40), /* DDBR */
193 COSTS_N_INSNS (37), /* DDR */
194 COSTS_N_INSNS (26), /* DDBR */
195 COSTS_N_INSNS (28), /* DER */
196 COSTS_N_INSNS (30), /* DLGR */
197 COSTS_N_INSNS (23), /* DLR */
198 COSTS_N_INSNS (23), /* DR */
199 COSTS_N_INSNS (24), /* DSGFR */
200 COSTS_N_INSNS (24), /* DSGR */
201 };
202
203 extern int reload_completed;
204
205 /* Save information from a "cmpxx" operation until the branch or scc is
206 emitted. */
207 rtx s390_compare_op0, s390_compare_op1;
208
209 /* Save the result of a compare_and_swap until the branch or scc is
210 emitted. */
211 rtx s390_compare_emitted = NULL_RTX;
212
213 /* Structure used to hold the components of a S/390 memory
214 address. A legitimate address on S/390 is of the general
215 form
216 base + index + displacement
217 where any of the components is optional.
218
219 base and index are registers of the class ADDR_REGS,
220 displacement is an unsigned 12-bit immediate constant. */
221
222 struct s390_address
223 {
224 rtx base;
225 rtx indx;
226 rtx disp;
227 bool pointer;
228 bool literal_pool;
229 };
230
231 /* Which cpu are we tuning for. */
232 enum processor_type s390_tune = PROCESSOR_max;
233 enum processor_flags s390_tune_flags;
234 /* Which instruction set architecture to use. */
235 enum processor_type s390_arch;
236 enum processor_flags s390_arch_flags;
237
238 HOST_WIDE_INT s390_warn_framesize = 0;
239 HOST_WIDE_INT s390_stack_size = 0;
240 HOST_WIDE_INT s390_stack_guard = 0;
241
242 /* The following structure is embedded in the machine
243 specific part of struct function. */
244
245 struct s390_frame_layout GTY (())
246 {
247 /* Offset within stack frame. */
248 HOST_WIDE_INT gprs_offset;
249 HOST_WIDE_INT f0_offset;
250 HOST_WIDE_INT f4_offset;
251 HOST_WIDE_INT f8_offset;
252 HOST_WIDE_INT backchain_offset;
253
254 /* Number of first and last gpr where slots in the register
255 save area are reserved for. */
256 int first_save_gpr_slot;
257 int last_save_gpr_slot;
258
259 /* Number of first and last gpr to be saved, restored. */
260 int first_save_gpr;
261 int first_restore_gpr;
262 int last_save_gpr;
263 int last_restore_gpr;
264
265 /* Bits standing for floating point registers. Set, if the
266 respective register has to be saved. Starting with reg 16 (f0)
267 at the rightmost bit.
268 Bit 15 - 8 7 6 5 4 3 2 1 0
269 fpr 15 - 8 7 5 3 1 6 4 2 0
270 reg 31 - 24 23 22 21 20 19 18 17 16 */
271 unsigned int fpr_bitmap;
272
273 /* Number of floating point registers f8-f15 which must be saved. */
274 int high_fprs;
275
276 /* Set if return address needs to be saved.
277 This flag is set by s390_return_addr_rtx if it could not use
278 the initial value of r14 and therefore depends on r14 saved
279 to the stack. */
280 bool save_return_addr_p;
281
282 /* Size of stack frame. */
283 HOST_WIDE_INT frame_size;
284 };
285
286 /* Define the structure for the machine field in struct function. */
287
288 struct machine_function GTY(())
289 {
290 struct s390_frame_layout frame_layout;
291
292 /* Literal pool base register. */
293 rtx base_reg;
294
295 /* True if we may need to perform branch splitting. */
296 bool split_branches_pending_p;
297
298 /* True during final stage of literal pool processing. */
299 bool decomposed_literal_pool_addresses_ok_p;
300
301 /* Some local-dynamic TLS symbol name. */
302 const char *some_ld_name;
303
304 bool has_landing_pad_p;
305 };
306
307 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
308
309 #define cfun_frame_layout (cfun->machine->frame_layout)
310 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
311 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
312 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
313 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
314 (1 << (BITNUM)))
315 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
316 (1 << (BITNUM))))
317
318 /* Number of GPRs and FPRs used for argument passing. */
319 #define GP_ARG_NUM_REG 5
320 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
321
322 /* A couple of shortcuts. */
323 #define CONST_OK_FOR_J(x) \
324 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
325 #define CONST_OK_FOR_K(x) \
326 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
327 #define CONST_OK_FOR_Os(x) \
328 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
329 #define CONST_OK_FOR_Op(x) \
330 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
331 #define CONST_OK_FOR_On(x) \
332 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
333
334 #define REGNO_PAIR_OK(REGNO, MODE) \
335 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
336
337 /* Return true if the back end supports mode MODE. */
338 static bool
s390_scalar_mode_supported_p(enum machine_mode mode)339 s390_scalar_mode_supported_p (enum machine_mode mode)
340 {
341 if (DECIMAL_FLOAT_MODE_P (mode))
342 return true;
343 else
344 return default_scalar_mode_supported_p (mode);
345 }
346
347 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
348
349 void
s390_set_has_landing_pad_p(bool value)350 s390_set_has_landing_pad_p (bool value)
351 {
352 cfun->machine->has_landing_pad_p = value;
353 }
354
355 /* If two condition code modes are compatible, return a condition code
356 mode which is compatible with both. Otherwise, return
357 VOIDmode. */
358
359 static enum machine_mode
s390_cc_modes_compatible(enum machine_mode m1,enum machine_mode m2)360 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
361 {
362 if (m1 == m2)
363 return m1;
364
365 switch (m1)
366 {
367 case CCZmode:
368 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
369 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
370 return m2;
371 return VOIDmode;
372
373 case CCSmode:
374 case CCUmode:
375 case CCTmode:
376 case CCSRmode:
377 case CCURmode:
378 case CCZ1mode:
379 if (m2 == CCZmode)
380 return m1;
381
382 return VOIDmode;
383
384 default:
385 return VOIDmode;
386 }
387 return VOIDmode;
388 }
389
390 /* Return true if SET either doesn't set the CC register, or else
391 the source and destination have matching CC modes and that
392 CC mode is at least as constrained as REQ_MODE. */
393
394 static bool
s390_match_ccmode_set(rtx set,enum machine_mode req_mode)395 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
396 {
397 enum machine_mode set_mode;
398
399 gcc_assert (GET_CODE (set) == SET);
400
401 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
402 return 1;
403
404 set_mode = GET_MODE (SET_DEST (set));
405 switch (set_mode)
406 {
407 case CCSmode:
408 case CCSRmode:
409 case CCUmode:
410 case CCURmode:
411 case CCLmode:
412 case CCL1mode:
413 case CCL2mode:
414 case CCL3mode:
415 case CCT1mode:
416 case CCT2mode:
417 case CCT3mode:
418 if (req_mode != set_mode)
419 return 0;
420 break;
421
422 case CCZmode:
423 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
424 && req_mode != CCSRmode && req_mode != CCURmode)
425 return 0;
426 break;
427
428 case CCAPmode:
429 case CCANmode:
430 if (req_mode != CCAmode)
431 return 0;
432 break;
433
434 default:
435 gcc_unreachable ();
436 }
437
438 return (GET_MODE (SET_SRC (set)) == set_mode);
439 }
440
441 /* Return true if every SET in INSN that sets the CC register
442 has source and destination with matching CC modes and that
443 CC mode is at least as constrained as REQ_MODE.
444 If REQ_MODE is VOIDmode, always return false. */
445
446 bool
s390_match_ccmode(rtx insn,enum machine_mode req_mode)447 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
448 {
449 int i;
450
451 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
452 if (req_mode == VOIDmode)
453 return false;
454
455 if (GET_CODE (PATTERN (insn)) == SET)
456 return s390_match_ccmode_set (PATTERN (insn), req_mode);
457
458 if (GET_CODE (PATTERN (insn)) == PARALLEL)
459 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
460 {
461 rtx set = XVECEXP (PATTERN (insn), 0, i);
462 if (GET_CODE (set) == SET)
463 if (!s390_match_ccmode_set (set, req_mode))
464 return false;
465 }
466
467 return true;
468 }
469
470 /* If a test-under-mask instruction can be used to implement
471 (compare (and ... OP1) OP2), return the CC mode required
472 to do that. Otherwise, return VOIDmode.
473 MIXED is true if the instruction can distinguish between
474 CC1 and CC2 for mixed selected bits (TMxx), it is false
475 if the instruction cannot (TM). */
476
477 enum machine_mode
s390_tm_ccmode(rtx op1,rtx op2,bool mixed)478 s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
479 {
480 int bit0, bit1;
481
482 /* ??? Fixme: should work on CONST_DOUBLE as well. */
483 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
484 return VOIDmode;
485
486 /* Selected bits all zero: CC0.
487 e.g.: int a; if ((a & (16 + 128)) == 0) */
488 if (INTVAL (op2) == 0)
489 return CCTmode;
490
491 /* Selected bits all one: CC3.
492 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
493 if (INTVAL (op2) == INTVAL (op1))
494 return CCT3mode;
495
496 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
497 int a;
498 if ((a & (16 + 128)) == 16) -> CCT1
499 if ((a & (16 + 128)) == 128) -> CCT2 */
500 if (mixed)
501 {
502 bit1 = exact_log2 (INTVAL (op2));
503 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
504 if (bit0 != -1 && bit1 != -1)
505 return bit0 > bit1 ? CCT1mode : CCT2mode;
506 }
507
508 return VOIDmode;
509 }
510
511 /* Given a comparison code OP (EQ, NE, etc.) and the operands
512 OP0 and OP1 of a COMPARE, return the mode to be used for the
513 comparison. */
514
515 enum machine_mode
s390_select_ccmode(enum rtx_code code,rtx op0,rtx op1)516 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
517 {
518 switch (code)
519 {
520 case EQ:
521 case NE:
522 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
523 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
524 return CCAPmode;
525 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
526 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
527 return CCAPmode;
528 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
529 || GET_CODE (op1) == NEG)
530 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
531 return CCLmode;
532
533 if (GET_CODE (op0) == AND)
534 {
535 /* Check whether we can potentially do it via TM. */
536 enum machine_mode ccmode;
537 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
538 if (ccmode != VOIDmode)
539 {
540 /* Relax CCTmode to CCZmode to allow fall-back to AND
541 if that turns out to be beneficial. */
542 return ccmode == CCTmode ? CCZmode : ccmode;
543 }
544 }
545
546 if (register_operand (op0, HImode)
547 && GET_CODE (op1) == CONST_INT
548 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
549 return CCT3mode;
550 if (register_operand (op0, QImode)
551 && GET_CODE (op1) == CONST_INT
552 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
553 return CCT3mode;
554
555 return CCZmode;
556
557 case LE:
558 case LT:
559 case GE:
560 case GT:
561 /* The only overflow condition of NEG and ABS happens when
562 -INT_MAX is used as parameter, which stays negative. So
563 we have an overflow from a positive value to a negative.
564 Using CCAP mode the resulting cc can be used for comparisons. */
565 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
566 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
567 return CCAPmode;
568
569 /* If constants are involved in an add instruction it is possible to use
570 the resulting cc for comparisons with zero. Knowing the sign of the
571 constant the overflow behavior gets predictable. e.g.:
572 int a, b; if ((b = a + c) > 0)
573 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
574 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
575 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
576 {
577 if (INTVAL (XEXP((op0), 1)) < 0)
578 return CCANmode;
579 else
580 return CCAPmode;
581 }
582 /* Fall through. */
583 case UNORDERED:
584 case ORDERED:
585 case UNEQ:
586 case UNLE:
587 case UNLT:
588 case UNGE:
589 case UNGT:
590 case LTGT:
591 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
592 && GET_CODE (op1) != CONST_INT)
593 return CCSRmode;
594 return CCSmode;
595
596 case LTU:
597 case GEU:
598 if (GET_CODE (op0) == PLUS
599 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
600 return CCL1mode;
601
602 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
603 && GET_CODE (op1) != CONST_INT)
604 return CCURmode;
605 return CCUmode;
606
607 case LEU:
608 case GTU:
609 if (GET_CODE (op0) == MINUS
610 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
611 return CCL2mode;
612
613 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
614 && GET_CODE (op1) != CONST_INT)
615 return CCURmode;
616 return CCUmode;
617
618 default:
619 gcc_unreachable ();
620 }
621 }
622
623 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
624 that we can implement more efficiently. */
625
626 void
s390_canonicalize_comparison(enum rtx_code * code,rtx * op0,rtx * op1)627 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
628 {
629 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
630 if ((*code == EQ || *code == NE)
631 && *op1 == const0_rtx
632 && GET_CODE (*op0) == ZERO_EXTRACT
633 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
634 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
635 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
636 {
637 rtx inner = XEXP (*op0, 0);
638 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
639 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
640 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
641
642 if (len > 0 && len < modesize
643 && pos >= 0 && pos + len <= modesize
644 && modesize <= HOST_BITS_PER_WIDE_INT)
645 {
646 unsigned HOST_WIDE_INT block;
647 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
648 block <<= modesize - pos - len;
649
650 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
651 gen_int_mode (block, GET_MODE (inner)));
652 }
653 }
654
655 /* Narrow AND of memory against immediate to enable TM. */
656 if ((*code == EQ || *code == NE)
657 && *op1 == const0_rtx
658 && GET_CODE (*op0) == AND
659 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
660 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
661 {
662 rtx inner = XEXP (*op0, 0);
663 rtx mask = XEXP (*op0, 1);
664
665 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
666 if (GET_CODE (inner) == SUBREG
667 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
668 && (GET_MODE_SIZE (GET_MODE (inner))
669 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
670 && ((INTVAL (mask)
671 & GET_MODE_MASK (GET_MODE (inner))
672 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
673 == 0))
674 inner = SUBREG_REG (inner);
675
676 /* Do not change volatile MEMs. */
677 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
678 {
679 int part = s390_single_part (XEXP (*op0, 1),
680 GET_MODE (inner), QImode, 0);
681 if (part >= 0)
682 {
683 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
684 inner = adjust_address_nv (inner, QImode, part);
685 *op0 = gen_rtx_AND (QImode, inner, mask);
686 }
687 }
688 }
689
690 /* Narrow comparisons against 0xffff to HImode if possible. */
691 if ((*code == EQ || *code == NE)
692 && GET_CODE (*op1) == CONST_INT
693 && INTVAL (*op1) == 0xffff
694 && SCALAR_INT_MODE_P (GET_MODE (*op0))
695 && (nonzero_bits (*op0, GET_MODE (*op0))
696 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
697 {
698 *op0 = gen_lowpart (HImode, *op0);
699 *op1 = constm1_rtx;
700 }
701
702
703 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
704 if (GET_CODE (*op0) == UNSPEC
705 && XINT (*op0, 1) == UNSPEC_CMPINT
706 && XVECLEN (*op0, 0) == 1
707 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
708 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
709 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
710 && *op1 == const0_rtx)
711 {
712 enum rtx_code new_code = UNKNOWN;
713 switch (*code)
714 {
715 case EQ: new_code = EQ; break;
716 case NE: new_code = NE; break;
717 case LT: new_code = GTU; break;
718 case GT: new_code = LTU; break;
719 case LE: new_code = GEU; break;
720 case GE: new_code = LEU; break;
721 default: break;
722 }
723
724 if (new_code != UNKNOWN)
725 {
726 *op0 = XVECEXP (*op0, 0, 0);
727 *code = new_code;
728 }
729 }
730
731 /* Simplify cascaded EQ, NE with const0_rtx. */
732 if ((*code == NE || *code == EQ)
733 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
734 && GET_MODE (*op0) == SImode
735 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
736 && REG_P (XEXP (*op0, 0))
737 && XEXP (*op0, 1) == const0_rtx
738 && *op1 == const0_rtx)
739 {
740 if ((*code == EQ && GET_CODE (*op0) == NE)
741 || (*code == NE && GET_CODE (*op0) == EQ))
742 *code = EQ;
743 else
744 *code = NE;
745 *op0 = XEXP (*op0, 0);
746 }
747
748 /* Prefer register over memory as first operand. */
749 if (MEM_P (*op0) && REG_P (*op1))
750 {
751 rtx tem = *op0; *op0 = *op1; *op1 = tem;
752 *code = swap_condition (*code);
753 }
754 }
755
756 /* Emit a compare instruction suitable to implement the comparison
757 OP0 CODE OP1. Return the correct condition RTL to be placed in
758 the IF_THEN_ELSE of the conditional branch testing the result. */
759
760 rtx
s390_emit_compare(enum rtx_code code,rtx op0,rtx op1)761 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
762 {
763 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
764 rtx ret = NULL_RTX;
765
766 /* Do not output a redundant compare instruction if a compare_and_swap
767 pattern already computed the result and the machine modes are compatible. */
768 if (s390_compare_emitted
769 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted), mode)
770 == GET_MODE (s390_compare_emitted)))
771 ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
772 else
773 {
774 rtx cc = gen_rtx_REG (mode, CC_REGNUM);
775
776 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
777 ret = gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
778 }
779 s390_compare_emitted = NULL_RTX;
780 return ret;
781 }
782
783 /* Emit a SImode compare and swap instruction setting MEM to NEW if OLD
784 matches CMP.
785 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
786 conditional branch testing the result. */
787
788 static rtx
s390_emit_compare_and_swap(enum rtx_code code,rtx old,rtx mem,rtx cmp,rtx new)789 s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem, rtx cmp, rtx new)
790 {
791 rtx ret;
792
793 emit_insn (gen_sync_compare_and_swap_ccsi (old, mem, cmp, new));
794 ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
795
796 s390_compare_emitted = NULL_RTX;
797
798 return ret;
799 }
800
801 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
802 unconditional jump, else a conditional jump under condition COND. */
803
804 void
s390_emit_jump(rtx target,rtx cond)805 s390_emit_jump (rtx target, rtx cond)
806 {
807 rtx insn;
808
809 target = gen_rtx_LABEL_REF (VOIDmode, target);
810 if (cond)
811 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
812
813 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
814 emit_jump_insn (insn);
815 }
816
817 /* Return branch condition mask to implement a branch
818 specified by CODE. Return -1 for invalid comparisons. */
819
820 int
s390_branch_condition_mask(rtx code)821 s390_branch_condition_mask (rtx code)
822 {
823 const int CC0 = 1 << 3;
824 const int CC1 = 1 << 2;
825 const int CC2 = 1 << 1;
826 const int CC3 = 1 << 0;
827
828 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
829 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
830 gcc_assert (XEXP (code, 1) == const0_rtx);
831
832 switch (GET_MODE (XEXP (code, 0)))
833 {
834 case CCZmode:
835 case CCZ1mode:
836 switch (GET_CODE (code))
837 {
838 case EQ: return CC0;
839 case NE: return CC1 | CC2 | CC3;
840 default: return -1;
841 }
842 break;
843
844 case CCT1mode:
845 switch (GET_CODE (code))
846 {
847 case EQ: return CC1;
848 case NE: return CC0 | CC2 | CC3;
849 default: return -1;
850 }
851 break;
852
853 case CCT2mode:
854 switch (GET_CODE (code))
855 {
856 case EQ: return CC2;
857 case NE: return CC0 | CC1 | CC3;
858 default: return -1;
859 }
860 break;
861
862 case CCT3mode:
863 switch (GET_CODE (code))
864 {
865 case EQ: return CC3;
866 case NE: return CC0 | CC1 | CC2;
867 default: return -1;
868 }
869 break;
870
871 case CCLmode:
872 switch (GET_CODE (code))
873 {
874 case EQ: return CC0 | CC2;
875 case NE: return CC1 | CC3;
876 default: return -1;
877 }
878 break;
879
880 case CCL1mode:
881 switch (GET_CODE (code))
882 {
883 case LTU: return CC2 | CC3; /* carry */
884 case GEU: return CC0 | CC1; /* no carry */
885 default: return -1;
886 }
887 break;
888
889 case CCL2mode:
890 switch (GET_CODE (code))
891 {
892 case GTU: return CC0 | CC1; /* borrow */
893 case LEU: return CC2 | CC3; /* no borrow */
894 default: return -1;
895 }
896 break;
897
898 case CCL3mode:
899 switch (GET_CODE (code))
900 {
901 case EQ: return CC0 | CC2;
902 case NE: return CC1 | CC3;
903 case LTU: return CC1;
904 case GTU: return CC3;
905 case LEU: return CC1 | CC2;
906 case GEU: return CC2 | CC3;
907 default: return -1;
908 }
909
910 case CCUmode:
911 switch (GET_CODE (code))
912 {
913 case EQ: return CC0;
914 case NE: return CC1 | CC2 | CC3;
915 case LTU: return CC1;
916 case GTU: return CC2;
917 case LEU: return CC0 | CC1;
918 case GEU: return CC0 | CC2;
919 default: return -1;
920 }
921 break;
922
923 case CCURmode:
924 switch (GET_CODE (code))
925 {
926 case EQ: return CC0;
927 case NE: return CC2 | CC1 | CC3;
928 case LTU: return CC2;
929 case GTU: return CC1;
930 case LEU: return CC0 | CC2;
931 case GEU: return CC0 | CC1;
932 default: return -1;
933 }
934 break;
935
936 case CCAPmode:
937 switch (GET_CODE (code))
938 {
939 case EQ: return CC0;
940 case NE: return CC1 | CC2 | CC3;
941 case LT: return CC1 | CC3;
942 case GT: return CC2;
943 case LE: return CC0 | CC1 | CC3;
944 case GE: return CC0 | CC2;
945 default: return -1;
946 }
947 break;
948
949 case CCANmode:
950 switch (GET_CODE (code))
951 {
952 case EQ: return CC0;
953 case NE: return CC1 | CC2 | CC3;
954 case LT: return CC1;
955 case GT: return CC2 | CC3;
956 case LE: return CC0 | CC1;
957 case GE: return CC0 | CC2 | CC3;
958 default: return -1;
959 }
960 break;
961
962 case CCSmode:
963 switch (GET_CODE (code))
964 {
965 case EQ: return CC0;
966 case NE: return CC1 | CC2 | CC3;
967 case LT: return CC1;
968 case GT: return CC2;
969 case LE: return CC0 | CC1;
970 case GE: return CC0 | CC2;
971 case UNORDERED: return CC3;
972 case ORDERED: return CC0 | CC1 | CC2;
973 case UNEQ: return CC0 | CC3;
974 case UNLT: return CC1 | CC3;
975 case UNGT: return CC2 | CC3;
976 case UNLE: return CC0 | CC1 | CC3;
977 case UNGE: return CC0 | CC2 | CC3;
978 case LTGT: return CC1 | CC2;
979 default: return -1;
980 }
981 break;
982
983 case CCSRmode:
984 switch (GET_CODE (code))
985 {
986 case EQ: return CC0;
987 case NE: return CC2 | CC1 | CC3;
988 case LT: return CC2;
989 case GT: return CC1;
990 case LE: return CC0 | CC2;
991 case GE: return CC0 | CC1;
992 case UNORDERED: return CC3;
993 case ORDERED: return CC0 | CC2 | CC1;
994 case UNEQ: return CC0 | CC3;
995 case UNLT: return CC2 | CC3;
996 case UNGT: return CC1 | CC3;
997 case UNLE: return CC0 | CC2 | CC3;
998 case UNGE: return CC0 | CC1 | CC3;
999 case LTGT: return CC2 | CC1;
1000 default: return -1;
1001 }
1002 break;
1003
1004 default:
1005 return -1;
1006 }
1007 }
1008
1009 /* If INV is false, return assembler mnemonic string to implement
1010 a branch specified by CODE. If INV is true, return mnemonic
1011 for the corresponding inverted branch. */
1012
1013 static const char *
s390_branch_condition_mnemonic(rtx code,int inv)1014 s390_branch_condition_mnemonic (rtx code, int inv)
1015 {
1016 static const char *const mnemonic[16] =
1017 {
1018 NULL, "o", "h", "nle",
1019 "l", "nhe", "lh", "ne",
1020 "e", "nlh", "he", "nl",
1021 "le", "nh", "no", NULL
1022 };
1023
1024 int mask = s390_branch_condition_mask (code);
1025 gcc_assert (mask >= 0);
1026
1027 if (inv)
1028 mask ^= 15;
1029
1030 gcc_assert (mask >= 1 && mask <= 14);
1031
1032 return mnemonic[mask];
1033 }
1034
1035 /* Return the part of op which has a value different from def.
1036 The size of the part is determined by mode.
1037 Use this function only if you already know that op really
1038 contains such a part. */
1039
1040 unsigned HOST_WIDE_INT
s390_extract_part(rtx op,enum machine_mode mode,int def)1041 s390_extract_part (rtx op, enum machine_mode mode, int def)
1042 {
1043 unsigned HOST_WIDE_INT value = 0;
1044 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
1045 int part_bits = GET_MODE_BITSIZE (mode);
1046 unsigned HOST_WIDE_INT part_mask
1047 = ((unsigned HOST_WIDE_INT)1 << part_bits) - 1;
1048 int i;
1049
1050 for (i = 0; i < max_parts; i++)
1051 {
1052 if (i == 0)
1053 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1054 else
1055 value >>= part_bits;
1056
1057 if ((value & part_mask) != (def & part_mask))
1058 return value & part_mask;
1059 }
1060
1061 gcc_unreachable ();
1062 }
1063
1064 /* If OP is an integer constant of mode MODE with exactly one
1065 part of mode PART_MODE unequal to DEF, return the number of that
1066 part. Otherwise, return -1. */
1067
1068 int
s390_single_part(rtx op,enum machine_mode mode,enum machine_mode part_mode,int def)1069 s390_single_part (rtx op,
1070 enum machine_mode mode,
1071 enum machine_mode part_mode,
1072 int def)
1073 {
1074 unsigned HOST_WIDE_INT value = 0;
1075 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1076 unsigned HOST_WIDE_INT part_mask
1077 = ((unsigned HOST_WIDE_INT)1 << GET_MODE_BITSIZE (part_mode)) - 1;
1078 int i, part = -1;
1079
1080 if (GET_CODE (op) != CONST_INT)
1081 return -1;
1082
1083 for (i = 0; i < n_parts; i++)
1084 {
1085 if (i == 0)
1086 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1087 else
1088 value >>= GET_MODE_BITSIZE (part_mode);
1089
1090 if ((value & part_mask) != (def & part_mask))
1091 {
1092 if (part != -1)
1093 return -1;
1094 else
1095 part = i;
1096 }
1097 }
1098 return part == -1 ? -1 : n_parts - 1 - part;
1099 }
1100
1101 /* Check whether we can (and want to) split a double-word
1102 move in mode MODE from SRC to DST into two single-word
1103 moves, moving the subword FIRST_SUBWORD first. */
1104
1105 bool
s390_split_ok_p(rtx dst,rtx src,enum machine_mode mode,int first_subword)1106 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1107 {
1108 /* Floating point registers cannot be split. */
1109 if (FP_REG_P (src) || FP_REG_P (dst))
1110 return false;
1111
1112 /* We don't need to split if operands are directly accessible. */
1113 if (s_operand (src, mode) || s_operand (dst, mode))
1114 return false;
1115
1116 /* Non-offsettable memory references cannot be split. */
1117 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1118 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1119 return false;
1120
1121 /* Moving the first subword must not clobber a register
1122 needed to move the second subword. */
1123 if (register_operand (dst, mode))
1124 {
1125 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1126 if (reg_overlap_mentioned_p (subreg, src))
1127 return false;
1128 }
1129
1130 return true;
1131 }
1132
1133 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1134 and [MEM2, MEM2 + SIZE] do overlap and false
1135 otherwise. */
1136
1137 bool
s390_overlap_p(rtx mem1,rtx mem2,HOST_WIDE_INT size)1138 s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
1139 {
1140 rtx addr1, addr2, addr_delta;
1141 HOST_WIDE_INT delta;
1142
1143 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1144 return true;
1145
1146 if (size == 0)
1147 return false;
1148
1149 addr1 = XEXP (mem1, 0);
1150 addr2 = XEXP (mem2, 0);
1151
1152 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1153
1154 /* This overlapping check is used by peepholes merging memory block operations.
1155 Overlapping operations would otherwise be recognized by the S/390 hardware
1156 and would fall back to a slower implementation. Allowing overlapping
1157 operations would lead to slow code but not to wrong code. Therefore we are
1158 somewhat optimistic if we cannot prove that the memory blocks are
1159 overlapping.
1160 That's why we return false here although this may accept operations on
1161 overlapping memory areas. */
1162 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
1163 return false;
1164
1165 delta = INTVAL (addr_delta);
1166
1167 if (delta == 0
1168 || (delta > 0 && delta < size)
1169 || (delta < 0 && -delta < size))
1170 return true;
1171
1172 return false;
1173 }
1174
1175 /* Check whether the address of memory reference MEM2 equals exactly
1176 the address of memory reference MEM1 plus DELTA. Return true if
1177 we can prove this to be the case, false otherwise. */
1178
1179 bool
s390_offset_p(rtx mem1,rtx mem2,rtx delta)1180 s390_offset_p (rtx mem1, rtx mem2, rtx delta)
1181 {
1182 rtx addr1, addr2, addr_delta;
1183
1184 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1185 return false;
1186
1187 addr1 = XEXP (mem1, 0);
1188 addr2 = XEXP (mem2, 0);
1189
1190 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1191 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
1192 return false;
1193
1194 return true;
1195 }
1196
1197 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1198
1199 void
s390_expand_logical_operator(enum rtx_code code,enum machine_mode mode,rtx * operands)1200 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1201 rtx *operands)
1202 {
1203 enum machine_mode wmode = mode;
1204 rtx dst = operands[0];
1205 rtx src1 = operands[1];
1206 rtx src2 = operands[2];
1207 rtx op, clob, tem;
1208
1209 /* If we cannot handle the operation directly, use a temp register. */
1210 if (!s390_logical_operator_ok_p (operands))
1211 dst = gen_reg_rtx (mode);
1212
1213 /* QImode and HImode patterns make sense only if we have a destination
1214 in memory. Otherwise perform the operation in SImode. */
1215 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1216 wmode = SImode;
1217
1218 /* Widen operands if required. */
1219 if (mode != wmode)
1220 {
1221 if (GET_CODE (dst) == SUBREG
1222 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1223 dst = tem;
1224 else if (REG_P (dst))
1225 dst = gen_rtx_SUBREG (wmode, dst, 0);
1226 else
1227 dst = gen_reg_rtx (wmode);
1228
1229 if (GET_CODE (src1) == SUBREG
1230 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1231 src1 = tem;
1232 else if (GET_MODE (src1) != VOIDmode)
1233 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1234
1235 if (GET_CODE (src2) == SUBREG
1236 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1237 src2 = tem;
1238 else if (GET_MODE (src2) != VOIDmode)
1239 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1240 }
1241
1242 /* Emit the instruction. */
1243 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1244 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1245 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1246
1247 /* Fix up the destination if needed. */
1248 if (dst != operands[0])
1249 emit_move_insn (operands[0], gen_lowpart (mode, dst));
1250 }
1251
1252 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1253
1254 bool
s390_logical_operator_ok_p(rtx * operands)1255 s390_logical_operator_ok_p (rtx *operands)
1256 {
1257 /* If the destination operand is in memory, it needs to coincide
1258 with one of the source operands. After reload, it has to be
1259 the first source operand. */
1260 if (GET_CODE (operands[0]) == MEM)
1261 return rtx_equal_p (operands[0], operands[1])
1262 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1263
1264 return true;
1265 }
1266
1267 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1268 operand IMMOP to switch from SS to SI type instructions. */
1269
1270 void
s390_narrow_logical_operator(enum rtx_code code,rtx * memop,rtx * immop)1271 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1272 {
1273 int def = code == AND ? -1 : 0;
1274 HOST_WIDE_INT mask;
1275 int part;
1276
1277 gcc_assert (GET_CODE (*memop) == MEM);
1278 gcc_assert (!MEM_VOLATILE_P (*memop));
1279
1280 mask = s390_extract_part (*immop, QImode, def);
1281 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1282 gcc_assert (part >= 0);
1283
1284 *memop = adjust_address (*memop, QImode, part);
1285 *immop = gen_int_mode (mask, QImode);
1286 }
1287
1288
1289 /* How to allocate a 'struct machine_function'. */
1290
1291 static struct machine_function *
s390_init_machine_status(void)1292 s390_init_machine_status (void)
1293 {
1294 return ggc_alloc_cleared (sizeof (struct machine_function));
1295 }
1296
1297 /* Change optimizations to be performed, depending on the
1298 optimization level.
1299
1300 LEVEL is the optimization level specified; 2 if `-O2' is
1301 specified, 1 if `-O' is specified, and 0 if neither is specified.
1302
1303 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1304
1305 void
optimization_options(int level ATTRIBUTE_UNUSED,int size ATTRIBUTE_UNUSED)1306 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1307 {
1308 /* ??? There are apparently still problems with -fcaller-saves. */
1309 flag_caller_saves = 0;
1310
1311 /* By default, always emit DWARF-2 unwind info. This allows debugging
1312 without maintaining a stack frame back-chain. */
1313 flag_asynchronous_unwind_tables = 1;
1314
1315 /* Use MVCLE instructions to decrease code size if requested. */
1316 if (size != 0)
1317 target_flags |= MASK_MVCLE;
1318 }
1319
1320 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1321 to the associated processor_type and processor_flags if so. */
1322
1323 static bool
s390_handle_arch_option(const char * arg,enum processor_type * type,enum processor_flags * flags)1324 s390_handle_arch_option (const char *arg,
1325 enum processor_type *type,
1326 enum processor_flags *flags)
1327 {
1328 static struct pta
1329 {
1330 const char *const name; /* processor name or nickname. */
1331 const enum processor_type processor;
1332 const enum processor_flags flags;
1333 }
1334 const processor_alias_table[] =
1335 {
1336 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1337 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1338 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1339 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1340 | PF_LONG_DISPLACEMENT},
1341 {"z9-109", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH
1342 | PF_LONG_DISPLACEMENT | PF_EXTIMM},
1343 };
1344 size_t i;
1345
1346 for (i = 0; i < ARRAY_SIZE (processor_alias_table); i++)
1347 if (strcmp (arg, processor_alias_table[i].name) == 0)
1348 {
1349 *type = processor_alias_table[i].processor;
1350 *flags = processor_alias_table[i].flags;
1351 return true;
1352 }
1353 return false;
1354 }
1355
1356 /* Implement TARGET_HANDLE_OPTION. */
1357
1358 static bool
s390_handle_option(size_t code,const char * arg,int value ATTRIBUTE_UNUSED)1359 s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1360 {
1361 switch (code)
1362 {
1363 case OPT_march_:
1364 return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
1365
1366 case OPT_mstack_guard_:
1367 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_guard) != 1)
1368 return false;
1369 if (exact_log2 (s390_stack_guard) == -1)
1370 error ("stack guard value must be an exact power of 2");
1371 return true;
1372
1373 case OPT_mstack_size_:
1374 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_size) != 1)
1375 return false;
1376 if (exact_log2 (s390_stack_size) == -1)
1377 error ("stack size must be an exact power of 2");
1378 return true;
1379
1380 case OPT_mtune_:
1381 return s390_handle_arch_option (arg, &s390_tune, &s390_tune_flags);
1382
1383 case OPT_mwarn_framesize_:
1384 return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_warn_framesize) == 1;
1385
1386 default:
1387 return true;
1388 }
1389 }
1390
1391 void
override_options(void)1392 override_options (void)
1393 {
1394 /* Set up function hooks. */
1395 init_machine_status = s390_init_machine_status;
1396
1397 /* Architecture mode defaults according to ABI. */
1398 if (!(target_flags_explicit & MASK_ZARCH))
1399 {
1400 if (TARGET_64BIT)
1401 target_flags |= MASK_ZARCH;
1402 else
1403 target_flags &= ~MASK_ZARCH;
1404 }
1405
1406 /* Determine processor architectural level. */
1407 if (!s390_arch_string)
1408 {
1409 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1410 s390_handle_arch_option (s390_arch_string, &s390_arch, &s390_arch_flags);
1411 }
1412
1413 /* Determine processor to tune for. */
1414 if (s390_tune == PROCESSOR_max)
1415 {
1416 s390_tune = s390_arch;
1417 s390_tune_flags = s390_arch_flags;
1418 }
1419
1420 /* Sanity checks. */
1421 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1422 error ("z/Architecture mode not supported on %s", s390_arch_string);
1423 if (TARGET_64BIT && !TARGET_ZARCH)
1424 error ("64-bit ABI not supported in ESA/390 mode");
1425
1426 /* Set processor cost function. */
1427 if (s390_tune == PROCESSOR_2094_Z9_109)
1428 s390_cost = &z9_109_cost;
1429 else if (s390_tune == PROCESSOR_2084_Z990)
1430 s390_cost = &z990_cost;
1431 else
1432 s390_cost = &z900_cost;
1433
1434 if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1435 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1436 "in combination");
1437
1438 if (s390_stack_size)
1439 {
1440 if (!s390_stack_guard)
1441 error ("-mstack-size implies use of -mstack-guard");
1442 else if (s390_stack_guard >= s390_stack_size)
1443 error ("stack size must be greater than the stack guard value");
1444 else if (s390_stack_size > 1 << 16)
1445 error ("stack size must not be greater than 64k");
1446 }
1447 else if (s390_stack_guard)
1448 error ("-mstack-guard implies use of -mstack-size");
1449
1450 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1451 if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
1452 target_flags |= MASK_LONG_DOUBLE_128;
1453 #endif
1454 }
1455
1456 /* Map for smallest class containing reg regno. */
1457
1458 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1459 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1460 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1461 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1462 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1463 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1464 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1465 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1466 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1467 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
1468 ACCESS_REGS, ACCESS_REGS
1469 };
1470
1471 /* Return attribute type of insn. */
1472
1473 static enum attr_type
s390_safe_attr_type(rtx insn)1474 s390_safe_attr_type (rtx insn)
1475 {
1476 if (recog_memoized (insn) >= 0)
1477 return get_attr_type (insn);
1478 else
1479 return TYPE_NONE;
1480 }
1481
1482 /* Return true if DISP is a valid short displacement. */
1483
1484 static bool
s390_short_displacement(rtx disp)1485 s390_short_displacement (rtx disp)
1486 {
1487 /* No displacement is OK. */
1488 if (!disp)
1489 return true;
1490
1491 /* Integer displacement in range. */
1492 if (GET_CODE (disp) == CONST_INT)
1493 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1494
1495 /* GOT offset is not OK, the GOT can be large. */
1496 if (GET_CODE (disp) == CONST
1497 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1498 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1499 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1500 return false;
1501
1502 /* All other symbolic constants are literal pool references,
1503 which are OK as the literal pool must be small. */
1504 if (GET_CODE (disp) == CONST)
1505 return true;
1506
1507 return false;
1508 }
1509
1510 /* Decompose a RTL expression ADDR for a memory address into
1511 its components, returned in OUT.
1512
1513 Returns false if ADDR is not a valid memory address, true
1514 otherwise. If OUT is NULL, don't return the components,
1515 but check for validity only.
1516
1517 Note: Only addresses in canonical form are recognized.
1518 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1519 canonical form so that they will be recognized. */
1520
1521 static int
s390_decompose_address(rtx addr,struct s390_address * out)1522 s390_decompose_address (rtx addr, struct s390_address *out)
1523 {
1524 HOST_WIDE_INT offset = 0;
1525 rtx base = NULL_RTX;
1526 rtx indx = NULL_RTX;
1527 rtx disp = NULL_RTX;
1528 rtx orig_disp;
1529 bool pointer = false;
1530 bool base_ptr = false;
1531 bool indx_ptr = false;
1532 bool literal_pool = false;
1533
1534 /* We may need to substitute the literal pool base register into the address
1535 below. However, at this point we do not know which register is going to
1536 be used as base, so we substitute the arg pointer register. This is going
1537 to be treated as holding a pointer below -- it shouldn't be used for any
1538 other purpose. */
1539 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
1540
1541 /* Decompose address into base + index + displacement. */
1542
1543 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1544 base = addr;
1545
1546 else if (GET_CODE (addr) == PLUS)
1547 {
1548 rtx op0 = XEXP (addr, 0);
1549 rtx op1 = XEXP (addr, 1);
1550 enum rtx_code code0 = GET_CODE (op0);
1551 enum rtx_code code1 = GET_CODE (op1);
1552
1553 if (code0 == REG || code0 == UNSPEC)
1554 {
1555 if (code1 == REG || code1 == UNSPEC)
1556 {
1557 indx = op0; /* index + base */
1558 base = op1;
1559 }
1560
1561 else
1562 {
1563 base = op0; /* base + displacement */
1564 disp = op1;
1565 }
1566 }
1567
1568 else if (code0 == PLUS)
1569 {
1570 indx = XEXP (op0, 0); /* index + base + disp */
1571 base = XEXP (op0, 1);
1572 disp = op1;
1573 }
1574
1575 else
1576 {
1577 return false;
1578 }
1579 }
1580
1581 else
1582 disp = addr; /* displacement */
1583
1584 /* Extract integer part of displacement. */
1585 orig_disp = disp;
1586 if (disp)
1587 {
1588 if (GET_CODE (disp) == CONST_INT)
1589 {
1590 offset = INTVAL (disp);
1591 disp = NULL_RTX;
1592 }
1593 else if (GET_CODE (disp) == CONST
1594 && GET_CODE (XEXP (disp, 0)) == PLUS
1595 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1596 {
1597 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1598 disp = XEXP (XEXP (disp, 0), 0);
1599 }
1600 }
1601
1602 /* Strip off CONST here to avoid special case tests later. */
1603 if (disp && GET_CODE (disp) == CONST)
1604 disp = XEXP (disp, 0);
1605
1606 /* We can convert literal pool addresses to
1607 displacements by basing them off the base register. */
1608 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
1609 {
1610 /* Either base or index must be free to hold the base register. */
1611 if (!base)
1612 base = fake_pool_base, literal_pool = true;
1613 else if (!indx)
1614 indx = fake_pool_base, literal_pool = true;
1615 else
1616 return false;
1617
1618 /* Mark up the displacement. */
1619 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
1620 UNSPEC_LTREL_OFFSET);
1621 }
1622
1623 /* Validate base register. */
1624 if (base)
1625 {
1626 if (GET_CODE (base) == UNSPEC)
1627 switch (XINT (base, 1))
1628 {
1629 case UNSPEC_LTREF:
1630 if (!disp)
1631 disp = gen_rtx_UNSPEC (Pmode,
1632 gen_rtvec (1, XVECEXP (base, 0, 0)),
1633 UNSPEC_LTREL_OFFSET);
1634 else
1635 return false;
1636
1637 base = XVECEXP (base, 0, 1);
1638 break;
1639
1640 case UNSPEC_LTREL_BASE:
1641 if (XVECLEN (base, 0) == 1)
1642 base = fake_pool_base, literal_pool = true;
1643 else
1644 base = XVECEXP (base, 0, 1);
1645 break;
1646
1647 default:
1648 return false;
1649 }
1650
1651 if (!REG_P (base)
1652 || (GET_MODE (base) != SImode
1653 && GET_MODE (base) != Pmode))
1654 return false;
1655
1656 if (REGNO (base) == STACK_POINTER_REGNUM
1657 || REGNO (base) == FRAME_POINTER_REGNUM
1658 || ((reload_completed || reload_in_progress)
1659 && frame_pointer_needed
1660 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1661 || REGNO (base) == ARG_POINTER_REGNUM
1662 || (flag_pic
1663 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1664 pointer = base_ptr = true;
1665
1666 if ((reload_completed || reload_in_progress)
1667 && base == cfun->machine->base_reg)
1668 pointer = base_ptr = literal_pool = true;
1669 }
1670
1671 /* Validate index register. */
1672 if (indx)
1673 {
1674 if (GET_CODE (indx) == UNSPEC)
1675 switch (XINT (indx, 1))
1676 {
1677 case UNSPEC_LTREF:
1678 if (!disp)
1679 disp = gen_rtx_UNSPEC (Pmode,
1680 gen_rtvec (1, XVECEXP (indx, 0, 0)),
1681 UNSPEC_LTREL_OFFSET);
1682 else
1683 return false;
1684
1685 indx = XVECEXP (indx, 0, 1);
1686 break;
1687
1688 case UNSPEC_LTREL_BASE:
1689 if (XVECLEN (indx, 0) == 1)
1690 indx = fake_pool_base, literal_pool = true;
1691 else
1692 indx = XVECEXP (indx, 0, 1);
1693 break;
1694
1695 default:
1696 return false;
1697 }
1698
1699 if (!REG_P (indx)
1700 || (GET_MODE (indx) != SImode
1701 && GET_MODE (indx) != Pmode))
1702 return false;
1703
1704 if (REGNO (indx) == STACK_POINTER_REGNUM
1705 || REGNO (indx) == FRAME_POINTER_REGNUM
1706 || ((reload_completed || reload_in_progress)
1707 && frame_pointer_needed
1708 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1709 || REGNO (indx) == ARG_POINTER_REGNUM
1710 || (flag_pic
1711 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1712 pointer = indx_ptr = true;
1713
1714 if ((reload_completed || reload_in_progress)
1715 && indx == cfun->machine->base_reg)
1716 pointer = indx_ptr = literal_pool = true;
1717 }
1718
1719 /* Prefer to use pointer as base, not index. */
1720 if (base && indx && !base_ptr
1721 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
1722 {
1723 rtx tmp = base;
1724 base = indx;
1725 indx = tmp;
1726 }
1727
1728 /* Validate displacement. */
1729 if (!disp)
1730 {
1731 /* If virtual registers are involved, the displacement will change later
1732 anyway as the virtual registers get eliminated. This could make a
1733 valid displacement invalid, but it is more likely to make an invalid
1734 displacement valid, because we sometimes access the register save area
1735 via negative offsets to one of those registers.
1736 Thus we don't check the displacement for validity here. If after
1737 elimination the displacement turns out to be invalid after all,
1738 this is fixed up by reload in any case. */
1739 if (base != arg_pointer_rtx
1740 && indx != arg_pointer_rtx
1741 && base != return_address_pointer_rtx
1742 && indx != return_address_pointer_rtx
1743 && base != frame_pointer_rtx
1744 && indx != frame_pointer_rtx
1745 && base != virtual_stack_vars_rtx
1746 && indx != virtual_stack_vars_rtx)
1747 if (!DISP_IN_RANGE (offset))
1748 return false;
1749 }
1750 else
1751 {
1752 /* All the special cases are pointers. */
1753 pointer = true;
1754
1755 /* In the small-PIC case, the linker converts @GOT
1756 and @GOTNTPOFF offsets to possible displacements. */
1757 if (GET_CODE (disp) == UNSPEC
1758 && (XINT (disp, 1) == UNSPEC_GOT
1759 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
1760 && flag_pic == 1)
1761 {
1762 ;
1763 }
1764
1765 /* Accept chunkified literal pool symbol references. */
1766 else if (cfun && cfun->machine
1767 && cfun->machine->decomposed_literal_pool_addresses_ok_p
1768 && GET_CODE (disp) == MINUS
1769 && GET_CODE (XEXP (disp, 0)) == LABEL_REF
1770 && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
1771 {
1772 ;
1773 }
1774
1775 /* Accept literal pool references. */
1776 else if (GET_CODE (disp) == UNSPEC
1777 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
1778 {
1779 orig_disp = gen_rtx_CONST (Pmode, disp);
1780 if (offset)
1781 {
1782 /* If we have an offset, make sure it does not
1783 exceed the size of the constant pool entry. */
1784 rtx sym = XVECEXP (disp, 0, 0);
1785 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
1786 return false;
1787
1788 orig_disp = plus_constant (orig_disp, offset);
1789 }
1790 }
1791
1792 else
1793 return false;
1794 }
1795
1796 if (!base && !indx)
1797 pointer = true;
1798
1799 if (out)
1800 {
1801 out->base = base;
1802 out->indx = indx;
1803 out->disp = orig_disp;
1804 out->pointer = pointer;
1805 out->literal_pool = literal_pool;
1806 }
1807
1808 return true;
1809 }
1810
1811 /* Decompose a RTL expression OP for a shift count into its components,
1812 and return the base register in BASE and the offset in OFFSET.
1813
1814 Return true if OP is a valid shift count, false if not. */
1815
1816 bool
s390_decompose_shift_count(rtx op,rtx * base,HOST_WIDE_INT * offset)1817 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
1818 {
1819 HOST_WIDE_INT off = 0;
1820
1821 /* We can have an integer constant, an address register,
1822 or a sum of the two. */
1823 if (GET_CODE (op) == CONST_INT)
1824 {
1825 off = INTVAL (op);
1826 op = NULL_RTX;
1827 }
1828 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1829 {
1830 off = INTVAL (XEXP (op, 1));
1831 op = XEXP (op, 0);
1832 }
1833 while (op && GET_CODE (op) == SUBREG)
1834 op = SUBREG_REG (op);
1835
1836 if (op && GET_CODE (op) != REG)
1837 return false;
1838
1839 if (offset)
1840 *offset = off;
1841 if (base)
1842 *base = op;
1843
1844 return true;
1845 }
1846
1847
1848 /* Return true if CODE is a valid address without index. */
1849
1850 bool
s390_legitimate_address_without_index_p(rtx op)1851 s390_legitimate_address_without_index_p (rtx op)
1852 {
1853 struct s390_address addr;
1854
1855 if (!s390_decompose_address (XEXP (op, 0), &addr))
1856 return false;
1857 if (addr.indx)
1858 return false;
1859
1860 return true;
1861 }
1862
1863
1864 /* Evaluates constraint strings described by the regular expression
1865 ([A|B](Q|R|S|T))|U|W and returns 1 if OP is a valid operand for the
1866 constraint given in STR, or 0 else. */
1867
1868 int
s390_mem_constraint(const char * str,rtx op)1869 s390_mem_constraint (const char *str, rtx op)
1870 {
1871 struct s390_address addr;
1872 char c = str[0];
1873
1874 /* Check for offsettable variants of memory constraints. */
1875 if (c == 'A')
1876 {
1877 /* Only accept non-volatile MEMs. */
1878 if (!MEM_P (op) || MEM_VOLATILE_P (op))
1879 return 0;
1880
1881 if ((reload_completed || reload_in_progress)
1882 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
1883 return 0;
1884
1885 c = str[1];
1886 }
1887
1888 /* Check for non-literal-pool variants of memory constraints. */
1889 else if (c == 'B')
1890 {
1891 if (GET_CODE (op) != MEM)
1892 return 0;
1893 if (!s390_decompose_address (XEXP (op, 0), &addr))
1894 return 0;
1895 if (addr.literal_pool)
1896 return 0;
1897
1898 c = str[1];
1899 }
1900
1901 switch (c)
1902 {
1903 case 'Q':
1904 if (GET_CODE (op) != MEM)
1905 return 0;
1906 if (!s390_decompose_address (XEXP (op, 0), &addr))
1907 return 0;
1908 if (addr.indx)
1909 return 0;
1910
1911 if (TARGET_LONG_DISPLACEMENT)
1912 {
1913 if (!s390_short_displacement (addr.disp))
1914 return 0;
1915 }
1916 break;
1917
1918 case 'R':
1919 if (GET_CODE (op) != MEM)
1920 return 0;
1921
1922 if (TARGET_LONG_DISPLACEMENT)
1923 {
1924 if (!s390_decompose_address (XEXP (op, 0), &addr))
1925 return 0;
1926 if (!s390_short_displacement (addr.disp))
1927 return 0;
1928 }
1929 break;
1930
1931 case 'S':
1932 if (!TARGET_LONG_DISPLACEMENT)
1933 return 0;
1934 if (GET_CODE (op) != MEM)
1935 return 0;
1936 if (!s390_decompose_address (XEXP (op, 0), &addr))
1937 return 0;
1938 if (addr.indx)
1939 return 0;
1940 if (s390_short_displacement (addr.disp))
1941 return 0;
1942 break;
1943
1944 case 'T':
1945 if (!TARGET_LONG_DISPLACEMENT)
1946 return 0;
1947 if (GET_CODE (op) != MEM)
1948 return 0;
1949 /* Any invalid address here will be fixed up by reload,
1950 so accept it for the most generic constraint. */
1951 if (s390_decompose_address (XEXP (op, 0), &addr)
1952 && s390_short_displacement (addr.disp))
1953 return 0;
1954 break;
1955
1956 case 'U':
1957 if (TARGET_LONG_DISPLACEMENT)
1958 {
1959 if (!s390_decompose_address (op, &addr))
1960 return 0;
1961 if (!s390_short_displacement (addr.disp))
1962 return 0;
1963 }
1964 break;
1965
1966 case 'W':
1967 if (!TARGET_LONG_DISPLACEMENT)
1968 return 0;
1969 /* Any invalid address here will be fixed up by reload,
1970 so accept it for the most generic constraint. */
1971 if (s390_decompose_address (op, &addr)
1972 && s390_short_displacement (addr.disp))
1973 return 0;
1974 break;
1975
1976 case 'Y':
1977 /* Simply check for the basic form of a shift count. Reload will
1978 take care of making sure we have a proper base register. */
1979 if (!s390_decompose_shift_count (op, NULL, NULL))
1980 return 0;
1981 break;
1982
1983 default:
1984 return 0;
1985 }
1986
1987 return 1;
1988 }
1989
1990
1991
1992 /* Evaluates constraint strings starting with letter O. Input
1993 parameter C is the second letter following the "O" in the constraint
1994 string. Returns 1 if VALUE meets the respective constraint and 0
1995 otherwise. */
1996
1997 int
s390_O_constraint_str(const char c,HOST_WIDE_INT value)1998 s390_O_constraint_str (const char c, HOST_WIDE_INT value)
1999 {
2000 if (!TARGET_EXTIMM)
2001 return 0;
2002
2003 switch (c)
2004 {
2005 case 's':
2006 return trunc_int_for_mode (value, SImode) == value;
2007
2008 case 'p':
2009 return value == 0
2010 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
2011
2012 case 'n':
2013 return value == -1
2014 || s390_single_part (GEN_INT (value), DImode, SImode, -1) == 1;
2015
2016 default:
2017 gcc_unreachable ();
2018 }
2019 }
2020
2021
2022 /* Evaluates constraint strings starting with letter N. Parameter STR
2023 contains the letters following letter "N" in the constraint string.
2024 Returns true if VALUE matches the constraint. */
2025
2026 int
s390_N_constraint_str(const char * str,HOST_WIDE_INT value)2027 s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
2028 {
2029 enum machine_mode mode, part_mode;
2030 int def;
2031 int part, part_goal;
2032
2033
2034 if (str[0] == 'x')
2035 part_goal = -1;
2036 else
2037 part_goal = str[0] - '0';
2038
2039 switch (str[1])
2040 {
2041 case 'Q':
2042 part_mode = QImode;
2043 break;
2044 case 'H':
2045 part_mode = HImode;
2046 break;
2047 case 'S':
2048 part_mode = SImode;
2049 break;
2050 default:
2051 return 0;
2052 }
2053
2054 switch (str[2])
2055 {
2056 case 'H':
2057 mode = HImode;
2058 break;
2059 case 'S':
2060 mode = SImode;
2061 break;
2062 case 'D':
2063 mode = DImode;
2064 break;
2065 default:
2066 return 0;
2067 }
2068
2069 switch (str[3])
2070 {
2071 case '0':
2072 def = 0;
2073 break;
2074 case 'F':
2075 def = -1;
2076 break;
2077 default:
2078 return 0;
2079 }
2080
2081 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
2082 return 0;
2083
2084 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
2085 if (part < 0)
2086 return 0;
2087 if (part_goal != -1 && part_goal != part)
2088 return 0;
2089
2090 return 1;
2091 }
2092
2093
2094 /* Returns true if the input parameter VALUE is a float zero. */
2095
2096 int
s390_float_const_zero_p(rtx value)2097 s390_float_const_zero_p (rtx value)
2098 {
2099 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
2100 && value == CONST0_RTX (GET_MODE (value)));
2101 }
2102
2103
2104 /* Compute a (partial) cost for rtx X. Return true if the complete
2105 cost has been computed, and false if subexpressions should be
2106 scanned. In either case, *TOTAL contains the cost result.
2107 CODE contains GET_CODE (x), OUTER_CODE contains the code
2108 of the superexpression of x. */
2109
2110 static bool
s390_rtx_costs(rtx x,int code,int outer_code,int * total)2111 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
2112 {
2113 switch (code)
2114 {
2115 case CONST:
2116 case CONST_INT:
2117 case LABEL_REF:
2118 case SYMBOL_REF:
2119 case CONST_DOUBLE:
2120 case MEM:
2121 *total = 0;
2122 return true;
2123
2124 case ASHIFT:
2125 case ASHIFTRT:
2126 case LSHIFTRT:
2127 case ROTATE:
2128 case ROTATERT:
2129 case AND:
2130 case IOR:
2131 case XOR:
2132 case NEG:
2133 case NOT:
2134 *total = COSTS_N_INSNS (1);
2135 return false;
2136
2137 case PLUS:
2138 case MINUS:
2139 /* Check for multiply and add. */
2140 if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2141 && GET_CODE (XEXP (x, 0)) == MULT
2142 && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD)
2143 {
2144 /* This is the multiply and add case. */
2145 if (GET_MODE (x) == DFmode)
2146 *total = s390_cost->madbr;
2147 else
2148 *total = s390_cost->maebr;
2149 *total += rtx_cost (XEXP (XEXP (x, 0), 0), MULT)
2150 + rtx_cost (XEXP (XEXP (x, 0), 1), MULT)
2151 + rtx_cost (XEXP (x, 1), code);
2152 return true; /* Do not do an additional recursive descent. */
2153 }
2154 *total = COSTS_N_INSNS (1);
2155 return false;
2156
2157 case MULT:
2158 switch (GET_MODE (x))
2159 {
2160 case SImode:
2161 {
2162 rtx left = XEXP (x, 0);
2163 rtx right = XEXP (x, 1);
2164 if (GET_CODE (right) == CONST_INT
2165 && CONST_OK_FOR_K (INTVAL (right)))
2166 *total = s390_cost->mhi;
2167 else if (GET_CODE (left) == SIGN_EXTEND)
2168 *total = s390_cost->mh;
2169 else
2170 *total = s390_cost->ms; /* msr, ms, msy */
2171 break;
2172 }
2173 case DImode:
2174 {
2175 rtx left = XEXP (x, 0);
2176 rtx right = XEXP (x, 1);
2177 if (TARGET_64BIT)
2178 {
2179 if (GET_CODE (right) == CONST_INT
2180 && CONST_OK_FOR_K (INTVAL (right)))
2181 *total = s390_cost->mghi;
2182 else if (GET_CODE (left) == SIGN_EXTEND)
2183 *total = s390_cost->msgf;
2184 else
2185 *total = s390_cost->msg; /* msgr, msg */
2186 }
2187 else /* TARGET_31BIT */
2188 {
2189 if (GET_CODE (left) == SIGN_EXTEND
2190 && GET_CODE (right) == SIGN_EXTEND)
2191 /* mulsidi case: mr, m */
2192 *total = s390_cost->m;
2193 else if (GET_CODE (left) == ZERO_EXTEND
2194 && GET_CODE (right) == ZERO_EXTEND
2195 && TARGET_CPU_ZARCH)
2196 /* umulsidi case: ml, mlr */
2197 *total = s390_cost->ml;
2198 else
2199 /* Complex calculation is required. */
2200 *total = COSTS_N_INSNS (40);
2201 }
2202 break;
2203 }
2204 case SFmode:
2205 case DFmode:
2206 *total = s390_cost->mult_df;
2207 break;
2208 case TFmode:
2209 *total = s390_cost->mxbr;
2210 break;
2211 default:
2212 return false;
2213 }
2214 return false;
2215
2216 case UDIV:
2217 case UMOD:
2218 if (GET_MODE (x) == TImode) /* 128 bit division */
2219 *total = s390_cost->dlgr;
2220 else if (GET_MODE (x) == DImode)
2221 {
2222 rtx right = XEXP (x, 1);
2223 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2224 *total = s390_cost->dlr;
2225 else /* 64 by 64 bit division */
2226 *total = s390_cost->dlgr;
2227 }
2228 else if (GET_MODE (x) == SImode) /* 32 bit division */
2229 *total = s390_cost->dlr;
2230 return false;
2231
2232 case DIV:
2233 case MOD:
2234 if (GET_MODE (x) == DImode)
2235 {
2236 rtx right = XEXP (x, 1);
2237 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2238 if (TARGET_64BIT)
2239 *total = s390_cost->dsgfr;
2240 else
2241 *total = s390_cost->dr;
2242 else /* 64 by 64 bit division */
2243 *total = s390_cost->dsgr;
2244 }
2245 else if (GET_MODE (x) == SImode) /* 32 bit division */
2246 *total = s390_cost->dlr;
2247 else if (GET_MODE (x) == SFmode)
2248 {
2249 if (TARGET_IEEE_FLOAT)
2250 *total = s390_cost->debr;
2251 else /* TARGET_IBM_FLOAT */
2252 *total = s390_cost->der;
2253 }
2254 else if (GET_MODE (x) == DFmode)
2255 {
2256 if (TARGET_IEEE_FLOAT)
2257 *total = s390_cost->ddbr;
2258 else /* TARGET_IBM_FLOAT */
2259 *total = s390_cost->ddr;
2260 }
2261 else if (GET_MODE (x) == TFmode)
2262 {
2263 if (TARGET_IEEE_FLOAT)
2264 *total = s390_cost->dxbr;
2265 else /* TARGET_IBM_FLOAT */
2266 *total = s390_cost->dxr;
2267 }
2268 return false;
2269
2270 case SQRT:
2271 if (GET_MODE (x) == SFmode)
2272 *total = s390_cost->sqebr;
2273 else if (GET_MODE (x) == DFmode)
2274 *total = s390_cost->sqdbr;
2275 else /* TFmode */
2276 *total = s390_cost->sqxbr;
2277 return false;
2278
2279 case SIGN_EXTEND:
2280 case ZERO_EXTEND:
2281 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2282 || outer_code == PLUS || outer_code == MINUS
2283 || outer_code == COMPARE)
2284 *total = 0;
2285 return false;
2286
2287 case COMPARE:
2288 *total = COSTS_N_INSNS (1);
2289 if (GET_CODE (XEXP (x, 0)) == AND
2290 && GET_CODE (XEXP (x, 1)) == CONST_INT
2291 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2292 {
2293 rtx op0 = XEXP (XEXP (x, 0), 0);
2294 rtx op1 = XEXP (XEXP (x, 0), 1);
2295 rtx op2 = XEXP (x, 1);
2296
2297 if (memory_operand (op0, GET_MODE (op0))
2298 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
2299 return true;
2300 if (register_operand (op0, GET_MODE (op0))
2301 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2302 return true;
2303 }
2304 return false;
2305
2306 default:
2307 return false;
2308 }
2309 }
2310
2311 /* Return the cost of an address rtx ADDR. */
2312
2313 static int
s390_address_cost(rtx addr)2314 s390_address_cost (rtx addr)
2315 {
2316 struct s390_address ad;
2317 if (!s390_decompose_address (addr, &ad))
2318 return 1000;
2319
2320 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2321 }
2322
2323 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2324 otherwise return 0. */
2325
2326 int
tls_symbolic_operand(rtx op)2327 tls_symbolic_operand (rtx op)
2328 {
2329 if (GET_CODE (op) != SYMBOL_REF)
2330 return 0;
2331 return SYMBOL_REF_TLS_MODEL (op);
2332 }
2333
2334 /* Split DImode access register reference REG (on 64-bit) into its constituent
2335 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2336 gen_highpart cannot be used as they assume all registers are word-sized,
2337 while our access registers have only half that size. */
2338
2339 void
s390_split_access_reg(rtx reg,rtx * lo,rtx * hi)2340 s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2341 {
2342 gcc_assert (TARGET_64BIT);
2343 gcc_assert (ACCESS_REG_P (reg));
2344 gcc_assert (GET_MODE (reg) == DImode);
2345 gcc_assert (!(REGNO (reg) & 1));
2346
2347 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2348 *hi = gen_rtx_REG (SImode, REGNO (reg));
2349 }
2350
2351 /* Return true if OP contains a symbol reference */
2352
2353 bool
symbolic_reference_mentioned_p(rtx op)2354 symbolic_reference_mentioned_p (rtx op)
2355 {
2356 const char *fmt;
2357 int i;
2358
2359 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2360 return 1;
2361
2362 fmt = GET_RTX_FORMAT (GET_CODE (op));
2363 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2364 {
2365 if (fmt[i] == 'E')
2366 {
2367 int j;
2368
2369 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2370 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2371 return 1;
2372 }
2373
2374 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2375 return 1;
2376 }
2377
2378 return 0;
2379 }
2380
2381 /* Return true if OP contains a reference to a thread-local symbol. */
2382
2383 bool
tls_symbolic_reference_mentioned_p(rtx op)2384 tls_symbolic_reference_mentioned_p (rtx op)
2385 {
2386 const char *fmt;
2387 int i;
2388
2389 if (GET_CODE (op) == SYMBOL_REF)
2390 return tls_symbolic_operand (op);
2391
2392 fmt = GET_RTX_FORMAT (GET_CODE (op));
2393 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2394 {
2395 if (fmt[i] == 'E')
2396 {
2397 int j;
2398
2399 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2400 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2401 return true;
2402 }
2403
2404 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2405 return true;
2406 }
2407
2408 return false;
2409 }
2410
2411
2412 /* Return true if OP is a legitimate general operand when
2413 generating PIC code. It is given that flag_pic is on
2414 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2415
2416 int
legitimate_pic_operand_p(rtx op)2417 legitimate_pic_operand_p (rtx op)
2418 {
2419 /* Accept all non-symbolic constants. */
2420 if (!SYMBOLIC_CONST (op))
2421 return 1;
2422
2423 /* Reject everything else; must be handled
2424 via emit_symbolic_move. */
2425 return 0;
2426 }
2427
2428 /* Returns true if the constant value OP is a legitimate general operand.
2429 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2430
2431 int
legitimate_constant_p(rtx op)2432 legitimate_constant_p (rtx op)
2433 {
2434 /* Accept all non-symbolic constants. */
2435 if (!SYMBOLIC_CONST (op))
2436 return 1;
2437
2438 /* Accept immediate LARL operands. */
2439 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2440 return 1;
2441
2442 /* Thread-local symbols are never legal constants. This is
2443 so that emit_call knows that computing such addresses
2444 might require a function call. */
2445 if (TLS_SYMBOLIC_CONST (op))
2446 return 0;
2447
2448 /* In the PIC case, symbolic constants must *not* be
2449 forced into the literal pool. We accept them here,
2450 so that they will be handled by emit_symbolic_move. */
2451 if (flag_pic)
2452 return 1;
2453
2454 /* All remaining non-PIC symbolic constants are
2455 forced into the literal pool. */
2456 return 0;
2457 }
2458
2459 /* Determine if it's legal to put X into the constant pool. This
2460 is not possible if X contains the address of a symbol that is
2461 not constant (TLS) or not known at final link time (PIC). */
2462
2463 static bool
s390_cannot_force_const_mem(rtx x)2464 s390_cannot_force_const_mem (rtx x)
2465 {
2466 switch (GET_CODE (x))
2467 {
2468 case CONST_INT:
2469 case CONST_DOUBLE:
2470 /* Accept all non-symbolic constants. */
2471 return false;
2472
2473 case LABEL_REF:
2474 /* Labels are OK iff we are non-PIC. */
2475 return flag_pic != 0;
2476
2477 case SYMBOL_REF:
2478 /* 'Naked' TLS symbol references are never OK,
2479 non-TLS symbols are OK iff we are non-PIC. */
2480 if (tls_symbolic_operand (x))
2481 return true;
2482 else
2483 return flag_pic != 0;
2484
2485 case CONST:
2486 return s390_cannot_force_const_mem (XEXP (x, 0));
2487 case PLUS:
2488 case MINUS:
2489 return s390_cannot_force_const_mem (XEXP (x, 0))
2490 || s390_cannot_force_const_mem (XEXP (x, 1));
2491
2492 case UNSPEC:
2493 switch (XINT (x, 1))
2494 {
2495 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2496 case UNSPEC_LTREL_OFFSET:
2497 case UNSPEC_GOT:
2498 case UNSPEC_GOTOFF:
2499 case UNSPEC_PLTOFF:
2500 case UNSPEC_TLSGD:
2501 case UNSPEC_TLSLDM:
2502 case UNSPEC_NTPOFF:
2503 case UNSPEC_DTPOFF:
2504 case UNSPEC_GOTNTPOFF:
2505 case UNSPEC_INDNTPOFF:
2506 return false;
2507
2508 /* If the literal pool shares the code section, be put
2509 execute template placeholders into the pool as well. */
2510 case UNSPEC_INSN:
2511 return TARGET_CPU_ZARCH;
2512
2513 default:
2514 return true;
2515 }
2516 break;
2517
2518 default:
2519 gcc_unreachable ();
2520 }
2521 }
2522
2523 /* Returns true if the constant value OP is a legitimate general
2524 operand during and after reload. The difference to
2525 legitimate_constant_p is that this function will not accept
2526 a constant that would need to be forced to the literal pool
2527 before it can be used as operand. */
2528
2529 bool
legitimate_reload_constant_p(rtx op)2530 legitimate_reload_constant_p (rtx op)
2531 {
2532 /* Accept la(y) operands. */
2533 if (GET_CODE (op) == CONST_INT
2534 && DISP_IN_RANGE (INTVAL (op)))
2535 return true;
2536
2537 /* Accept l(g)hi/l(g)fi operands. */
2538 if (GET_CODE (op) == CONST_INT
2539 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
2540 return true;
2541
2542 /* Accept lliXX operands. */
2543 if (TARGET_ZARCH
2544 && GET_CODE (op) == CONST_INT
2545 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2546 && s390_single_part (op, word_mode, HImode, 0) >= 0)
2547 return true;
2548
2549 if (TARGET_EXTIMM
2550 && GET_CODE (op) == CONST_INT
2551 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2552 && s390_single_part (op, word_mode, SImode, 0) >= 0)
2553 return true;
2554
2555 /* Accept larl operands. */
2556 if (TARGET_CPU_ZARCH
2557 && larl_operand (op, VOIDmode))
2558 return true;
2559
2560 /* Accept lzXX operands. */
2561 if (GET_CODE (op) == CONST_DOUBLE
2562 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', "G"))
2563 return true;
2564
2565 /* Accept double-word operands that can be split. */
2566 if (GET_CODE (op) == CONST_INT
2567 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op))
2568 {
2569 enum machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
2570 rtx hi = operand_subword (op, 0, 0, dword_mode);
2571 rtx lo = operand_subword (op, 1, 0, dword_mode);
2572 return legitimate_reload_constant_p (hi)
2573 && legitimate_reload_constant_p (lo);
2574 }
2575
2576 /* Everything else cannot be handled without reload. */
2577 return false;
2578 }
2579
2580 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2581 return the class of reg to actually use. */
2582
2583 enum reg_class
s390_preferred_reload_class(rtx op,enum reg_class class)2584 s390_preferred_reload_class (rtx op, enum reg_class class)
2585 {
2586 switch (GET_CODE (op))
2587 {
2588 /* Constants we cannot reload must be forced into the
2589 literal pool. */
2590
2591 case CONST_DOUBLE:
2592 case CONST_INT:
2593 if (legitimate_reload_constant_p (op))
2594 return class;
2595 else
2596 return NO_REGS;
2597
2598 /* If a symbolic constant or a PLUS is reloaded,
2599 it is most likely being used as an address, so
2600 prefer ADDR_REGS. If 'class' is not a superset
2601 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2602 case PLUS:
2603 case LABEL_REF:
2604 case SYMBOL_REF:
2605 case CONST:
2606 if (reg_class_subset_p (ADDR_REGS, class))
2607 return ADDR_REGS;
2608 else
2609 return NO_REGS;
2610
2611 default:
2612 break;
2613 }
2614
2615 return class;
2616 }
2617
2618 /* Return the register class of a scratch register needed to
2619 load IN into a register of class CLASS in MODE.
2620
2621 We need a temporary when loading a PLUS expression which
2622 is not a legitimate operand of the LOAD ADDRESS instruction. */
2623
2624 enum reg_class
s390_secondary_input_reload_class(enum reg_class class,enum machine_mode mode,rtx in)2625 s390_secondary_input_reload_class (enum reg_class class,
2626 enum machine_mode mode, rtx in)
2627 {
2628 if (s390_plus_operand (in, mode))
2629 return ADDR_REGS;
2630
2631 if (reg_classes_intersect_p (FP_REGS, class)
2632 && mode == TFmode
2633 && GET_CODE (in) == MEM
2634 && GET_CODE (XEXP (in, 0)) == PLUS
2635 && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT
2636 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1))
2637 + GET_MODE_SIZE (mode) - 1))
2638 return ADDR_REGS;
2639
2640 if (reg_classes_intersect_p (CC_REGS, class))
2641 return GENERAL_REGS;
2642
2643 return NO_REGS;
2644 }
2645
2646 /* Return the register class of a scratch register needed to
2647 store a register of class CLASS in MODE into OUT:
2648
2649 We need a temporary when storing a double-word to a
2650 non-offsettable memory address. */
2651
2652 enum reg_class
s390_secondary_output_reload_class(enum reg_class class,enum machine_mode mode,rtx out)2653 s390_secondary_output_reload_class (enum reg_class class,
2654 enum machine_mode mode, rtx out)
2655 {
2656 if ((TARGET_64BIT ? (mode == TImode || mode == TFmode)
2657 : (mode == DImode || mode == DFmode))
2658 && reg_classes_intersect_p (GENERAL_REGS, class)
2659 && GET_CODE (out) == MEM
2660 && GET_CODE (XEXP (out, 0)) == PLUS
2661 && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS
2662 && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2663 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2664 + GET_MODE_SIZE (mode) - 1))
2665 return ADDR_REGS;
2666
2667 if (reg_classes_intersect_p (FP_REGS, class)
2668 && mode == TFmode
2669 && GET_CODE (out) == MEM
2670 && GET_CODE (XEXP (out, 0)) == PLUS
2671 && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2672 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2673 + GET_MODE_SIZE (mode) - 1))
2674 return ADDR_REGS;
2675
2676 if (reg_classes_intersect_p (CC_REGS, class))
2677 return GENERAL_REGS;
2678
2679 return NO_REGS;
2680 }
2681
2682 /* Generate code to load SRC, which is PLUS that is not a
2683 legitimate operand for the LA instruction, into TARGET.
2684 SCRATCH may be used as scratch register. */
2685
2686 void
s390_expand_plus_operand(rtx target,rtx src,rtx scratch)2687 s390_expand_plus_operand (rtx target, rtx src,
2688 rtx scratch)
2689 {
2690 rtx sum1, sum2;
2691 struct s390_address ad;
2692
2693 /* src must be a PLUS; get its two operands. */
2694 gcc_assert (GET_CODE (src) == PLUS);
2695 gcc_assert (GET_MODE (src) == Pmode);
2696
2697 /* Check if any of the two operands is already scheduled
2698 for replacement by reload. This can happen e.g. when
2699 float registers occur in an address. */
2700 sum1 = find_replacement (&XEXP (src, 0));
2701 sum2 = find_replacement (&XEXP (src, 1));
2702 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2703
2704 /* If the address is already strictly valid, there's nothing to do. */
2705 if (!s390_decompose_address (src, &ad)
2706 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2707 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
2708 {
2709 /* Otherwise, one of the operands cannot be an address register;
2710 we reload its value into the scratch register. */
2711 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2712 {
2713 emit_move_insn (scratch, sum1);
2714 sum1 = scratch;
2715 }
2716 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2717 {
2718 emit_move_insn (scratch, sum2);
2719 sum2 = scratch;
2720 }
2721
2722 /* According to the way these invalid addresses are generated
2723 in reload.c, it should never happen (at least on s390) that
2724 *neither* of the PLUS components, after find_replacements
2725 was applied, is an address register. */
2726 if (sum1 == scratch && sum2 == scratch)
2727 {
2728 debug_rtx (src);
2729 gcc_unreachable ();
2730 }
2731
2732 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2733 }
2734
2735 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2736 is only ever performed on addresses, so we can mark the
2737 sum as legitimate for LA in any case. */
2738 s390_load_address (target, src);
2739 }
2740
2741
2742 /* Return true if ADDR is a valid memory address.
2743 STRICT specifies whether strict register checking applies. */
2744
2745 bool
legitimate_address_p(enum machine_mode mode ATTRIBUTE_UNUSED,rtx addr,int strict)2746 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2747 rtx addr, int strict)
2748 {
2749 struct s390_address ad;
2750 if (!s390_decompose_address (addr, &ad))
2751 return false;
2752
2753 if (strict)
2754 {
2755 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2756 return false;
2757
2758 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
2759 return false;
2760 }
2761 else
2762 {
2763 if (ad.base
2764 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
2765 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
2766 return false;
2767
2768 if (ad.indx
2769 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
2770 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
2771 return false;
2772 }
2773 return true;
2774 }
2775
2776 /* Return true if OP is a valid operand for the LA instruction.
2777 In 31-bit, we need to prove that the result is used as an
2778 address, as LA performs only a 31-bit addition. */
2779
2780 bool
legitimate_la_operand_p(rtx op)2781 legitimate_la_operand_p (rtx op)
2782 {
2783 struct s390_address addr;
2784 if (!s390_decompose_address (op, &addr))
2785 return false;
2786
2787 return (TARGET_64BIT || addr.pointer);
2788 }
2789
2790 /* Return true if it is valid *and* preferable to use LA to
2791 compute the sum of OP1 and OP2. */
2792
2793 bool
preferred_la_operand_p(rtx op1,rtx op2)2794 preferred_la_operand_p (rtx op1, rtx op2)
2795 {
2796 struct s390_address addr;
2797
2798 if (op2 != const0_rtx)
2799 op1 = gen_rtx_PLUS (Pmode, op1, op2);
2800
2801 if (!s390_decompose_address (op1, &addr))
2802 return false;
2803 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
2804 return false;
2805 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
2806 return false;
2807
2808 if (!TARGET_64BIT && !addr.pointer)
2809 return false;
2810
2811 if (addr.pointer)
2812 return true;
2813
2814 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2815 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2816 return true;
2817
2818 return false;
2819 }
2820
2821 /* Emit a forced load-address operation to load SRC into DST.
2822 This will use the LOAD ADDRESS instruction even in situations
2823 where legitimate_la_operand_p (SRC) returns false. */
2824
2825 void
s390_load_address(rtx dst,rtx src)2826 s390_load_address (rtx dst, rtx src)
2827 {
2828 if (TARGET_64BIT)
2829 emit_move_insn (dst, src);
2830 else
2831 emit_insn (gen_force_la_31 (dst, src));
2832 }
2833
2834 /* Return a legitimate reference for ORIG (an address) using the
2835 register REG. If REG is 0, a new pseudo is generated.
2836
2837 There are two types of references that must be handled:
2838
2839 1. Global data references must load the address from the GOT, via
2840 the PIC reg. An insn is emitted to do this load, and the reg is
2841 returned.
2842
2843 2. Static data references, constant pool addresses, and code labels
2844 compute the address as an offset from the GOT, whose base is in
2845 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2846 differentiate them from global data objects. The returned
2847 address is the PIC reg + an unspec constant.
2848
2849 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2850 reg also appears in the address. */
2851
2852 rtx
legitimize_pic_address(rtx orig,rtx reg)2853 legitimize_pic_address (rtx orig, rtx reg)
2854 {
2855 rtx addr = orig;
2856 rtx new = orig;
2857 rtx base;
2858
2859 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
2860
2861 if (GET_CODE (addr) == LABEL_REF
2862 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2863 {
2864 /* This is a local symbol. */
2865 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2866 {
2867 /* Access local symbols PC-relative via LARL.
2868 This is the same as in the non-PIC case, so it is
2869 handled automatically ... */
2870 }
2871 else
2872 {
2873 /* Access local symbols relative to the GOT. */
2874
2875 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2876
2877 if (reload_in_progress || reload_completed)
2878 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2879
2880 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2881 addr = gen_rtx_CONST (Pmode, addr);
2882 addr = force_const_mem (Pmode, addr);
2883 emit_move_insn (temp, addr);
2884
2885 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2886 if (reg != 0)
2887 {
2888 s390_load_address (reg, new);
2889 new = reg;
2890 }
2891 }
2892 }
2893 else if (GET_CODE (addr) == SYMBOL_REF)
2894 {
2895 if (reg == 0)
2896 reg = gen_reg_rtx (Pmode);
2897
2898 if (flag_pic == 1)
2899 {
2900 /* Assume GOT offset < 4k. This is handled the same way
2901 in both 31- and 64-bit code (@GOT). */
2902
2903 if (reload_in_progress || reload_completed)
2904 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2905
2906 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2907 new = gen_rtx_CONST (Pmode, new);
2908 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2909 new = gen_const_mem (Pmode, new);
2910 emit_move_insn (reg, new);
2911 new = reg;
2912 }
2913 else if (TARGET_CPU_ZARCH)
2914 {
2915 /* If the GOT offset might be >= 4k, we determine the position
2916 of the GOT entry via a PC-relative LARL (@GOTENT). */
2917
2918 rtx temp = gen_reg_rtx (Pmode);
2919
2920 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2921 new = gen_rtx_CONST (Pmode, new);
2922 emit_move_insn (temp, new);
2923
2924 new = gen_const_mem (Pmode, temp);
2925 emit_move_insn (reg, new);
2926 new = reg;
2927 }
2928 else
2929 {
2930 /* If the GOT offset might be >= 4k, we have to load it
2931 from the literal pool (@GOT). */
2932
2933 rtx temp = gen_reg_rtx (Pmode);
2934
2935 if (reload_in_progress || reload_completed)
2936 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2937
2938 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2939 addr = gen_rtx_CONST (Pmode, addr);
2940 addr = force_const_mem (Pmode, addr);
2941 emit_move_insn (temp, addr);
2942
2943 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2944 new = gen_const_mem (Pmode, new);
2945 emit_move_insn (reg, new);
2946 new = reg;
2947 }
2948 }
2949 else
2950 {
2951 if (GET_CODE (addr) == CONST)
2952 {
2953 addr = XEXP (addr, 0);
2954 if (GET_CODE (addr) == UNSPEC)
2955 {
2956 gcc_assert (XVECLEN (addr, 0) == 1);
2957 switch (XINT (addr, 1))
2958 {
2959 /* If someone moved a GOT-relative UNSPEC
2960 out of the literal pool, force them back in. */
2961 case UNSPEC_GOTOFF:
2962 case UNSPEC_PLTOFF:
2963 new = force_const_mem (Pmode, orig);
2964 break;
2965
2966 /* @GOT is OK as is if small. */
2967 case UNSPEC_GOT:
2968 if (flag_pic == 2)
2969 new = force_const_mem (Pmode, orig);
2970 break;
2971
2972 /* @GOTENT is OK as is. */
2973 case UNSPEC_GOTENT:
2974 break;
2975
2976 /* @PLT is OK as is on 64-bit, must be converted to
2977 GOT-relative @PLTOFF on 31-bit. */
2978 case UNSPEC_PLT:
2979 if (!TARGET_CPU_ZARCH)
2980 {
2981 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2982
2983 if (reload_in_progress || reload_completed)
2984 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2985
2986 addr = XVECEXP (addr, 0, 0);
2987 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2988 UNSPEC_PLTOFF);
2989 addr = gen_rtx_CONST (Pmode, addr);
2990 addr = force_const_mem (Pmode, addr);
2991 emit_move_insn (temp, addr);
2992
2993 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2994 if (reg != 0)
2995 {
2996 s390_load_address (reg, new);
2997 new = reg;
2998 }
2999 }
3000 break;
3001
3002 /* Everything else cannot happen. */
3003 default:
3004 gcc_unreachable ();
3005 }
3006 }
3007 else
3008 gcc_assert (GET_CODE (addr) == PLUS);
3009 }
3010 if (GET_CODE (addr) == PLUS)
3011 {
3012 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
3013
3014 gcc_assert (!TLS_SYMBOLIC_CONST (op0));
3015 gcc_assert (!TLS_SYMBOLIC_CONST (op1));
3016
3017 /* Check first to see if this is a constant offset
3018 from a local symbol reference. */
3019 if ((GET_CODE (op0) == LABEL_REF
3020 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
3021 && GET_CODE (op1) == CONST_INT)
3022 {
3023 if (TARGET_CPU_ZARCH
3024 && larl_operand (op0, VOIDmode)
3025 && INTVAL (op1) < (HOST_WIDE_INT)1 << 31
3026 && INTVAL (op1) >= -((HOST_WIDE_INT)1 << 31))
3027 {
3028 if (INTVAL (op1) & 1)
3029 {
3030 /* LARL can't handle odd offsets, so emit a
3031 pair of LARL and LA. */
3032 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3033
3034 if (!DISP_IN_RANGE (INTVAL (op1)))
3035 {
3036 HOST_WIDE_INT even = INTVAL (op1) - 1;
3037 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
3038 op0 = gen_rtx_CONST (Pmode, op0);
3039 op1 = const1_rtx;
3040 }
3041
3042 emit_move_insn (temp, op0);
3043 new = gen_rtx_PLUS (Pmode, temp, op1);
3044
3045 if (reg != 0)
3046 {
3047 s390_load_address (reg, new);
3048 new = reg;
3049 }
3050 }
3051 else
3052 {
3053 /* If the offset is even, we can just use LARL.
3054 This will happen automatically. */
3055 }
3056 }
3057 else
3058 {
3059 /* Access local symbols relative to the GOT. */
3060
3061 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3062
3063 if (reload_in_progress || reload_completed)
3064 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3065
3066 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
3067 UNSPEC_GOTOFF);
3068 addr = gen_rtx_PLUS (Pmode, addr, op1);
3069 addr = gen_rtx_CONST (Pmode, addr);
3070 addr = force_const_mem (Pmode, addr);
3071 emit_move_insn (temp, addr);
3072
3073 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3074 if (reg != 0)
3075 {
3076 s390_load_address (reg, new);
3077 new = reg;
3078 }
3079 }
3080 }
3081
3082 /* Now, check whether it is a GOT relative symbol plus offset
3083 that was pulled out of the literal pool. Force it back in. */
3084
3085 else if (GET_CODE (op0) == UNSPEC
3086 && GET_CODE (op1) == CONST_INT
3087 && XINT (op0, 1) == UNSPEC_GOTOFF)
3088 {
3089 gcc_assert (XVECLEN (op0, 0) == 1);
3090
3091 new = force_const_mem (Pmode, orig);
3092 }
3093
3094 /* Otherwise, compute the sum. */
3095 else
3096 {
3097 base = legitimize_pic_address (XEXP (addr, 0), reg);
3098 new = legitimize_pic_address (XEXP (addr, 1),
3099 base == reg ? NULL_RTX : reg);
3100 if (GET_CODE (new) == CONST_INT)
3101 new = plus_constant (base, INTVAL (new));
3102 else
3103 {
3104 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
3105 {
3106 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
3107 new = XEXP (new, 1);
3108 }
3109 new = gen_rtx_PLUS (Pmode, base, new);
3110 }
3111
3112 if (GET_CODE (new) == CONST)
3113 new = XEXP (new, 0);
3114 new = force_operand (new, 0);
3115 }
3116 }
3117 }
3118 return new;
3119 }
3120
3121 /* Load the thread pointer into a register. */
3122
3123 rtx
s390_get_thread_pointer(void)3124 s390_get_thread_pointer (void)
3125 {
3126 rtx tp = gen_reg_rtx (Pmode);
3127
3128 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
3129 mark_reg_pointer (tp, BITS_PER_WORD);
3130
3131 return tp;
3132 }
3133
3134 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3135 in s390_tls_symbol which always refers to __tls_get_offset.
3136 The returned offset is written to RESULT_REG and an USE rtx is
3137 generated for TLS_CALL. */
3138
3139 static GTY(()) rtx s390_tls_symbol;
3140
3141 static void
s390_emit_tls_call_insn(rtx result_reg,rtx tls_call)3142 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3143 {
3144 rtx insn;
3145
3146 gcc_assert (flag_pic);
3147
3148 if (!s390_tls_symbol)
3149 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
3150
3151 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
3152 gen_rtx_REG (Pmode, RETURN_REGNUM));
3153
3154 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
3155 CONST_OR_PURE_CALL_P (insn) = 1;
3156 }
3157
3158 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3159 this (thread-local) address. REG may be used as temporary. */
3160
3161 static rtx
legitimize_tls_address(rtx addr,rtx reg)3162 legitimize_tls_address (rtx addr, rtx reg)
3163 {
3164 rtx new, tls_call, temp, base, r2, insn;
3165
3166 if (GET_CODE (addr) == SYMBOL_REF)
3167 switch (tls_symbolic_operand (addr))
3168 {
3169 case TLS_MODEL_GLOBAL_DYNAMIC:
3170 start_sequence ();
3171 r2 = gen_rtx_REG (Pmode, 2);
3172 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
3173 new = gen_rtx_CONST (Pmode, tls_call);
3174 new = force_const_mem (Pmode, new);
3175 emit_move_insn (r2, new);
3176 s390_emit_tls_call_insn (r2, tls_call);
3177 insn = get_insns ();
3178 end_sequence ();
3179
3180 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3181 temp = gen_reg_rtx (Pmode);
3182 emit_libcall_block (insn, temp, r2, new);
3183
3184 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3185 if (reg != 0)
3186 {
3187 s390_load_address (reg, new);
3188 new = reg;
3189 }
3190 break;
3191
3192 case TLS_MODEL_LOCAL_DYNAMIC:
3193 start_sequence ();
3194 r2 = gen_rtx_REG (Pmode, 2);
3195 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
3196 new = gen_rtx_CONST (Pmode, tls_call);
3197 new = force_const_mem (Pmode, new);
3198 emit_move_insn (r2, new);
3199 s390_emit_tls_call_insn (r2, tls_call);
3200 insn = get_insns ();
3201 end_sequence ();
3202
3203 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
3204 temp = gen_reg_rtx (Pmode);
3205 emit_libcall_block (insn, temp, r2, new);
3206
3207 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3208 base = gen_reg_rtx (Pmode);
3209 s390_load_address (base, new);
3210
3211 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
3212 new = gen_rtx_CONST (Pmode, new);
3213 new = force_const_mem (Pmode, new);
3214 temp = gen_reg_rtx (Pmode);
3215 emit_move_insn (temp, new);
3216
3217 new = gen_rtx_PLUS (Pmode, base, temp);
3218 if (reg != 0)
3219 {
3220 s390_load_address (reg, new);
3221 new = reg;
3222 }
3223 break;
3224
3225 case TLS_MODEL_INITIAL_EXEC:
3226 if (flag_pic == 1)
3227 {
3228 /* Assume GOT offset < 4k. This is handled the same way
3229 in both 31- and 64-bit code. */
3230
3231 if (reload_in_progress || reload_completed)
3232 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3233
3234 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3235 new = gen_rtx_CONST (Pmode, new);
3236 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3237 new = gen_const_mem (Pmode, new);
3238 temp = gen_reg_rtx (Pmode);
3239 emit_move_insn (temp, new);
3240 }
3241 else if (TARGET_CPU_ZARCH)
3242 {
3243 /* If the GOT offset might be >= 4k, we determine the position
3244 of the GOT entry via a PC-relative LARL. */
3245
3246 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3247 new = gen_rtx_CONST (Pmode, new);
3248 temp = gen_reg_rtx (Pmode);
3249 emit_move_insn (temp, new);
3250
3251 new = gen_const_mem (Pmode, temp);
3252 temp = gen_reg_rtx (Pmode);
3253 emit_move_insn (temp, new);
3254 }
3255 else if (flag_pic)
3256 {
3257 /* If the GOT offset might be >= 4k, we have to load it
3258 from the literal pool. */
3259
3260 if (reload_in_progress || reload_completed)
3261 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3262
3263 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3264 new = gen_rtx_CONST (Pmode, new);
3265 new = force_const_mem (Pmode, new);
3266 temp = gen_reg_rtx (Pmode);
3267 emit_move_insn (temp, new);
3268
3269 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3270 new = gen_const_mem (Pmode, new);
3271
3272 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3273 temp = gen_reg_rtx (Pmode);
3274 emit_insn (gen_rtx_SET (Pmode, temp, new));
3275 }
3276 else
3277 {
3278 /* In position-dependent code, load the absolute address of
3279 the GOT entry from the literal pool. */
3280
3281 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3282 new = gen_rtx_CONST (Pmode, new);
3283 new = force_const_mem (Pmode, new);
3284 temp = gen_reg_rtx (Pmode);
3285 emit_move_insn (temp, new);
3286
3287 new = temp;
3288 new = gen_const_mem (Pmode, new);
3289 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3290 temp = gen_reg_rtx (Pmode);
3291 emit_insn (gen_rtx_SET (Pmode, temp, new));
3292 }
3293
3294 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3295 if (reg != 0)
3296 {
3297 s390_load_address (reg, new);
3298 new = reg;
3299 }
3300 break;
3301
3302 case TLS_MODEL_LOCAL_EXEC:
3303 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3304 new = gen_rtx_CONST (Pmode, new);
3305 new = force_const_mem (Pmode, new);
3306 temp = gen_reg_rtx (Pmode);
3307 emit_move_insn (temp, new);
3308
3309 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3310 if (reg != 0)
3311 {
3312 s390_load_address (reg, new);
3313 new = reg;
3314 }
3315 break;
3316
3317 default:
3318 gcc_unreachable ();
3319 }
3320
3321 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3322 {
3323 switch (XINT (XEXP (addr, 0), 1))
3324 {
3325 case UNSPEC_INDNTPOFF:
3326 gcc_assert (TARGET_CPU_ZARCH);
3327 new = addr;
3328 break;
3329
3330 default:
3331 gcc_unreachable ();
3332 }
3333 }
3334
3335 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3336 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3337 {
3338 new = XEXP (XEXP (addr, 0), 0);
3339 if (GET_CODE (new) != SYMBOL_REF)
3340 new = gen_rtx_CONST (Pmode, new);
3341
3342 new = legitimize_tls_address (new, reg);
3343 new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
3344 new = force_operand (new, 0);
3345 }
3346
3347 else
3348 gcc_unreachable (); /* for now ... */
3349
3350 return new;
3351 }
3352
3353 /* Emit insns to move operands[1] into operands[0]. */
3354
3355 void
emit_symbolic_move(rtx * operands)3356 emit_symbolic_move (rtx *operands)
3357 {
3358 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3359
3360 if (GET_CODE (operands[0]) == MEM)
3361 operands[1] = force_reg (Pmode, operands[1]);
3362 else if (TLS_SYMBOLIC_CONST (operands[1]))
3363 operands[1] = legitimize_tls_address (operands[1], temp);
3364 else if (flag_pic)
3365 operands[1] = legitimize_pic_address (operands[1], temp);
3366 }
3367
3368 /* Try machine-dependent ways of modifying an illegitimate address X
3369 to be legitimate. If we find one, return the new, valid address.
3370
3371 OLDX is the address as it was before break_out_memory_refs was called.
3372 In some cases it is useful to look at this to decide what needs to be done.
3373
3374 MODE is the mode of the operand pointed to by X.
3375
3376 When -fpic is used, special handling is needed for symbolic references.
3377 See comments by legitimize_pic_address for details. */
3378
3379 rtx
legitimize_address(rtx x,rtx oldx ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED)3380 legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3381 enum machine_mode mode ATTRIBUTE_UNUSED)
3382 {
3383 rtx constant_term = const0_rtx;
3384
3385 if (TLS_SYMBOLIC_CONST (x))
3386 {
3387 x = legitimize_tls_address (x, 0);
3388
3389 if (legitimate_address_p (mode, x, FALSE))
3390 return x;
3391 }
3392 else if (GET_CODE (x) == PLUS
3393 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
3394 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
3395 {
3396 return x;
3397 }
3398 else if (flag_pic)
3399 {
3400 if (SYMBOLIC_CONST (x)
3401 || (GET_CODE (x) == PLUS
3402 && (SYMBOLIC_CONST (XEXP (x, 0))
3403 || SYMBOLIC_CONST (XEXP (x, 1)))))
3404 x = legitimize_pic_address (x, 0);
3405
3406 if (legitimate_address_p (mode, x, FALSE))
3407 return x;
3408 }
3409
3410 x = eliminate_constant_term (x, &constant_term);
3411
3412 /* Optimize loading of large displacements by splitting them
3413 into the multiple of 4K and the rest; this allows the
3414 former to be CSE'd if possible.
3415
3416 Don't do this if the displacement is added to a register
3417 pointing into the stack frame, as the offsets will
3418 change later anyway. */
3419
3420 if (GET_CODE (constant_term) == CONST_INT
3421 && !TARGET_LONG_DISPLACEMENT
3422 && !DISP_IN_RANGE (INTVAL (constant_term))
3423 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3424 {
3425 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3426 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3427
3428 rtx temp = gen_reg_rtx (Pmode);
3429 rtx val = force_operand (GEN_INT (upper), temp);
3430 if (val != temp)
3431 emit_move_insn (temp, val);
3432
3433 x = gen_rtx_PLUS (Pmode, x, temp);
3434 constant_term = GEN_INT (lower);
3435 }
3436
3437 if (GET_CODE (x) == PLUS)
3438 {
3439 if (GET_CODE (XEXP (x, 0)) == REG)
3440 {
3441 rtx temp = gen_reg_rtx (Pmode);
3442 rtx val = force_operand (XEXP (x, 1), temp);
3443 if (val != temp)
3444 emit_move_insn (temp, val);
3445
3446 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3447 }
3448
3449 else if (GET_CODE (XEXP (x, 1)) == REG)
3450 {
3451 rtx temp = gen_reg_rtx (Pmode);
3452 rtx val = force_operand (XEXP (x, 0), temp);
3453 if (val != temp)
3454 emit_move_insn (temp, val);
3455
3456 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3457 }
3458 }
3459
3460 if (constant_term != const0_rtx)
3461 x = gen_rtx_PLUS (Pmode, x, constant_term);
3462
3463 return x;
3464 }
3465
3466 /* Try a machine-dependent way of reloading an illegitimate address AD
3467 operand. If we find one, push the reload and and return the new address.
3468
3469 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3470 and TYPE is the reload type of the current reload. */
3471
3472 rtx
legitimize_reload_address(rtx ad,enum machine_mode mode ATTRIBUTE_UNUSED,int opnum,int type)3473 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3474 int opnum, int type)
3475 {
3476 if (!optimize || TARGET_LONG_DISPLACEMENT)
3477 return NULL_RTX;
3478
3479 if (GET_CODE (ad) == PLUS)
3480 {
3481 rtx tem = simplify_binary_operation (PLUS, Pmode,
3482 XEXP (ad, 0), XEXP (ad, 1));
3483 if (tem)
3484 ad = tem;
3485 }
3486
3487 if (GET_CODE (ad) == PLUS
3488 && GET_CODE (XEXP (ad, 0)) == REG
3489 && GET_CODE (XEXP (ad, 1)) == CONST_INT
3490 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3491 {
3492 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3493 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3494 rtx cst, tem, new;
3495
3496 cst = GEN_INT (upper);
3497 if (!legitimate_reload_constant_p (cst))
3498 cst = force_const_mem (Pmode, cst);
3499
3500 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3501 new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3502
3503 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3504 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3505 opnum, (enum reload_type) type);
3506 return new;
3507 }
3508
3509 return NULL_RTX;
3510 }
3511
3512 /* Emit code to move LEN bytes from DST to SRC. */
3513
3514 void
s390_expand_movmem(rtx dst,rtx src,rtx len)3515 s390_expand_movmem (rtx dst, rtx src, rtx len)
3516 {
3517 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3518 {
3519 if (INTVAL (len) > 0)
3520 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3521 }
3522
3523 else if (TARGET_MVCLE)
3524 {
3525 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3526 }
3527
3528 else
3529 {
3530 rtx dst_addr, src_addr, count, blocks, temp;
3531 rtx loop_start_label = gen_label_rtx ();
3532 rtx loop_end_label = gen_label_rtx ();
3533 rtx end_label = gen_label_rtx ();
3534 enum machine_mode mode;
3535
3536 mode = GET_MODE (len);
3537 if (mode == VOIDmode)
3538 mode = Pmode;
3539
3540 dst_addr = gen_reg_rtx (Pmode);
3541 src_addr = gen_reg_rtx (Pmode);
3542 count = gen_reg_rtx (mode);
3543 blocks = gen_reg_rtx (mode);
3544
3545 convert_move (count, len, 1);
3546 emit_cmp_and_jump_insns (count, const0_rtx,
3547 EQ, NULL_RTX, mode, 1, end_label);
3548
3549 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3550 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3551 dst = change_address (dst, VOIDmode, dst_addr);
3552 src = change_address (src, VOIDmode, src_addr);
3553
3554 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3555 if (temp != count)
3556 emit_move_insn (count, temp);
3557
3558 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3559 if (temp != blocks)
3560 emit_move_insn (blocks, temp);
3561
3562 emit_cmp_and_jump_insns (blocks, const0_rtx,
3563 EQ, NULL_RTX, mode, 1, loop_end_label);
3564
3565 emit_label (loop_start_label);
3566
3567 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3568 s390_load_address (dst_addr,
3569 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3570 s390_load_address (src_addr,
3571 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3572
3573 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3574 if (temp != blocks)
3575 emit_move_insn (blocks, temp);
3576
3577 emit_cmp_and_jump_insns (blocks, const0_rtx,
3578 EQ, NULL_RTX, mode, 1, loop_end_label);
3579
3580 emit_jump (loop_start_label);
3581 emit_label (loop_end_label);
3582
3583 emit_insn (gen_movmem_short (dst, src,
3584 convert_to_mode (Pmode, count, 1)));
3585 emit_label (end_label);
3586 }
3587 }
3588
3589 /* Emit code to set LEN bytes at DST to VAL.
3590 Make use of clrmem if VAL is zero. */
3591
3592 void
s390_expand_setmem(rtx dst,rtx len,rtx val)3593 s390_expand_setmem (rtx dst, rtx len, rtx val)
3594 {
3595 if (GET_CODE (len) == CONST_INT && INTVAL (len) == 0)
3596 return;
3597
3598 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
3599
3600 if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
3601 {
3602 if (val == const0_rtx && INTVAL (len) <= 256)
3603 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3604 else
3605 {
3606 /* Initialize memory by storing the first byte. */
3607 emit_move_insn (adjust_address (dst, QImode, 0), val);
3608
3609 if (INTVAL (len) > 1)
3610 {
3611 /* Initiate 1 byte overlap move.
3612 The first byte of DST is propagated through DSTP1.
3613 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3614 DST is set to size 1 so the rest of the memory location
3615 does not count as source operand. */
3616 rtx dstp1 = adjust_address (dst, VOIDmode, 1);
3617 set_mem_size (dst, const1_rtx);
3618
3619 emit_insn (gen_movmem_short (dstp1, dst,
3620 GEN_INT (INTVAL (len) - 2)));
3621 }
3622 }
3623 }
3624
3625 else if (TARGET_MVCLE)
3626 {
3627 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
3628 emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
3629 }
3630
3631 else
3632 {
3633 rtx dst_addr, src_addr, count, blocks, temp, dstp1 = NULL_RTX;
3634 rtx loop_start_label = gen_label_rtx ();
3635 rtx loop_end_label = gen_label_rtx ();
3636 rtx end_label = gen_label_rtx ();
3637 enum machine_mode mode;
3638
3639 mode = GET_MODE (len);
3640 if (mode == VOIDmode)
3641 mode = Pmode;
3642
3643 dst_addr = gen_reg_rtx (Pmode);
3644 src_addr = gen_reg_rtx (Pmode);
3645 count = gen_reg_rtx (mode);
3646 blocks = gen_reg_rtx (mode);
3647
3648 convert_move (count, len, 1);
3649 emit_cmp_and_jump_insns (count, const0_rtx,
3650 EQ, NULL_RTX, mode, 1, end_label);
3651
3652 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3653 dst = change_address (dst, VOIDmode, dst_addr);
3654
3655 if (val == const0_rtx)
3656 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3657 else
3658 {
3659 dstp1 = adjust_address (dst, VOIDmode, 1);
3660 set_mem_size (dst, const1_rtx);
3661
3662 /* Initialize memory by storing the first byte. */
3663 emit_move_insn (adjust_address (dst, QImode, 0), val);
3664
3665 /* If count is 1 we are done. */
3666 emit_cmp_and_jump_insns (count, const1_rtx,
3667 EQ, NULL_RTX, mode, 1, end_label);
3668
3669 temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1, 0);
3670 }
3671 if (temp != count)
3672 emit_move_insn (count, temp);
3673
3674 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3675 if (temp != blocks)
3676 emit_move_insn (blocks, temp);
3677
3678 emit_cmp_and_jump_insns (blocks, const0_rtx,
3679 EQ, NULL_RTX, mode, 1, loop_end_label);
3680
3681 emit_label (loop_start_label);
3682
3683 if (val == const0_rtx)
3684 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3685 else
3686 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255)));
3687 s390_load_address (dst_addr,
3688 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3689
3690 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3691 if (temp != blocks)
3692 emit_move_insn (blocks, temp);
3693
3694 emit_cmp_and_jump_insns (blocks, const0_rtx,
3695 EQ, NULL_RTX, mode, 1, loop_end_label);
3696
3697 emit_jump (loop_start_label);
3698 emit_label (loop_end_label);
3699
3700 if (val == const0_rtx)
3701 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3702 else
3703 emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1)));
3704 emit_label (end_label);
3705 }
3706 }
3707
3708 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3709 and return the result in TARGET. */
3710
3711 void
s390_expand_cmpmem(rtx target,rtx op0,rtx op1,rtx len)3712 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3713 {
3714 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
3715 rtx tmp;
3716
3717 /* As the result of CMPINT is inverted compared to what we need,
3718 we have to swap the operands. */
3719 tmp = op0; op0 = op1; op1 = tmp;
3720
3721 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3722 {
3723 if (INTVAL (len) > 0)
3724 {
3725 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3726 emit_insn (gen_cmpint (target, ccreg));
3727 }
3728 else
3729 emit_move_insn (target, const0_rtx);
3730 }
3731 else if (TARGET_MVCLE)
3732 {
3733 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3734 emit_insn (gen_cmpint (target, ccreg));
3735 }
3736 else
3737 {
3738 rtx addr0, addr1, count, blocks, temp;
3739 rtx loop_start_label = gen_label_rtx ();
3740 rtx loop_end_label = gen_label_rtx ();
3741 rtx end_label = gen_label_rtx ();
3742 enum machine_mode mode;
3743
3744 mode = GET_MODE (len);
3745 if (mode == VOIDmode)
3746 mode = Pmode;
3747
3748 addr0 = gen_reg_rtx (Pmode);
3749 addr1 = gen_reg_rtx (Pmode);
3750 count = gen_reg_rtx (mode);
3751 blocks = gen_reg_rtx (mode);
3752
3753 convert_move (count, len, 1);
3754 emit_cmp_and_jump_insns (count, const0_rtx,
3755 EQ, NULL_RTX, mode, 1, end_label);
3756
3757 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3758 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3759 op0 = change_address (op0, VOIDmode, addr0);
3760 op1 = change_address (op1, VOIDmode, addr1);
3761
3762 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3763 if (temp != count)
3764 emit_move_insn (count, temp);
3765
3766 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3767 if (temp != blocks)
3768 emit_move_insn (blocks, temp);
3769
3770 emit_cmp_and_jump_insns (blocks, const0_rtx,
3771 EQ, NULL_RTX, mode, 1, loop_end_label);
3772
3773 emit_label (loop_start_label);
3774
3775 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3776 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3777 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3778 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3779 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3780 emit_jump_insn (temp);
3781
3782 s390_load_address (addr0,
3783 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3784 s390_load_address (addr1,
3785 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3786
3787 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3788 if (temp != blocks)
3789 emit_move_insn (blocks, temp);
3790
3791 emit_cmp_and_jump_insns (blocks, const0_rtx,
3792 EQ, NULL_RTX, mode, 1, loop_end_label);
3793
3794 emit_jump (loop_start_label);
3795 emit_label (loop_end_label);
3796
3797 emit_insn (gen_cmpmem_short (op0, op1,
3798 convert_to_mode (Pmode, count, 1)));
3799 emit_label (end_label);
3800
3801 emit_insn (gen_cmpint (target, ccreg));
3802 }
3803 }
3804
3805
3806 /* Expand conditional increment or decrement using alc/slb instructions.
3807 Should generate code setting DST to either SRC or SRC + INCREMENT,
3808 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3809 Returns true if successful, false otherwise.
3810
3811 That makes it possible to implement some if-constructs without jumps e.g.:
3812 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3813 unsigned int a, b, c;
3814 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3815 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3816 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3817 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3818
3819 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3820 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3821 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3822 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3823 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3824
3825 bool
s390_expand_addcc(enum rtx_code cmp_code,rtx cmp_op0,rtx cmp_op1,rtx dst,rtx src,rtx increment)3826 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3827 rtx dst, rtx src, rtx increment)
3828 {
3829 enum machine_mode cmp_mode;
3830 enum machine_mode cc_mode;
3831 rtx op_res;
3832 rtx insn;
3833 rtvec p;
3834 int ret;
3835
3836 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3837 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3838 cmp_mode = SImode;
3839 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3840 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3841 cmp_mode = DImode;
3842 else
3843 return false;
3844
3845 /* Try ADD LOGICAL WITH CARRY. */
3846 if (increment == const1_rtx)
3847 {
3848 /* Determine CC mode to use. */
3849 if (cmp_code == EQ || cmp_code == NE)
3850 {
3851 if (cmp_op1 != const0_rtx)
3852 {
3853 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3854 NULL_RTX, 0, OPTAB_WIDEN);
3855 cmp_op1 = const0_rtx;
3856 }
3857
3858 cmp_code = cmp_code == EQ ? LEU : GTU;
3859 }
3860
3861 if (cmp_code == LTU || cmp_code == LEU)
3862 {
3863 rtx tem = cmp_op0;
3864 cmp_op0 = cmp_op1;
3865 cmp_op1 = tem;
3866 cmp_code = swap_condition (cmp_code);
3867 }
3868
3869 switch (cmp_code)
3870 {
3871 case GTU:
3872 cc_mode = CCUmode;
3873 break;
3874
3875 case GEU:
3876 cc_mode = CCL3mode;
3877 break;
3878
3879 default:
3880 return false;
3881 }
3882
3883 /* Emit comparison instruction pattern. */
3884 if (!register_operand (cmp_op0, cmp_mode))
3885 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3886
3887 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3888 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3889 /* We use insn_invalid_p here to add clobbers if required. */
3890 ret = insn_invalid_p (emit_insn (insn));
3891 gcc_assert (!ret);
3892
3893 /* Emit ALC instruction pattern. */
3894 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3895 gen_rtx_REG (cc_mode, CC_REGNUM),
3896 const0_rtx);
3897
3898 if (src != const0_rtx)
3899 {
3900 if (!register_operand (src, GET_MODE (dst)))
3901 src = force_reg (GET_MODE (dst), src);
3902
3903 src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3904 op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3905 }
3906
3907 p = rtvec_alloc (2);
3908 RTVEC_ELT (p, 0) =
3909 gen_rtx_SET (VOIDmode, dst, op_res);
3910 RTVEC_ELT (p, 1) =
3911 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3912 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3913
3914 return true;
3915 }
3916
3917 /* Try SUBTRACT LOGICAL WITH BORROW. */
3918 if (increment == constm1_rtx)
3919 {
3920 /* Determine CC mode to use. */
3921 if (cmp_code == EQ || cmp_code == NE)
3922 {
3923 if (cmp_op1 != const0_rtx)
3924 {
3925 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3926 NULL_RTX, 0, OPTAB_WIDEN);
3927 cmp_op1 = const0_rtx;
3928 }
3929
3930 cmp_code = cmp_code == EQ ? LEU : GTU;
3931 }
3932
3933 if (cmp_code == GTU || cmp_code == GEU)
3934 {
3935 rtx tem = cmp_op0;
3936 cmp_op0 = cmp_op1;
3937 cmp_op1 = tem;
3938 cmp_code = swap_condition (cmp_code);
3939 }
3940
3941 switch (cmp_code)
3942 {
3943 case LEU:
3944 cc_mode = CCUmode;
3945 break;
3946
3947 case LTU:
3948 cc_mode = CCL3mode;
3949 break;
3950
3951 default:
3952 return false;
3953 }
3954
3955 /* Emit comparison instruction pattern. */
3956 if (!register_operand (cmp_op0, cmp_mode))
3957 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3958
3959 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3960 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3961 /* We use insn_invalid_p here to add clobbers if required. */
3962 ret = insn_invalid_p (emit_insn (insn));
3963 gcc_assert (!ret);
3964
3965 /* Emit SLB instruction pattern. */
3966 if (!register_operand (src, GET_MODE (dst)))
3967 src = force_reg (GET_MODE (dst), src);
3968
3969 op_res = gen_rtx_MINUS (GET_MODE (dst),
3970 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3971 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3972 gen_rtx_REG (cc_mode, CC_REGNUM),
3973 const0_rtx));
3974 p = rtvec_alloc (2);
3975 RTVEC_ELT (p, 0) =
3976 gen_rtx_SET (VOIDmode, dst, op_res);
3977 RTVEC_ELT (p, 1) =
3978 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3979 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3980
3981 return true;
3982 }
3983
3984 return false;
3985 }
3986
3987 /* Expand code for the insv template. Return true if successful, false else. */
3988
3989 bool
s390_expand_insv(rtx dest,rtx op1,rtx op2,rtx src)3990 s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
3991 {
3992 int bitsize = INTVAL (op1);
3993 int bitpos = INTVAL (op2);
3994
3995 /* We need byte alignment. */
3996 if (bitsize % BITS_PER_UNIT)
3997 return false;
3998
3999 if (bitpos == 0
4000 && memory_operand (dest, VOIDmode)
4001 && (register_operand (src, word_mode)
4002 || const_int_operand (src, VOIDmode)))
4003 {
4004 /* Emit standard pattern if possible. */
4005 enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT);
4006 if (GET_MODE_BITSIZE (mode) == bitsize)
4007 emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src));
4008
4009 /* (set (ze (mem)) (const_int)). */
4010 else if (const_int_operand (src, VOIDmode))
4011 {
4012 int size = bitsize / BITS_PER_UNIT;
4013 rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode,
4014 GET_MODE_SIZE (word_mode) - size);
4015
4016 dest = adjust_address (dest, BLKmode, 0);
4017 set_mem_size (dest, GEN_INT (size));
4018 s390_expand_movmem (dest, src_mem, GEN_INT (size));
4019 }
4020
4021 /* (set (ze (mem)) (reg)). */
4022 else if (register_operand (src, word_mode))
4023 {
4024 if (bitsize <= GET_MODE_BITSIZE (SImode))
4025 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
4026 const0_rtx), src);
4027 else
4028 {
4029 /* Emit st,stcmh sequence. */
4030 int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode);
4031 int size = stcmh_width / BITS_PER_UNIT;
4032
4033 emit_move_insn (adjust_address (dest, SImode, size),
4034 gen_lowpart (SImode, src));
4035 set_mem_size (dest, GEN_INT (size));
4036 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT
4037 (stcmh_width), const0_rtx),
4038 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT
4039 (GET_MODE_BITSIZE (SImode))));
4040 }
4041 }
4042 else
4043 return false;
4044
4045 return true;
4046 }
4047
4048 /* (set (ze (reg)) (const_int)). */
4049 if (TARGET_ZARCH
4050 && register_operand (dest, word_mode)
4051 && (bitpos % 16) == 0
4052 && (bitsize % 16) == 0
4053 && const_int_operand (src, VOIDmode))
4054 {
4055 HOST_WIDE_INT val = INTVAL (src);
4056 int regpos = bitpos + bitsize;
4057
4058 while (regpos > bitpos)
4059 {
4060 enum machine_mode putmode;
4061 int putsize;
4062
4063 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
4064 putmode = SImode;
4065 else
4066 putmode = HImode;
4067
4068 putsize = GET_MODE_BITSIZE (putmode);
4069 regpos -= putsize;
4070 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4071 GEN_INT (putsize),
4072 GEN_INT (regpos)),
4073 gen_int_mode (val, putmode));
4074 val >>= putsize;
4075 }
4076 gcc_assert (regpos == bitpos);
4077 return true;
4078 }
4079
4080 return false;
4081 }
4082
4083 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4084 register that holds VAL of mode MODE shifted by COUNT bits. */
4085
4086 static inline rtx
s390_expand_mask_and_shift(rtx val,enum machine_mode mode,rtx count)4087 s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
4088 {
4089 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
4090 NULL_RTX, 1, OPTAB_DIRECT);
4091 return expand_simple_binop (SImode, ASHIFT, val, count,
4092 NULL_RTX, 1, OPTAB_DIRECT);
4093 }
4094
4095 /* Structure to hold the initial parameters for a compare_and_swap operation
4096 in HImode and QImode. */
4097
4098 struct alignment_context
4099 {
4100 rtx memsi; /* SI aligned memory location. */
4101 rtx shift; /* Bit offset with regard to lsb. */
4102 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
4103 rtx modemaski; /* ~modemask */
4104 bool aligned; /* True if memory is aligned, false else. */
4105 };
4106
4107 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4108 structure AC for transparent simplifying, if the memory alignment is known
4109 to be at least 32bit. MEM is the memory location for the actual operation
4110 and MODE its mode. */
4111
4112 static void
init_alignment_context(struct alignment_context * ac,rtx mem,enum machine_mode mode)4113 init_alignment_context (struct alignment_context *ac, rtx mem,
4114 enum machine_mode mode)
4115 {
4116 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
4117 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
4118
4119 if (ac->aligned)
4120 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
4121 else
4122 {
4123 /* Alignment is unknown. */
4124 rtx byteoffset, addr, align;
4125
4126 /* Force the address into a register. */
4127 addr = force_reg (Pmode, XEXP (mem, 0));
4128
4129 /* Align it to SImode. */
4130 align = expand_simple_binop (Pmode, AND, addr,
4131 GEN_INT (-GET_MODE_SIZE (SImode)),
4132 NULL_RTX, 1, OPTAB_DIRECT);
4133 /* Generate MEM. */
4134 ac->memsi = gen_rtx_MEM (SImode, align);
4135 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
4136 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
4137 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
4138
4139 /* Calculate shiftcount. */
4140 byteoffset = expand_simple_binop (Pmode, AND, addr,
4141 GEN_INT (GET_MODE_SIZE (SImode) - 1),
4142 NULL_RTX, 1, OPTAB_DIRECT);
4143 /* As we already have some offset, evaluate the remaining distance. */
4144 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
4145 NULL_RTX, 1, OPTAB_DIRECT);
4146
4147 }
4148 /* Shift is the byte count, but we need the bitcount. */
4149 ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
4150 NULL_RTX, 1, OPTAB_DIRECT);
4151 /* Calculate masks. */
4152 ac->modemask = expand_simple_binop (SImode, ASHIFT,
4153 GEN_INT (GET_MODE_MASK (mode)), ac->shift,
4154 NULL_RTX, 1, OPTAB_DIRECT);
4155 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
4156 }
4157
4158 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4159 the memory location, CMP the old value to compare MEM with and NEW the value
4160 to set if CMP == MEM.
4161 CMP is never in memory for compare_and_swap_cc because
4162 expand_bool_compare_and_swap puts it into a register for later compare. */
4163
4164 void
s390_expand_cs_hqi(enum machine_mode mode,rtx target,rtx mem,rtx cmp,rtx new)4165 s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx new)
4166 {
4167 struct alignment_context ac;
4168 rtx cmpv, newv, val, resv, cc;
4169 rtx res = gen_reg_rtx (SImode);
4170 rtx csloop = gen_label_rtx ();
4171 rtx csend = gen_label_rtx ();
4172
4173 gcc_assert (register_operand (target, VOIDmode));
4174 gcc_assert (MEM_P (mem));
4175
4176 init_alignment_context (&ac, mem, mode);
4177
4178 /* Shift the values to the correct bit positions. */
4179 if (!(ac.aligned && MEM_P (cmp)))
4180 cmp = s390_expand_mask_and_shift (cmp, mode, ac.shift);
4181 if (!(ac.aligned && MEM_P (new)))
4182 new = s390_expand_mask_and_shift (new, mode, ac.shift);
4183
4184 /* Load full word. Subsequent loads are performed by CS. */
4185 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
4186 NULL_RTX, 1, OPTAB_DIRECT);
4187
4188 /* Start CS loop. */
4189 emit_label (csloop);
4190 /* val = "<mem>00..0<mem>"
4191 * cmp = "00..0<cmp>00..0"
4192 * new = "00..0<new>00..0"
4193 */
4194
4195 /* Patch cmp and new with val at correct position. */
4196 if (ac.aligned && MEM_P (cmp))
4197 {
4198 cmpv = force_reg (SImode, val);
4199 store_bit_field (cmpv, GET_MODE_BITSIZE (mode), 0, SImode, cmp);
4200 }
4201 else
4202 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
4203 NULL_RTX, 1, OPTAB_DIRECT));
4204 if (ac.aligned && MEM_P (new))
4205 {
4206 newv = force_reg (SImode, val);
4207 store_bit_field (newv, GET_MODE_BITSIZE (mode), 0, SImode, new);
4208 }
4209 else
4210 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new, val,
4211 NULL_RTX, 1, OPTAB_DIRECT));
4212
4213 /* Jump to end if we're done (likely?). */
4214 s390_emit_jump (csend, s390_emit_compare_and_swap (EQ, res, ac.memsi,
4215 cmpv, newv));
4216
4217 /* Check for changes outside mode. */
4218 resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
4219 NULL_RTX, 1, OPTAB_DIRECT);
4220 cc = s390_emit_compare (NE, resv, val);
4221 emit_move_insn (val, resv);
4222 /* Loop internal if so. */
4223 s390_emit_jump (csloop, cc);
4224
4225 emit_label (csend);
4226
4227 /* Return the correct part of the bitfield. */
4228 convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
4229 NULL_RTX, 1, OPTAB_DIRECT), 1);
4230 }
4231
4232 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4233 and VAL the value to play with. If AFTER is true then store the the value
4234 MEM holds after the operation, if AFTER is false then store the value MEM
4235 holds before the operation. If TARGET is zero then discard that value, else
4236 store it to TARGET. */
4237
4238 void
s390_expand_atomic(enum machine_mode mode,enum rtx_code code,rtx target,rtx mem,rtx val,bool after)4239 s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
4240 rtx target, rtx mem, rtx val, bool after)
4241 {
4242 struct alignment_context ac;
4243 rtx cmp;
4244 rtx new = gen_reg_rtx (SImode);
4245 rtx orig = gen_reg_rtx (SImode);
4246 rtx csloop = gen_label_rtx ();
4247
4248 gcc_assert (!target || register_operand (target, VOIDmode));
4249 gcc_assert (MEM_P (mem));
4250
4251 init_alignment_context (&ac, mem, mode);
4252
4253 /* Shift val to the correct bit positions.
4254 Preserve "icm", but prevent "ex icm". */
4255 if (!(ac.aligned && code == SET && MEM_P (val)))
4256 val = s390_expand_mask_and_shift (val, mode, ac.shift);
4257
4258 /* Further preparation insns. */
4259 if (code == PLUS || code == MINUS)
4260 emit_move_insn (orig, val);
4261 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
4262 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
4263 NULL_RTX, 1, OPTAB_DIRECT);
4264
4265 /* Load full word. Subsequent loads are performed by CS. */
4266 cmp = force_reg (SImode, ac.memsi);
4267
4268 /* Start CS loop. */
4269 emit_label (csloop);
4270 emit_move_insn (new, cmp);
4271
4272 /* Patch new with val at correct position. */
4273 switch (code)
4274 {
4275 case PLUS:
4276 case MINUS:
4277 val = expand_simple_binop (SImode, code, new, orig,
4278 NULL_RTX, 1, OPTAB_DIRECT);
4279 val = expand_simple_binop (SImode, AND, val, ac.modemask,
4280 NULL_RTX, 1, OPTAB_DIRECT);
4281 /* FALLTHRU */
4282 case SET:
4283 if (ac.aligned && MEM_P (val))
4284 store_bit_field (new, GET_MODE_BITSIZE (mode), 0, SImode, val);
4285 else
4286 {
4287 new = expand_simple_binop (SImode, AND, new, ac.modemaski,
4288 NULL_RTX, 1, OPTAB_DIRECT);
4289 new = expand_simple_binop (SImode, IOR, new, val,
4290 NULL_RTX, 1, OPTAB_DIRECT);
4291 }
4292 break;
4293 case AND:
4294 case IOR:
4295 case XOR:
4296 new = expand_simple_binop (SImode, code, new, val,
4297 NULL_RTX, 1, OPTAB_DIRECT);
4298 break;
4299 case MULT: /* NAND */
4300 new = expand_simple_binop (SImode, XOR, new, ac.modemask,
4301 NULL_RTX, 1, OPTAB_DIRECT);
4302 new = expand_simple_binop (SImode, AND, new, val,
4303 NULL_RTX, 1, OPTAB_DIRECT);
4304 break;
4305 default:
4306 gcc_unreachable ();
4307 }
4308
4309 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
4310 ac.memsi, cmp, new));
4311
4312 /* Return the correct part of the bitfield. */
4313 if (target)
4314 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
4315 after ? new : cmp, ac.shift,
4316 NULL_RTX, 1, OPTAB_DIRECT), 1);
4317 }
4318
4319 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4320 We need to emit DTP-relative relocations. */
4321
4322 static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
4323
4324 static void
s390_output_dwarf_dtprel(FILE * file,int size,rtx x)4325 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
4326 {
4327 switch (size)
4328 {
4329 case 4:
4330 fputs ("\t.long\t", file);
4331 break;
4332 case 8:
4333 fputs ("\t.quad\t", file);
4334 break;
4335 default:
4336 gcc_unreachable ();
4337 }
4338 output_addr_const (file, x);
4339 fputs ("@DTPOFF", file);
4340 }
4341
4342 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4343 /* Implement TARGET_MANGLE_FUNDAMENTAL_TYPE. */
4344
4345 static const char *
s390_mangle_fundamental_type(tree type)4346 s390_mangle_fundamental_type (tree type)
4347 {
4348 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
4349 && TARGET_LONG_DOUBLE_128)
4350 return "g";
4351
4352 /* For all other types, use normal C++ mangling. */
4353 return NULL;
4354 }
4355 #endif
4356
4357 /* In the name of slightly smaller debug output, and to cater to
4358 general assembler lossage, recognize various UNSPEC sequences
4359 and turn them back into a direct symbol reference. */
4360
4361 static rtx
s390_delegitimize_address(rtx orig_x)4362 s390_delegitimize_address (rtx orig_x)
4363 {
4364 rtx x = orig_x, y;
4365
4366 if (GET_CODE (x) != MEM)
4367 return orig_x;
4368
4369 x = XEXP (x, 0);
4370 if (GET_CODE (x) == PLUS
4371 && GET_CODE (XEXP (x, 1)) == CONST
4372 && GET_CODE (XEXP (x, 0)) == REG
4373 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
4374 {
4375 y = XEXP (XEXP (x, 1), 0);
4376 if (GET_CODE (y) == UNSPEC
4377 && XINT (y, 1) == UNSPEC_GOT)
4378 return XVECEXP (y, 0, 0);
4379 return orig_x;
4380 }
4381
4382 if (GET_CODE (x) == CONST)
4383 {
4384 y = XEXP (x, 0);
4385 if (GET_CODE (y) == UNSPEC
4386 && XINT (y, 1) == UNSPEC_GOTENT)
4387 return XVECEXP (y, 0, 0);
4388 return orig_x;
4389 }
4390
4391 return orig_x;
4392 }
4393
4394 /* Output operand OP to stdio stream FILE.
4395 OP is an address (register + offset) which is not used to address data;
4396 instead the rightmost bits are interpreted as the value. */
4397
4398 static void
print_shift_count_operand(FILE * file,rtx op)4399 print_shift_count_operand (FILE *file, rtx op)
4400 {
4401 HOST_WIDE_INT offset;
4402 rtx base;
4403
4404 /* Extract base register and offset. */
4405 if (!s390_decompose_shift_count (op, &base, &offset))
4406 gcc_unreachable ();
4407
4408 /* Sanity check. */
4409 if (base)
4410 {
4411 gcc_assert (GET_CODE (base) == REG);
4412 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
4413 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
4414 }
4415
4416 /* Offsets are constricted to twelve bits. */
4417 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
4418 if (base)
4419 fprintf (file, "(%s)", reg_names[REGNO (base)]);
4420 }
4421
4422 /* See 'get_some_local_dynamic_name'. */
4423
4424 static int
get_some_local_dynamic_name_1(rtx * px,void * data ATTRIBUTE_UNUSED)4425 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4426 {
4427 rtx x = *px;
4428
4429 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
4430 {
4431 x = get_pool_constant (x);
4432 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
4433 }
4434
4435 if (GET_CODE (x) == SYMBOL_REF
4436 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
4437 {
4438 cfun->machine->some_ld_name = XSTR (x, 0);
4439 return 1;
4440 }
4441
4442 return 0;
4443 }
4444
4445 /* Locate some local-dynamic symbol still in use by this function
4446 so that we can print its name in local-dynamic base patterns. */
4447
4448 static const char *
get_some_local_dynamic_name(void)4449 get_some_local_dynamic_name (void)
4450 {
4451 rtx insn;
4452
4453 if (cfun->machine->some_ld_name)
4454 return cfun->machine->some_ld_name;
4455
4456 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4457 if (INSN_P (insn)
4458 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4459 return cfun->machine->some_ld_name;
4460
4461 gcc_unreachable ();
4462 }
4463
4464 /* Output machine-dependent UNSPECs occurring in address constant X
4465 in assembler syntax to stdio stream FILE. Returns true if the
4466 constant X could be recognized, false otherwise. */
4467
4468 bool
s390_output_addr_const_extra(FILE * file,rtx x)4469 s390_output_addr_const_extra (FILE *file, rtx x)
4470 {
4471 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
4472 switch (XINT (x, 1))
4473 {
4474 case UNSPEC_GOTENT:
4475 output_addr_const (file, XVECEXP (x, 0, 0));
4476 fprintf (file, "@GOTENT");
4477 return true;
4478 case UNSPEC_GOT:
4479 output_addr_const (file, XVECEXP (x, 0, 0));
4480 fprintf (file, "@GOT");
4481 return true;
4482 case UNSPEC_GOTOFF:
4483 output_addr_const (file, XVECEXP (x, 0, 0));
4484 fprintf (file, "@GOTOFF");
4485 return true;
4486 case UNSPEC_PLT:
4487 output_addr_const (file, XVECEXP (x, 0, 0));
4488 fprintf (file, "@PLT");
4489 return true;
4490 case UNSPEC_PLTOFF:
4491 output_addr_const (file, XVECEXP (x, 0, 0));
4492 fprintf (file, "@PLTOFF");
4493 return true;
4494 case UNSPEC_TLSGD:
4495 output_addr_const (file, XVECEXP (x, 0, 0));
4496 fprintf (file, "@TLSGD");
4497 return true;
4498 case UNSPEC_TLSLDM:
4499 assemble_name (file, get_some_local_dynamic_name ());
4500 fprintf (file, "@TLSLDM");
4501 return true;
4502 case UNSPEC_DTPOFF:
4503 output_addr_const (file, XVECEXP (x, 0, 0));
4504 fprintf (file, "@DTPOFF");
4505 return true;
4506 case UNSPEC_NTPOFF:
4507 output_addr_const (file, XVECEXP (x, 0, 0));
4508 fprintf (file, "@NTPOFF");
4509 return true;
4510 case UNSPEC_GOTNTPOFF:
4511 output_addr_const (file, XVECEXP (x, 0, 0));
4512 fprintf (file, "@GOTNTPOFF");
4513 return true;
4514 case UNSPEC_INDNTPOFF:
4515 output_addr_const (file, XVECEXP (x, 0, 0));
4516 fprintf (file, "@INDNTPOFF");
4517 return true;
4518 }
4519
4520 return false;
4521 }
4522
4523 /* Output address operand ADDR in assembler syntax to
4524 stdio stream FILE. */
4525
4526 void
print_operand_address(FILE * file,rtx addr)4527 print_operand_address (FILE *file, rtx addr)
4528 {
4529 struct s390_address ad;
4530
4531 if (!s390_decompose_address (addr, &ad)
4532 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4533 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
4534 output_operand_lossage ("cannot decompose address");
4535
4536 if (ad.disp)
4537 output_addr_const (file, ad.disp);
4538 else
4539 fprintf (file, "0");
4540
4541 if (ad.base && ad.indx)
4542 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
4543 reg_names[REGNO (ad.base)]);
4544 else if (ad.base)
4545 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4546 }
4547
4548 /* Output operand X in assembler syntax to stdio stream FILE.
4549 CODE specified the format flag. The following format flags
4550 are recognized:
4551
4552 'C': print opcode suffix for branch condition.
4553 'D': print opcode suffix for inverse branch condition.
4554 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4555 'G': print the size of the operand in bytes.
4556 'O': print only the displacement of a memory reference.
4557 'R': print only the base register of a memory reference.
4558 'S': print S-type memory reference (base+displacement).
4559 'N': print the second word of a DImode operand.
4560 'M': print the second word of a TImode operand.
4561 'Y': print shift count operand.
4562
4563 'b': print integer X as if it's an unsigned byte.
4564 'x': print integer X as if it's an unsigned halfword.
4565 'h': print integer X as if it's a signed halfword.
4566 'i': print the first nonzero HImode part of X.
4567 'j': print the first HImode part unequal to -1 of X.
4568 'k': print the first nonzero SImode part of X.
4569 'm': print the first SImode part unequal to -1 of X.
4570 'o': print integer X as if it's an unsigned 32bit word. */
4571
4572 void
print_operand(FILE * file,rtx x,int code)4573 print_operand (FILE *file, rtx x, int code)
4574 {
4575 switch (code)
4576 {
4577 case 'C':
4578 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4579 return;
4580
4581 case 'D':
4582 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4583 return;
4584
4585 case 'J':
4586 if (GET_CODE (x) == SYMBOL_REF)
4587 {
4588 fprintf (file, "%s", ":tls_load:");
4589 output_addr_const (file, x);
4590 }
4591 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
4592 {
4593 fprintf (file, "%s", ":tls_gdcall:");
4594 output_addr_const (file, XVECEXP (x, 0, 0));
4595 }
4596 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
4597 {
4598 fprintf (file, "%s", ":tls_ldcall:");
4599 assemble_name (file, get_some_local_dynamic_name ());
4600 }
4601 else
4602 gcc_unreachable ();
4603 return;
4604
4605 case 'G':
4606 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
4607 return;
4608
4609 case 'O':
4610 {
4611 struct s390_address ad;
4612 int ret;
4613
4614 gcc_assert (GET_CODE (x) == MEM);
4615 ret = s390_decompose_address (XEXP (x, 0), &ad);
4616 gcc_assert (ret);
4617 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4618 gcc_assert (!ad.indx);
4619
4620 if (ad.disp)
4621 output_addr_const (file, ad.disp);
4622 else
4623 fprintf (file, "0");
4624 }
4625 return;
4626
4627 case 'R':
4628 {
4629 struct s390_address ad;
4630 int ret;
4631
4632 gcc_assert (GET_CODE (x) == MEM);
4633 ret = s390_decompose_address (XEXP (x, 0), &ad);
4634 gcc_assert (ret);
4635 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4636 gcc_assert (!ad.indx);
4637
4638 if (ad.base)
4639 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
4640 else
4641 fprintf (file, "0");
4642 }
4643 return;
4644
4645 case 'S':
4646 {
4647 struct s390_address ad;
4648 int ret;
4649
4650 gcc_assert (GET_CODE (x) == MEM);
4651 ret = s390_decompose_address (XEXP (x, 0), &ad);
4652 gcc_assert (ret);
4653 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4654 gcc_assert (!ad.indx);
4655
4656 if (ad.disp)
4657 output_addr_const (file, ad.disp);
4658 else
4659 fprintf (file, "0");
4660
4661 if (ad.base)
4662 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4663 }
4664 return;
4665
4666 case 'N':
4667 if (GET_CODE (x) == REG)
4668 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4669 else if (GET_CODE (x) == MEM)
4670 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
4671 else
4672 gcc_unreachable ();
4673 break;
4674
4675 case 'M':
4676 if (GET_CODE (x) == REG)
4677 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4678 else if (GET_CODE (x) == MEM)
4679 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
4680 else
4681 gcc_unreachable ();
4682 break;
4683
4684 case 'Y':
4685 print_shift_count_operand (file, x);
4686 return;
4687 }
4688
4689 switch (GET_CODE (x))
4690 {
4691 case REG:
4692 fprintf (file, "%s", reg_names[REGNO (x)]);
4693 break;
4694
4695 case MEM:
4696 output_address (XEXP (x, 0));
4697 break;
4698
4699 case CONST:
4700 case CODE_LABEL:
4701 case LABEL_REF:
4702 case SYMBOL_REF:
4703 output_addr_const (file, x);
4704 break;
4705
4706 case CONST_INT:
4707 if (code == 'b')
4708 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
4709 else if (code == 'x')
4710 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
4711 else if (code == 'h')
4712 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
4713 else if (code == 'i')
4714 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4715 s390_extract_part (x, HImode, 0));
4716 else if (code == 'j')
4717 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4718 s390_extract_part (x, HImode, -1));
4719 else if (code == 'k')
4720 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4721 s390_extract_part (x, SImode, 0));
4722 else if (code == 'm')
4723 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4724 s390_extract_part (x, SImode, -1));
4725 else if (code == 'o')
4726 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff);
4727 else
4728 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4729 break;
4730
4731 case CONST_DOUBLE:
4732 gcc_assert (GET_MODE (x) == VOIDmode);
4733 if (code == 'b')
4734 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
4735 else if (code == 'x')
4736 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
4737 else if (code == 'h')
4738 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
4739 else
4740 gcc_unreachable ();
4741 break;
4742
4743 default:
4744 fatal_insn ("UNKNOWN in print_operand !?", x);
4745 break;
4746 }
4747 }
4748
4749 /* Target hook for assembling integer objects. We need to define it
4750 here to work a round a bug in some versions of GAS, which couldn't
4751 handle values smaller than INT_MIN when printed in decimal. */
4752
4753 static bool
s390_assemble_integer(rtx x,unsigned int size,int aligned_p)4754 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
4755 {
4756 if (size == 8 && aligned_p
4757 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
4758 {
4759 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
4760 INTVAL (x));
4761 return true;
4762 }
4763 return default_assemble_integer (x, size, aligned_p);
4764 }
4765
4766 /* Returns true if register REGNO is used for forming
4767 a memory address in expression X. */
4768
4769 static bool
reg_used_in_mem_p(int regno,rtx x)4770 reg_used_in_mem_p (int regno, rtx x)
4771 {
4772 enum rtx_code code = GET_CODE (x);
4773 int i, j;
4774 const char *fmt;
4775
4776 if (code == MEM)
4777 {
4778 if (refers_to_regno_p (regno, regno+1,
4779 XEXP (x, 0), 0))
4780 return true;
4781 }
4782 else if (code == SET
4783 && GET_CODE (SET_DEST (x)) == PC)
4784 {
4785 if (refers_to_regno_p (regno, regno+1,
4786 SET_SRC (x), 0))
4787 return true;
4788 }
4789
4790 fmt = GET_RTX_FORMAT (code);
4791 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4792 {
4793 if (fmt[i] == 'e'
4794 && reg_used_in_mem_p (regno, XEXP (x, i)))
4795 return true;
4796
4797 else if (fmt[i] == 'E')
4798 for (j = 0; j < XVECLEN (x, i); j++)
4799 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4800 return true;
4801 }
4802 return false;
4803 }
4804
4805 /* Returns true if expression DEP_RTX sets an address register
4806 used by instruction INSN to address memory. */
4807
4808 static bool
addr_generation_dependency_p(rtx dep_rtx,rtx insn)4809 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4810 {
4811 rtx target, pat;
4812
4813 if (GET_CODE (dep_rtx) == INSN)
4814 dep_rtx = PATTERN (dep_rtx);
4815
4816 if (GET_CODE (dep_rtx) == SET)
4817 {
4818 target = SET_DEST (dep_rtx);
4819 if (GET_CODE (target) == STRICT_LOW_PART)
4820 target = XEXP (target, 0);
4821 while (GET_CODE (target) == SUBREG)
4822 target = SUBREG_REG (target);
4823
4824 if (GET_CODE (target) == REG)
4825 {
4826 int regno = REGNO (target);
4827
4828 if (s390_safe_attr_type (insn) == TYPE_LA)
4829 {
4830 pat = PATTERN (insn);
4831 if (GET_CODE (pat) == PARALLEL)
4832 {
4833 gcc_assert (XVECLEN (pat, 0) == 2);
4834 pat = XVECEXP (pat, 0, 0);
4835 }
4836 gcc_assert (GET_CODE (pat) == SET);
4837 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4838 }
4839 else if (get_attr_atype (insn) == ATYPE_AGEN)
4840 return reg_used_in_mem_p (regno, PATTERN (insn));
4841 }
4842 }
4843 return false;
4844 }
4845
4846 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4847
4848 int
s390_agen_dep_p(rtx dep_insn,rtx insn)4849 s390_agen_dep_p (rtx dep_insn, rtx insn)
4850 {
4851 rtx dep_rtx = PATTERN (dep_insn);
4852 int i;
4853
4854 if (GET_CODE (dep_rtx) == SET
4855 && addr_generation_dependency_p (dep_rtx, insn))
4856 return 1;
4857 else if (GET_CODE (dep_rtx) == PARALLEL)
4858 {
4859 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4860 {
4861 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4862 return 1;
4863 }
4864 }
4865 return 0;
4866 }
4867
4868 /* A C statement (sans semicolon) to update the integer scheduling priority
4869 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4870 reduce the priority to execute INSN later. Do not define this macro if
4871 you do not need to adjust the scheduling priorities of insns.
4872
4873 A STD instruction should be scheduled earlier,
4874 in order to use the bypass. */
4875
4876 static int
s390_adjust_priority(rtx insn ATTRIBUTE_UNUSED,int priority)4877 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4878 {
4879 if (! INSN_P (insn))
4880 return priority;
4881
4882 if (s390_tune != PROCESSOR_2084_Z990
4883 && s390_tune != PROCESSOR_2094_Z9_109)
4884 return priority;
4885
4886 switch (s390_safe_attr_type (insn))
4887 {
4888 case TYPE_FSTOREDF:
4889 case TYPE_FSTORESF:
4890 priority = priority << 3;
4891 break;
4892 case TYPE_STORE:
4893 case TYPE_STM:
4894 priority = priority << 1;
4895 break;
4896 default:
4897 break;
4898 }
4899 return priority;
4900 }
4901
4902 /* The number of instructions that can be issued per cycle. */
4903
4904 static int
s390_issue_rate(void)4905 s390_issue_rate (void)
4906 {
4907 if (s390_tune == PROCESSOR_2084_Z990
4908 || s390_tune == PROCESSOR_2094_Z9_109)
4909 return 3;
4910 return 1;
4911 }
4912
4913 static int
s390_first_cycle_multipass_dfa_lookahead(void)4914 s390_first_cycle_multipass_dfa_lookahead (void)
4915 {
4916 return 4;
4917 }
4918
4919
4920 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4921 Fix up MEMs as required. */
4922
4923 static void
annotate_constant_pool_refs(rtx * x)4924 annotate_constant_pool_refs (rtx *x)
4925 {
4926 int i, j;
4927 const char *fmt;
4928
4929 gcc_assert (GET_CODE (*x) != SYMBOL_REF
4930 || !CONSTANT_POOL_ADDRESS_P (*x));
4931
4932 /* Literal pool references can only occur inside a MEM ... */
4933 if (GET_CODE (*x) == MEM)
4934 {
4935 rtx memref = XEXP (*x, 0);
4936
4937 if (GET_CODE (memref) == SYMBOL_REF
4938 && CONSTANT_POOL_ADDRESS_P (memref))
4939 {
4940 rtx base = cfun->machine->base_reg;
4941 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4942 UNSPEC_LTREF);
4943
4944 *x = replace_equiv_address (*x, addr);
4945 return;
4946 }
4947
4948 if (GET_CODE (memref) == CONST
4949 && GET_CODE (XEXP (memref, 0)) == PLUS
4950 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4951 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4952 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4953 {
4954 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4955 rtx sym = XEXP (XEXP (memref, 0), 0);
4956 rtx base = cfun->machine->base_reg;
4957 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4958 UNSPEC_LTREF);
4959
4960 *x = replace_equiv_address (*x, plus_constant (addr, off));
4961 return;
4962 }
4963 }
4964
4965 /* ... or a load-address type pattern. */
4966 if (GET_CODE (*x) == SET)
4967 {
4968 rtx addrref = SET_SRC (*x);
4969
4970 if (GET_CODE (addrref) == SYMBOL_REF
4971 && CONSTANT_POOL_ADDRESS_P (addrref))
4972 {
4973 rtx base = cfun->machine->base_reg;
4974 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4975 UNSPEC_LTREF);
4976
4977 SET_SRC (*x) = addr;
4978 return;
4979 }
4980
4981 if (GET_CODE (addrref) == CONST
4982 && GET_CODE (XEXP (addrref, 0)) == PLUS
4983 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4984 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4985 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4986 {
4987 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4988 rtx sym = XEXP (XEXP (addrref, 0), 0);
4989 rtx base = cfun->machine->base_reg;
4990 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4991 UNSPEC_LTREF);
4992
4993 SET_SRC (*x) = plus_constant (addr, off);
4994 return;
4995 }
4996 }
4997
4998 /* Annotate LTREL_BASE as well. */
4999 if (GET_CODE (*x) == UNSPEC
5000 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5001 {
5002 rtx base = cfun->machine->base_reg;
5003 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
5004 UNSPEC_LTREL_BASE);
5005 return;
5006 }
5007
5008 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5009 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5010 {
5011 if (fmt[i] == 'e')
5012 {
5013 annotate_constant_pool_refs (&XEXP (*x, i));
5014 }
5015 else if (fmt[i] == 'E')
5016 {
5017 for (j = 0; j < XVECLEN (*x, i); j++)
5018 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
5019 }
5020 }
5021 }
5022
5023 /* Split all branches that exceed the maximum distance.
5024 Returns true if this created a new literal pool entry. */
5025
5026 static int
s390_split_branches(void)5027 s390_split_branches (void)
5028 {
5029 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5030 int new_literal = 0, ret;
5031 rtx insn, pat, tmp, target;
5032 rtx *label;
5033
5034 /* We need correct insn addresses. */
5035
5036 shorten_branches (get_insns ());
5037
5038 /* Find all branches that exceed 64KB, and split them. */
5039
5040 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5041 {
5042 if (GET_CODE (insn) != JUMP_INSN)
5043 continue;
5044
5045 pat = PATTERN (insn);
5046 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5047 pat = XVECEXP (pat, 0, 0);
5048 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
5049 continue;
5050
5051 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
5052 {
5053 label = &SET_SRC (pat);
5054 }
5055 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
5056 {
5057 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
5058 label = &XEXP (SET_SRC (pat), 1);
5059 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
5060 label = &XEXP (SET_SRC (pat), 2);
5061 else
5062 continue;
5063 }
5064 else
5065 continue;
5066
5067 if (get_attr_length (insn) <= 4)
5068 continue;
5069
5070 /* We are going to use the return register as scratch register,
5071 make sure it will be saved/restored by the prologue/epilogue. */
5072 cfun_frame_layout.save_return_addr_p = 1;
5073
5074 if (!flag_pic)
5075 {
5076 new_literal = 1;
5077 tmp = force_const_mem (Pmode, *label);
5078 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
5079 INSN_ADDRESSES_NEW (tmp, -1);
5080 annotate_constant_pool_refs (&PATTERN (tmp));
5081
5082 target = temp_reg;
5083 }
5084 else
5085 {
5086 new_literal = 1;
5087 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
5088 UNSPEC_LTREL_OFFSET);
5089 target = gen_rtx_CONST (Pmode, target);
5090 target = force_const_mem (Pmode, target);
5091 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
5092 INSN_ADDRESSES_NEW (tmp, -1);
5093 annotate_constant_pool_refs (&PATTERN (tmp));
5094
5095 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
5096 cfun->machine->base_reg),
5097 UNSPEC_LTREL_BASE);
5098 target = gen_rtx_PLUS (Pmode, temp_reg, target);
5099 }
5100
5101 ret = validate_change (insn, label, target, 0);
5102 gcc_assert (ret);
5103 }
5104
5105 return new_literal;
5106 }
5107
5108
5109 /* Find an annotated literal pool symbol referenced in RTX X,
5110 and store it at REF. Will abort if X contains references to
5111 more than one such pool symbol; multiple references to the same
5112 symbol are allowed, however.
5113
5114 The rtx pointed to by REF must be initialized to NULL_RTX
5115 by the caller before calling this routine. */
5116
5117 static void
find_constant_pool_ref(rtx x,rtx * ref)5118 find_constant_pool_ref (rtx x, rtx *ref)
5119 {
5120 int i, j;
5121 const char *fmt;
5122
5123 /* Ignore LTREL_BASE references. */
5124 if (GET_CODE (x) == UNSPEC
5125 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5126 return;
5127 /* Likewise POOL_ENTRY insns. */
5128 if (GET_CODE (x) == UNSPEC_VOLATILE
5129 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
5130 return;
5131
5132 gcc_assert (GET_CODE (x) != SYMBOL_REF
5133 || !CONSTANT_POOL_ADDRESS_P (x));
5134
5135 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
5136 {
5137 rtx sym = XVECEXP (x, 0, 0);
5138 gcc_assert (GET_CODE (sym) == SYMBOL_REF
5139 && CONSTANT_POOL_ADDRESS_P (sym));
5140
5141 if (*ref == NULL_RTX)
5142 *ref = sym;
5143 else
5144 gcc_assert (*ref == sym);
5145
5146 return;
5147 }
5148
5149 fmt = GET_RTX_FORMAT (GET_CODE (x));
5150 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5151 {
5152 if (fmt[i] == 'e')
5153 {
5154 find_constant_pool_ref (XEXP (x, i), ref);
5155 }
5156 else if (fmt[i] == 'E')
5157 {
5158 for (j = 0; j < XVECLEN (x, i); j++)
5159 find_constant_pool_ref (XVECEXP (x, i, j), ref);
5160 }
5161 }
5162 }
5163
5164 /* Replace every reference to the annotated literal pool
5165 symbol REF in X by its base plus OFFSET. */
5166
5167 static void
replace_constant_pool_ref(rtx * x,rtx ref,rtx offset)5168 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
5169 {
5170 int i, j;
5171 const char *fmt;
5172
5173 gcc_assert (*x != ref);
5174
5175 if (GET_CODE (*x) == UNSPEC
5176 && XINT (*x, 1) == UNSPEC_LTREF
5177 && XVECEXP (*x, 0, 0) == ref)
5178 {
5179 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
5180 return;
5181 }
5182
5183 if (GET_CODE (*x) == PLUS
5184 && GET_CODE (XEXP (*x, 1)) == CONST_INT
5185 && GET_CODE (XEXP (*x, 0)) == UNSPEC
5186 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
5187 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
5188 {
5189 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
5190 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
5191 return;
5192 }
5193
5194 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5195 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5196 {
5197 if (fmt[i] == 'e')
5198 {
5199 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
5200 }
5201 else if (fmt[i] == 'E')
5202 {
5203 for (j = 0; j < XVECLEN (*x, i); j++)
5204 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
5205 }
5206 }
5207 }
5208
5209 /* Check whether X contains an UNSPEC_LTREL_BASE.
5210 Return its constant pool symbol if found, NULL_RTX otherwise. */
5211
5212 static rtx
find_ltrel_base(rtx x)5213 find_ltrel_base (rtx x)
5214 {
5215 int i, j;
5216 const char *fmt;
5217
5218 if (GET_CODE (x) == UNSPEC
5219 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5220 return XVECEXP (x, 0, 0);
5221
5222 fmt = GET_RTX_FORMAT (GET_CODE (x));
5223 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5224 {
5225 if (fmt[i] == 'e')
5226 {
5227 rtx fnd = find_ltrel_base (XEXP (x, i));
5228 if (fnd)
5229 return fnd;
5230 }
5231 else if (fmt[i] == 'E')
5232 {
5233 for (j = 0; j < XVECLEN (x, i); j++)
5234 {
5235 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
5236 if (fnd)
5237 return fnd;
5238 }
5239 }
5240 }
5241
5242 return NULL_RTX;
5243 }
5244
5245 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5246
5247 static void
replace_ltrel_base(rtx * x)5248 replace_ltrel_base (rtx *x)
5249 {
5250 int i, j;
5251 const char *fmt;
5252
5253 if (GET_CODE (*x) == UNSPEC
5254 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5255 {
5256 *x = XVECEXP (*x, 0, 1);
5257 return;
5258 }
5259
5260 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5261 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5262 {
5263 if (fmt[i] == 'e')
5264 {
5265 replace_ltrel_base (&XEXP (*x, i));
5266 }
5267 else if (fmt[i] == 'E')
5268 {
5269 for (j = 0; j < XVECLEN (*x, i); j++)
5270 replace_ltrel_base (&XVECEXP (*x, i, j));
5271 }
5272 }
5273 }
5274
5275
5276 /* We keep a list of constants which we have to add to internal
5277 constant tables in the middle of large functions. */
5278
5279 #define NR_C_MODES 11
5280 enum machine_mode constant_modes[NR_C_MODES] =
5281 {
5282 TFmode, TImode, TDmode,
5283 DFmode, DImode, DDmode,
5284 SFmode, SImode, SDmode,
5285 HImode,
5286 QImode
5287 };
5288
5289 struct constant
5290 {
5291 struct constant *next;
5292 rtx value;
5293 rtx label;
5294 };
5295
5296 struct constant_pool
5297 {
5298 struct constant_pool *next;
5299 rtx first_insn;
5300 rtx pool_insn;
5301 bitmap insns;
5302
5303 struct constant *constants[NR_C_MODES];
5304 struct constant *execute;
5305 rtx label;
5306 int size;
5307 };
5308
5309 /* Allocate new constant_pool structure. */
5310
5311 static struct constant_pool *
s390_alloc_pool(void)5312 s390_alloc_pool (void)
5313 {
5314 struct constant_pool *pool;
5315 int i;
5316
5317 pool = (struct constant_pool *) xmalloc (sizeof *pool);
5318 pool->next = NULL;
5319 for (i = 0; i < NR_C_MODES; i++)
5320 pool->constants[i] = NULL;
5321
5322 pool->execute = NULL;
5323 pool->label = gen_label_rtx ();
5324 pool->first_insn = NULL_RTX;
5325 pool->pool_insn = NULL_RTX;
5326 pool->insns = BITMAP_ALLOC (NULL);
5327 pool->size = 0;
5328
5329 return pool;
5330 }
5331
5332 /* Create new constant pool covering instructions starting at INSN
5333 and chain it to the end of POOL_LIST. */
5334
5335 static struct constant_pool *
s390_start_pool(struct constant_pool ** pool_list,rtx insn)5336 s390_start_pool (struct constant_pool **pool_list, rtx insn)
5337 {
5338 struct constant_pool *pool, **prev;
5339
5340 pool = s390_alloc_pool ();
5341 pool->first_insn = insn;
5342
5343 for (prev = pool_list; *prev; prev = &(*prev)->next)
5344 ;
5345 *prev = pool;
5346
5347 return pool;
5348 }
5349
5350 /* End range of instructions covered by POOL at INSN and emit
5351 placeholder insn representing the pool. */
5352
5353 static void
s390_end_pool(struct constant_pool * pool,rtx insn)5354 s390_end_pool (struct constant_pool *pool, rtx insn)
5355 {
5356 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
5357
5358 if (!insn)
5359 insn = get_last_insn ();
5360
5361 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
5362 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5363 }
5364
5365 /* Add INSN to the list of insns covered by POOL. */
5366
5367 static void
s390_add_pool_insn(struct constant_pool * pool,rtx insn)5368 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
5369 {
5370 bitmap_set_bit (pool->insns, INSN_UID (insn));
5371 }
5372
5373 /* Return pool out of POOL_LIST that covers INSN. */
5374
5375 static struct constant_pool *
s390_find_pool(struct constant_pool * pool_list,rtx insn)5376 s390_find_pool (struct constant_pool *pool_list, rtx insn)
5377 {
5378 struct constant_pool *pool;
5379
5380 for (pool = pool_list; pool; pool = pool->next)
5381 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
5382 break;
5383
5384 return pool;
5385 }
5386
5387 /* Add constant VAL of mode MODE to the constant pool POOL. */
5388
5389 static void
s390_add_constant(struct constant_pool * pool,rtx val,enum machine_mode mode)5390 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
5391 {
5392 struct constant *c;
5393 int i;
5394
5395 for (i = 0; i < NR_C_MODES; i++)
5396 if (constant_modes[i] == mode)
5397 break;
5398 gcc_assert (i != NR_C_MODES);
5399
5400 for (c = pool->constants[i]; c != NULL; c = c->next)
5401 if (rtx_equal_p (val, c->value))
5402 break;
5403
5404 if (c == NULL)
5405 {
5406 c = (struct constant *) xmalloc (sizeof *c);
5407 c->value = val;
5408 c->label = gen_label_rtx ();
5409 c->next = pool->constants[i];
5410 pool->constants[i] = c;
5411 pool->size += GET_MODE_SIZE (mode);
5412 }
5413 }
5414
5415 /* Find constant VAL of mode MODE in the constant pool POOL.
5416 Return an RTX describing the distance from the start of
5417 the pool to the location of the new constant. */
5418
5419 static rtx
s390_find_constant(struct constant_pool * pool,rtx val,enum machine_mode mode)5420 s390_find_constant (struct constant_pool *pool, rtx val,
5421 enum machine_mode mode)
5422 {
5423 struct constant *c;
5424 rtx offset;
5425 int i;
5426
5427 for (i = 0; i < NR_C_MODES; i++)
5428 if (constant_modes[i] == mode)
5429 break;
5430 gcc_assert (i != NR_C_MODES);
5431
5432 for (c = pool->constants[i]; c != NULL; c = c->next)
5433 if (rtx_equal_p (val, c->value))
5434 break;
5435
5436 gcc_assert (c);
5437
5438 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5439 gen_rtx_LABEL_REF (Pmode, pool->label));
5440 offset = gen_rtx_CONST (Pmode, offset);
5441 return offset;
5442 }
5443
5444 /* Check whether INSN is an execute. Return the label_ref to its
5445 execute target template if so, NULL_RTX otherwise. */
5446
5447 static rtx
s390_execute_label(rtx insn)5448 s390_execute_label (rtx insn)
5449 {
5450 if (GET_CODE (insn) == INSN
5451 && GET_CODE (PATTERN (insn)) == PARALLEL
5452 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
5453 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
5454 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
5455
5456 return NULL_RTX;
5457 }
5458
5459 /* Add execute target for INSN to the constant pool POOL. */
5460
5461 static void
s390_add_execute(struct constant_pool * pool,rtx insn)5462 s390_add_execute (struct constant_pool *pool, rtx insn)
5463 {
5464 struct constant *c;
5465
5466 for (c = pool->execute; c != NULL; c = c->next)
5467 if (INSN_UID (insn) == INSN_UID (c->value))
5468 break;
5469
5470 if (c == NULL)
5471 {
5472 c = (struct constant *) xmalloc (sizeof *c);
5473 c->value = insn;
5474 c->label = gen_label_rtx ();
5475 c->next = pool->execute;
5476 pool->execute = c;
5477 pool->size += 6;
5478 }
5479 }
5480
5481 /* Find execute target for INSN in the constant pool POOL.
5482 Return an RTX describing the distance from the start of
5483 the pool to the location of the execute target. */
5484
5485 static rtx
s390_find_execute(struct constant_pool * pool,rtx insn)5486 s390_find_execute (struct constant_pool *pool, rtx insn)
5487 {
5488 struct constant *c;
5489 rtx offset;
5490
5491 for (c = pool->execute; c != NULL; c = c->next)
5492 if (INSN_UID (insn) == INSN_UID (c->value))
5493 break;
5494
5495 gcc_assert (c);
5496
5497 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5498 gen_rtx_LABEL_REF (Pmode, pool->label));
5499 offset = gen_rtx_CONST (Pmode, offset);
5500 return offset;
5501 }
5502
5503 /* For an execute INSN, extract the execute target template. */
5504
5505 static rtx
s390_execute_target(rtx insn)5506 s390_execute_target (rtx insn)
5507 {
5508 rtx pattern = PATTERN (insn);
5509 gcc_assert (s390_execute_label (insn));
5510
5511 if (XVECLEN (pattern, 0) == 2)
5512 {
5513 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
5514 }
5515 else
5516 {
5517 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
5518 int i;
5519
5520 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
5521 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
5522
5523 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
5524 }
5525
5526 return pattern;
5527 }
5528
5529 /* Indicate that INSN cannot be duplicated. This is the case for
5530 execute insns that carry a unique label. */
5531
5532 static bool
s390_cannot_copy_insn_p(rtx insn)5533 s390_cannot_copy_insn_p (rtx insn)
5534 {
5535 rtx label = s390_execute_label (insn);
5536 return label && label != const0_rtx;
5537 }
5538
5539 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5540 do not emit the pool base label. */
5541
5542 static void
s390_dump_pool(struct constant_pool * pool,bool remote_label)5543 s390_dump_pool (struct constant_pool *pool, bool remote_label)
5544 {
5545 struct constant *c;
5546 rtx insn = pool->pool_insn;
5547 int i;
5548
5549 /* Switch to rodata section. */
5550 if (TARGET_CPU_ZARCH)
5551 {
5552 insn = emit_insn_after (gen_pool_section_start (), insn);
5553 INSN_ADDRESSES_NEW (insn, -1);
5554 }
5555
5556 /* Ensure minimum pool alignment. */
5557 if (TARGET_CPU_ZARCH)
5558 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
5559 else
5560 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
5561 INSN_ADDRESSES_NEW (insn, -1);
5562
5563 /* Emit pool base label. */
5564 if (!remote_label)
5565 {
5566 insn = emit_label_after (pool->label, insn);
5567 INSN_ADDRESSES_NEW (insn, -1);
5568 }
5569
5570 /* Dump constants in descending alignment requirement order,
5571 ensuring proper alignment for every constant. */
5572 for (i = 0; i < NR_C_MODES; i++)
5573 for (c = pool->constants[i]; c; c = c->next)
5574 {
5575 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5576 rtx value = c->value;
5577 if (GET_CODE (value) == CONST
5578 && GET_CODE (XEXP (value, 0)) == UNSPEC
5579 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
5580 && XVECLEN (XEXP (value, 0), 0) == 1)
5581 {
5582 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
5583 gen_rtx_LABEL_REF (VOIDmode, pool->label));
5584 value = gen_rtx_CONST (VOIDmode, value);
5585 }
5586
5587 insn = emit_label_after (c->label, insn);
5588 INSN_ADDRESSES_NEW (insn, -1);
5589
5590 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
5591 gen_rtvec (1, value),
5592 UNSPECV_POOL_ENTRY);
5593 insn = emit_insn_after (value, insn);
5594 INSN_ADDRESSES_NEW (insn, -1);
5595 }
5596
5597 /* Ensure minimum alignment for instructions. */
5598 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
5599 INSN_ADDRESSES_NEW (insn, -1);
5600
5601 /* Output in-pool execute template insns. */
5602 for (c = pool->execute; c; c = c->next)
5603 {
5604 insn = emit_label_after (c->label, insn);
5605 INSN_ADDRESSES_NEW (insn, -1);
5606
5607 insn = emit_insn_after (s390_execute_target (c->value), insn);
5608 INSN_ADDRESSES_NEW (insn, -1);
5609 }
5610
5611 /* Switch back to previous section. */
5612 if (TARGET_CPU_ZARCH)
5613 {
5614 insn = emit_insn_after (gen_pool_section_end (), insn);
5615 INSN_ADDRESSES_NEW (insn, -1);
5616 }
5617
5618 insn = emit_barrier_after (insn);
5619 INSN_ADDRESSES_NEW (insn, -1);
5620
5621 /* Remove placeholder insn. */
5622 remove_insn (pool->pool_insn);
5623 }
5624
5625 /* Free all memory used by POOL. */
5626
5627 static void
s390_free_pool(struct constant_pool * pool)5628 s390_free_pool (struct constant_pool *pool)
5629 {
5630 struct constant *c, *next;
5631 int i;
5632
5633 for (i = 0; i < NR_C_MODES; i++)
5634 for (c = pool->constants[i]; c; c = next)
5635 {
5636 next = c->next;
5637 free (c);
5638 }
5639
5640 for (c = pool->execute; c; c = next)
5641 {
5642 next = c->next;
5643 free (c);
5644 }
5645
5646 BITMAP_FREE (pool->insns);
5647 free (pool);
5648 }
5649
5650
5651 /* Collect main literal pool. Return NULL on overflow. */
5652
5653 static struct constant_pool *
s390_mainpool_start(void)5654 s390_mainpool_start (void)
5655 {
5656 struct constant_pool *pool;
5657 rtx insn;
5658
5659 pool = s390_alloc_pool ();
5660
5661 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5662 {
5663 if (GET_CODE (insn) == INSN
5664 && GET_CODE (PATTERN (insn)) == SET
5665 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
5666 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
5667 {
5668 gcc_assert (!pool->pool_insn);
5669 pool->pool_insn = insn;
5670 }
5671
5672 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5673 {
5674 s390_add_execute (pool, insn);
5675 }
5676 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5677 {
5678 rtx pool_ref = NULL_RTX;
5679 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5680 if (pool_ref)
5681 {
5682 rtx constant = get_pool_constant (pool_ref);
5683 enum machine_mode mode = get_pool_mode (pool_ref);
5684 s390_add_constant (pool, constant, mode);
5685 }
5686 }
5687 }
5688
5689 gcc_assert (pool->pool_insn || pool->size == 0);
5690
5691 if (pool->size >= 4096)
5692 {
5693 /* We're going to chunkify the pool, so remove the main
5694 pool placeholder insn. */
5695 remove_insn (pool->pool_insn);
5696
5697 s390_free_pool (pool);
5698 pool = NULL;
5699 }
5700
5701 return pool;
5702 }
5703
5704 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5705 Modify the current function to output the pool constants as well as
5706 the pool register setup instruction. */
5707
5708 static void
s390_mainpool_finish(struct constant_pool * pool)5709 s390_mainpool_finish (struct constant_pool *pool)
5710 {
5711 rtx base_reg = cfun->machine->base_reg;
5712 rtx insn;
5713
5714 /* If the pool is empty, we're done. */
5715 if (pool->size == 0)
5716 {
5717 /* We don't actually need a base register after all. */
5718 cfun->machine->base_reg = NULL_RTX;
5719
5720 if (pool->pool_insn)
5721 remove_insn (pool->pool_insn);
5722 s390_free_pool (pool);
5723 return;
5724 }
5725
5726 /* We need correct insn addresses. */
5727 shorten_branches (get_insns ());
5728
5729 /* On zSeries, we use a LARL to load the pool register. The pool is
5730 located in the .rodata section, so we emit it after the function. */
5731 if (TARGET_CPU_ZARCH)
5732 {
5733 insn = gen_main_base_64 (base_reg, pool->label);
5734 insn = emit_insn_after (insn, pool->pool_insn);
5735 INSN_ADDRESSES_NEW (insn, -1);
5736 remove_insn (pool->pool_insn);
5737
5738 insn = get_last_insn ();
5739 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5740 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5741
5742 s390_dump_pool (pool, 0);
5743 }
5744
5745 /* On S/390, if the total size of the function's code plus literal pool
5746 does not exceed 4096 bytes, we use BASR to set up a function base
5747 pointer, and emit the literal pool at the end of the function. */
5748 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5749 + pool->size + 8 /* alignment slop */ < 4096)
5750 {
5751 insn = gen_main_base_31_small (base_reg, pool->label);
5752 insn = emit_insn_after (insn, pool->pool_insn);
5753 INSN_ADDRESSES_NEW (insn, -1);
5754 remove_insn (pool->pool_insn);
5755
5756 insn = emit_label_after (pool->label, insn);
5757 INSN_ADDRESSES_NEW (insn, -1);
5758
5759 insn = get_last_insn ();
5760 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5761 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5762
5763 s390_dump_pool (pool, 1);
5764 }
5765
5766 /* Otherwise, we emit an inline literal pool and use BASR to branch
5767 over it, setting up the pool register at the same time. */
5768 else
5769 {
5770 rtx pool_end = gen_label_rtx ();
5771
5772 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
5773 insn = emit_insn_after (insn, pool->pool_insn);
5774 INSN_ADDRESSES_NEW (insn, -1);
5775 remove_insn (pool->pool_insn);
5776
5777 insn = emit_label_after (pool->label, insn);
5778 INSN_ADDRESSES_NEW (insn, -1);
5779
5780 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5781 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5782
5783 insn = emit_label_after (pool_end, pool->pool_insn);
5784 INSN_ADDRESSES_NEW (insn, -1);
5785
5786 s390_dump_pool (pool, 1);
5787 }
5788
5789
5790 /* Replace all literal pool references. */
5791
5792 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5793 {
5794 if (INSN_P (insn))
5795 replace_ltrel_base (&PATTERN (insn));
5796
5797 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5798 {
5799 rtx addr, pool_ref = NULL_RTX;
5800 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5801 if (pool_ref)
5802 {
5803 if (s390_execute_label (insn))
5804 addr = s390_find_execute (pool, insn);
5805 else
5806 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
5807 get_pool_mode (pool_ref));
5808
5809 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5810 INSN_CODE (insn) = -1;
5811 }
5812 }
5813 }
5814
5815
5816 /* Free the pool. */
5817 s390_free_pool (pool);
5818 }
5819
5820 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5821 We have decided we cannot use this pool, so revert all changes
5822 to the current function that were done by s390_mainpool_start. */
5823 static void
s390_mainpool_cancel(struct constant_pool * pool)5824 s390_mainpool_cancel (struct constant_pool *pool)
5825 {
5826 /* We didn't actually change the instruction stream, so simply
5827 free the pool memory. */
5828 s390_free_pool (pool);
5829 }
5830
5831
5832 /* Chunkify the literal pool. */
5833
5834 #define S390_POOL_CHUNK_MIN 0xc00
5835 #define S390_POOL_CHUNK_MAX 0xe00
5836
5837 static struct constant_pool *
s390_chunkify_start(void)5838 s390_chunkify_start (void)
5839 {
5840 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
5841 int extra_size = 0;
5842 bitmap far_labels;
5843 rtx pending_ltrel = NULL_RTX;
5844 rtx insn;
5845
5846 rtx (*gen_reload_base) (rtx, rtx) =
5847 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
5848
5849
5850 /* We need correct insn addresses. */
5851
5852 shorten_branches (get_insns ());
5853
5854 /* Scan all insns and move literals to pool chunks. */
5855
5856 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5857 {
5858 /* Check for pending LTREL_BASE. */
5859 if (INSN_P (insn))
5860 {
5861 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5862 if (ltrel_base)
5863 {
5864 gcc_assert (ltrel_base == pending_ltrel);
5865 pending_ltrel = NULL_RTX;
5866 }
5867 }
5868
5869 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5870 {
5871 if (!curr_pool)
5872 curr_pool = s390_start_pool (&pool_list, insn);
5873
5874 s390_add_execute (curr_pool, insn);
5875 s390_add_pool_insn (curr_pool, insn);
5876 }
5877 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5878 {
5879 rtx pool_ref = NULL_RTX;
5880 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5881 if (pool_ref)
5882 {
5883 rtx constant = get_pool_constant (pool_ref);
5884 enum machine_mode mode = get_pool_mode (pool_ref);
5885
5886 if (!curr_pool)
5887 curr_pool = s390_start_pool (&pool_list, insn);
5888
5889 s390_add_constant (curr_pool, constant, mode);
5890 s390_add_pool_insn (curr_pool, insn);
5891
5892 /* Don't split the pool chunk between a LTREL_OFFSET load
5893 and the corresponding LTREL_BASE. */
5894 if (GET_CODE (constant) == CONST
5895 && GET_CODE (XEXP (constant, 0)) == UNSPEC
5896 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5897 {
5898 gcc_assert (!pending_ltrel);
5899 pending_ltrel = pool_ref;
5900 }
5901 }
5902 }
5903
5904 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5905 {
5906 if (curr_pool)
5907 s390_add_pool_insn (curr_pool, insn);
5908 /* An LTREL_BASE must follow within the same basic block. */
5909 gcc_assert (!pending_ltrel);
5910 }
5911
5912 if (!curr_pool
5913 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5914 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5915 continue;
5916
5917 if (TARGET_CPU_ZARCH)
5918 {
5919 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5920 continue;
5921
5922 s390_end_pool (curr_pool, NULL_RTX);
5923 curr_pool = NULL;
5924 }
5925 else
5926 {
5927 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5928 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5929 + extra_size;
5930
5931 /* We will later have to insert base register reload insns.
5932 Those will have an effect on code size, which we need to
5933 consider here. This calculation makes rather pessimistic
5934 worst-case assumptions. */
5935 if (GET_CODE (insn) == CODE_LABEL)
5936 extra_size += 6;
5937
5938 if (chunk_size < S390_POOL_CHUNK_MIN
5939 && curr_pool->size < S390_POOL_CHUNK_MIN)
5940 continue;
5941
5942 /* Pool chunks can only be inserted after BARRIERs ... */
5943 if (GET_CODE (insn) == BARRIER)
5944 {
5945 s390_end_pool (curr_pool, insn);
5946 curr_pool = NULL;
5947 extra_size = 0;
5948 }
5949
5950 /* ... so if we don't find one in time, create one. */
5951 else if ((chunk_size > S390_POOL_CHUNK_MAX
5952 || curr_pool->size > S390_POOL_CHUNK_MAX))
5953 {
5954 rtx label, jump, barrier;
5955
5956 /* We can insert the barrier only after a 'real' insn. */
5957 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5958 continue;
5959 if (get_attr_length (insn) == 0)
5960 continue;
5961
5962 /* Don't separate LTREL_BASE from the corresponding
5963 LTREL_OFFSET load. */
5964 if (pending_ltrel)
5965 continue;
5966
5967 label = gen_label_rtx ();
5968 jump = emit_jump_insn_after (gen_jump (label), insn);
5969 barrier = emit_barrier_after (jump);
5970 insn = emit_label_after (label, barrier);
5971 JUMP_LABEL (jump) = label;
5972 LABEL_NUSES (label) = 1;
5973
5974 INSN_ADDRESSES_NEW (jump, -1);
5975 INSN_ADDRESSES_NEW (barrier, -1);
5976 INSN_ADDRESSES_NEW (insn, -1);
5977
5978 s390_end_pool (curr_pool, barrier);
5979 curr_pool = NULL;
5980 extra_size = 0;
5981 }
5982 }
5983 }
5984
5985 if (curr_pool)
5986 s390_end_pool (curr_pool, NULL_RTX);
5987 gcc_assert (!pending_ltrel);
5988
5989 /* Find all labels that are branched into
5990 from an insn belonging to a different chunk. */
5991
5992 far_labels = BITMAP_ALLOC (NULL);
5993
5994 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5995 {
5996 /* Labels marked with LABEL_PRESERVE_P can be target
5997 of non-local jumps, so we have to mark them.
5998 The same holds for named labels.
5999
6000 Don't do that, however, if it is the label before
6001 a jump table. */
6002
6003 if (GET_CODE (insn) == CODE_LABEL
6004 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
6005 {
6006 rtx vec_insn = next_real_insn (insn);
6007 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6008 PATTERN (vec_insn) : NULL_RTX;
6009 if (!vec_pat
6010 || !(GET_CODE (vec_pat) == ADDR_VEC
6011 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6012 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
6013 }
6014
6015 /* If we have a direct jump (conditional or unconditional)
6016 or a casesi jump, check all potential targets. */
6017 else if (GET_CODE (insn) == JUMP_INSN)
6018 {
6019 rtx pat = PATTERN (insn);
6020 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
6021 pat = XVECEXP (pat, 0, 0);
6022
6023 if (GET_CODE (pat) == SET)
6024 {
6025 rtx label = JUMP_LABEL (insn);
6026 if (label)
6027 {
6028 if (s390_find_pool (pool_list, label)
6029 != s390_find_pool (pool_list, insn))
6030 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6031 }
6032 }
6033 else if (GET_CODE (pat) == PARALLEL
6034 && XVECLEN (pat, 0) == 2
6035 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
6036 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
6037 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
6038 {
6039 /* Find the jump table used by this casesi jump. */
6040 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
6041 rtx vec_insn = next_real_insn (vec_label);
6042 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6043 PATTERN (vec_insn) : NULL_RTX;
6044 if (vec_pat
6045 && (GET_CODE (vec_pat) == ADDR_VEC
6046 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6047 {
6048 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
6049
6050 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
6051 {
6052 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
6053
6054 if (s390_find_pool (pool_list, label)
6055 != s390_find_pool (pool_list, insn))
6056 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6057 }
6058 }
6059 }
6060 }
6061 }
6062
6063 /* Insert base register reload insns before every pool. */
6064
6065 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6066 {
6067 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6068 curr_pool->label);
6069 rtx insn = curr_pool->first_insn;
6070 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
6071 }
6072
6073 /* Insert base register reload insns at every far label. */
6074
6075 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6076 if (GET_CODE (insn) == CODE_LABEL
6077 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
6078 {
6079 struct constant_pool *pool = s390_find_pool (pool_list, insn);
6080 if (pool)
6081 {
6082 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6083 pool->label);
6084 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
6085 }
6086 }
6087
6088
6089 BITMAP_FREE (far_labels);
6090
6091
6092 /* Recompute insn addresses. */
6093
6094 init_insn_lengths ();
6095 shorten_branches (get_insns ());
6096
6097 return pool_list;
6098 }
6099
6100 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6101 After we have decided to use this list, finish implementing
6102 all changes to the current function as required. */
6103
6104 static void
s390_chunkify_finish(struct constant_pool * pool_list)6105 s390_chunkify_finish (struct constant_pool *pool_list)
6106 {
6107 struct constant_pool *curr_pool = NULL;
6108 rtx insn;
6109
6110
6111 /* Replace all literal pool references. */
6112
6113 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6114 {
6115 if (INSN_P (insn))
6116 replace_ltrel_base (&PATTERN (insn));
6117
6118 curr_pool = s390_find_pool (pool_list, insn);
6119 if (!curr_pool)
6120 continue;
6121
6122 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6123 {
6124 rtx addr, pool_ref = NULL_RTX;
6125 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6126 if (pool_ref)
6127 {
6128 if (s390_execute_label (insn))
6129 addr = s390_find_execute (curr_pool, insn);
6130 else
6131 addr = s390_find_constant (curr_pool,
6132 get_pool_constant (pool_ref),
6133 get_pool_mode (pool_ref));
6134
6135 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
6136 INSN_CODE (insn) = -1;
6137 }
6138 }
6139 }
6140
6141 /* Dump out all literal pools. */
6142
6143 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6144 s390_dump_pool (curr_pool, 0);
6145
6146 /* Free pool list. */
6147
6148 while (pool_list)
6149 {
6150 struct constant_pool *next = pool_list->next;
6151 s390_free_pool (pool_list);
6152 pool_list = next;
6153 }
6154 }
6155
6156 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6157 We have decided we cannot use this list, so revert all changes
6158 to the current function that were done by s390_chunkify_start. */
6159
6160 static void
s390_chunkify_cancel(struct constant_pool * pool_list)6161 s390_chunkify_cancel (struct constant_pool *pool_list)
6162 {
6163 struct constant_pool *curr_pool = NULL;
6164 rtx insn;
6165
6166 /* Remove all pool placeholder insns. */
6167
6168 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6169 {
6170 /* Did we insert an extra barrier? Remove it. */
6171 rtx barrier = PREV_INSN (curr_pool->pool_insn);
6172 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
6173 rtx label = NEXT_INSN (curr_pool->pool_insn);
6174
6175 if (jump && GET_CODE (jump) == JUMP_INSN
6176 && barrier && GET_CODE (barrier) == BARRIER
6177 && label && GET_CODE (label) == CODE_LABEL
6178 && GET_CODE (PATTERN (jump)) == SET
6179 && SET_DEST (PATTERN (jump)) == pc_rtx
6180 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
6181 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
6182 {
6183 remove_insn (jump);
6184 remove_insn (barrier);
6185 remove_insn (label);
6186 }
6187
6188 remove_insn (curr_pool->pool_insn);
6189 }
6190
6191 /* Remove all base register reload insns. */
6192
6193 for (insn = get_insns (); insn; )
6194 {
6195 rtx next_insn = NEXT_INSN (insn);
6196
6197 if (GET_CODE (insn) == INSN
6198 && GET_CODE (PATTERN (insn)) == SET
6199 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
6200 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
6201 remove_insn (insn);
6202
6203 insn = next_insn;
6204 }
6205
6206 /* Free pool list. */
6207
6208 while (pool_list)
6209 {
6210 struct constant_pool *next = pool_list->next;
6211 s390_free_pool (pool_list);
6212 pool_list = next;
6213 }
6214 }
6215
6216
6217 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6218
6219 void
s390_output_pool_entry(rtx exp,enum machine_mode mode,unsigned int align)6220 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
6221 {
6222 REAL_VALUE_TYPE r;
6223
6224 switch (GET_MODE_CLASS (mode))
6225 {
6226 case MODE_FLOAT:
6227 case MODE_DECIMAL_FLOAT:
6228 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
6229
6230 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
6231 assemble_real (r, mode, align);
6232 break;
6233
6234 case MODE_INT:
6235 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
6236 break;
6237
6238 default:
6239 gcc_unreachable ();
6240 }
6241 }
6242
6243
6244 /* Return an RTL expression representing the value of the return address
6245 for the frame COUNT steps up from the current frame. FRAME is the
6246 frame pointer of that frame. */
6247
6248 rtx
s390_return_addr_rtx(int count,rtx frame ATTRIBUTE_UNUSED)6249 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
6250 {
6251 int offset;
6252 rtx addr;
6253
6254 /* Without backchain, we fail for all but the current frame. */
6255
6256 if (!TARGET_BACKCHAIN && count > 0)
6257 return NULL_RTX;
6258
6259 /* For the current frame, we need to make sure the initial
6260 value of RETURN_REGNUM is actually saved. */
6261
6262 if (count == 0)
6263 {
6264 /* On non-z architectures branch splitting could overwrite r14. */
6265 if (TARGET_CPU_ZARCH)
6266 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
6267 else
6268 {
6269 cfun_frame_layout.save_return_addr_p = true;
6270 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
6271 }
6272 }
6273
6274 if (TARGET_PACKED_STACK)
6275 offset = -2 * UNITS_PER_WORD;
6276 else
6277 offset = RETURN_REGNUM * UNITS_PER_WORD;
6278
6279 addr = plus_constant (frame, offset);
6280 addr = memory_address (Pmode, addr);
6281 return gen_rtx_MEM (Pmode, addr);
6282 }
6283
6284 /* Return an RTL expression representing the back chain stored in
6285 the current stack frame. */
6286
6287 rtx
s390_back_chain_rtx(void)6288 s390_back_chain_rtx (void)
6289 {
6290 rtx chain;
6291
6292 gcc_assert (TARGET_BACKCHAIN);
6293
6294 if (TARGET_PACKED_STACK)
6295 chain = plus_constant (stack_pointer_rtx,
6296 STACK_POINTER_OFFSET - UNITS_PER_WORD);
6297 else
6298 chain = stack_pointer_rtx;
6299
6300 chain = gen_rtx_MEM (Pmode, chain);
6301 return chain;
6302 }
6303
6304 /* Find first call clobbered register unused in a function.
6305 This could be used as base register in a leaf function
6306 or for holding the return address before epilogue. */
6307
6308 static int
find_unused_clobbered_reg(void)6309 find_unused_clobbered_reg (void)
6310 {
6311 int i;
6312 for (i = 0; i < 6; i++)
6313 if (!regs_ever_live[i])
6314 return i;
6315 return 0;
6316 }
6317
6318
6319 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6320 clobbered hard regs in SETREG. */
6321
6322 static void
s390_reg_clobbered_rtx(rtx setreg,rtx set_insn ATTRIBUTE_UNUSED,void * data)6323 s390_reg_clobbered_rtx (rtx setreg, rtx set_insn ATTRIBUTE_UNUSED, void *data)
6324 {
6325 int *regs_ever_clobbered = (int *)data;
6326 unsigned int i, regno;
6327 enum machine_mode mode = GET_MODE (setreg);
6328
6329 if (GET_CODE (setreg) == SUBREG)
6330 {
6331 rtx inner = SUBREG_REG (setreg);
6332 if (!GENERAL_REG_P (inner))
6333 return;
6334 regno = subreg_regno (setreg);
6335 }
6336 else if (GENERAL_REG_P (setreg))
6337 regno = REGNO (setreg);
6338 else
6339 return;
6340
6341 for (i = regno;
6342 i < regno + HARD_REGNO_NREGS (regno, mode);
6343 i++)
6344 regs_ever_clobbered[i] = 1;
6345 }
6346
6347 /* Walks through all basic blocks of the current function looking
6348 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6349 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6350 each of those regs. */
6351
6352 static void
s390_regs_ever_clobbered(int * regs_ever_clobbered)6353 s390_regs_ever_clobbered (int *regs_ever_clobbered)
6354 {
6355 basic_block cur_bb;
6356 rtx cur_insn;
6357 unsigned int i;
6358
6359 memset (regs_ever_clobbered, 0, 16 * sizeof (int));
6360
6361 /* For non-leaf functions we have to consider all call clobbered regs to be
6362 clobbered. */
6363 if (!current_function_is_leaf)
6364 {
6365 for (i = 0; i < 16; i++)
6366 regs_ever_clobbered[i] = call_really_used_regs[i];
6367 }
6368
6369 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6370 this work is done by liveness analysis (mark_regs_live_at_end).
6371 Special care is needed for functions containing landing pads. Landing pads
6372 may use the eh registers, but the code which sets these registers is not
6373 contained in that function. Hence s390_regs_ever_clobbered is not able to
6374 deal with this automatically. */
6375 if (current_function_calls_eh_return || cfun->machine->has_landing_pad_p)
6376 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
6377 if (current_function_calls_eh_return
6378 || (cfun->machine->has_landing_pad_p
6379 && regs_ever_live [EH_RETURN_DATA_REGNO (i)]))
6380 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
6381
6382 /* For nonlocal gotos all call-saved registers have to be saved.
6383 This flag is also set for the unwinding code in libgcc.
6384 See expand_builtin_unwind_init. For regs_ever_live this is done by
6385 reload. */
6386 if (current_function_has_nonlocal_label)
6387 for (i = 0; i < 16; i++)
6388 if (!call_really_used_regs[i])
6389 regs_ever_clobbered[i] = 1;
6390
6391 FOR_EACH_BB (cur_bb)
6392 {
6393 FOR_BB_INSNS (cur_bb, cur_insn)
6394 {
6395 if (INSN_P (cur_insn))
6396 note_stores (PATTERN (cur_insn),
6397 s390_reg_clobbered_rtx,
6398 regs_ever_clobbered);
6399 }
6400 }
6401 }
6402
6403 /* Determine the frame area which actually has to be accessed
6404 in the function epilogue. The values are stored at the
6405 given pointers AREA_BOTTOM (address of the lowest used stack
6406 address) and AREA_TOP (address of the first item which does
6407 not belong to the stack frame). */
6408
6409 static void
s390_frame_area(int * area_bottom,int * area_top)6410 s390_frame_area (int *area_bottom, int *area_top)
6411 {
6412 int b, t;
6413 int i;
6414
6415 b = INT_MAX;
6416 t = INT_MIN;
6417
6418 if (cfun_frame_layout.first_restore_gpr != -1)
6419 {
6420 b = (cfun_frame_layout.gprs_offset
6421 + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
6422 t = b + (cfun_frame_layout.last_restore_gpr
6423 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
6424 }
6425
6426 if (TARGET_64BIT && cfun_save_high_fprs_p)
6427 {
6428 b = MIN (b, cfun_frame_layout.f8_offset);
6429 t = MAX (t, (cfun_frame_layout.f8_offset
6430 + cfun_frame_layout.high_fprs * 8));
6431 }
6432
6433 if (!TARGET_64BIT)
6434 for (i = 2; i < 4; i++)
6435 if (cfun_fpr_bit_p (i))
6436 {
6437 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
6438 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
6439 }
6440
6441 *area_bottom = b;
6442 *area_top = t;
6443 }
6444
6445 /* Fill cfun->machine with info about register usage of current function.
6446 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6447
6448 static void
s390_register_info(int clobbered_regs[])6449 s390_register_info (int clobbered_regs[])
6450 {
6451 int i, j;
6452
6453 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6454 cfun_frame_layout.fpr_bitmap = 0;
6455 cfun_frame_layout.high_fprs = 0;
6456 if (TARGET_64BIT)
6457 for (i = 24; i < 32; i++)
6458 if (regs_ever_live[i] && !global_regs[i])
6459 {
6460 cfun_set_fpr_bit (i - 16);
6461 cfun_frame_layout.high_fprs++;
6462 }
6463
6464 /* Find first and last gpr to be saved. We trust regs_ever_live
6465 data, except that we don't save and restore global registers.
6466
6467 Also, all registers with special meaning to the compiler need
6468 to be handled extra. */
6469
6470 s390_regs_ever_clobbered (clobbered_regs);
6471
6472 for (i = 0; i < 16; i++)
6473 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i];
6474
6475 if (frame_pointer_needed)
6476 clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
6477
6478 if (flag_pic)
6479 clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
6480 |= regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
6481
6482 clobbered_regs[BASE_REGNUM]
6483 |= (cfun->machine->base_reg
6484 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
6485
6486 clobbered_regs[RETURN_REGNUM]
6487 |= (!current_function_is_leaf
6488 || TARGET_TPF_PROFILING
6489 || cfun->machine->split_branches_pending_p
6490 || cfun_frame_layout.save_return_addr_p
6491 || current_function_calls_eh_return
6492 || current_function_stdarg);
6493
6494 clobbered_regs[STACK_POINTER_REGNUM]
6495 |= (!current_function_is_leaf
6496 || TARGET_TPF_PROFILING
6497 || cfun_save_high_fprs_p
6498 || get_frame_size () > 0
6499 || current_function_calls_alloca
6500 || current_function_stdarg);
6501
6502 for (i = 6; i < 16; i++)
6503 if (regs_ever_live[i] || clobbered_regs[i])
6504 break;
6505 for (j = 15; j > i; j--)
6506 if (regs_ever_live[j] || clobbered_regs[j])
6507 break;
6508
6509 if (i == 16)
6510 {
6511 /* Nothing to save/restore. */
6512 cfun_frame_layout.first_save_gpr_slot = -1;
6513 cfun_frame_layout.last_save_gpr_slot = -1;
6514 cfun_frame_layout.first_save_gpr = -1;
6515 cfun_frame_layout.first_restore_gpr = -1;
6516 cfun_frame_layout.last_save_gpr = -1;
6517 cfun_frame_layout.last_restore_gpr = -1;
6518 }
6519 else
6520 {
6521 /* Save slots for gprs from i to j. */
6522 cfun_frame_layout.first_save_gpr_slot = i;
6523 cfun_frame_layout.last_save_gpr_slot = j;
6524
6525 for (i = cfun_frame_layout.first_save_gpr_slot;
6526 i < cfun_frame_layout.last_save_gpr_slot + 1;
6527 i++)
6528 if (clobbered_regs[i])
6529 break;
6530
6531 for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
6532 if (clobbered_regs[j])
6533 break;
6534
6535 if (i == cfun_frame_layout.last_save_gpr_slot + 1)
6536 {
6537 /* Nothing to save/restore. */
6538 cfun_frame_layout.first_save_gpr = -1;
6539 cfun_frame_layout.first_restore_gpr = -1;
6540 cfun_frame_layout.last_save_gpr = -1;
6541 cfun_frame_layout.last_restore_gpr = -1;
6542 }
6543 else
6544 {
6545 /* Save / Restore from gpr i to j. */
6546 cfun_frame_layout.first_save_gpr = i;
6547 cfun_frame_layout.first_restore_gpr = i;
6548 cfun_frame_layout.last_save_gpr = j;
6549 cfun_frame_layout.last_restore_gpr = j;
6550 }
6551 }
6552
6553 if (current_function_stdarg)
6554 {
6555 /* Varargs functions need to save gprs 2 to 6. */
6556 if (cfun->va_list_gpr_size
6557 && current_function_args_info.gprs < GP_ARG_NUM_REG)
6558 {
6559 int min_gpr = current_function_args_info.gprs;
6560 int max_gpr = min_gpr + cfun->va_list_gpr_size;
6561 if (max_gpr > GP_ARG_NUM_REG)
6562 max_gpr = GP_ARG_NUM_REG;
6563
6564 if (cfun_frame_layout.first_save_gpr == -1
6565 || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
6566 {
6567 cfun_frame_layout.first_save_gpr = 2 + min_gpr;
6568 cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
6569 }
6570
6571 if (cfun_frame_layout.last_save_gpr == -1
6572 || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
6573 {
6574 cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
6575 cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
6576 }
6577 }
6578
6579 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6580 if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
6581 && current_function_args_info.fprs < FP_ARG_NUM_REG)
6582 {
6583 int min_fpr = current_function_args_info.fprs;
6584 int max_fpr = min_fpr + cfun->va_list_fpr_size;
6585 if (max_fpr > FP_ARG_NUM_REG)
6586 max_fpr = FP_ARG_NUM_REG;
6587
6588 /* ??? This is currently required to ensure proper location
6589 of the fpr save slots within the va_list save area. */
6590 if (TARGET_PACKED_STACK)
6591 min_fpr = 0;
6592
6593 for (i = min_fpr; i < max_fpr; i++)
6594 cfun_set_fpr_bit (i);
6595 }
6596 }
6597
6598 if (!TARGET_64BIT)
6599 for (i = 2; i < 4; i++)
6600 if (regs_ever_live[i + 16] && !global_regs[i + 16])
6601 cfun_set_fpr_bit (i);
6602 }
6603
6604 /* Fill cfun->machine with info about frame of current function. */
6605
6606 static void
s390_frame_info(void)6607 s390_frame_info (void)
6608 {
6609 int i;
6610
6611 cfun_frame_layout.frame_size = get_frame_size ();
6612 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
6613 fatal_error ("total size of local variables exceeds architecture limit");
6614
6615 if (!TARGET_PACKED_STACK)
6616 {
6617 cfun_frame_layout.backchain_offset = 0;
6618 cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
6619 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
6620 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
6621 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
6622 * UNITS_PER_WORD);
6623 }
6624 else if (TARGET_BACKCHAIN) /* kernel stack layout */
6625 {
6626 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
6627 - UNITS_PER_WORD);
6628 cfun_frame_layout.gprs_offset
6629 = (cfun_frame_layout.backchain_offset
6630 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
6631 * UNITS_PER_WORD);
6632
6633 if (TARGET_64BIT)
6634 {
6635 cfun_frame_layout.f4_offset
6636 = (cfun_frame_layout.gprs_offset
6637 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6638
6639 cfun_frame_layout.f0_offset
6640 = (cfun_frame_layout.f4_offset
6641 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6642 }
6643 else
6644 {
6645 /* On 31 bit we have to care about alignment of the
6646 floating point regs to provide fastest access. */
6647 cfun_frame_layout.f0_offset
6648 = ((cfun_frame_layout.gprs_offset
6649 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
6650 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6651
6652 cfun_frame_layout.f4_offset
6653 = (cfun_frame_layout.f0_offset
6654 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6655 }
6656 }
6657 else /* no backchain */
6658 {
6659 cfun_frame_layout.f4_offset
6660 = (STACK_POINTER_OFFSET
6661 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6662
6663 cfun_frame_layout.f0_offset
6664 = (cfun_frame_layout.f4_offset
6665 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6666
6667 cfun_frame_layout.gprs_offset
6668 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
6669 }
6670
6671 if (current_function_is_leaf
6672 && !TARGET_TPF_PROFILING
6673 && cfun_frame_layout.frame_size == 0
6674 && !cfun_save_high_fprs_p
6675 && !current_function_calls_alloca
6676 && !current_function_stdarg)
6677 return;
6678
6679 if (!TARGET_PACKED_STACK)
6680 cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
6681 + current_function_outgoing_args_size
6682 + cfun_frame_layout.high_fprs * 8);
6683 else
6684 {
6685 if (TARGET_BACKCHAIN)
6686 cfun_frame_layout.frame_size += UNITS_PER_WORD;
6687
6688 /* No alignment trouble here because f8-f15 are only saved under
6689 64 bit. */
6690 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
6691 cfun_frame_layout.f4_offset),
6692 cfun_frame_layout.gprs_offset)
6693 - cfun_frame_layout.high_fprs * 8);
6694
6695 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
6696
6697 for (i = 0; i < 8; i++)
6698 if (cfun_fpr_bit_p (i))
6699 cfun_frame_layout.frame_size += 8;
6700
6701 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
6702
6703 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6704 the frame size to sustain 8 byte alignment of stack frames. */
6705 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
6706 STACK_BOUNDARY / BITS_PER_UNIT - 1)
6707 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
6708
6709 cfun_frame_layout.frame_size += current_function_outgoing_args_size;
6710 }
6711 }
6712
6713 /* Generate frame layout. Fills in register and frame data for the current
6714 function in cfun->machine. This routine can be called multiple times;
6715 it will re-do the complete frame layout every time. */
6716
6717 static void
s390_init_frame_layout(void)6718 s390_init_frame_layout (void)
6719 {
6720 HOST_WIDE_INT frame_size;
6721 int base_used;
6722 int clobbered_regs[16];
6723
6724 /* On S/390 machines, we may need to perform branch splitting, which
6725 will require both base and return address register. We have no
6726 choice but to assume we're going to need them until right at the
6727 end of the machine dependent reorg phase. */
6728 if (!TARGET_CPU_ZARCH)
6729 cfun->machine->split_branches_pending_p = true;
6730
6731 do
6732 {
6733 frame_size = cfun_frame_layout.frame_size;
6734
6735 /* Try to predict whether we'll need the base register. */
6736 base_used = cfun->machine->split_branches_pending_p
6737 || current_function_uses_const_pool
6738 || (!DISP_IN_RANGE (frame_size)
6739 && !CONST_OK_FOR_K (frame_size));
6740
6741 /* Decide which register to use as literal pool base. In small
6742 leaf functions, try to use an unused call-clobbered register
6743 as base register to avoid save/restore overhead. */
6744 if (!base_used)
6745 cfun->machine->base_reg = NULL_RTX;
6746 else if (current_function_is_leaf && !regs_ever_live[5])
6747 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
6748 else
6749 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6750
6751 s390_register_info (clobbered_regs);
6752 s390_frame_info ();
6753 }
6754 while (frame_size != cfun_frame_layout.frame_size);
6755 }
6756
6757 /* Update frame layout. Recompute actual register save data based on
6758 current info and update regs_ever_live for the special registers.
6759 May be called multiple times, but may never cause *more* registers
6760 to be saved than s390_init_frame_layout allocated room for. */
6761
6762 static void
s390_update_frame_layout(void)6763 s390_update_frame_layout (void)
6764 {
6765 int clobbered_regs[16];
6766
6767 s390_register_info (clobbered_regs);
6768
6769 regs_ever_live[BASE_REGNUM] = clobbered_regs[BASE_REGNUM];
6770 regs_ever_live[RETURN_REGNUM] = clobbered_regs[RETURN_REGNUM];
6771 regs_ever_live[STACK_POINTER_REGNUM] = clobbered_regs[STACK_POINTER_REGNUM];
6772
6773 if (cfun->machine->base_reg)
6774 regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
6775 }
6776
6777 /* Return true if it is legal to put a value with MODE into REGNO. */
6778
6779 bool
s390_hard_regno_mode_ok(unsigned int regno,enum machine_mode mode)6780 s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
6781 {
6782 switch (REGNO_REG_CLASS (regno))
6783 {
6784 case FP_REGS:
6785 if (REGNO_PAIR_OK (regno, mode))
6786 {
6787 if (mode == SImode || mode == DImode)
6788 return true;
6789
6790 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
6791 return true;
6792 }
6793 break;
6794 case ADDR_REGS:
6795 if (FRAME_REGNO_P (regno) && mode == Pmode)
6796 return true;
6797
6798 /* fallthrough */
6799 case GENERAL_REGS:
6800 if (REGNO_PAIR_OK (regno, mode))
6801 {
6802 if (TARGET_64BIT
6803 || (mode != TFmode && mode != TCmode && mode != TDmode))
6804 return true;
6805 }
6806 break;
6807 case CC_REGS:
6808 if (GET_MODE_CLASS (mode) == MODE_CC)
6809 return true;
6810 break;
6811 case ACCESS_REGS:
6812 if (REGNO_PAIR_OK (regno, mode))
6813 {
6814 if (mode == SImode || mode == Pmode)
6815 return true;
6816 }
6817 break;
6818 default:
6819 return false;
6820 }
6821
6822 return false;
6823 }
6824
6825 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6826
6827 bool
s390_hard_regno_rename_ok(unsigned int old_reg,unsigned int new_reg)6828 s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
6829 {
6830 /* Once we've decided upon a register to use as base register, it must
6831 no longer be used for any other purpose. */
6832 if (cfun->machine->base_reg)
6833 if (REGNO (cfun->machine->base_reg) == old_reg
6834 || REGNO (cfun->machine->base_reg) == new_reg)
6835 return false;
6836
6837 return true;
6838 }
6839
6840 /* Maximum number of registers to represent a value of mode MODE
6841 in a register of class CLASS. */
6842
6843 bool
s390_class_max_nregs(enum reg_class class,enum machine_mode mode)6844 s390_class_max_nregs (enum reg_class class, enum machine_mode mode)
6845 {
6846 switch (class)
6847 {
6848 case FP_REGS:
6849 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6850 return 2 * ((GET_MODE_SIZE (mode) / 2 + 8 - 1) / 8);
6851 else
6852 return (GET_MODE_SIZE (mode) + 8 - 1) / 8;
6853 case ACCESS_REGS:
6854 return (GET_MODE_SIZE (mode) + 4 - 1) / 4;
6855 default:
6856 break;
6857 }
6858 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6859 }
6860
6861 /* Return true if register FROM can be eliminated via register TO. */
6862
6863 bool
s390_can_eliminate(int from,int to)6864 s390_can_eliminate (int from, int to)
6865 {
6866 /* On zSeries machines, we have not marked the base register as fixed.
6867 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6868 If a function requires the base register, we say here that this
6869 elimination cannot be performed. This will cause reload to free
6870 up the base register (as if it were fixed). On the other hand,
6871 if the current function does *not* require the base register, we
6872 say here the elimination succeeds, which in turn allows reload
6873 to allocate the base register for any other purpose. */
6874 if (from == BASE_REGNUM && to == BASE_REGNUM)
6875 {
6876 if (TARGET_CPU_ZARCH)
6877 {
6878 s390_init_frame_layout ();
6879 return cfun->machine->base_reg == NULL_RTX;
6880 }
6881
6882 return false;
6883 }
6884
6885 /* Everything else must point into the stack frame. */
6886 gcc_assert (to == STACK_POINTER_REGNUM
6887 || to == HARD_FRAME_POINTER_REGNUM);
6888
6889 gcc_assert (from == FRAME_POINTER_REGNUM
6890 || from == ARG_POINTER_REGNUM
6891 || from == RETURN_ADDRESS_POINTER_REGNUM);
6892
6893 /* Make sure we actually saved the return address. */
6894 if (from == RETURN_ADDRESS_POINTER_REGNUM)
6895 if (!current_function_calls_eh_return
6896 && !current_function_stdarg
6897 && !cfun_frame_layout.save_return_addr_p)
6898 return false;
6899
6900 return true;
6901 }
6902
6903 /* Return offset between register FROM and TO initially after prolog. */
6904
6905 HOST_WIDE_INT
s390_initial_elimination_offset(int from,int to)6906 s390_initial_elimination_offset (int from, int to)
6907 {
6908 HOST_WIDE_INT offset;
6909 int index;
6910
6911 /* ??? Why are we called for non-eliminable pairs? */
6912 if (!s390_can_eliminate (from, to))
6913 return 0;
6914
6915 switch (from)
6916 {
6917 case FRAME_POINTER_REGNUM:
6918 offset = (get_frame_size()
6919 + STACK_POINTER_OFFSET
6920 + current_function_outgoing_args_size);
6921 break;
6922
6923 case ARG_POINTER_REGNUM:
6924 s390_init_frame_layout ();
6925 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6926 break;
6927
6928 case RETURN_ADDRESS_POINTER_REGNUM:
6929 s390_init_frame_layout ();
6930 index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
6931 gcc_assert (index >= 0);
6932 offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
6933 offset += index * UNITS_PER_WORD;
6934 break;
6935
6936 case BASE_REGNUM:
6937 offset = 0;
6938 break;
6939
6940 default:
6941 gcc_unreachable ();
6942 }
6943
6944 return offset;
6945 }
6946
6947 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6948 to register BASE. Return generated insn. */
6949
6950 static rtx
save_fpr(rtx base,int offset,int regnum)6951 save_fpr (rtx base, int offset, int regnum)
6952 {
6953 rtx addr;
6954 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6955
6956 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
6957 set_mem_alias_set (addr, get_varargs_alias_set ());
6958 else
6959 set_mem_alias_set (addr, get_frame_alias_set ());
6960
6961 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
6962 }
6963
6964 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6965 to register BASE. Return generated insn. */
6966
6967 static rtx
restore_fpr(rtx base,int offset,int regnum)6968 restore_fpr (rtx base, int offset, int regnum)
6969 {
6970 rtx addr;
6971 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6972 set_mem_alias_set (addr, get_frame_alias_set ());
6973
6974 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
6975 }
6976
6977 /* Generate insn to save registers FIRST to LAST into
6978 the register save area located at offset OFFSET
6979 relative to register BASE. */
6980
6981 static rtx
save_gprs(rtx base,int offset,int first,int last)6982 save_gprs (rtx base, int offset, int first, int last)
6983 {
6984 rtx addr, insn, note;
6985 int i;
6986
6987 addr = plus_constant (base, offset);
6988 addr = gen_rtx_MEM (Pmode, addr);
6989
6990 set_mem_alias_set (addr, get_frame_alias_set ());
6991
6992 /* Special-case single register. */
6993 if (first == last)
6994 {
6995 if (TARGET_64BIT)
6996 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6997 else
6998 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6999
7000 RTX_FRAME_RELATED_P (insn) = 1;
7001 return insn;
7002 }
7003
7004
7005 insn = gen_store_multiple (addr,
7006 gen_rtx_REG (Pmode, first),
7007 GEN_INT (last - first + 1));
7008
7009 if (first <= 6 && current_function_stdarg)
7010 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7011 {
7012 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
7013
7014 if (first + i <= 6)
7015 set_mem_alias_set (mem, get_varargs_alias_set ());
7016 }
7017
7018 /* We need to set the FRAME_RELATED flag on all SETs
7019 inside the store-multiple pattern.
7020
7021 However, we must not emit DWARF records for registers 2..5
7022 if they are stored for use by variable arguments ...
7023
7024 ??? Unfortunately, it is not enough to simply not the
7025 FRAME_RELATED flags for those SETs, because the first SET
7026 of the PARALLEL is always treated as if it had the flag
7027 set, even if it does not. Therefore we emit a new pattern
7028 without those registers as REG_FRAME_RELATED_EXPR note. */
7029
7030 if (first >= 6)
7031 {
7032 rtx pat = PATTERN (insn);
7033
7034 for (i = 0; i < XVECLEN (pat, 0); i++)
7035 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
7036 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
7037
7038 RTX_FRAME_RELATED_P (insn) = 1;
7039 }
7040 else if (last >= 6)
7041 {
7042 addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
7043 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
7044 gen_rtx_REG (Pmode, 6),
7045 GEN_INT (last - 6 + 1));
7046 note = PATTERN (note);
7047
7048 REG_NOTES (insn) =
7049 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7050 note, REG_NOTES (insn));
7051
7052 for (i = 0; i < XVECLEN (note, 0); i++)
7053 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
7054 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
7055
7056 RTX_FRAME_RELATED_P (insn) = 1;
7057 }
7058
7059 return insn;
7060 }
7061
7062 /* Generate insn to restore registers FIRST to LAST from
7063 the register save area located at offset OFFSET
7064 relative to register BASE. */
7065
7066 static rtx
restore_gprs(rtx base,int offset,int first,int last)7067 restore_gprs (rtx base, int offset, int first, int last)
7068 {
7069 rtx addr, insn;
7070
7071 addr = plus_constant (base, offset);
7072 addr = gen_rtx_MEM (Pmode, addr);
7073 set_mem_alias_set (addr, get_frame_alias_set ());
7074
7075 /* Special-case single register. */
7076 if (first == last)
7077 {
7078 if (TARGET_64BIT)
7079 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
7080 else
7081 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
7082
7083 return insn;
7084 }
7085
7086 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
7087 addr,
7088 GEN_INT (last - first + 1));
7089 return insn;
7090 }
7091
7092 /* Return insn sequence to load the GOT register. */
7093
7094 static GTY(()) rtx got_symbol;
7095 rtx
s390_load_got(void)7096 s390_load_got (void)
7097 {
7098 rtx insns;
7099
7100 if (!got_symbol)
7101 {
7102 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7103 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
7104 }
7105
7106 start_sequence ();
7107
7108 if (TARGET_CPU_ZARCH)
7109 {
7110 emit_move_insn (pic_offset_table_rtx, got_symbol);
7111 }
7112 else
7113 {
7114 rtx offset;
7115
7116 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
7117 UNSPEC_LTREL_OFFSET);
7118 offset = gen_rtx_CONST (Pmode, offset);
7119 offset = force_const_mem (Pmode, offset);
7120
7121 emit_move_insn (pic_offset_table_rtx, offset);
7122
7123 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
7124 UNSPEC_LTREL_BASE);
7125 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
7126
7127 emit_move_insn (pic_offset_table_rtx, offset);
7128 }
7129
7130 insns = get_insns ();
7131 end_sequence ();
7132 return insns;
7133 }
7134
7135 /* Expand the prologue into a bunch of separate insns. */
7136
7137 void
s390_emit_prologue(void)7138 s390_emit_prologue (void)
7139 {
7140 rtx insn, addr;
7141 rtx temp_reg;
7142 int i;
7143 int offset;
7144 int next_fpr = 0;
7145
7146 /* Complete frame layout. */
7147
7148 s390_update_frame_layout ();
7149
7150 /* Annotate all constant pool references to let the scheduler know
7151 they implicitly use the base register. */
7152
7153 push_topmost_sequence ();
7154
7155 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7156 if (INSN_P (insn))
7157 annotate_constant_pool_refs (&PATTERN (insn));
7158
7159 pop_topmost_sequence ();
7160
7161 /* Choose best register to use for temp use within prologue.
7162 See below for why TPF must use the register 1. */
7163
7164 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
7165 && !current_function_is_leaf
7166 && !TARGET_TPF_PROFILING)
7167 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7168 else
7169 temp_reg = gen_rtx_REG (Pmode, 1);
7170
7171 /* Save call saved gprs. */
7172 if (cfun_frame_layout.first_save_gpr != -1)
7173 {
7174 insn = save_gprs (stack_pointer_rtx,
7175 cfun_frame_layout.gprs_offset +
7176 UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
7177 - cfun_frame_layout.first_save_gpr_slot),
7178 cfun_frame_layout.first_save_gpr,
7179 cfun_frame_layout.last_save_gpr);
7180 emit_insn (insn);
7181 }
7182
7183 /* Dummy insn to mark literal pool slot. */
7184
7185 if (cfun->machine->base_reg)
7186 emit_insn (gen_main_pool (cfun->machine->base_reg));
7187
7188 offset = cfun_frame_layout.f0_offset;
7189
7190 /* Save f0 and f2. */
7191 for (i = 0; i < 2; i++)
7192 {
7193 if (cfun_fpr_bit_p (i))
7194 {
7195 save_fpr (stack_pointer_rtx, offset, i + 16);
7196 offset += 8;
7197 }
7198 else if (!TARGET_PACKED_STACK)
7199 offset += 8;
7200 }
7201
7202 /* Save f4 and f6. */
7203 offset = cfun_frame_layout.f4_offset;
7204 for (i = 2; i < 4; i++)
7205 {
7206 if (cfun_fpr_bit_p (i))
7207 {
7208 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7209 offset += 8;
7210
7211 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7212 therefore are not frame related. */
7213 if (!call_really_used_regs[i + 16])
7214 RTX_FRAME_RELATED_P (insn) = 1;
7215 }
7216 else if (!TARGET_PACKED_STACK)
7217 offset += 8;
7218 }
7219
7220 if (TARGET_PACKED_STACK
7221 && cfun_save_high_fprs_p
7222 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
7223 {
7224 offset = (cfun_frame_layout.f8_offset
7225 + (cfun_frame_layout.high_fprs - 1) * 8);
7226
7227 for (i = 15; i > 7 && offset >= 0; i--)
7228 if (cfun_fpr_bit_p (i))
7229 {
7230 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7231
7232 RTX_FRAME_RELATED_P (insn) = 1;
7233 offset -= 8;
7234 }
7235 if (offset >= cfun_frame_layout.f8_offset)
7236 next_fpr = i + 16;
7237 }
7238
7239 if (!TARGET_PACKED_STACK)
7240 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
7241
7242 /* Decrement stack pointer. */
7243
7244 if (cfun_frame_layout.frame_size > 0)
7245 {
7246 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
7247
7248 if (s390_stack_size)
7249 {
7250 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
7251 & ~(s390_stack_guard - 1));
7252 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
7253 GEN_INT (stack_check_mask));
7254
7255 if (TARGET_64BIT)
7256 gen_cmpdi (t, const0_rtx);
7257 else
7258 gen_cmpsi (t, const0_rtx);
7259
7260 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
7261 gen_rtx_REG (CCmode,
7262 CC_REGNUM),
7263 const0_rtx),
7264 const0_rtx));
7265 }
7266
7267 if (s390_warn_framesize > 0
7268 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7269 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
7270 current_function_name (), cfun_frame_layout.frame_size);
7271
7272 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
7273 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7274
7275 /* Save incoming stack pointer into temp reg. */
7276 if (TARGET_BACKCHAIN || next_fpr)
7277 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
7278
7279 /* Subtract frame size from stack pointer. */
7280
7281 if (DISP_IN_RANGE (INTVAL (frame_off)))
7282 {
7283 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7284 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7285 frame_off));
7286 insn = emit_insn (insn);
7287 }
7288 else
7289 {
7290 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7291 frame_off = force_const_mem (Pmode, frame_off);
7292
7293 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
7294 annotate_constant_pool_refs (&PATTERN (insn));
7295 }
7296
7297 RTX_FRAME_RELATED_P (insn) = 1;
7298 REG_NOTES (insn) =
7299 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7300 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7301 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7302 GEN_INT (-cfun_frame_layout.frame_size))),
7303 REG_NOTES (insn));
7304
7305 /* Set backchain. */
7306
7307 if (TARGET_BACKCHAIN)
7308 {
7309 if (cfun_frame_layout.backchain_offset)
7310 addr = gen_rtx_MEM (Pmode,
7311 plus_constant (stack_pointer_rtx,
7312 cfun_frame_layout.backchain_offset));
7313 else
7314 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
7315 set_mem_alias_set (addr, get_frame_alias_set ());
7316 insn = emit_insn (gen_move_insn (addr, temp_reg));
7317 }
7318
7319 /* If we support asynchronous exceptions (e.g. for Java),
7320 we need to make sure the backchain pointer is set up
7321 before any possibly trapping memory access. */
7322
7323 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
7324 {
7325 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
7326 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
7327 }
7328 }
7329
7330 /* Save fprs 8 - 15 (64 bit ABI). */
7331
7332 if (cfun_save_high_fprs_p && next_fpr)
7333 {
7334 insn = emit_insn (gen_add2_insn (temp_reg,
7335 GEN_INT (cfun_frame_layout.f8_offset)));
7336
7337 offset = 0;
7338
7339 for (i = 24; i <= next_fpr; i++)
7340 if (cfun_fpr_bit_p (i - 16))
7341 {
7342 rtx addr = plus_constant (stack_pointer_rtx,
7343 cfun_frame_layout.frame_size
7344 + cfun_frame_layout.f8_offset
7345 + offset);
7346
7347 insn = save_fpr (temp_reg, offset, i);
7348 offset += 8;
7349 RTX_FRAME_RELATED_P (insn) = 1;
7350 REG_NOTES (insn) =
7351 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7352 gen_rtx_SET (VOIDmode,
7353 gen_rtx_MEM (DFmode, addr),
7354 gen_rtx_REG (DFmode, i)),
7355 REG_NOTES (insn));
7356 }
7357 }
7358
7359 /* Set frame pointer, if needed. */
7360
7361 if (frame_pointer_needed)
7362 {
7363 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
7364 RTX_FRAME_RELATED_P (insn) = 1;
7365 }
7366
7367 /* Set up got pointer, if needed. */
7368
7369 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
7370 {
7371 rtx insns = s390_load_got ();
7372
7373 for (insn = insns; insn; insn = NEXT_INSN (insn))
7374 {
7375 annotate_constant_pool_refs (&PATTERN (insn));
7376
7377 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
7378 REG_NOTES (insn));
7379 }
7380
7381 emit_insn (insns);
7382 }
7383
7384 if (TARGET_TPF_PROFILING)
7385 {
7386 /* Generate a BAS instruction to serve as a function
7387 entry intercept to facilitate the use of tracing
7388 algorithms located at the branch target. */
7389 emit_insn (gen_prologue_tpf ());
7390
7391 /* Emit a blockage here so that all code
7392 lies between the profiling mechanisms. */
7393 emit_insn (gen_blockage ());
7394 }
7395 }
7396
7397 /* Expand the epilogue into a bunch of separate insns. */
7398
7399 void
s390_emit_epilogue(bool sibcall)7400 s390_emit_epilogue (bool sibcall)
7401 {
7402 rtx frame_pointer, return_reg;
7403 int area_bottom, area_top, offset = 0;
7404 int next_offset;
7405 rtvec p;
7406 int i;
7407
7408 if (TARGET_TPF_PROFILING)
7409 {
7410
7411 /* Generate a BAS instruction to serve as a function
7412 entry intercept to facilitate the use of tracing
7413 algorithms located at the branch target. */
7414
7415 /* Emit a blockage here so that all code
7416 lies between the profiling mechanisms. */
7417 emit_insn (gen_blockage ());
7418
7419 emit_insn (gen_epilogue_tpf ());
7420 }
7421
7422 /* Check whether to use frame or stack pointer for restore. */
7423
7424 frame_pointer = (frame_pointer_needed
7425 ? hard_frame_pointer_rtx : stack_pointer_rtx);
7426
7427 s390_frame_area (&area_bottom, &area_top);
7428
7429 /* Check whether we can access the register save area.
7430 If not, increment the frame pointer as required. */
7431
7432 if (area_top <= area_bottom)
7433 {
7434 /* Nothing to restore. */
7435 }
7436 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
7437 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
7438 {
7439 /* Area is in range. */
7440 offset = cfun_frame_layout.frame_size;
7441 }
7442 else
7443 {
7444 rtx insn, frame_off;
7445
7446 offset = area_bottom < 0 ? -area_bottom : 0;
7447 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
7448
7449 if (DISP_IN_RANGE (INTVAL (frame_off)))
7450 {
7451 insn = gen_rtx_SET (VOIDmode, frame_pointer,
7452 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
7453 insn = emit_insn (insn);
7454 }
7455 else
7456 {
7457 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7458 frame_off = force_const_mem (Pmode, frame_off);
7459
7460 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
7461 annotate_constant_pool_refs (&PATTERN (insn));
7462 }
7463 }
7464
7465 /* Restore call saved fprs. */
7466
7467 if (TARGET_64BIT)
7468 {
7469 if (cfun_save_high_fprs_p)
7470 {
7471 next_offset = cfun_frame_layout.f8_offset;
7472 for (i = 24; i < 32; i++)
7473 {
7474 if (cfun_fpr_bit_p (i - 16))
7475 {
7476 restore_fpr (frame_pointer,
7477 offset + next_offset, i);
7478 next_offset += 8;
7479 }
7480 }
7481 }
7482
7483 }
7484 else
7485 {
7486 next_offset = cfun_frame_layout.f4_offset;
7487 for (i = 18; i < 20; i++)
7488 {
7489 if (cfun_fpr_bit_p (i - 16))
7490 {
7491 restore_fpr (frame_pointer,
7492 offset + next_offset, i);
7493 next_offset += 8;
7494 }
7495 else if (!TARGET_PACKED_STACK)
7496 next_offset += 8;
7497 }
7498
7499 }
7500
7501 /* Return register. */
7502
7503 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7504
7505 /* Restore call saved gprs. */
7506
7507 if (cfun_frame_layout.first_restore_gpr != -1)
7508 {
7509 rtx insn, addr;
7510 int i;
7511
7512 /* Check for global register and save them
7513 to stack location from where they get restored. */
7514
7515 for (i = cfun_frame_layout.first_restore_gpr;
7516 i <= cfun_frame_layout.last_restore_gpr;
7517 i++)
7518 {
7519 /* These registers are special and need to be
7520 restored in any case. */
7521 if (i == STACK_POINTER_REGNUM
7522 || i == RETURN_REGNUM
7523 || i == BASE_REGNUM
7524 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
7525 continue;
7526
7527 if (global_regs[i])
7528 {
7529 addr = plus_constant (frame_pointer,
7530 offset + cfun_frame_layout.gprs_offset
7531 + (i - cfun_frame_layout.first_save_gpr_slot)
7532 * UNITS_PER_WORD);
7533 addr = gen_rtx_MEM (Pmode, addr);
7534 set_mem_alias_set (addr, get_frame_alias_set ());
7535 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
7536 }
7537 }
7538
7539 if (! sibcall)
7540 {
7541 /* Fetch return address from stack before load multiple,
7542 this will do good for scheduling. */
7543
7544 if (cfun_frame_layout.save_return_addr_p
7545 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
7546 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
7547 {
7548 int return_regnum = find_unused_clobbered_reg();
7549 if (!return_regnum)
7550 return_regnum = 4;
7551 return_reg = gen_rtx_REG (Pmode, return_regnum);
7552
7553 addr = plus_constant (frame_pointer,
7554 offset + cfun_frame_layout.gprs_offset
7555 + (RETURN_REGNUM
7556 - cfun_frame_layout.first_save_gpr_slot)
7557 * UNITS_PER_WORD);
7558 addr = gen_rtx_MEM (Pmode, addr);
7559 set_mem_alias_set (addr, get_frame_alias_set ());
7560 emit_move_insn (return_reg, addr);
7561 }
7562 }
7563
7564 insn = restore_gprs (frame_pointer,
7565 offset + cfun_frame_layout.gprs_offset
7566 + (cfun_frame_layout.first_restore_gpr
7567 - cfun_frame_layout.first_save_gpr_slot)
7568 * UNITS_PER_WORD,
7569 cfun_frame_layout.first_restore_gpr,
7570 cfun_frame_layout.last_restore_gpr);
7571 emit_insn (insn);
7572 }
7573
7574 if (! sibcall)
7575 {
7576
7577 /* Return to caller. */
7578
7579 p = rtvec_alloc (2);
7580
7581 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
7582 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
7583 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
7584 }
7585 }
7586
7587
7588 /* Return the size in bytes of a function argument of
7589 type TYPE and/or mode MODE. At least one of TYPE or
7590 MODE must be specified. */
7591
7592 static int
s390_function_arg_size(enum machine_mode mode,tree type)7593 s390_function_arg_size (enum machine_mode mode, tree type)
7594 {
7595 if (type)
7596 return int_size_in_bytes (type);
7597
7598 /* No type info available for some library calls ... */
7599 if (mode != BLKmode)
7600 return GET_MODE_SIZE (mode);
7601
7602 /* If we have neither type nor mode, abort */
7603 gcc_unreachable ();
7604 }
7605
7606 /* Return true if a function argument of type TYPE and mode MODE
7607 is to be passed in a floating-point register, if available. */
7608
7609 static bool
s390_function_arg_float(enum machine_mode mode,tree type)7610 s390_function_arg_float (enum machine_mode mode, tree type)
7611 {
7612 int size = s390_function_arg_size (mode, type);
7613 if (size > 8)
7614 return false;
7615
7616 /* Soft-float changes the ABI: no floating-point registers are used. */
7617 if (TARGET_SOFT_FLOAT)
7618 return false;
7619
7620 /* No type info available for some library calls ... */
7621 if (!type)
7622 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
7623
7624 /* The ABI says that record types with a single member are treated
7625 just like that member would be. */
7626 while (TREE_CODE (type) == RECORD_TYPE)
7627 {
7628 tree field, single = NULL_TREE;
7629
7630 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
7631 {
7632 if (TREE_CODE (field) != FIELD_DECL)
7633 continue;
7634
7635 if (single == NULL_TREE)
7636 single = TREE_TYPE (field);
7637 else
7638 return false;
7639 }
7640
7641 if (single == NULL_TREE)
7642 return false;
7643 else
7644 type = single;
7645 }
7646
7647 return TREE_CODE (type) == REAL_TYPE;
7648 }
7649
7650 /* Return true if a function argument of type TYPE and mode MODE
7651 is to be passed in an integer register, or a pair of integer
7652 registers, if available. */
7653
7654 static bool
s390_function_arg_integer(enum machine_mode mode,tree type)7655 s390_function_arg_integer (enum machine_mode mode, tree type)
7656 {
7657 int size = s390_function_arg_size (mode, type);
7658 if (size > 8)
7659 return false;
7660
7661 /* No type info available for some library calls ... */
7662 if (!type)
7663 return GET_MODE_CLASS (mode) == MODE_INT
7664 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
7665
7666 /* We accept small integral (and similar) types. */
7667 if (INTEGRAL_TYPE_P (type)
7668 || POINTER_TYPE_P (type)
7669 || TREE_CODE (type) == OFFSET_TYPE
7670 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
7671 return true;
7672
7673 /* We also accept structs of size 1, 2, 4, 8 that are not
7674 passed in floating-point registers. */
7675 if (AGGREGATE_TYPE_P (type)
7676 && exact_log2 (size) >= 0
7677 && !s390_function_arg_float (mode, type))
7678 return true;
7679
7680 return false;
7681 }
7682
7683 /* Return 1 if a function argument of type TYPE and mode MODE
7684 is to be passed by reference. The ABI specifies that only
7685 structures of size 1, 2, 4, or 8 bytes are passed by value,
7686 all other structures (and complex numbers) are passed by
7687 reference. */
7688
7689 static bool
s390_pass_by_reference(CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED,enum machine_mode mode,tree type,bool named ATTRIBUTE_UNUSED)7690 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
7691 enum machine_mode mode, tree type,
7692 bool named ATTRIBUTE_UNUSED)
7693 {
7694 int size = s390_function_arg_size (mode, type);
7695 if (size > 8)
7696 return true;
7697
7698 if (type)
7699 {
7700 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
7701 return 1;
7702
7703 if (TREE_CODE (type) == COMPLEX_TYPE
7704 || TREE_CODE (type) == VECTOR_TYPE)
7705 return 1;
7706 }
7707
7708 return 0;
7709 }
7710
7711 /* Update the data in CUM to advance over an argument of mode MODE and
7712 data type TYPE. (TYPE is null for libcalls where that information
7713 may not be available.). The boolean NAMED specifies whether the
7714 argument is a named argument (as opposed to an unnamed argument
7715 matching an ellipsis). */
7716
7717 void
s390_function_arg_advance(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named ATTRIBUTE_UNUSED)7718 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7719 tree type, int named ATTRIBUTE_UNUSED)
7720 {
7721 if (s390_function_arg_float (mode, type))
7722 {
7723 cum->fprs += 1;
7724 }
7725 else if (s390_function_arg_integer (mode, type))
7726 {
7727 int size = s390_function_arg_size (mode, type);
7728 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
7729 }
7730 else
7731 gcc_unreachable ();
7732 }
7733
7734 /* Define where to put the arguments to a function.
7735 Value is zero to push the argument on the stack,
7736 or a hard register in which to store the argument.
7737
7738 MODE is the argument's machine mode.
7739 TYPE is the data type of the argument (as a tree).
7740 This is null for libcalls where that information may
7741 not be available.
7742 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7743 the preceding args and about the function being called.
7744 NAMED is nonzero if this argument is a named parameter
7745 (otherwise it is an extra parameter matching an ellipsis).
7746
7747 On S/390, we use general purpose registers 2 through 6 to
7748 pass integer, pointer, and certain structure arguments, and
7749 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7750 to pass floating point arguments. All remaining arguments
7751 are pushed to the stack. */
7752
7753 rtx
s390_function_arg(CUMULATIVE_ARGS * cum,enum machine_mode mode,tree type,int named ATTRIBUTE_UNUSED)7754 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
7755 int named ATTRIBUTE_UNUSED)
7756 {
7757 if (s390_function_arg_float (mode, type))
7758 {
7759 if (cum->fprs + 1 > FP_ARG_NUM_REG)
7760 return 0;
7761 else
7762 return gen_rtx_REG (mode, cum->fprs + 16);
7763 }
7764 else if (s390_function_arg_integer (mode, type))
7765 {
7766 int size = s390_function_arg_size (mode, type);
7767 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
7768
7769 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
7770 return 0;
7771 else
7772 return gen_rtx_REG (mode, cum->gprs + 2);
7773 }
7774
7775 /* After the real arguments, expand_call calls us once again
7776 with a void_type_node type. Whatever we return here is
7777 passed as operand 2 to the call expanders.
7778
7779 We don't need this feature ... */
7780 else if (type == void_type_node)
7781 return const0_rtx;
7782
7783 gcc_unreachable ();
7784 }
7785
7786 /* Return true if return values of type TYPE should be returned
7787 in a memory buffer whose address is passed by the caller as
7788 hidden first argument. */
7789
7790 static bool
s390_return_in_memory(tree type,tree fundecl ATTRIBUTE_UNUSED)7791 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
7792 {
7793 /* We accept small integral (and similar) types. */
7794 if (INTEGRAL_TYPE_P (type)
7795 || POINTER_TYPE_P (type)
7796 || TREE_CODE (type) == OFFSET_TYPE
7797 || TREE_CODE (type) == REAL_TYPE)
7798 return int_size_in_bytes (type) > 8;
7799
7800 /* Aggregates and similar constructs are always returned
7801 in memory. */
7802 if (AGGREGATE_TYPE_P (type)
7803 || TREE_CODE (type) == COMPLEX_TYPE
7804 || TREE_CODE (type) == VECTOR_TYPE)
7805 return true;
7806
7807 /* ??? We get called on all sorts of random stuff from
7808 aggregate_value_p. We can't abort, but it's not clear
7809 what's safe to return. Pretend it's a struct I guess. */
7810 return true;
7811 }
7812
7813 /* Define where to return a (scalar) value of type TYPE.
7814 If TYPE is null, define where to return a (scalar)
7815 value of mode MODE from a libcall. */
7816
7817 rtx
s390_function_value(tree type,enum machine_mode mode)7818 s390_function_value (tree type, enum machine_mode mode)
7819 {
7820 if (type)
7821 {
7822 int unsignedp = TYPE_UNSIGNED (type);
7823 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
7824 }
7825
7826 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
7827 gcc_assert (GET_MODE_SIZE (mode) <= 8);
7828
7829 if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
7830 return gen_rtx_REG (mode, 16);
7831 else
7832 return gen_rtx_REG (mode, 2);
7833 }
7834
7835
7836 /* Create and return the va_list datatype.
7837
7838 On S/390, va_list is an array type equivalent to
7839
7840 typedef struct __va_list_tag
7841 {
7842 long __gpr;
7843 long __fpr;
7844 void *__overflow_arg_area;
7845 void *__reg_save_area;
7846 } va_list[1];
7847
7848 where __gpr and __fpr hold the number of general purpose
7849 or floating point arguments used up to now, respectively,
7850 __overflow_arg_area points to the stack location of the
7851 next argument passed on the stack, and __reg_save_area
7852 always points to the start of the register area in the
7853 call frame of the current function. The function prologue
7854 saves all registers used for argument passing into this
7855 area if the function uses variable arguments. */
7856
7857 static tree
s390_build_builtin_va_list(void)7858 s390_build_builtin_va_list (void)
7859 {
7860 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
7861
7862 record = lang_hooks.types.make_type (RECORD_TYPE);
7863
7864 type_decl =
7865 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
7866
7867 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
7868 long_integer_type_node);
7869 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
7870 long_integer_type_node);
7871 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
7872 ptr_type_node);
7873 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
7874 ptr_type_node);
7875
7876 va_list_gpr_counter_field = f_gpr;
7877 va_list_fpr_counter_field = f_fpr;
7878
7879 DECL_FIELD_CONTEXT (f_gpr) = record;
7880 DECL_FIELD_CONTEXT (f_fpr) = record;
7881 DECL_FIELD_CONTEXT (f_ovf) = record;
7882 DECL_FIELD_CONTEXT (f_sav) = record;
7883
7884 TREE_CHAIN (record) = type_decl;
7885 TYPE_NAME (record) = type_decl;
7886 TYPE_FIELDS (record) = f_gpr;
7887 TREE_CHAIN (f_gpr) = f_fpr;
7888 TREE_CHAIN (f_fpr) = f_ovf;
7889 TREE_CHAIN (f_ovf) = f_sav;
7890
7891 layout_type (record);
7892
7893 /* The correct type is an array type of one element. */
7894 return build_array_type (record, build_index_type (size_zero_node));
7895 }
7896
7897 /* Implement va_start by filling the va_list structure VALIST.
7898 STDARG_P is always true, and ignored.
7899 NEXTARG points to the first anonymous stack argument.
7900
7901 The following global variables are used to initialize
7902 the va_list structure:
7903
7904 current_function_args_info:
7905 holds number of gprs and fprs used for named arguments.
7906 current_function_arg_offset_rtx:
7907 holds the offset of the first anonymous stack argument
7908 (relative to the virtual arg pointer). */
7909
7910 void
s390_va_start(tree valist,rtx nextarg ATTRIBUTE_UNUSED)7911 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
7912 {
7913 HOST_WIDE_INT n_gpr, n_fpr;
7914 int off;
7915 tree f_gpr, f_fpr, f_ovf, f_sav;
7916 tree gpr, fpr, ovf, sav, t;
7917
7918 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7919 f_fpr = TREE_CHAIN (f_gpr);
7920 f_ovf = TREE_CHAIN (f_fpr);
7921 f_sav = TREE_CHAIN (f_ovf);
7922
7923 valist = build_va_arg_indirect_ref (valist);
7924 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7925 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7926 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7927 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7928
7929 /* Count number of gp and fp argument registers used. */
7930
7931 n_gpr = current_function_args_info.gprs;
7932 n_fpr = current_function_args_info.fprs;
7933
7934 if (cfun->va_list_gpr_size)
7935 {
7936 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
7937 build_int_cst (NULL_TREE, n_gpr));
7938 TREE_SIDE_EFFECTS (t) = 1;
7939 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7940 }
7941
7942 if (cfun->va_list_fpr_size)
7943 {
7944 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
7945 build_int_cst (NULL_TREE, n_fpr));
7946 TREE_SIDE_EFFECTS (t) = 1;
7947 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7948 }
7949
7950 /* Find the overflow area. */
7951 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
7952 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
7953 {
7954 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
7955
7956 off = INTVAL (current_function_arg_offset_rtx);
7957 off = off < 0 ? 0 : off;
7958 if (TARGET_DEBUG_ARG)
7959 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7960 (int)n_gpr, (int)n_fpr, off);
7961
7962 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
7963
7964 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
7965 TREE_SIDE_EFFECTS (t) = 1;
7966 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7967 }
7968
7969 /* Find the register save area. */
7970 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
7971 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
7972 {
7973 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
7974 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
7975 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
7976
7977 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
7978 TREE_SIDE_EFFECTS (t) = 1;
7979 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7980 }
7981 }
7982
7983 /* Implement va_arg by updating the va_list structure
7984 VALIST as required to retrieve an argument of type
7985 TYPE, and returning that argument.
7986
7987 Generates code equivalent to:
7988
7989 if (integral value) {
7990 if (size <= 4 && args.gpr < 5 ||
7991 size > 4 && args.gpr < 4 )
7992 ret = args.reg_save_area[args.gpr+8]
7993 else
7994 ret = *args.overflow_arg_area++;
7995 } else if (float value) {
7996 if (args.fgpr < 2)
7997 ret = args.reg_save_area[args.fpr+64]
7998 else
7999 ret = *args.overflow_arg_area++;
8000 } else if (aggregate value) {
8001 if (args.gpr < 5)
8002 ret = *args.reg_save_area[args.gpr]
8003 else
8004 ret = **args.overflow_arg_area++;
8005 } */
8006
8007 static tree
s390_gimplify_va_arg(tree valist,tree type,tree * pre_p,tree * post_p ATTRIBUTE_UNUSED)8008 s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
8009 tree *post_p ATTRIBUTE_UNUSED)
8010 {
8011 tree f_gpr, f_fpr, f_ovf, f_sav;
8012 tree gpr, fpr, ovf, sav, reg, t, u;
8013 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
8014 tree lab_false, lab_over, addr;
8015
8016 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8017 f_fpr = TREE_CHAIN (f_gpr);
8018 f_ovf = TREE_CHAIN (f_fpr);
8019 f_sav = TREE_CHAIN (f_ovf);
8020
8021 valist = build_va_arg_indirect_ref (valist);
8022 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8023 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
8024 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
8025 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
8026
8027 size = int_size_in_bytes (type);
8028
8029 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8030 {
8031 if (TARGET_DEBUG_ARG)
8032 {
8033 fprintf (stderr, "va_arg: aggregate type");
8034 debug_tree (type);
8035 }
8036
8037 /* Aggregates are passed by reference. */
8038 indirect_p = 1;
8039 reg = gpr;
8040 n_reg = 1;
8041
8042 /* kernel stack layout on 31 bit: It is assumed here that no padding
8043 will be added by s390_frame_info because for va_args always an even
8044 number of gprs has to be saved r15-r2 = 14 regs. */
8045 sav_ofs = 2 * UNITS_PER_WORD;
8046 sav_scale = UNITS_PER_WORD;
8047 size = UNITS_PER_WORD;
8048 max_reg = GP_ARG_NUM_REG - n_reg;
8049 }
8050 else if (s390_function_arg_float (TYPE_MODE (type), type))
8051 {
8052 if (TARGET_DEBUG_ARG)
8053 {
8054 fprintf (stderr, "va_arg: float type");
8055 debug_tree (type);
8056 }
8057
8058 /* FP args go in FP registers, if present. */
8059 indirect_p = 0;
8060 reg = fpr;
8061 n_reg = 1;
8062 sav_ofs = 16 * UNITS_PER_WORD;
8063 sav_scale = 8;
8064 max_reg = FP_ARG_NUM_REG - n_reg;
8065 }
8066 else
8067 {
8068 if (TARGET_DEBUG_ARG)
8069 {
8070 fprintf (stderr, "va_arg: other type");
8071 debug_tree (type);
8072 }
8073
8074 /* Otherwise into GP registers. */
8075 indirect_p = 0;
8076 reg = gpr;
8077 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
8078
8079 /* kernel stack layout on 31 bit: It is assumed here that no padding
8080 will be added by s390_frame_info because for va_args always an even
8081 number of gprs has to be saved r15-r2 = 14 regs. */
8082 sav_ofs = 2 * UNITS_PER_WORD;
8083
8084 if (size < UNITS_PER_WORD)
8085 sav_ofs += UNITS_PER_WORD - size;
8086
8087 sav_scale = UNITS_PER_WORD;
8088 max_reg = GP_ARG_NUM_REG - n_reg;
8089 }
8090
8091 /* Pull the value out of the saved registers ... */
8092
8093 lab_false = create_artificial_label ();
8094 lab_over = create_artificial_label ();
8095 addr = create_tmp_var (ptr_type_node, "addr");
8096 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
8097
8098 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
8099 t = build2 (GT_EXPR, boolean_type_node, reg, t);
8100 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8101 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8102 gimplify_and_add (t, pre_p);
8103
8104 t = build2 (PLUS_EXPR, ptr_type_node, sav,
8105 fold_convert (ptr_type_node, size_int (sav_ofs)));
8106 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
8107 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
8108 t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
8109
8110 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
8111 gimplify_and_add (t, pre_p);
8112
8113 t = build1 (GOTO_EXPR, void_type_node, lab_over);
8114 gimplify_and_add (t, pre_p);
8115
8116 t = build1 (LABEL_EXPR, void_type_node, lab_false);
8117 append_to_statement_list (t, pre_p);
8118
8119
8120 /* ... Otherwise out of the overflow area. */
8121
8122 t = ovf;
8123 if (size < UNITS_PER_WORD)
8124 t = build2 (PLUS_EXPR, ptr_type_node, t,
8125 fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
8126
8127 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8128
8129 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
8130 gimplify_and_add (u, pre_p);
8131
8132 t = build2 (PLUS_EXPR, ptr_type_node, t,
8133 fold_convert (ptr_type_node, size_int (size)));
8134 t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
8135 gimplify_and_add (t, pre_p);
8136
8137 t = build1 (LABEL_EXPR, void_type_node, lab_over);
8138 append_to_statement_list (t, pre_p);
8139
8140
8141 /* Increment register save count. */
8142
8143 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
8144 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
8145 gimplify_and_add (u, pre_p);
8146
8147 if (indirect_p)
8148 {
8149 t = build_pointer_type (build_pointer_type (type));
8150 addr = fold_convert (t, addr);
8151 addr = build_va_arg_indirect_ref (addr);
8152 }
8153 else
8154 {
8155 t = build_pointer_type (type);
8156 addr = fold_convert (t, addr);
8157 }
8158
8159 return build_va_arg_indirect_ref (addr);
8160 }
8161
8162
8163 /* Builtins. */
8164
8165 enum s390_builtin
8166 {
8167 S390_BUILTIN_THREAD_POINTER,
8168 S390_BUILTIN_SET_THREAD_POINTER,
8169
8170 S390_BUILTIN_max
8171 };
8172
8173 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
8174 CODE_FOR_get_tp_64,
8175 CODE_FOR_set_tp_64
8176 };
8177
8178 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
8179 CODE_FOR_get_tp_31,
8180 CODE_FOR_set_tp_31
8181 };
8182
8183 static void
s390_init_builtins(void)8184 s390_init_builtins (void)
8185 {
8186 tree ftype;
8187
8188 ftype = build_function_type (ptr_type_node, void_list_node);
8189 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
8190 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
8191 NULL, NULL_TREE);
8192
8193 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
8194 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
8195 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
8196 NULL, NULL_TREE);
8197 }
8198
8199 /* Expand an expression EXP that calls a built-in function,
8200 with result going to TARGET if that's convenient
8201 (and in mode MODE if that's convenient).
8202 SUBTARGET may be used as the target for computing one of EXP's operands.
8203 IGNORE is nonzero if the value is to be ignored. */
8204
8205 static rtx
s390_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)8206 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8207 enum machine_mode mode ATTRIBUTE_UNUSED,
8208 int ignore ATTRIBUTE_UNUSED)
8209 {
8210 #define MAX_ARGS 2
8211
8212 unsigned int const *code_for_builtin =
8213 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
8214
8215 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8216 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8217 tree arglist = TREE_OPERAND (exp, 1);
8218 enum insn_code icode;
8219 rtx op[MAX_ARGS], pat;
8220 int arity;
8221 bool nonvoid;
8222
8223 if (fcode >= S390_BUILTIN_max)
8224 internal_error ("bad builtin fcode");
8225 icode = code_for_builtin[fcode];
8226 if (icode == 0)
8227 internal_error ("bad builtin fcode");
8228
8229 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
8230
8231 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
8232 arglist;
8233 arglist = TREE_CHAIN (arglist), arity++)
8234 {
8235 const struct insn_operand_data *insn_op;
8236
8237 tree arg = TREE_VALUE (arglist);
8238 if (arg == error_mark_node)
8239 return NULL_RTX;
8240 if (arity > MAX_ARGS)
8241 return NULL_RTX;
8242
8243 insn_op = &insn_data[icode].operand[arity + nonvoid];
8244
8245 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
8246
8247 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
8248 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
8249 }
8250
8251 if (nonvoid)
8252 {
8253 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8254 if (!target
8255 || GET_MODE (target) != tmode
8256 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
8257 target = gen_reg_rtx (tmode);
8258 }
8259
8260 switch (arity)
8261 {
8262 case 0:
8263 pat = GEN_FCN (icode) (target);
8264 break;
8265 case 1:
8266 if (nonvoid)
8267 pat = GEN_FCN (icode) (target, op[0]);
8268 else
8269 pat = GEN_FCN (icode) (op[0]);
8270 break;
8271 case 2:
8272 pat = GEN_FCN (icode) (target, op[0], op[1]);
8273 break;
8274 default:
8275 gcc_unreachable ();
8276 }
8277 if (!pat)
8278 return NULL_RTX;
8279 emit_insn (pat);
8280
8281 if (nonvoid)
8282 return target;
8283 else
8284 return const0_rtx;
8285 }
8286
8287
8288 /* Output assembly code for the trampoline template to
8289 stdio stream FILE.
8290
8291 On S/390, we use gpr 1 internally in the trampoline code;
8292 gpr 0 is used to hold the static chain. */
8293
8294 void
s390_trampoline_template(FILE * file)8295 s390_trampoline_template (FILE *file)
8296 {
8297 rtx op[2];
8298 op[0] = gen_rtx_REG (Pmode, 0);
8299 op[1] = gen_rtx_REG (Pmode, 1);
8300
8301 if (TARGET_64BIT)
8302 {
8303 output_asm_insn ("basr\t%1,0", op);
8304 output_asm_insn ("lmg\t%0,%1,14(%1)", op);
8305 output_asm_insn ("br\t%1", op);
8306 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
8307 }
8308 else
8309 {
8310 output_asm_insn ("basr\t%1,0", op);
8311 output_asm_insn ("lm\t%0,%1,6(%1)", op);
8312 output_asm_insn ("br\t%1", op);
8313 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
8314 }
8315 }
8316
8317 /* Emit RTL insns to initialize the variable parts of a trampoline.
8318 FNADDR is an RTX for the address of the function's pure code.
8319 CXT is an RTX for the static chain value for the function. */
8320
8321 void
s390_initialize_trampoline(rtx addr,rtx fnaddr,rtx cxt)8322 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
8323 {
8324 emit_move_insn (gen_rtx_MEM (Pmode,
8325 memory_address (Pmode,
8326 plus_constant (addr, (TARGET_64BIT ? 16 : 8)))), cxt);
8327 emit_move_insn (gen_rtx_MEM (Pmode,
8328 memory_address (Pmode,
8329 plus_constant (addr, (TARGET_64BIT ? 24 : 12)))), fnaddr);
8330 }
8331
8332 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8333 LOW and HIGH, independent of the host word size. */
8334
8335 rtx
s390_gen_rtx_const_DI(int high,int low)8336 s390_gen_rtx_const_DI (int high, int low)
8337 {
8338 #if HOST_BITS_PER_WIDE_INT >= 64
8339 HOST_WIDE_INT val;
8340 val = (HOST_WIDE_INT)high;
8341 val <<= 32;
8342 val |= (HOST_WIDE_INT)low;
8343
8344 return GEN_INT (val);
8345 #else
8346 #if HOST_BITS_PER_WIDE_INT >= 32
8347 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
8348 #else
8349 gcc_unreachable ();
8350 #endif
8351 #endif
8352 }
8353
8354 /* Output assembler code to FILE to increment profiler label # LABELNO
8355 for profiling a function entry. */
8356
8357 void
s390_function_profiler(FILE * file,int labelno)8358 s390_function_profiler (FILE *file, int labelno)
8359 {
8360 rtx op[7];
8361
8362 char label[128];
8363 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
8364
8365 fprintf (file, "# function profiler \n");
8366
8367 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
8368 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
8369 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
8370
8371 op[2] = gen_rtx_REG (Pmode, 1);
8372 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
8373 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
8374
8375 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
8376 if (flag_pic)
8377 {
8378 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
8379 op[4] = gen_rtx_CONST (Pmode, op[4]);
8380 }
8381
8382 if (TARGET_64BIT)
8383 {
8384 output_asm_insn ("stg\t%0,%1", op);
8385 output_asm_insn ("larl\t%2,%3", op);
8386 output_asm_insn ("brasl\t%0,%4", op);
8387 output_asm_insn ("lg\t%0,%1", op);
8388 }
8389 else if (!flag_pic)
8390 {
8391 op[6] = gen_label_rtx ();
8392
8393 output_asm_insn ("st\t%0,%1", op);
8394 output_asm_insn ("bras\t%2,%l6", op);
8395 output_asm_insn (".long\t%4", op);
8396 output_asm_insn (".long\t%3", op);
8397 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8398 output_asm_insn ("l\t%0,0(%2)", op);
8399 output_asm_insn ("l\t%2,4(%2)", op);
8400 output_asm_insn ("basr\t%0,%0", op);
8401 output_asm_insn ("l\t%0,%1", op);
8402 }
8403 else
8404 {
8405 op[5] = gen_label_rtx ();
8406 op[6] = gen_label_rtx ();
8407
8408 output_asm_insn ("st\t%0,%1", op);
8409 output_asm_insn ("bras\t%2,%l6", op);
8410 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
8411 output_asm_insn (".long\t%4-%l5", op);
8412 output_asm_insn (".long\t%3-%l5", op);
8413 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8414 output_asm_insn ("lr\t%0,%2", op);
8415 output_asm_insn ("a\t%0,0(%2)", op);
8416 output_asm_insn ("a\t%2,4(%2)", op);
8417 output_asm_insn ("basr\t%0,%0", op);
8418 output_asm_insn ("l\t%0,%1", op);
8419 }
8420 }
8421
8422 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8423 into its SYMBOL_REF_FLAGS. */
8424
8425 static void
s390_encode_section_info(tree decl,rtx rtl,int first)8426 s390_encode_section_info (tree decl, rtx rtl, int first)
8427 {
8428 default_encode_section_info (decl, rtl, first);
8429
8430 /* If a variable has a forced alignment to < 2 bytes, mark it with
8431 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8432 if (TREE_CODE (decl) == VAR_DECL
8433 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
8434 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
8435 }
8436
8437 /* Output thunk to FILE that implements a C++ virtual function call (with
8438 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8439 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8440 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8441 relative to the resulting this pointer. */
8442
8443 static void
s390_output_mi_thunk(FILE * file,tree thunk ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset,tree function)8444 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
8445 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8446 tree function)
8447 {
8448 rtx op[10];
8449 int nonlocal = 0;
8450
8451 /* Operand 0 is the target function. */
8452 op[0] = XEXP (DECL_RTL (function), 0);
8453 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
8454 {
8455 nonlocal = 1;
8456 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
8457 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
8458 op[0] = gen_rtx_CONST (Pmode, op[0]);
8459 }
8460
8461 /* Operand 1 is the 'this' pointer. */
8462 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8463 op[1] = gen_rtx_REG (Pmode, 3);
8464 else
8465 op[1] = gen_rtx_REG (Pmode, 2);
8466
8467 /* Operand 2 is the delta. */
8468 op[2] = GEN_INT (delta);
8469
8470 /* Operand 3 is the vcall_offset. */
8471 op[3] = GEN_INT (vcall_offset);
8472
8473 /* Operand 4 is the temporary register. */
8474 op[4] = gen_rtx_REG (Pmode, 1);
8475
8476 /* Operands 5 to 8 can be used as labels. */
8477 op[5] = NULL_RTX;
8478 op[6] = NULL_RTX;
8479 op[7] = NULL_RTX;
8480 op[8] = NULL_RTX;
8481
8482 /* Operand 9 can be used for temporary register. */
8483 op[9] = NULL_RTX;
8484
8485 /* Generate code. */
8486 if (TARGET_64BIT)
8487 {
8488 /* Setup literal pool pointer if required. */
8489 if ((!DISP_IN_RANGE (delta)
8490 && !CONST_OK_FOR_K (delta)
8491 && !CONST_OK_FOR_Os (delta))
8492 || (!DISP_IN_RANGE (vcall_offset)
8493 && !CONST_OK_FOR_K (vcall_offset)
8494 && !CONST_OK_FOR_Os (vcall_offset)))
8495 {
8496 op[5] = gen_label_rtx ();
8497 output_asm_insn ("larl\t%4,%5", op);
8498 }
8499
8500 /* Add DELTA to this pointer. */
8501 if (delta)
8502 {
8503 if (CONST_OK_FOR_J (delta))
8504 output_asm_insn ("la\t%1,%2(%1)", op);
8505 else if (DISP_IN_RANGE (delta))
8506 output_asm_insn ("lay\t%1,%2(%1)", op);
8507 else if (CONST_OK_FOR_K (delta))
8508 output_asm_insn ("aghi\t%1,%2", op);
8509 else if (CONST_OK_FOR_Os (delta))
8510 output_asm_insn ("agfi\t%1,%2", op);
8511 else
8512 {
8513 op[6] = gen_label_rtx ();
8514 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
8515 }
8516 }
8517
8518 /* Perform vcall adjustment. */
8519 if (vcall_offset)
8520 {
8521 if (DISP_IN_RANGE (vcall_offset))
8522 {
8523 output_asm_insn ("lg\t%4,0(%1)", op);
8524 output_asm_insn ("ag\t%1,%3(%4)", op);
8525 }
8526 else if (CONST_OK_FOR_K (vcall_offset))
8527 {
8528 output_asm_insn ("lghi\t%4,%3", op);
8529 output_asm_insn ("ag\t%4,0(%1)", op);
8530 output_asm_insn ("ag\t%1,0(%4)", op);
8531 }
8532 else if (CONST_OK_FOR_Os (vcall_offset))
8533 {
8534 output_asm_insn ("lgfi\t%4,%3", op);
8535 output_asm_insn ("ag\t%4,0(%1)", op);
8536 output_asm_insn ("ag\t%1,0(%4)", op);
8537 }
8538 else
8539 {
8540 op[7] = gen_label_rtx ();
8541 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
8542 output_asm_insn ("ag\t%4,0(%1)", op);
8543 output_asm_insn ("ag\t%1,0(%4)", op);
8544 }
8545 }
8546
8547 /* Jump to target. */
8548 output_asm_insn ("jg\t%0", op);
8549
8550 /* Output literal pool if required. */
8551 if (op[5])
8552 {
8553 output_asm_insn (".align\t4", op);
8554 targetm.asm_out.internal_label (file, "L",
8555 CODE_LABEL_NUMBER (op[5]));
8556 }
8557 if (op[6])
8558 {
8559 targetm.asm_out.internal_label (file, "L",
8560 CODE_LABEL_NUMBER (op[6]));
8561 output_asm_insn (".long\t%2", op);
8562 }
8563 if (op[7])
8564 {
8565 targetm.asm_out.internal_label (file, "L",
8566 CODE_LABEL_NUMBER (op[7]));
8567 output_asm_insn (".long\t%3", op);
8568 }
8569 }
8570 else
8571 {
8572 /* Setup base pointer if required. */
8573 if (!vcall_offset
8574 || (!DISP_IN_RANGE (delta)
8575 && !CONST_OK_FOR_K (delta)
8576 && !CONST_OK_FOR_Os (delta))
8577 || (!DISP_IN_RANGE (delta)
8578 && !CONST_OK_FOR_K (vcall_offset)
8579 && !CONST_OK_FOR_Os (vcall_offset)))
8580 {
8581 op[5] = gen_label_rtx ();
8582 output_asm_insn ("basr\t%4,0", op);
8583 targetm.asm_out.internal_label (file, "L",
8584 CODE_LABEL_NUMBER (op[5]));
8585 }
8586
8587 /* Add DELTA to this pointer. */
8588 if (delta)
8589 {
8590 if (CONST_OK_FOR_J (delta))
8591 output_asm_insn ("la\t%1,%2(%1)", op);
8592 else if (DISP_IN_RANGE (delta))
8593 output_asm_insn ("lay\t%1,%2(%1)", op);
8594 else if (CONST_OK_FOR_K (delta))
8595 output_asm_insn ("ahi\t%1,%2", op);
8596 else if (CONST_OK_FOR_Os (delta))
8597 output_asm_insn ("afi\t%1,%2", op);
8598 else
8599 {
8600 op[6] = gen_label_rtx ();
8601 output_asm_insn ("a\t%1,%6-%5(%4)", op);
8602 }
8603 }
8604
8605 /* Perform vcall adjustment. */
8606 if (vcall_offset)
8607 {
8608 if (CONST_OK_FOR_J (vcall_offset))
8609 {
8610 output_asm_insn ("l\t%4,0(%1)", op);
8611 output_asm_insn ("a\t%1,%3(%4)", op);
8612 }
8613 else if (DISP_IN_RANGE (vcall_offset))
8614 {
8615 output_asm_insn ("l\t%4,0(%1)", op);
8616 output_asm_insn ("ay\t%1,%3(%4)", op);
8617 }
8618 else if (CONST_OK_FOR_K (vcall_offset))
8619 {
8620 output_asm_insn ("lhi\t%4,%3", op);
8621 output_asm_insn ("a\t%4,0(%1)", op);
8622 output_asm_insn ("a\t%1,0(%4)", op);
8623 }
8624 else if (CONST_OK_FOR_Os (vcall_offset))
8625 {
8626 output_asm_insn ("iilf\t%4,%3", op);
8627 output_asm_insn ("a\t%4,0(%1)", op);
8628 output_asm_insn ("a\t%1,0(%4)", op);
8629 }
8630 else
8631 {
8632 op[7] = gen_label_rtx ();
8633 output_asm_insn ("l\t%4,%7-%5(%4)", op);
8634 output_asm_insn ("a\t%4,0(%1)", op);
8635 output_asm_insn ("a\t%1,0(%4)", op);
8636 }
8637
8638 /* We had to clobber the base pointer register.
8639 Re-setup the base pointer (with a different base). */
8640 op[5] = gen_label_rtx ();
8641 output_asm_insn ("basr\t%4,0", op);
8642 targetm.asm_out.internal_label (file, "L",
8643 CODE_LABEL_NUMBER (op[5]));
8644 }
8645
8646 /* Jump to target. */
8647 op[8] = gen_label_rtx ();
8648
8649 if (!flag_pic)
8650 output_asm_insn ("l\t%4,%8-%5(%4)", op);
8651 else if (!nonlocal)
8652 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8653 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8654 else if (flag_pic == 1)
8655 {
8656 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8657 output_asm_insn ("l\t%4,%0(%4)", op);
8658 }
8659 else if (flag_pic == 2)
8660 {
8661 op[9] = gen_rtx_REG (Pmode, 0);
8662 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
8663 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8664 output_asm_insn ("ar\t%4,%9", op);
8665 output_asm_insn ("l\t%4,0(%4)", op);
8666 }
8667
8668 output_asm_insn ("br\t%4", op);
8669
8670 /* Output literal pool. */
8671 output_asm_insn (".align\t4", op);
8672
8673 if (nonlocal && flag_pic == 2)
8674 output_asm_insn (".long\t%0", op);
8675 if (nonlocal)
8676 {
8677 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
8678 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
8679 }
8680
8681 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
8682 if (!flag_pic)
8683 output_asm_insn (".long\t%0", op);
8684 else
8685 output_asm_insn (".long\t%0-%5", op);
8686
8687 if (op[6])
8688 {
8689 targetm.asm_out.internal_label (file, "L",
8690 CODE_LABEL_NUMBER (op[6]));
8691 output_asm_insn (".long\t%2", op);
8692 }
8693 if (op[7])
8694 {
8695 targetm.asm_out.internal_label (file, "L",
8696 CODE_LABEL_NUMBER (op[7]));
8697 output_asm_insn (".long\t%3", op);
8698 }
8699 }
8700 }
8701
8702 static bool
s390_valid_pointer_mode(enum machine_mode mode)8703 s390_valid_pointer_mode (enum machine_mode mode)
8704 {
8705 return (mode == SImode || (TARGET_64BIT && mode == DImode));
8706 }
8707
8708 /* Checks whether the given ARGUMENT_LIST would use a caller
8709 saved register. This is used to decide whether sibling call
8710 optimization could be performed on the respective function
8711 call. */
8712
8713 static bool
s390_call_saved_register_used(tree argument_list)8714 s390_call_saved_register_used (tree argument_list)
8715 {
8716 CUMULATIVE_ARGS cum;
8717 tree parameter;
8718 enum machine_mode mode;
8719 tree type;
8720 rtx parm_rtx;
8721 int reg;
8722
8723 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
8724
8725 while (argument_list)
8726 {
8727 parameter = TREE_VALUE (argument_list);
8728 argument_list = TREE_CHAIN (argument_list);
8729
8730 gcc_assert (parameter);
8731
8732 /* For an undeclared variable passed as parameter we will get
8733 an ERROR_MARK node here. */
8734 if (TREE_CODE (parameter) == ERROR_MARK)
8735 return true;
8736
8737 type = TREE_TYPE (parameter);
8738 gcc_assert (type);
8739
8740 mode = TYPE_MODE (type);
8741 gcc_assert (mode);
8742
8743 if (pass_by_reference (&cum, mode, type, true))
8744 {
8745 mode = Pmode;
8746 type = build_pointer_type (type);
8747 }
8748
8749 parm_rtx = s390_function_arg (&cum, mode, type, 0);
8750
8751 s390_function_arg_advance (&cum, mode, type, 0);
8752
8753 if (parm_rtx && REG_P (parm_rtx))
8754 {
8755 for (reg = 0;
8756 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
8757 reg++)
8758 if (! call_used_regs[reg + REGNO (parm_rtx)])
8759 return true;
8760 }
8761 }
8762 return false;
8763 }
8764
8765 /* Return true if the given call expression can be
8766 turned into a sibling call.
8767 DECL holds the declaration of the function to be called whereas
8768 EXP is the call expression itself. */
8769
8770 static bool
s390_function_ok_for_sibcall(tree decl,tree exp)8771 s390_function_ok_for_sibcall (tree decl, tree exp)
8772 {
8773 /* The TPF epilogue uses register 1. */
8774 if (TARGET_TPF_PROFILING)
8775 return false;
8776
8777 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8778 which would have to be restored before the sibcall. */
8779 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
8780 return false;
8781
8782 /* Register 6 on s390 is available as an argument register but unfortunately
8783 "caller saved". This makes functions needing this register for arguments
8784 not suitable for sibcalls. */
8785 if (TREE_OPERAND (exp, 1)
8786 && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
8787 return false;
8788
8789 return true;
8790 }
8791
8792 /* Return the fixed registers used for condition codes. */
8793
8794 static bool
s390_fixed_condition_code_regs(unsigned int * p1,unsigned int * p2)8795 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
8796 {
8797 *p1 = CC_REGNUM;
8798 *p2 = INVALID_REGNUM;
8799
8800 return true;
8801 }
8802
8803 /* This function is used by the call expanders of the machine description.
8804 It emits the call insn itself together with the necessary operations
8805 to adjust the target address and returns the emitted insn.
8806 ADDR_LOCATION is the target address rtx
8807 TLS_CALL the location of the thread-local symbol
8808 RESULT_REG the register where the result of the call should be stored
8809 RETADDR_REG the register where the return address should be stored
8810 If this parameter is NULL_RTX the call is considered
8811 to be a sibling call. */
8812
8813 rtx
s390_emit_call(rtx addr_location,rtx tls_call,rtx result_reg,rtx retaddr_reg)8814 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
8815 rtx retaddr_reg)
8816 {
8817 bool plt_call = false;
8818 rtx insn;
8819 rtx call;
8820 rtx clobber;
8821 rtvec vec;
8822
8823 /* Direct function calls need special treatment. */
8824 if (GET_CODE (addr_location) == SYMBOL_REF)
8825 {
8826 /* When calling a global routine in PIC mode, we must
8827 replace the symbol itself with the PLT stub. */
8828 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
8829 {
8830 addr_location = gen_rtx_UNSPEC (Pmode,
8831 gen_rtvec (1, addr_location),
8832 UNSPEC_PLT);
8833 addr_location = gen_rtx_CONST (Pmode, addr_location);
8834 plt_call = true;
8835 }
8836
8837 /* Unless we can use the bras(l) insn, force the
8838 routine address into a register. */
8839 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
8840 {
8841 if (flag_pic)
8842 addr_location = legitimize_pic_address (addr_location, 0);
8843 else
8844 addr_location = force_reg (Pmode, addr_location);
8845 }
8846 }
8847
8848 /* If it is already an indirect call or the code above moved the
8849 SYMBOL_REF to somewhere else make sure the address can be found in
8850 register 1. */
8851 if (retaddr_reg == NULL_RTX
8852 && GET_CODE (addr_location) != SYMBOL_REF
8853 && !plt_call)
8854 {
8855 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
8856 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
8857 }
8858
8859 addr_location = gen_rtx_MEM (QImode, addr_location);
8860 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8861
8862 if (result_reg != NULL_RTX)
8863 call = gen_rtx_SET (VOIDmode, result_reg, call);
8864
8865 if (retaddr_reg != NULL_RTX)
8866 {
8867 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
8868
8869 if (tls_call != NULL_RTX)
8870 vec = gen_rtvec (3, call, clobber,
8871 gen_rtx_USE (VOIDmode, tls_call));
8872 else
8873 vec = gen_rtvec (2, call, clobber);
8874
8875 call = gen_rtx_PARALLEL (VOIDmode, vec);
8876 }
8877
8878 insn = emit_call_insn (call);
8879
8880 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8881 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
8882 {
8883 /* s390_function_ok_for_sibcall should
8884 have denied sibcalls in this case. */
8885 gcc_assert (retaddr_reg != NULL_RTX);
8886
8887 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
8888 }
8889 return insn;
8890 }
8891
8892 /* Implement CONDITIONAL_REGISTER_USAGE. */
8893
8894 void
s390_conditional_register_usage(void)8895 s390_conditional_register_usage (void)
8896 {
8897 int i;
8898
8899 if (flag_pic)
8900 {
8901 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8902 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8903 }
8904 if (TARGET_CPU_ZARCH)
8905 {
8906 fixed_regs[BASE_REGNUM] = 0;
8907 call_used_regs[BASE_REGNUM] = 0;
8908 fixed_regs[RETURN_REGNUM] = 0;
8909 call_used_regs[RETURN_REGNUM] = 0;
8910 }
8911 if (TARGET_64BIT)
8912 {
8913 for (i = 24; i < 32; i++)
8914 call_used_regs[i] = call_really_used_regs[i] = 0;
8915 }
8916 else
8917 {
8918 for (i = 18; i < 20; i++)
8919 call_used_regs[i] = call_really_used_regs[i] = 0;
8920 }
8921
8922 if (TARGET_SOFT_FLOAT)
8923 {
8924 for (i = 16; i < 32; i++)
8925 call_used_regs[i] = fixed_regs[i] = 1;
8926 }
8927 }
8928
8929 /* Corresponding function to eh_return expander. */
8930
8931 static GTY(()) rtx s390_tpf_eh_return_symbol;
8932 void
s390_emit_tpf_eh_return(rtx target)8933 s390_emit_tpf_eh_return (rtx target)
8934 {
8935 rtx insn, reg;
8936
8937 if (!s390_tpf_eh_return_symbol)
8938 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
8939
8940 reg = gen_rtx_REG (Pmode, 2);
8941
8942 emit_move_insn (reg, target);
8943 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
8944 gen_rtx_REG (Pmode, RETURN_REGNUM));
8945 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
8946
8947 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
8948 }
8949
8950 /* Rework the prologue/epilogue to avoid saving/restoring
8951 registers unnecessarily. */
8952
8953 static void
s390_optimize_prologue(void)8954 s390_optimize_prologue (void)
8955 {
8956 rtx insn, new_insn, next_insn;
8957
8958 /* Do a final recompute of the frame-related data. */
8959
8960 s390_update_frame_layout ();
8961
8962 /* If all special registers are in fact used, there's nothing we
8963 can do, so no point in walking the insn list. */
8964
8965 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
8966 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
8967 && (TARGET_CPU_ZARCH
8968 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
8969 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
8970 return;
8971
8972 /* Search for prologue/epilogue insns and replace them. */
8973
8974 for (insn = get_insns (); insn; insn = next_insn)
8975 {
8976 int first, last, off;
8977 rtx set, base, offset;
8978
8979 next_insn = NEXT_INSN (insn);
8980
8981 if (GET_CODE (insn) != INSN)
8982 continue;
8983
8984 if (GET_CODE (PATTERN (insn)) == PARALLEL
8985 && store_multiple_operation (PATTERN (insn), VOIDmode))
8986 {
8987 set = XVECEXP (PATTERN (insn), 0, 0);
8988 first = REGNO (SET_SRC (set));
8989 last = first + XVECLEN (PATTERN (insn), 0) - 1;
8990 offset = const0_rtx;
8991 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
8992 off = INTVAL (offset);
8993
8994 if (GET_CODE (base) != REG || off < 0)
8995 continue;
8996 if (cfun_frame_layout.first_save_gpr != -1
8997 && (cfun_frame_layout.first_save_gpr < first
8998 || cfun_frame_layout.last_save_gpr > last))
8999 continue;
9000 if (REGNO (base) != STACK_POINTER_REGNUM
9001 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9002 continue;
9003 if (first > BASE_REGNUM || last < BASE_REGNUM)
9004 continue;
9005
9006 if (cfun_frame_layout.first_save_gpr != -1)
9007 {
9008 new_insn = save_gprs (base,
9009 off + (cfun_frame_layout.first_save_gpr
9010 - first) * UNITS_PER_WORD,
9011 cfun_frame_layout.first_save_gpr,
9012 cfun_frame_layout.last_save_gpr);
9013 new_insn = emit_insn_before (new_insn, insn);
9014 INSN_ADDRESSES_NEW (new_insn, -1);
9015 }
9016
9017 remove_insn (insn);
9018 continue;
9019 }
9020
9021 if (cfun_frame_layout.first_save_gpr == -1
9022 && GET_CODE (PATTERN (insn)) == SET
9023 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
9024 && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
9025 || (!TARGET_CPU_ZARCH
9026 && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
9027 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
9028 {
9029 set = PATTERN (insn);
9030 first = REGNO (SET_SRC (set));
9031 offset = const0_rtx;
9032 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9033 off = INTVAL (offset);
9034
9035 if (GET_CODE (base) != REG || off < 0)
9036 continue;
9037 if (REGNO (base) != STACK_POINTER_REGNUM
9038 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9039 continue;
9040
9041 remove_insn (insn);
9042 continue;
9043 }
9044
9045 if (GET_CODE (PATTERN (insn)) == PARALLEL
9046 && load_multiple_operation (PATTERN (insn), VOIDmode))
9047 {
9048 set = XVECEXP (PATTERN (insn), 0, 0);
9049 first = REGNO (SET_DEST (set));
9050 last = first + XVECLEN (PATTERN (insn), 0) - 1;
9051 offset = const0_rtx;
9052 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9053 off = INTVAL (offset);
9054
9055 if (GET_CODE (base) != REG || off < 0)
9056 continue;
9057 if (cfun_frame_layout.first_restore_gpr != -1
9058 && (cfun_frame_layout.first_restore_gpr < first
9059 || cfun_frame_layout.last_restore_gpr > last))
9060 continue;
9061 if (REGNO (base) != STACK_POINTER_REGNUM
9062 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9063 continue;
9064 if (first > BASE_REGNUM || last < BASE_REGNUM)
9065 continue;
9066
9067 if (cfun_frame_layout.first_restore_gpr != -1)
9068 {
9069 new_insn = restore_gprs (base,
9070 off + (cfun_frame_layout.first_restore_gpr
9071 - first) * UNITS_PER_WORD,
9072 cfun_frame_layout.first_restore_gpr,
9073 cfun_frame_layout.last_restore_gpr);
9074 new_insn = emit_insn_before (new_insn, insn);
9075 INSN_ADDRESSES_NEW (new_insn, -1);
9076 }
9077
9078 remove_insn (insn);
9079 continue;
9080 }
9081
9082 if (cfun_frame_layout.first_restore_gpr == -1
9083 && GET_CODE (PATTERN (insn)) == SET
9084 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
9085 && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
9086 || (!TARGET_CPU_ZARCH
9087 && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
9088 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
9089 {
9090 set = PATTERN (insn);
9091 first = REGNO (SET_DEST (set));
9092 offset = const0_rtx;
9093 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9094 off = INTVAL (offset);
9095
9096 if (GET_CODE (base) != REG || off < 0)
9097 continue;
9098 if (REGNO (base) != STACK_POINTER_REGNUM
9099 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9100 continue;
9101
9102 remove_insn (insn);
9103 continue;
9104 }
9105 }
9106 }
9107
9108 /* Perform machine-dependent processing. */
9109
9110 static void
s390_reorg(void)9111 s390_reorg (void)
9112 {
9113 bool pool_overflow = false;
9114
9115 /* Make sure all splits have been performed; splits after
9116 machine_dependent_reorg might confuse insn length counts. */
9117 split_all_insns_noflow ();
9118
9119 /* From here on decomposed literal pool addresses must be accepted. */
9120 cfun->machine->decomposed_literal_pool_addresses_ok_p = true;
9121
9122 /* Install the main literal pool and the associated base
9123 register load insns.
9124
9125 In addition, there are two problematic situations we need
9126 to correct:
9127
9128 - the literal pool might be > 4096 bytes in size, so that
9129 some of its elements cannot be directly accessed
9130
9131 - a branch target might be > 64K away from the branch, so that
9132 it is not possible to use a PC-relative instruction.
9133
9134 To fix those, we split the single literal pool into multiple
9135 pool chunks, reloading the pool base register at various
9136 points throughout the function to ensure it always points to
9137 the pool chunk the following code expects, and / or replace
9138 PC-relative branches by absolute branches.
9139
9140 However, the two problems are interdependent: splitting the
9141 literal pool can move a branch further away from its target,
9142 causing the 64K limit to overflow, and on the other hand,
9143 replacing a PC-relative branch by an absolute branch means
9144 we need to put the branch target address into the literal
9145 pool, possibly causing it to overflow.
9146
9147 So, we loop trying to fix up both problems until we manage
9148 to satisfy both conditions at the same time. Note that the
9149 loop is guaranteed to terminate as every pass of the loop
9150 strictly decreases the total number of PC-relative branches
9151 in the function. (This is not completely true as there
9152 might be branch-over-pool insns introduced by chunkify_start.
9153 Those never need to be split however.) */
9154
9155 for (;;)
9156 {
9157 struct constant_pool *pool = NULL;
9158
9159 /* Collect the literal pool. */
9160 if (!pool_overflow)
9161 {
9162 pool = s390_mainpool_start ();
9163 if (!pool)
9164 pool_overflow = true;
9165 }
9166
9167 /* If literal pool overflowed, start to chunkify it. */
9168 if (pool_overflow)
9169 pool = s390_chunkify_start ();
9170
9171 /* Split out-of-range branches. If this has created new
9172 literal pool entries, cancel current chunk list and
9173 recompute it. zSeries machines have large branch
9174 instructions, so we never need to split a branch. */
9175 if (!TARGET_CPU_ZARCH && s390_split_branches ())
9176 {
9177 if (pool_overflow)
9178 s390_chunkify_cancel (pool);
9179 else
9180 s390_mainpool_cancel (pool);
9181
9182 continue;
9183 }
9184
9185 /* If we made it up to here, both conditions are satisfied.
9186 Finish up literal pool related changes. */
9187 if (pool_overflow)
9188 s390_chunkify_finish (pool);
9189 else
9190 s390_mainpool_finish (pool);
9191
9192 /* We're done splitting branches. */
9193 cfun->machine->split_branches_pending_p = false;
9194 break;
9195 }
9196
9197 /* Generate out-of-pool execute target insns. */
9198 if (TARGET_CPU_ZARCH)
9199 {
9200 rtx insn, label, target;
9201
9202 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9203 {
9204 label = s390_execute_label (insn);
9205 if (!label)
9206 continue;
9207
9208 gcc_assert (label != const0_rtx);
9209
9210 target = emit_label (XEXP (label, 0));
9211 INSN_ADDRESSES_NEW (target, -1);
9212
9213 target = emit_insn (s390_execute_target (insn));
9214 INSN_ADDRESSES_NEW (target, -1);
9215 }
9216 }
9217
9218 /* Try to optimize prologue and epilogue further. */
9219 s390_optimize_prologue ();
9220 }
9221
9222
9223 /* Initialize GCC target structure. */
9224
9225 #undef TARGET_ASM_ALIGNED_HI_OP
9226 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9227 #undef TARGET_ASM_ALIGNED_DI_OP
9228 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9229 #undef TARGET_ASM_INTEGER
9230 #define TARGET_ASM_INTEGER s390_assemble_integer
9231
9232 #undef TARGET_ASM_OPEN_PAREN
9233 #define TARGET_ASM_OPEN_PAREN ""
9234
9235 #undef TARGET_ASM_CLOSE_PAREN
9236 #define TARGET_ASM_CLOSE_PAREN ""
9237
9238 #undef TARGET_DEFAULT_TARGET_FLAGS
9239 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9240 #undef TARGET_HANDLE_OPTION
9241 #define TARGET_HANDLE_OPTION s390_handle_option
9242
9243 #undef TARGET_ENCODE_SECTION_INFO
9244 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9245
9246 #ifdef HAVE_AS_TLS
9247 #undef TARGET_HAVE_TLS
9248 #define TARGET_HAVE_TLS true
9249 #endif
9250 #undef TARGET_CANNOT_FORCE_CONST_MEM
9251 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9252
9253 #undef TARGET_DELEGITIMIZE_ADDRESS
9254 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9255
9256 #undef TARGET_RETURN_IN_MEMORY
9257 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9258
9259 #undef TARGET_INIT_BUILTINS
9260 #define TARGET_INIT_BUILTINS s390_init_builtins
9261 #undef TARGET_EXPAND_BUILTIN
9262 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
9263
9264 #undef TARGET_ASM_OUTPUT_MI_THUNK
9265 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9266 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9267 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9268
9269 #undef TARGET_SCHED_ADJUST_PRIORITY
9270 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9271 #undef TARGET_SCHED_ISSUE_RATE
9272 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9273 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9274 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9275
9276 #undef TARGET_CANNOT_COPY_INSN_P
9277 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9278 #undef TARGET_RTX_COSTS
9279 #define TARGET_RTX_COSTS s390_rtx_costs
9280 #undef TARGET_ADDRESS_COST
9281 #define TARGET_ADDRESS_COST s390_address_cost
9282
9283 #undef TARGET_MACHINE_DEPENDENT_REORG
9284 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9285
9286 #undef TARGET_VALID_POINTER_MODE
9287 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9288
9289 #undef TARGET_BUILD_BUILTIN_VA_LIST
9290 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9291 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9292 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9293
9294 #undef TARGET_PROMOTE_FUNCTION_ARGS
9295 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9296 #undef TARGET_PROMOTE_FUNCTION_RETURN
9297 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9298 #undef TARGET_PASS_BY_REFERENCE
9299 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9300
9301 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9302 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9303
9304 #undef TARGET_FIXED_CONDITION_CODE_REGS
9305 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9306
9307 #undef TARGET_CC_MODES_COMPATIBLE
9308 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9309
9310 #undef TARGET_INVALID_WITHIN_DOLOOP
9311 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9312
9313 #ifdef HAVE_AS_TLS
9314 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9315 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9316 #endif
9317
9318 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9319 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
9320 #define TARGET_MANGLE_FUNDAMENTAL_TYPE s390_mangle_fundamental_type
9321 #endif
9322
9323 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9324 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
9325
9326 struct gcc_target targetm = TARGET_INITIALIZER;
9327
9328 #include "gt-s390.h"
9329