xref: /openbsd/gnu/gcc/gcc/config/s390/s390.c (revision 404b540a)
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