OSDN Git Service

* config/s390/s390.c (s390_split_branches): Add return
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / s390.c
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2    Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3    Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4                   Ulrich Weigand (uweigand@de.ibm.com).
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "tm_p.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "except.h"
37 #include "function.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "reload.h"
41 #include "toplev.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "ggc.h"
45 #include "target.h"
46 #include "target-def.h"
47 #include "debug.h"
48 #include "langhooks.h"
49 #include "optabs.h"
50
51 static bool s390_assemble_integer PARAMS ((rtx, unsigned int, int));
52 static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
53 static int s390_adjust_priority PARAMS ((rtx, int));
54 static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx, 
55                                              unsigned HOST_WIDE_INT));
56 static void s390_encode_section_info PARAMS ((tree, int));
57
58 #undef  TARGET_ASM_ALIGNED_HI_OP
59 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
60 #undef  TARGET_ASM_ALIGNED_DI_OP
61 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
62 #undef  TARGET_ASM_INTEGER
63 #define TARGET_ASM_INTEGER s390_assemble_integer
64
65 #undef  TARGET_ASM_OPEN_PAREN
66 #define TARGET_ASM_OPEN_PAREN ""
67
68 #undef  TARGET_ASM_CLOSE_PAREN
69 #define TARGET_ASM_CLOSE_PAREN ""
70
71 #undef  TARGET_ASM_SELECT_RTX_SECTION
72 #define TARGET_ASM_SELECT_RTX_SECTION  s390_select_rtx_section
73
74 #undef  TARGET_SCHED_ADJUST_COST
75 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
76
77 #undef  TARGET_SCHED_ADJUST_PRIORITY
78 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
79
80 #undef  TARGET_ENCODE_SECTION_INFO
81 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
82
83 struct gcc_target targetm = TARGET_INITIALIZER;
84
85 extern int reload_completed;
86
87 /* The alias set for prologue/epilogue register save/restore.  */
88 static int s390_sr_alias_set = 0;
89
90 /* Save information from a "cmpxx" operation until the branch or scc is
91    emitted.  */
92 rtx s390_compare_op0, s390_compare_op1;
93
94 /* Structure used to hold the components of a S/390 memory
95    address.  A legitimate address on S/390 is of the general
96    form
97           base + index + displacement
98    where any of the components is optional.
99
100    base and index are registers of the class ADDR_REGS,
101    displacement is an unsigned 12-bit immediate constant.  */
102
103 struct s390_address
104 {
105   rtx base;
106   rtx indx;
107   rtx disp;
108   int pointer;
109 };
110
111 /* Structure containing information for prologue and epilogue.  */ 
112
113 struct s390_frame
114 {
115   int frame_pointer_p;
116   int save_fprs_p;
117   int first_save_gpr;
118   int first_restore_gpr;
119   int last_save_gpr;
120   int arg_frame_offset;
121
122   HOST_WIDE_INT frame_size;
123 };
124
125 static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
126 static int s390_branch_condition_mask PARAMS ((rtx));
127 static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
128 static int check_mode PARAMS ((rtx, enum machine_mode *));
129 static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
130 static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
131 static int reg_used_in_mem_p PARAMS ((int, rtx));
132 static int addr_generation_dependency_p PARAMS ((rtx, rtx));
133 static int s390_split_branches PARAMS ((rtx, bool *));
134 static void find_constant_pool_ref PARAMS ((rtx, rtx *));
135 static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
136 static int find_base_register_in_addr PARAMS ((struct s390_address *));
137 static bool find_base_register_ref PARAMS ((rtx));
138 static void replace_base_register_ref PARAMS ((rtx *, rtx));
139 static void s390_optimize_prolog PARAMS ((int));
140 static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
141 static int find_unused_clobbered_reg PARAMS ((void));
142 static void s390_frame_info PARAMS ((struct s390_frame *));
143 static rtx save_fpr PARAMS ((rtx, int, int));
144 static rtx restore_fpr PARAMS ((rtx, int, int));
145 static rtx save_gprs PARAMS ((rtx, int, int, int));
146 static rtx restore_gprs PARAMS ((rtx, int, int, int));
147 static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
148
149  
150 /* Return true if SET either doesn't set the CC register, or else
151    the source and destination have matching CC modes and that 
152    CC mode is at least as constrained as REQ_MODE.  */
153  
154 static int
155 s390_match_ccmode_set (set, req_mode)
156      rtx set;
157      enum machine_mode req_mode;
158 {
159   enum machine_mode set_mode;
160
161   if (GET_CODE (set) != SET)
162     abort ();
163
164   if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
165     return 1;
166
167   set_mode = GET_MODE (SET_DEST (set));
168   switch (set_mode)
169     {
170     case CCSmode:
171     case CCSRmode:
172     case CCUmode:
173     case CCURmode:
174     case CCLmode:
175     case CCL1mode:
176     case CCL2mode:
177     case CCT1mode:
178     case CCT2mode:
179     case CCT3mode:
180       if (req_mode != set_mode)
181         return 0;
182       break;
183
184     case CCZmode:
185       if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
186           && req_mode != CCSRmode && req_mode != CCURmode)
187         return 0;
188       break;
189
190     case CCAPmode:
191     case CCANmode:
192       if (req_mode != CCAmode)
193         return 0;
194       break;
195  
196     default:
197       abort ();
198     }
199  
200   return (GET_MODE (SET_SRC (set)) == set_mode);
201 }
202
203 /* Return true if every SET in INSN that sets the CC register 
204    has source and destination with matching CC modes and that 
205    CC mode is at least as constrained as REQ_MODE.  
206    If REQ_MODE is VOIDmode, always return false.  */
207  
208 int
209 s390_match_ccmode (insn, req_mode)
210      rtx insn;
211      enum machine_mode req_mode;
212 {
213   int i;
214
215   /* s390_tm_ccmode returns VOIDmode to indicate failure.  */
216   if (req_mode == VOIDmode)
217     return 0;
218
219   if (GET_CODE (PATTERN (insn)) == SET)
220     return s390_match_ccmode_set (PATTERN (insn), req_mode);
221
222   if (GET_CODE (PATTERN (insn)) == PARALLEL)
223       for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
224         {
225           rtx set = XVECEXP (PATTERN (insn), 0, i);
226           if (GET_CODE (set) == SET)
227             if (!s390_match_ccmode_set (set, req_mode))
228               return 0;
229         }
230
231   return 1;
232 }
233
234 /* If a test-under-mask instruction can be used to implement 
235    (compare (and ... OP1) OP2), return the CC mode required
236    to do that.  Otherwise, return VOIDmode.  
237    MIXED is true if the instruction can distinguish between
238    CC1 and CC2 for mixed selected bits (TMxx), it is false
239    if the instruction cannot (TM).  */
240
241 enum machine_mode
242 s390_tm_ccmode (op1, op2, mixed)
243      rtx op1;
244      rtx op2;
245      int mixed;
246 {
247   int bit0, bit1;
248
249   /* ??? Fixme: should work on CONST_DOUBLE as well.  */
250   if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
251     return VOIDmode;
252
253   /* Selected bits all zero: CC0.  */
254   if (INTVAL (op2) == 0)
255     return CCTmode;
256
257   /* Selected bits all one: CC3.  */
258   if (INTVAL (op2) == INTVAL (op1))
259     return CCT3mode;
260
261   /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2.  */
262   if (mixed)
263     {
264       bit1 = exact_log2 (INTVAL (op2));
265       bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
266       if (bit0 != -1 && bit1 != -1)
267         return bit0 > bit1 ? CCT1mode : CCT2mode;
268     }
269
270   return VOIDmode;
271 }
272
273 /* Given a comparison code OP (EQ, NE, etc.) and the operands 
274    OP0 and OP1 of a COMPARE, return the mode to be used for the 
275    comparison.  */
276
277 enum machine_mode
278 s390_select_ccmode (code, op0, op1) 
279      enum rtx_code code;
280      rtx op0;
281      rtx op1;
282 {
283   switch (code)
284     {
285       case EQ:
286       case NE:
287         if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
288             && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K')) 
289           return CCAPmode;
290         if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
291             || GET_CODE (op1) == NEG)
292           return CCLmode;
293
294         if (GET_CODE (op0) == AND)
295           {
296             /* Check whether we can potentially do it via TM.  */
297             enum machine_mode ccmode;
298             ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
299             if (ccmode != VOIDmode)
300               {
301                 /* Relax CCTmode to CCZmode to allow fall-back to AND
302                    if that turns out to be beneficial.  */
303                 return ccmode == CCTmode ? CCZmode : ccmode;
304               }
305           }
306
307         if (register_operand (op0, HImode) 
308             && GET_CODE (op1) == CONST_INT
309             && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
310           return CCT3mode;
311         if (register_operand (op0, QImode) 
312             && GET_CODE (op1) == CONST_INT
313             && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
314           return CCT3mode;
315
316         return CCZmode;
317
318       case LE:
319       case LT:
320       case GE:
321       case GT:
322           if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
323               && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K')) 
324             {
325               if (INTVAL (XEXP((op0), 1)) < 0)
326                 return CCANmode;
327               else
328                 return CCAPmode;
329             }
330       case UNORDERED:
331       case ORDERED:
332       case UNEQ:
333       case UNLE:
334       case UNLT:
335       case UNGE:
336       case UNGT:
337       case LTGT:
338         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
339             && GET_CODE (op1) != CONST_INT)
340           return CCSRmode;
341         return CCSmode;
342
343       case LTU:
344       case GEU:
345         if (GET_CODE (op0) == PLUS)
346           return CCL1mode;
347
348         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
349             && GET_CODE (op1) != CONST_INT)
350           return CCURmode;
351         return CCUmode;
352
353       case LEU:
354       case GTU:
355         if (GET_CODE (op0) == MINUS)
356           return CCL2mode;
357
358         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
359             && GET_CODE (op1) != CONST_INT)
360           return CCURmode;
361         return CCUmode;
362
363       default:
364         abort ();
365     }
366 }
367
368 /* Return branch condition mask to implement a branch 
369    specified by CODE.  */
370
371 static int
372 s390_branch_condition_mask (code)
373     rtx code;
374
375   const int CC0 = 1 << 3;
376   const int CC1 = 1 << 2;
377   const int CC2 = 1 << 1;
378   const int CC3 = 1 << 0;
379
380   if (GET_CODE (XEXP (code, 0)) != REG
381       || REGNO (XEXP (code, 0)) != CC_REGNUM
382       || XEXP (code, 1) != const0_rtx)
383     abort ();
384
385   switch (GET_MODE (XEXP (code, 0)))
386     {
387     case CCZmode:
388       switch (GET_CODE (code))
389         {
390         case EQ:        return CC0;
391         case NE:        return CC1 | CC2 | CC3;
392         default:
393           abort ();
394         }
395       break;
396
397     case CCT1mode:
398       switch (GET_CODE (code))
399         {
400         case EQ:        return CC1;
401         case NE:        return CC0 | CC2 | CC3;
402         default:
403           abort ();
404         }
405       break;
406
407     case CCT2mode:
408       switch (GET_CODE (code))
409         {
410         case EQ:        return CC2;
411         case NE:        return CC0 | CC1 | CC3;
412         default:
413           abort ();
414         }
415       break;
416
417     case CCT3mode:
418       switch (GET_CODE (code))
419         {
420         case EQ:        return CC3;
421         case NE:        return CC0 | CC1 | CC2;
422         default:
423           abort ();
424         }
425       break;
426
427     case CCLmode:
428       switch (GET_CODE (code))
429         {
430         case EQ:        return CC0 | CC2;
431         case NE:        return CC1 | CC3;
432         default:
433           abort ();
434         }
435       break;
436
437     case CCL1mode:
438       switch (GET_CODE (code))
439         {
440         case LTU:       return CC2 | CC3;  /* carry */
441         case GEU:       return CC0 | CC1;  /* no carry */
442         default:
443           abort ();
444         }
445       break;
446
447     case CCL2mode:
448       switch (GET_CODE (code))
449         {
450         case GTU:       return CC0 | CC1;  /* borrow */
451         case LEU:       return CC2 | CC3;  /* no borrow */
452         default:
453           abort ();
454         }
455       break;
456
457     case CCUmode:
458       switch (GET_CODE (code))
459         {
460         case EQ:        return CC0;
461         case NE:        return CC1 | CC2 | CC3;
462         case LTU:       return CC1;
463         case GTU:       return CC2;
464         case LEU:       return CC0 | CC1;
465         case GEU:       return CC0 | CC2;
466         default:
467           abort ();
468         }
469       break;
470
471     case CCURmode:
472       switch (GET_CODE (code))
473         {
474         case EQ:        return CC0;
475         case NE:        return CC2 | CC1 | CC3;
476         case LTU:       return CC2;
477         case GTU:       return CC1;
478         case LEU:       return CC0 | CC2;
479         case GEU:       return CC0 | CC1;
480         default:
481           abort ();
482         }
483       break;
484
485     case CCAPmode:
486       switch (GET_CODE (code))
487         {
488         case EQ:        return CC0;
489         case NE:        return CC1 | CC2 | CC3;
490         case LT:        return CC1 | CC3;
491         case GT:        return CC2;
492         case LE:        return CC0 | CC1 | CC3;
493         case GE:        return CC0 | CC2;
494         default:
495           abort ();
496         }
497       break;
498
499     case CCANmode:
500       switch (GET_CODE (code))
501         {
502         case EQ:        return CC0;
503         case NE:        return CC1 | CC2 | CC3;
504         case LT:        return CC1;
505         case GT:        return CC2 | CC3;
506         case LE:        return CC0 | CC1;
507         case GE:        return CC0 | CC2 | CC3;
508         default:
509           abort ();
510         }
511       break;
512
513     case CCSmode:
514       switch (GET_CODE (code))
515         {
516         case EQ:        return CC0;
517         case NE:        return CC1 | CC2 | CC3;
518         case LT:        return CC1;
519         case GT:        return CC2;
520         case LE:        return CC0 | CC1;
521         case GE:        return CC0 | CC2;
522         case UNORDERED: return CC3;
523         case ORDERED:   return CC0 | CC1 | CC2;
524         case UNEQ:      return CC0 | CC3;
525         case UNLT:      return CC1 | CC3;
526         case UNGT:      return CC2 | CC3;
527         case UNLE:      return CC0 | CC1 | CC3;
528         case UNGE:      return CC0 | CC2 | CC3;
529         case LTGT:      return CC1 | CC2;
530         default:
531           abort ();
532         }
533       break;
534
535     case CCSRmode:
536       switch (GET_CODE (code))
537         {
538         case EQ:        return CC0;
539         case NE:        return CC2 | CC1 | CC3;
540         case LT:        return CC2;
541         case GT:        return CC1;
542         case LE:        return CC0 | CC2;
543         case GE:        return CC0 | CC1;
544         case UNORDERED: return CC3;
545         case ORDERED:   return CC0 | CC2 | CC1;
546         case UNEQ:      return CC0 | CC3;
547         case UNLT:      return CC2 | CC3;
548         case UNGT:      return CC1 | CC3;
549         case UNLE:      return CC0 | CC2 | CC3;
550         case UNGE:      return CC0 | CC1 | CC3;
551         case LTGT:      return CC2 | CC1;
552         default:
553           abort ();
554         }
555       break;
556
557     default:
558       abort ();
559     }
560 }
561
562 /* If INV is false, return assembler mnemonic string to implement 
563    a branch specified by CODE.  If INV is true, return mnemonic 
564    for the corresponding inverted branch.  */
565
566 static const char *
567 s390_branch_condition_mnemonic (code, inv)
568      rtx code;
569      int inv;
570 {
571   static const char *const mnemonic[16] =
572     {
573       NULL, "o", "h", "nle",
574       "l", "nhe", "lh", "ne",
575       "e", "nlh", "he", "nl",
576       "le", "nh", "no", NULL
577     };
578
579   int mask = s390_branch_condition_mask (code);
580
581   if (inv)
582     mask ^= 15;
583
584   if (mask < 1 || mask > 14)
585     abort ();
586
587   return mnemonic[mask];
588 }
589
590 /* If OP is an integer constant of mode MODE with exactly one
591    HImode subpart unequal to DEF, return the number of that 
592    subpart.  As a special case, all HImode subparts of OP are
593    equal to DEF, return zero.  Otherwise, return -1.  */
594
595 int
596 s390_single_hi (op, mode, def)
597      rtx op;
598      enum machine_mode mode;
599      int def;
600 {
601   if (GET_CODE (op) == CONST_INT)
602     {
603       unsigned HOST_WIDE_INT value;
604       int n_parts = GET_MODE_SIZE (mode) / 2;
605       int i, part = -1;
606
607       for (i = 0; i < n_parts; i++)
608         {
609           if (i == 0)
610             value = (unsigned HOST_WIDE_INT) INTVAL (op);
611           else
612             value >>= 16;
613
614           if ((value & 0xffff) != (unsigned)(def & 0xffff))
615             {
616               if (part != -1)
617                 return -1;
618               else
619                 part = i;
620             }
621         }
622
623       return part == -1 ? 0 : (n_parts - 1 - part);
624     }
625
626   else if (GET_CODE (op) == CONST_DOUBLE
627            && GET_MODE (op) == VOIDmode)
628     {
629       unsigned HOST_WIDE_INT value;
630       int n_parts = GET_MODE_SIZE (mode) / 2;
631       int i, part = -1;
632
633       for (i = 0; i < n_parts; i++)
634         {
635           if (i == 0)
636             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
637           else if (i == HOST_BITS_PER_WIDE_INT / 16)
638             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
639           else
640             value >>= 16;
641
642           if ((value & 0xffff) != (unsigned)(def & 0xffff))
643             {
644               if (part != -1)
645                 return -1;
646               else
647                 part = i;
648             }
649         }
650
651       return part == -1 ? 0 : (n_parts - 1 - part);
652     }
653
654   return -1;      
655 }
656
657 /* Extract the HImode part number PART from integer 
658    constant OP of mode MODE.  */
659
660 int
661 s390_extract_hi (op, mode, part)
662     rtx op;
663     enum machine_mode mode;
664     int part;
665 {
666   int n_parts = GET_MODE_SIZE (mode) / 2;
667   if (part < 0 || part >= n_parts)
668     abort();
669   else
670     part = n_parts - 1 - part;
671
672   if (GET_CODE (op) == CONST_INT)
673     {
674       unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
675       return ((value >> (16 * part)) & 0xffff);
676     }
677   else if (GET_CODE (op) == CONST_DOUBLE
678            && GET_MODE (op) == VOIDmode)
679     {
680       unsigned HOST_WIDE_INT value;
681       if (part < HOST_BITS_PER_WIDE_INT / 16)
682         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
683       else
684         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
685         part -= HOST_BITS_PER_WIDE_INT / 16;
686
687       return ((value >> (16 * part)) & 0xffff); 
688     }
689
690   abort ();
691 }
692
693 /* If OP is an integer constant of mode MODE with exactly one
694    QImode subpart unequal to DEF, return the number of that 
695    subpart.  As a special case, all QImode subparts of OP are
696    equal to DEF, return zero.  Otherwise, return -1.  */
697
698 int
699 s390_single_qi (op, mode, def)
700      rtx op;
701      enum machine_mode mode;
702      int def;
703 {
704   if (GET_CODE (op) == CONST_INT)
705     {
706       unsigned HOST_WIDE_INT value;
707       int n_parts = GET_MODE_SIZE (mode);
708       int i, part = -1;
709
710       for (i = 0; i < n_parts; i++)
711         {
712           if (i == 0)
713             value = (unsigned HOST_WIDE_INT) INTVAL (op);
714           else
715             value >>= 8;
716
717           if ((value & 0xff) != (unsigned)(def & 0xff))
718             {
719               if (part != -1)
720                 return -1;
721               else
722                 part = i;
723             }
724         }
725
726       return part == -1 ? 0 : (n_parts - 1 - part);
727     }
728
729   else if (GET_CODE (op) == CONST_DOUBLE
730            && GET_MODE (op) == VOIDmode)
731     {
732       unsigned HOST_WIDE_INT value;
733       int n_parts = GET_MODE_SIZE (mode);
734       int i, part = -1;
735
736       for (i = 0; i < n_parts; i++)
737         {
738           if (i == 0)
739             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
740           else if (i == HOST_BITS_PER_WIDE_INT / 8)
741             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
742           else
743             value >>= 8;
744
745           if ((value & 0xff) != (unsigned)(def & 0xff))
746             {
747               if (part != -1)
748                 return -1;
749               else
750                 part = i;
751             }
752         }
753
754       return part == -1 ? 0 : (n_parts - 1 - part);
755     }
756
757   return -1;      
758 }
759
760 /* Extract the QImode part number PART from integer 
761    constant OP of mode MODE.  */
762
763 int
764 s390_extract_qi (op, mode, part)
765     rtx op;
766     enum machine_mode mode;
767     int part;
768 {
769   int n_parts = GET_MODE_SIZE (mode);
770   if (part < 0 || part >= n_parts)
771     abort();
772   else
773     part = n_parts - 1 - part;
774
775   if (GET_CODE (op) == CONST_INT)
776     {
777       unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
778       return ((value >> (8 * part)) & 0xff);
779     }
780   else if (GET_CODE (op) == CONST_DOUBLE
781            && GET_MODE (op) == VOIDmode)
782     {
783       unsigned HOST_WIDE_INT value;
784       if (part < HOST_BITS_PER_WIDE_INT / 8)
785         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
786       else
787         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
788         part -= HOST_BITS_PER_WIDE_INT / 8;
789
790       return ((value >> (8 * part)) & 0xff); 
791     }
792
793   abort ();
794 }
795
796
797 /* Change optimizations to be performed, depending on the 
798    optimization level.
799
800    LEVEL is the optimization level specified; 2 if `-O2' is
801    specified, 1 if `-O' is specified, and 0 if neither is specified.
802
803    SIZE is nonzero if `-Os' is specified and zero otherwise.  */
804
805 void
806 optimization_options (level, size)
807      int level ATTRIBUTE_UNUSED;
808      int size ATTRIBUTE_UNUSED;
809 {
810 }
811
812 void
813 override_options ()
814 {
815   /* Acquire a unique set number for our register saves and restores.  */
816   s390_sr_alias_set = new_alias_set ();
817 }
818
819
820 /* Map for smallest class containing reg regno.  */
821
822 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
823 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
824   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
825   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
826   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
827   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
828   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
829   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
830   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
831   ADDR_REGS,    NO_REGS,   ADDR_REGS 
832 };
833
834
835 /* Return true if OP a (const_int 0) operand.
836    OP is the current operation.
837    MODE is the current operation mode.  */
838  
839 int
840 const0_operand (op, mode)
841      register rtx op;
842      enum machine_mode mode;
843 {
844   return op == CONST0_RTX (mode);
845 }
846
847 /* Return true if OP is constant.
848    OP is the current operation.
849    MODE is the current operation mode.  */
850
851 int
852 consttable_operand (op, mode)
853      rtx op;
854      enum machine_mode mode ATTRIBUTE_UNUSED;
855 {
856   return CONSTANT_P (op);
857 }
858
859 /* Return true if the mode of operand OP matches MODE.
860    If MODE is set to VOIDmode, set it to the mode of OP.  */ 
861
862 static int
863 check_mode (op, mode)
864      register rtx op;
865      enum machine_mode *mode;
866 {
867   if (*mode == VOIDmode)
868       *mode = GET_MODE (op);
869   else
870   {
871     if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
872        return 0;
873   }
874   return 1;
875 }
876
877 /* Return true if OP a valid operand for the LARL instruction.
878    OP is the current operation.
879    MODE is the current operation mode.  */
880
881 int
882 larl_operand (op, mode)
883      register rtx op;
884      enum machine_mode mode;
885 {
886   if (! check_mode (op, &mode))
887     return 0;
888
889   /* Allow labels and local symbols.  */
890   if (GET_CODE (op) == LABEL_REF)
891     return 1;
892   if (GET_CODE (op) == SYMBOL_REF
893       && (!flag_pic || SYMBOL_REF_FLAG (op) 
894           || CONSTANT_POOL_ADDRESS_P (op)))
895     return 1;
896
897   /* Everything else must have a CONST, so strip it.  */
898   if (GET_CODE (op) != CONST)
899     return 0;
900   op = XEXP (op, 0);
901
902   /* Allow adding *even* constants.  */
903   if (GET_CODE (op) == PLUS)
904     {
905       if (GET_CODE (XEXP (op, 1)) != CONST_INT
906           || (INTVAL (XEXP (op, 1)) & 1) != 0)
907         return 0;
908       op = XEXP (op, 0);
909     }
910
911   /* Labels and local symbols allowed here as well.  */
912   if (GET_CODE (op) == LABEL_REF)
913     return 1;
914   if (GET_CODE (op) == SYMBOL_REF
915       && (!flag_pic || SYMBOL_REF_FLAG (op)
916           || CONSTANT_POOL_ADDRESS_P (op)))
917     return 1;
918
919   /* Now we must have a @GOTENT offset or @PLT stub.  */
920   if (GET_CODE (op) == UNSPEC
921       && XINT (op, 1) == 111)
922     return 1;
923   if (GET_CODE (op) == UNSPEC
924       && XINT (op, 1) == 113)
925     return 1;
926
927   return 0;
928 }
929
930 /* Return true if OP is a valid FP-Register.
931    OP is the current operation.
932    MODE is the current operation mode.  */
933
934 int
935 fp_operand (op, mode)
936      register rtx op;
937      enum machine_mode mode;
938 {
939   register enum rtx_code code = GET_CODE (op);
940   if (! check_mode (op, &mode))
941     return 0;
942   if (code == REG && REGNO_OK_FOR_FP_P (REGNO (op)))
943     return 1;
944   else
945     return 0;
946 }
947
948 /* Helper routine to implement s_operand and s_imm_operand.
949    OP is the current operation.
950    MODE is the current operation mode.
951    ALLOW_IMMEDIATE specifies whether immediate operands should
952    be accepted or not.  */
953
954 static int
955 general_s_operand (op, mode, allow_immediate)
956      register rtx op;
957      enum machine_mode mode;
958      int allow_immediate;
959 {
960   struct s390_address addr;
961
962   /* Call general_operand first, so that we don't have to
963      check for many special cases.  */
964   if (!general_operand (op, mode))
965     return 0;
966
967   /* Just like memory_operand, allow (subreg (mem ...))
968      after reload.  */
969   if (reload_completed 
970       && GET_CODE (op) == SUBREG 
971       && GET_CODE (SUBREG_REG (op)) == MEM)
972     op = SUBREG_REG (op);
973
974   switch (GET_CODE (op))
975     {
976       /* Constants that we are sure will be forced to the
977          literal pool in reload are OK as s-operand.  Note
978          that we cannot call s390_preferred_reload_class here
979          because it might not be known yet at this point 
980          whether the current function is a leaf or not.  */
981       case CONST_INT:
982       case CONST_DOUBLE:
983         if (!allow_immediate || reload_completed)
984           break;
985         if (!legitimate_reload_constant_p (op))
986           return 1;
987         if (!TARGET_64BIT)
988           return 1;
989         break;
990
991       /* Memory operands are OK unless they already use an
992          index register.  */
993       case MEM:
994         if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
995           return 1;
996         if (s390_decompose_address (XEXP (op, 0), &addr) 
997             && !addr.indx)
998           return 1;
999         break;
1000
1001       default:
1002         break;
1003     }
1004
1005   return 0;
1006 }
1007
1008 /* Return true if OP is a valid S-type operand.
1009    OP is the current operation.
1010    MODE is the current operation mode.  */
1011
1012 int
1013 s_operand (op, mode)
1014      register rtx op;
1015      enum machine_mode mode;
1016 {
1017   return general_s_operand (op, mode, 0);
1018 }
1019
1020 /* Return true if OP is a valid S-type operand or an immediate 
1021    operand that can be addressed as S-type operand by forcing 
1022    it into the literal pool.
1023    OP is the current operation.
1024    MODE is the current operation mode.  */
1025
1026 int
1027 s_imm_operand (op, mode)
1028      register rtx op;
1029      enum machine_mode mode;
1030 {
1031   return general_s_operand (op, mode, 1);
1032 }
1033
1034 /* Return true if OP is a valid operand for a 'Q' constraint.
1035    This differs from s_operand in that only memory operands
1036    without index register are accepted, nothing else.  */
1037
1038 int
1039 q_constraint (op)
1040      register rtx op;
1041 {
1042   struct s390_address addr;
1043
1044   if (GET_CODE (op) != MEM)
1045     return 0;
1046
1047   if (!s390_decompose_address (XEXP (op, 0), &addr))
1048     return 0;
1049
1050   if (addr.indx)
1051     return 0;
1052
1053   return 1;
1054 }
1055
1056 /* Return the cost of an address rtx ADDR.  */
1057
1058 int
1059 s390_address_cost (addr)
1060      rtx addr;
1061 {
1062   struct s390_address ad;
1063   if (!s390_decompose_address (addr, &ad))
1064     return 1000;
1065
1066   return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1067 }
1068
1069 /* Return true if OP is a valid operand for the BRAS instruction.
1070    OP is the current operation.
1071    MODE is the current operation mode.  */
1072
1073 int
1074 bras_sym_operand (op, mode)
1075      register rtx op;
1076      enum machine_mode mode ATTRIBUTE_UNUSED;
1077 {
1078   register enum rtx_code code = GET_CODE (op);
1079
1080   /* Allow SYMBOL_REFs.  */
1081   if (code == SYMBOL_REF)
1082     return 1;
1083
1084   /* Allow @PLT stubs.  */
1085   if (code == CONST
1086       && GET_CODE (XEXP (op, 0)) == UNSPEC
1087       && XINT (XEXP (op, 0), 1) == 113)
1088     return 1;
1089   return 0;
1090 }
1091
1092 \f
1093 /* Return true if OP is a load multiple operation.  It is known to be a
1094    PARALLEL and the first section will be tested. 
1095    OP is the current operation.
1096    MODE is the current operation mode.  */
1097
1098 int
1099 load_multiple_operation (op, mode)
1100      rtx op;
1101      enum machine_mode mode ATTRIBUTE_UNUSED;
1102 {
1103   int count = XVECLEN (op, 0);
1104   unsigned int dest_regno;
1105   rtx src_addr;
1106   int i, off;
1107
1108
1109   /* Perform a quick check so we don't blow up below.  */
1110   if (count <= 1
1111       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1112       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1113       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1114     return 0;
1115
1116   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1117   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1118
1119   /* Check, is base, or base + displacement.  */
1120
1121   if (GET_CODE (src_addr) == REG)
1122     off = 0;
1123   else if (GET_CODE (src_addr) == PLUS
1124            && GET_CODE (XEXP (src_addr, 0)) == REG 
1125            && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1126     {
1127       off = INTVAL (XEXP (src_addr, 1));
1128       src_addr = XEXP (src_addr, 0);
1129     }
1130   else
1131     return 0;
1132
1133   if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
1134     return 0;
1135
1136   for (i = 1; i < count; i++)
1137     {
1138       rtx elt = XVECEXP (op, 0, i);
1139
1140       if (GET_CODE (elt) != SET
1141           || GET_CODE (SET_DEST (elt)) != REG
1142           || GET_MODE (SET_DEST (elt)) != Pmode
1143           || REGNO (SET_DEST (elt)) != dest_regno + i
1144           || GET_CODE (SET_SRC (elt)) != MEM
1145           || GET_MODE (SET_SRC (elt)) != Pmode
1146           || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1147           || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1148           || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1149           || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1150              != off + i * UNITS_PER_WORD)
1151         return 0;
1152     }
1153
1154   return 1;
1155 }
1156
1157 /* Return true if OP is a store multiple operation.  It is known to be a
1158    PARALLEL and the first section will be tested. 
1159    OP is the current operation.
1160    MODE is the current operation mode.  */
1161
1162 int
1163 store_multiple_operation (op, mode)
1164      rtx op;
1165      enum machine_mode mode ATTRIBUTE_UNUSED;
1166 {
1167   int count = XVECLEN (op, 0);
1168   unsigned int src_regno;
1169   rtx dest_addr;
1170   int i, off;
1171
1172   /* Perform a quick check so we don't blow up below.  */
1173   if (count <= 1
1174       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1175       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1176       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1177     return 0;
1178
1179   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1180   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1181
1182   /* Check, is base, or base + displacement.  */
1183
1184   if (GET_CODE (dest_addr) == REG)
1185     off = 0;
1186   else if (GET_CODE (dest_addr) == PLUS
1187            && GET_CODE (XEXP (dest_addr, 0)) == REG 
1188            && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1189     {
1190       off = INTVAL (XEXP (dest_addr, 1));
1191       dest_addr = XEXP (dest_addr, 0);
1192     }
1193   else
1194     return 0;
1195
1196   if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
1197     return 0;
1198
1199   for (i = 1; i < count; i++)
1200     {
1201       rtx elt = XVECEXP (op, 0, i);
1202
1203       if (GET_CODE (elt) != SET
1204           || GET_CODE (SET_SRC (elt)) != REG
1205           || GET_MODE (SET_SRC (elt)) != Pmode
1206           || REGNO (SET_SRC (elt)) != src_regno + i
1207           || GET_CODE (SET_DEST (elt)) != MEM
1208           || GET_MODE (SET_DEST (elt)) != Pmode
1209           || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1210           || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1211           || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1212           || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1213              != off + i * UNITS_PER_WORD)
1214         return 0;
1215     }
1216   return 1;
1217 }
1218
1219
1220 /* Return true if OP contains a symbol reference */
1221
1222 int
1223 symbolic_reference_mentioned_p (op)
1224      rtx op;
1225 {
1226   register const char *fmt;
1227   register int i;
1228
1229   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1230     return 1;
1231
1232   fmt = GET_RTX_FORMAT (GET_CODE (op));
1233   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1234     {
1235       if (fmt[i] == 'E')
1236         {
1237           register int j;
1238
1239           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1240             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1241               return 1;
1242         }
1243
1244       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1245         return 1;
1246     }
1247
1248   return 0;
1249 }
1250
1251
1252 /* Return true if OP is a legitimate general operand when 
1253    generating PIC code.  It is given that flag_pic is on 
1254    and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1255
1256 int
1257 legitimate_pic_operand_p (op)
1258      register rtx op;
1259 {
1260   /* Accept all non-symbolic constants.  */
1261   if (!SYMBOLIC_CONST (op))
1262     return 1;
1263
1264   /* Reject everything else; must be handled 
1265      via emit_pic_move.  */
1266   return 0;
1267 }
1268
1269 /* Returns true if the constant value OP is a legitimate general operand.
1270    It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1271
1272 int
1273 legitimate_constant_p (op)
1274      register rtx op;
1275 {
1276   /* Accept all non-symbolic constants.  */
1277   if (!SYMBOLIC_CONST (op))
1278     return 1;
1279
1280   /* In the PIC case, symbolic constants must *not* be
1281      forced into the literal pool.  We accept them here,
1282      so that they will be handled by emit_pic_move.  */
1283   if (flag_pic)
1284     return 1;
1285
1286   /* Even in the non-PIC case, we can accept immediate
1287      LARL operands here.  */
1288   if (TARGET_64BIT)
1289     return larl_operand (op, VOIDmode);
1290
1291   /* All remaining non-PIC symbolic constants are
1292      forced into the literal pool.  */
1293   return 0;
1294 }
1295
1296 /* Returns true if the constant value OP is a legitimate general
1297    operand during and after reload.  The difference to 
1298    legitimate_constant_p is that this function will not accept
1299    a constant that would need to be forced to the literal pool
1300    before it can be used as operand.  */
1301
1302 int
1303 legitimate_reload_constant_p (op)
1304      register rtx op;
1305 {
1306   /* Accept l(g)hi operands.  */
1307   if (GET_CODE (op) == CONST_INT
1308       && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
1309     return 1;
1310
1311   /* Accept lliXX operands.  */
1312   if (TARGET_64BIT
1313       && s390_single_hi (op, DImode, 0) >= 0)
1314   return 1;
1315
1316   /* Accept larl operands.  */
1317   if (TARGET_64BIT
1318       && larl_operand (op, VOIDmode))
1319     return 1;
1320
1321   /* Everything else cannot be handled without reload.  */
1322   return 0;
1323 }
1324
1325 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1326    return the class of reg to actually use.  */
1327
1328 enum reg_class
1329 s390_preferred_reload_class (op, class)
1330      rtx op;
1331      enum reg_class class;
1332 {
1333   /* This can happen if a floating point constant is being
1334      reloaded into an integer register.  Leave well alone.  */
1335   if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1336       && class != FP_REGS)
1337     return class;
1338
1339   switch (GET_CODE (op))
1340     {
1341       /* Constants we cannot reload must be forced into the
1342          literal pool.  For constants we *could* handle directly,
1343          it might still be preferable to put them in the pool and
1344          use a memory-to-memory instruction.
1345
1346          However, try to avoid needlessly allocating a literal
1347          pool in a routine that wouldn't otherwise need any.
1348          Heuristically, we assume that 64-bit leaf functions
1349          typically don't need a literal pool, all others do.  */
1350       case CONST_DOUBLE:
1351       case CONST_INT:
1352         if (!legitimate_reload_constant_p (op))
1353           return NO_REGS;
1354
1355         if (TARGET_64BIT && current_function_is_leaf)
1356           return class;
1357
1358         return NO_REGS;
1359
1360       /* If a symbolic constant or a PLUS is reloaded,
1361          it is most likely being used as an address, so
1362          prefer ADDR_REGS.  If 'class' is not a superset
1363          of ADDR_REGS, e.g. FP_REGS, reject this reload.  */
1364       case PLUS:
1365       case LABEL_REF:
1366       case SYMBOL_REF:
1367       case CONST:
1368         if (reg_class_subset_p (ADDR_REGS, class))
1369           return ADDR_REGS;
1370         else
1371           return NO_REGS;
1372
1373       default:
1374         break;
1375     }
1376
1377   return class;
1378 }
1379
1380 /* Return the register class of a scratch register needed to
1381    load IN into a register of class CLASS in MODE.
1382
1383    We need a temporary when loading a PLUS expression which
1384    is not a legitimate operand of the LOAD ADDRESS instruction.  */
1385
1386 enum reg_class
1387 s390_secondary_input_reload_class (class, mode, in)
1388      enum reg_class class ATTRIBUTE_UNUSED;
1389      enum machine_mode mode;
1390      rtx in;
1391 {
1392   if (s390_plus_operand (in, mode))
1393     return ADDR_REGS;
1394
1395   return NO_REGS;
1396 }
1397
1398 /* Return true if OP is a PLUS that is not a legitimate
1399    operand for the LA instruction. 
1400    OP is the current operation.
1401    MODE is the current operation mode.  */
1402
1403 int
1404 s390_plus_operand (op, mode)
1405      register rtx op;
1406      enum machine_mode mode;
1407 {
1408   if (!check_mode (op, &mode) || mode != Pmode)
1409     return FALSE;
1410
1411   if (GET_CODE (op) != PLUS)
1412     return FALSE;
1413
1414   if (legitimate_la_operand_p (op))
1415     return FALSE;
1416
1417   return TRUE;
1418 }
1419
1420 /* Generate code to load SRC, which is PLUS that is not a
1421    legitimate operand for the LA instruction, into TARGET.
1422    SCRATCH may be used as scratch register.  */
1423
1424 void
1425 s390_expand_plus_operand (target, src, scratch)
1426      register rtx target;
1427      register rtx src;
1428      register rtx scratch;
1429 {
1430   rtx sum1, sum2;
1431   struct s390_address ad;
1432
1433   /* src must be a PLUS; get its two operands.  */
1434   if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
1435     abort ();
1436
1437   /* Check if any of the two operands is already scheduled
1438      for replacement by reload.  This can happen e.g. when
1439      float registers occur in an address.  */
1440   sum1 = find_replacement (&XEXP (src, 0));
1441   sum2 = find_replacement (&XEXP (src, 1));
1442   src = gen_rtx_PLUS (Pmode, sum1, sum2);
1443
1444   /* If the address is already strictly valid, there's nothing to do.  */
1445   if (!s390_decompose_address (src, &ad)
1446       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1447       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
1448     {
1449       /* Otherwise, one of the operands cannot be an address register;
1450          we reload its value into the scratch register.  */
1451       if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
1452         {
1453           emit_move_insn (scratch, sum1);
1454           sum1 = scratch;
1455         }
1456       if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
1457         {
1458           emit_move_insn (scratch, sum2);
1459           sum2 = scratch;
1460         }
1461
1462       /* According to the way these invalid addresses are generated
1463          in reload.c, it should never happen (at least on s390) that
1464          *neither* of the PLUS components, after find_replacements
1465          was applied, is an address register.  */
1466       if (sum1 == scratch && sum2 == scratch)
1467         {
1468           debug_rtx (src);
1469           abort ();
1470         }
1471
1472       src = gen_rtx_PLUS (Pmode, sum1, sum2);
1473     }
1474
1475   /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
1476      is only ever performed on addresses, so we can mark the
1477      sum as legitimate for LA in any case.  */
1478   s390_load_address (target, src);
1479 }
1480
1481
1482 /* Decompose a RTL expression ADDR for a memory address into
1483    its components, returned in OUT.
1484
1485    Returns 0 if ADDR is not a valid memory address, nonzero
1486    otherwise.  If OUT is NULL, don't return the components,
1487    but check for validity only.
1488
1489    Note: Only addresses in canonical form are recognized.
1490    LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1491    canonical form so that they will be recognized.  */
1492
1493 static int
1494 s390_decompose_address (addr, out)
1495      register rtx addr;
1496      struct s390_address *out;
1497 {
1498   rtx base = NULL_RTX;
1499   rtx indx = NULL_RTX;
1500   rtx disp = NULL_RTX;
1501   int pointer = FALSE;
1502
1503   /* Decompose address into base + index + displacement.  */
1504
1505   if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1506     base = addr;
1507
1508   else if (GET_CODE (addr) == PLUS)
1509     {
1510       rtx op0 = XEXP (addr, 0);
1511       rtx op1 = XEXP (addr, 1);
1512       enum rtx_code code0 = GET_CODE (op0);
1513       enum rtx_code code1 = GET_CODE (op1);
1514
1515       if (code0 == REG || code0 == UNSPEC)
1516         {
1517           if (code1 == REG || code1 == UNSPEC)
1518             {
1519               indx = op0;       /* index + base */
1520               base = op1;
1521             }
1522
1523           else
1524             {
1525               base = op0;       /* base + displacement */
1526               disp = op1;
1527             }
1528         }
1529
1530       else if (code0 == PLUS)
1531         {
1532           indx = XEXP (op0, 0); /* index + base + disp */
1533           base = XEXP (op0, 1);
1534           disp = op1;
1535         }
1536
1537       else
1538         {
1539           return FALSE;
1540         }
1541     }
1542
1543   else
1544     disp = addr;                /* displacement */
1545
1546
1547   /* Validate base register.  */
1548   if (base)
1549     {
1550       if (GET_CODE (base) == UNSPEC)
1551         {
1552           if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
1553               return FALSE;
1554           base = XVECEXP (base, 0, 0);
1555           pointer = TRUE;
1556         }
1557
1558       if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
1559           return FALSE;
1560
1561       if (REGNO (base) == BASE_REGISTER
1562           || REGNO (base) == STACK_POINTER_REGNUM
1563           || REGNO (base) == FRAME_POINTER_REGNUM
1564           || ((reload_completed || reload_in_progress)
1565               && frame_pointer_needed
1566               && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1567           || REGNO (base) == ARG_POINTER_REGNUM
1568           || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
1569               && REGNO (base) <= LAST_VIRTUAL_REGISTER)
1570           || (flag_pic
1571               && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1572         pointer = TRUE;
1573     }
1574
1575   /* Validate index register.  */
1576   if (indx)
1577     {
1578       if (GET_CODE (indx) == UNSPEC)
1579         {
1580           if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
1581               return FALSE;
1582           indx = XVECEXP (indx, 0, 0);
1583           pointer = TRUE;
1584         }
1585
1586       if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
1587           return FALSE;
1588
1589       if (REGNO (indx) == BASE_REGISTER
1590           || REGNO (indx) == STACK_POINTER_REGNUM
1591           || REGNO (indx) == FRAME_POINTER_REGNUM
1592           || ((reload_completed || reload_in_progress)
1593               && frame_pointer_needed
1594               && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1595           || REGNO (indx) == ARG_POINTER_REGNUM
1596           || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
1597               && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
1598           || (flag_pic
1599               && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1600         pointer = TRUE;
1601     }
1602
1603   /* Validate displacement.  */
1604   if (disp)
1605     {
1606       /* Allow integer constant in range.  */
1607       if (GET_CODE (disp) == CONST_INT)
1608         {
1609           if (INTVAL (disp) < 0 || INTVAL (disp) >= 4096)
1610               return FALSE;
1611         }
1612
1613       /* In the small-PIC case, the linker converts @GOT12 
1614          offsets to possible displacements.  */
1615       else if (GET_CODE (disp) == CONST
1616                && GET_CODE (XEXP (disp, 0)) == UNSPEC
1617                && XINT (XEXP (disp, 0), 1) == 110)
1618         {
1619           if (flag_pic != 1)
1620             return FALSE;
1621
1622           pointer = TRUE;
1623         }
1624
1625       /* Accept chunkfied literal pool symbol references.  */
1626       else if (GET_CODE (disp) == CONST
1627                && GET_CODE (XEXP (disp, 0)) == MINUS
1628                && GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF
1629                && GET_CODE (XEXP (XEXP (disp, 0), 1)) == LABEL_REF)
1630         {
1631           pointer = TRUE;
1632         }
1633  
1634       /* Likewise if a constant offset is present.  */
1635       else if (GET_CODE (disp) == CONST
1636                && GET_CODE (XEXP (disp, 0)) == PLUS
1637                && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
1638                && GET_CODE (XEXP (XEXP (disp, 0), 0)) == MINUS
1639                && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 0)) == LABEL_REF
1640                && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 1)) == LABEL_REF)
1641         {
1642           pointer = TRUE;
1643         }
1644
1645       /* We can convert literal pool addresses to 
1646          displacements by basing them off the base register.  */
1647       else
1648         {
1649           /* In some cases, we can accept an additional
1650              small constant offset.  Split these off here.  */
1651
1652           unsigned int offset = 0;
1653
1654           if (GET_CODE (disp) == CONST
1655               && GET_CODE (XEXP (disp, 0)) == PLUS
1656               && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1657             {
1658               offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1659               disp = XEXP (XEXP (disp, 0), 0);
1660             }
1661
1662           /* Now we must have a literal pool address.  */
1663           if (GET_CODE (disp) != SYMBOL_REF
1664               || !CONSTANT_POOL_ADDRESS_P (disp))
1665             return FALSE;
1666
1667           /* In 64-bit PIC mode we cannot accept symbolic 
1668              constants in the constant pool.  */
1669           if (TARGET_64BIT && flag_pic
1670               && SYMBOLIC_CONST (get_pool_constant (disp)))
1671             return FALSE;
1672
1673           /* If we have an offset, make sure it does not
1674              exceed the size of the constant pool entry.  */
1675           if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
1676             return FALSE;
1677
1678           /* Either base or index must be free to 
1679              hold the base register.  */
1680           if (base && indx)
1681             return FALSE;
1682
1683           /* Convert the address.  */
1684           if (base)
1685             indx = gen_rtx_REG (Pmode, BASE_REGISTER);
1686           else
1687             base = gen_rtx_REG (Pmode, BASE_REGISTER);
1688
1689           disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
1690           disp = gen_rtx_CONST (Pmode, disp);
1691
1692           if (offset)
1693             disp = plus_constant (disp, offset);
1694
1695           pointer = TRUE;
1696         }
1697     }
1698
1699   if (!base && !indx)
1700     pointer = TRUE;
1701    
1702   if (out)
1703     {
1704       out->base = base;
1705       out->indx = indx;
1706       out->disp = disp;
1707       out->pointer = pointer;
1708     }
1709
1710   return TRUE;
1711 }
1712
1713 /* Return nonzero if ADDR is a valid memory address.
1714    STRICT specifies whether strict register checking applies.  */
1715
1716 int
1717 legitimate_address_p (mode, addr, strict)
1718      enum machine_mode mode ATTRIBUTE_UNUSED;
1719      register rtx addr;
1720      int strict;
1721 {
1722   struct s390_address ad;
1723   if (!s390_decompose_address (addr, &ad))
1724     return FALSE;
1725
1726   if (strict)
1727     {
1728       if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1729         return FALSE;
1730       if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
1731         return FALSE;
1732     }
1733   else
1734     {
1735       if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
1736         return FALSE;
1737       if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
1738         return FALSE;
1739     }
1740
1741   return TRUE;
1742 }
1743
1744 /* Return 1 if OP is a valid operand for the LA instruction.
1745    In 31-bit, we need to prove that the result is used as an
1746    address, as LA performs only a 31-bit addition.  */
1747
1748 int
1749 legitimate_la_operand_p (op)
1750      register rtx op;
1751 {
1752   struct s390_address addr;
1753   if (!s390_decompose_address (op, &addr))
1754     return FALSE;
1755
1756   if (TARGET_64BIT || addr.pointer)
1757     return TRUE;
1758
1759   return FALSE;
1760 }
1761
1762 /* Return 1 if OP is a valid operand for the LA instruction,
1763    and we prefer to use LA over addition to compute it.
1764    If STRICT is true, only accept operands that will never
1765    change to something we cannot recognize as preferred.  */
1766    
1767 int
1768 preferred_la_operand_p (op, strict)
1769      register rtx op;
1770      int strict;
1771 {
1772   struct s390_address addr;
1773   if (!s390_decompose_address (op, &addr))
1774     return FALSE;
1775
1776   if (!TARGET_64BIT && !addr.pointer)
1777     return FALSE;
1778
1779   if (addr.pointer)
1780     return TRUE;
1781
1782   if (!strict) 
1783     if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
1784         || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
1785       return TRUE;
1786
1787   return FALSE;
1788 }
1789
1790 /* Emit a forced load-address operation to load SRC into DST.
1791    This will use the LOAD ADDRESS instruction even in situations
1792    where legitimate_la_operand_p (SRC) returns false.  */
1793
1794 void
1795 s390_load_address (dst, src)
1796      rtx dst;
1797      rtx src;
1798 {
1799   if (TARGET_64BIT)
1800     emit_move_insn (dst, src);
1801   else
1802     emit_insn (gen_force_la_31 (dst, src));
1803 }
1804
1805 /* Return a legitimate reference for ORIG (an address) using the
1806    register REG.  If REG is 0, a new pseudo is generated.
1807
1808    There are two types of references that must be handled:
1809
1810    1. Global data references must load the address from the GOT, via
1811       the PIC reg.  An insn is emitted to do this load, and the reg is
1812       returned.
1813
1814    2. Static data references, constant pool addresses, and code labels
1815       compute the address as an offset from the GOT, whose base is in
1816       the PIC reg.  Static data objects have SYMBOL_REF_FLAG set to
1817       differentiate them from global data objects.  The returned
1818       address is the PIC reg + an unspec constant.
1819
1820    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
1821    reg also appears in the address.  */
1822
1823 rtx
1824 legitimize_pic_address (orig, reg)
1825      rtx orig;
1826      rtx reg;
1827 {
1828   rtx addr = orig;
1829   rtx new = orig;
1830   rtx base;
1831
1832   if (GET_CODE (addr) == LABEL_REF
1833       || (GET_CODE (addr) == SYMBOL_REF
1834           && (SYMBOL_REF_FLAG (addr) 
1835               || CONSTANT_POOL_ADDRESS_P (addr))))
1836     {
1837       /* This is a local symbol.  */
1838       if (TARGET_64BIT)
1839         {
1840           /* Access local symbols PC-relative via LARL.  
1841              This is the same as in the non-PIC case, so it is 
1842              handled automatically ...  */
1843         }
1844       else
1845         {
1846           /* Access local symbols relative to the literal pool.  */
1847
1848           rtx temp = reg? reg : gen_reg_rtx (Pmode);
1849
1850           addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 100);
1851           addr = gen_rtx_CONST (SImode, addr);
1852           addr = force_const_mem (SImode, addr);
1853           emit_move_insn (temp, addr);
1854
1855           base = gen_rtx_REG (Pmode, BASE_REGISTER);
1856           base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
1857           new = gen_rtx_PLUS (Pmode, base, temp);
1858
1859           if (reg != 0)
1860             {
1861               emit_move_insn (reg, new);
1862               new = reg;
1863             }
1864         }
1865     }
1866   else if (GET_CODE (addr) == SYMBOL_REF)
1867     {
1868       if (reg == 0)
1869         reg = gen_reg_rtx (Pmode);
1870
1871       if (flag_pic == 1)
1872         {
1873           /* Assume GOT offset < 4k.  This is handled the same way
1874              in both 31- and 64-bit code (@GOT12).  */
1875
1876           if (reload_in_progress || reload_completed)
1877             regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
1878
1879           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
1880           new = gen_rtx_CONST (Pmode, new);
1881           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
1882           new = gen_rtx_MEM (Pmode, new);
1883           RTX_UNCHANGING_P (new) = 1;
1884           emit_move_insn (reg, new);
1885           new = reg;
1886         }
1887       else if (TARGET_64BIT)
1888         {
1889           /* If the GOT offset might be >= 4k, we determine the position
1890              of the GOT entry via a PC-relative LARL (@GOTENT).  */
1891
1892           rtx temp = gen_reg_rtx (Pmode);
1893
1894           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
1895           new = gen_rtx_CONST (Pmode, new);
1896           emit_move_insn (temp, new);
1897
1898           new = gen_rtx_MEM (Pmode, temp);
1899           RTX_UNCHANGING_P (new) = 1;
1900           emit_move_insn (reg, new);
1901           new = reg;
1902         }
1903       else
1904         {
1905           /* If the GOT offset might be >= 4k, we have to load it 
1906              from the literal pool (@GOT).  */
1907
1908           rtx temp = gen_reg_rtx (Pmode);
1909
1910           if (reload_in_progress || reload_completed)
1911             regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
1912
1913           addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 112);
1914           addr = gen_rtx_CONST (SImode, addr);
1915           addr = force_const_mem (SImode, addr);
1916           emit_move_insn (temp, addr);
1917
1918           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
1919           new = gen_rtx_MEM (Pmode, new);
1920           RTX_UNCHANGING_P (new) = 1;
1921           emit_move_insn (reg, new);
1922           new = reg;
1923         }
1924     }      
1925   else
1926     {
1927       if (GET_CODE (addr) == CONST)
1928         {
1929           addr = XEXP (addr, 0);
1930           if (GET_CODE (addr) == UNSPEC)
1931             {
1932               if (XVECLEN (addr, 0) != 1)
1933                 abort ();
1934               switch (XINT (addr, 1))
1935                 {
1936                   /* If someone moved an @GOT or lt-relative UNSPEC
1937                      out of the literal pool, force them back in.  */
1938                   case 100:
1939                   case 112:
1940                   case 114:
1941                     new = force_const_mem (SImode, orig);
1942                     break;
1943
1944                   /* @GOTENT is OK as is.  */
1945                   case 111:
1946                     break;
1947
1948                   /* @PLT is OK as is on 64-bit, must be converted to
1949                      lt-relative PLT on 31-bit.  */
1950                   case 113:
1951                     if (!TARGET_64BIT)
1952                       {
1953                         rtx temp = reg? reg : gen_reg_rtx (Pmode);
1954
1955                         addr = XVECEXP (addr, 0, 0);
1956                         addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 114);
1957                         addr = gen_rtx_CONST (SImode, addr);
1958                         addr = force_const_mem (SImode, addr);
1959                         emit_move_insn (temp, addr);
1960
1961                         base = gen_rtx_REG (Pmode, BASE_REGISTER);
1962                         base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
1963                         new = gen_rtx_PLUS (Pmode, base, temp);
1964
1965                         if (reg != 0)
1966                           {
1967                             emit_move_insn (reg, new);
1968                             new = reg;
1969                           }
1970                       }
1971                     break;
1972
1973                   /* Everything else cannot happen.  */
1974                   default:
1975                     abort ();
1976                 }
1977             }
1978           else if (GET_CODE (addr) != PLUS)
1979             abort ();
1980         }
1981       if (GET_CODE (addr) == PLUS)
1982         {
1983           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
1984           /* Check first to see if this is a constant offset 
1985              from a local symbol reference.  */
1986           if ((GET_CODE (op0) == LABEL_REF
1987                 || (GET_CODE (op0) == SYMBOL_REF
1988                     && (SYMBOL_REF_FLAG (op0)
1989                         || CONSTANT_POOL_ADDRESS_P (op0))))
1990               && GET_CODE (op1) == CONST_INT)
1991             {
1992               if (TARGET_64BIT)
1993                 {
1994                   if (INTVAL (op1) & 1)
1995                     {
1996                       /* LARL can't handle odd offsets, so emit a 
1997                          pair of LARL and LA.  */
1998                       rtx temp = reg? reg : gen_reg_rtx (Pmode);
1999
2000                       if (INTVAL (op1) < 0 || INTVAL (op1) >= 4096)
2001                         {
2002                           int even = INTVAL (op1) - 1;
2003                           op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2004                           op0 = gen_rtx_CONST (Pmode, op0);
2005                           op1 = GEN_INT (1);
2006                         }
2007
2008                       emit_move_insn (temp, op0);
2009                       new = gen_rtx_PLUS (Pmode, temp, op1);
2010
2011                       if (reg != 0)
2012                         {
2013                           emit_move_insn (reg, new);
2014                           new = reg;
2015                         }
2016                     }
2017                   else
2018                     {
2019                       /* If the offset is even, we can just use LARL.
2020                          This will happen automatically.  */
2021                     }
2022                 }
2023               else
2024                 {
2025                   /* Access local symbols relative to the literal pool.  */
2026
2027                   rtx temp = reg? reg : gen_reg_rtx (Pmode);
2028
2029                   addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), 100);
2030                   addr = gen_rtx_PLUS (SImode, addr, op1);
2031                   addr = gen_rtx_CONST (SImode, addr);
2032                   addr = force_const_mem (SImode, addr);
2033                   emit_move_insn (temp, addr);
2034
2035                   base = gen_rtx_REG (Pmode, BASE_REGISTER);
2036                   base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
2037                   new = gen_rtx_PLUS (Pmode, base, temp);
2038
2039                   if (reg != 0)
2040                     {
2041                       emit_move_insn (reg, new);
2042                       new = reg;
2043                     }
2044                 }
2045             }
2046
2047           /* Now, check whether it is an LT-relative symbol plus offset
2048              that was pulled out of the literal pool.  Force it back in.  */
2049
2050           else if (GET_CODE (op0) == UNSPEC
2051                    && GET_CODE (op1) == CONST_INT)
2052             {
2053               if (XVECLEN (op0, 0) != 1)
2054                 abort ();
2055               if (XINT (op0, 1) != 100)
2056                 abort ();
2057
2058               new = force_const_mem (SImode, orig);
2059             }
2060
2061           /* Otherwise, compute the sum.  */
2062           else
2063             {
2064               base = legitimize_pic_address (XEXP (addr, 0), reg);
2065               new  = legitimize_pic_address (XEXP (addr, 1),
2066                                              base == reg ? NULL_RTX : reg);
2067               if (GET_CODE (new) == CONST_INT)
2068                 new = plus_constant (base, INTVAL (new));
2069               else
2070                 {
2071                   if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2072                     {
2073                       base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2074                       new = XEXP (new, 1);
2075                     }
2076                   new = gen_rtx_PLUS (Pmode, base, new);
2077                 }
2078
2079               if (GET_CODE (new) == CONST)
2080                 new = XEXP (new, 0);
2081               new = force_operand (new, 0);
2082             }
2083         }
2084     }
2085   return new;
2086 }
2087
2088 /* Emit insns to move operands[1] into operands[0].  */
2089
2090 void
2091 emit_pic_move (operands, mode)
2092      rtx *operands;
2093      enum machine_mode mode ATTRIBUTE_UNUSED;
2094 {
2095   rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2096
2097   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2098     operands[1] = force_reg (Pmode, operands[1]);
2099   else
2100     operands[1] = legitimize_pic_address (operands[1], temp);
2101 }
2102
2103 /* Try machine-dependent ways of modifying an illegitimate address X
2104    to be legitimate.  If we find one, return the new, valid address.
2105
2106    OLDX is the address as it was before break_out_memory_refs was called.
2107    In some cases it is useful to look at this to decide what needs to be done.
2108
2109    MODE is the mode of the operand pointed to by X.
2110
2111    When -fpic is used, special handling is needed for symbolic references.
2112    See comments by legitimize_pic_address for details.  */
2113
2114 rtx
2115 legitimize_address (x, oldx, mode)
2116      register rtx x;
2117      register rtx oldx ATTRIBUTE_UNUSED;
2118      enum machine_mode mode ATTRIBUTE_UNUSED;
2119 {
2120   rtx constant_term = const0_rtx;
2121
2122   if (flag_pic)
2123     {
2124       if (SYMBOLIC_CONST (x)
2125           || (GET_CODE (x) == PLUS 
2126               && (SYMBOLIC_CONST (XEXP (x, 0)) 
2127                   || SYMBOLIC_CONST (XEXP (x, 1)))))
2128           x = legitimize_pic_address (x, 0);
2129
2130       if (legitimate_address_p (mode, x, FALSE))
2131         return x;
2132     }
2133
2134   x = eliminate_constant_term (x, &constant_term);
2135
2136   /* Optimize loading of large displacements by splitting them
2137      into the multiple of 4K and the rest; this allows the
2138      former to be CSE'd if possible. 
2139
2140      Don't do this if the displacement is added to a register
2141      pointing into the stack frame, as the offsets will
2142      change later anyway.  */
2143
2144   if (GET_CODE (constant_term) == CONST_INT
2145       && (INTVAL (constant_term) < 0
2146           || INTVAL (constant_term) >= 4096)
2147       && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
2148     {
2149       HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
2150       HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
2151
2152       rtx temp = gen_reg_rtx (Pmode);
2153       rtx val  = force_operand (GEN_INT (upper), temp);
2154       if (val != temp)
2155         emit_move_insn (temp, val);
2156
2157       x = gen_rtx_PLUS (Pmode, x, temp);
2158       constant_term = GEN_INT (lower);
2159     }
2160
2161   if (GET_CODE (x) == PLUS)
2162     {
2163       if (GET_CODE (XEXP (x, 0)) == REG)
2164         {
2165           register rtx temp = gen_reg_rtx (Pmode);
2166           register rtx val  = force_operand (XEXP (x, 1), temp);
2167           if (val != temp)
2168             emit_move_insn (temp, val);
2169
2170           x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
2171         }
2172
2173       else if (GET_CODE (XEXP (x, 1)) == REG)
2174         {
2175           register rtx temp = gen_reg_rtx (Pmode);
2176           register rtx val  = force_operand (XEXP (x, 0), temp);
2177           if (val != temp)
2178             emit_move_insn (temp, val);
2179
2180           x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
2181         }
2182     }
2183
2184   if (constant_term != const0_rtx)
2185     x = gen_rtx_PLUS (Pmode, x, constant_term);
2186
2187   return x;
2188 }
2189
2190 /* Emit code to move LEN bytes from DST to SRC.  */
2191
2192 void
2193 s390_expand_movstr (dst, src, len)
2194      rtx dst;
2195      rtx src;
2196      rtx len;
2197 {
2198   rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) = 
2199     TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
2200   rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) = 
2201     TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
2202
2203
2204   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2205     {
2206       if (INTVAL (len) > 0)
2207         emit_insn ((*gen_short) (dst, src, GEN_INT (INTVAL (len) - 1)));
2208     }
2209
2210   else if (TARGET_MVCLE)
2211     {
2212       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2213       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2214       rtx reg0 = gen_reg_rtx (double_mode);
2215       rtx reg1 = gen_reg_rtx (double_mode);
2216
2217       emit_move_insn (gen_highpart (single_mode, reg0), 
2218                       force_operand (XEXP (dst, 0), NULL_RTX));
2219       emit_move_insn (gen_highpart (single_mode, reg1), 
2220                       force_operand (XEXP (src, 0), NULL_RTX));
2221
2222       convert_move (gen_lowpart (single_mode, reg0), len, 1);
2223       convert_move (gen_lowpart (single_mode, reg1), len, 1);
2224
2225       emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
2226     }
2227
2228   else
2229     {
2230       rtx dst_addr, src_addr, count, blocks, temp;
2231       rtx end_label = gen_label_rtx ();
2232       enum machine_mode mode;
2233       tree type;
2234
2235       mode = GET_MODE (len);
2236       if (mode == VOIDmode)
2237         mode = word_mode;
2238
2239       type = (*lang_hooks.types.type_for_mode) (mode, 1);
2240       if (!type)
2241         abort ();
2242
2243       dst_addr = gen_reg_rtx (Pmode);
2244       src_addr = gen_reg_rtx (Pmode);
2245       count = gen_reg_rtx (mode);
2246       blocks = gen_reg_rtx (mode);
2247
2248       convert_move (count, len, 1);
2249       emit_cmp_and_jump_insns (count, const0_rtx, 
2250                                EQ, NULL_RTX, mode, 1, end_label);
2251
2252       emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2253       emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
2254       dst = change_address (dst, VOIDmode, dst_addr);
2255       src = change_address (src, VOIDmode, src_addr);
2256      
2257       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2258       if (temp != count)
2259         emit_move_insn (count, temp);
2260
2261       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2262       if (temp != blocks)
2263         emit_move_insn (blocks, temp);
2264
2265       expand_start_loop (1);
2266       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2267                                            make_tree (type, blocks),
2268                                            make_tree (type, const0_rtx)));
2269
2270       emit_insn ((*gen_short) (dst, src, GEN_INT (255)));
2271       s390_load_address (dst_addr, 
2272                          gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
2273       s390_load_address (src_addr, 
2274                          gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
2275       
2276       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2277       if (temp != blocks)
2278         emit_move_insn (blocks, temp);
2279
2280       expand_end_loop ();
2281
2282       emit_insn ((*gen_short) (dst, src, convert_to_mode (word_mode, count, 1)));
2283       emit_label (end_label);
2284     }
2285 }
2286
2287 /* Emit code to clear LEN bytes at DST.  */
2288
2289 void
2290 s390_expand_clrstr (dst, len)
2291      rtx dst;
2292      rtx len;
2293 {
2294   rtx (*gen_short) PARAMS ((rtx, rtx)) = 
2295     TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
2296   rtx (*gen_long) PARAMS ((rtx, rtx, rtx)) = 
2297     TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
2298
2299
2300   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2301     {
2302       if (INTVAL (len) > 0)
2303         emit_insn ((*gen_short) (dst, GEN_INT (INTVAL (len) - 1)));
2304     }
2305
2306   else if (TARGET_MVCLE)
2307     {
2308       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2309       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2310       rtx reg0 = gen_reg_rtx (double_mode);
2311       rtx reg1 = gen_reg_rtx (double_mode);
2312
2313       emit_move_insn (gen_highpart (single_mode, reg0), 
2314                       force_operand (XEXP (dst, 0), NULL_RTX));
2315       convert_move (gen_lowpart (single_mode, reg0), len, 1);
2316
2317       emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
2318       emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
2319
2320       emit_insn ((*gen_long) (reg0, reg1, reg0));
2321     }
2322
2323   else
2324     {
2325       rtx dst_addr, src_addr, count, blocks, temp;
2326       rtx end_label = gen_label_rtx ();
2327       enum machine_mode mode;
2328       tree type;
2329
2330       mode = GET_MODE (len);
2331       if (mode == VOIDmode)
2332         mode = word_mode;
2333
2334       type = (*lang_hooks.types.type_for_mode) (mode, 1);
2335       if (!type)
2336         abort ();
2337
2338       dst_addr = gen_reg_rtx (Pmode);
2339       src_addr = gen_reg_rtx (Pmode);
2340       count = gen_reg_rtx (mode);
2341       blocks = gen_reg_rtx (mode);
2342
2343       convert_move (count, len, 1);
2344       emit_cmp_and_jump_insns (count, const0_rtx, 
2345                                EQ, NULL_RTX, mode, 1, end_label);
2346
2347       emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2348       dst = change_address (dst, VOIDmode, dst_addr);
2349      
2350       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2351       if (temp != count)
2352         emit_move_insn (count, temp);
2353
2354       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2355       if (temp != blocks)
2356         emit_move_insn (blocks, temp);
2357
2358       expand_start_loop (1);
2359       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2360                                            make_tree (type, blocks),
2361                                            make_tree (type, const0_rtx)));
2362
2363       emit_insn ((*gen_short) (dst, GEN_INT (255)));
2364       s390_load_address (dst_addr, 
2365                          gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
2366       
2367       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2368       if (temp != blocks)
2369         emit_move_insn (blocks, temp);
2370
2371       expand_end_loop ();
2372
2373       emit_insn ((*gen_short) (dst, convert_to_mode (word_mode, count, 1)));
2374       emit_label (end_label);
2375     }
2376 }
2377
2378 /* Emit code to compare LEN bytes at OP0 with those at OP1,
2379    and return the result in TARGET.  */
2380
2381 void
2382 s390_expand_cmpstr (target, op0, op1, len)
2383      rtx target;
2384      rtx op0;
2385      rtx op1;
2386      rtx len;
2387 {
2388   rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) = 
2389     TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31;
2390   rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) = 
2391     TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31;
2392   rtx (*gen_result) PARAMS ((rtx)) =
2393     GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
2394
2395   op0 = protect_from_queue (op0, 0);
2396   op1 = protect_from_queue (op1, 0);
2397   len = protect_from_queue (len, 0);
2398
2399   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2400     {
2401       if (INTVAL (len) > 0)
2402         {
2403           emit_insn ((*gen_short) (op0, op1, GEN_INT (INTVAL (len) - 1)));
2404           emit_insn ((*gen_result) (target));
2405         }
2406       else
2407         emit_move_insn (target, const0_rtx);
2408     }
2409
2410   else if (TARGET_MVCLE)
2411     {
2412       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2413       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2414       rtx reg0 = gen_reg_rtx (double_mode);
2415       rtx reg1 = gen_reg_rtx (double_mode);
2416
2417       emit_move_insn (gen_highpart (single_mode, reg0), 
2418                       force_operand (XEXP (op0, 0), NULL_RTX));
2419       emit_move_insn (gen_highpart (single_mode, reg1), 
2420                       force_operand (XEXP (op1, 0), NULL_RTX));
2421
2422       convert_move (gen_lowpart (single_mode, reg0), len, 1);
2423       convert_move (gen_lowpart (single_mode, reg1), len, 1);
2424
2425       emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
2426       emit_insn ((*gen_result) (target));
2427     }
2428
2429   else
2430     {
2431       rtx addr0, addr1, count, blocks, temp;
2432       rtx end_label = gen_label_rtx ();
2433       enum machine_mode mode;
2434       tree type;
2435
2436       mode = GET_MODE (len);
2437       if (mode == VOIDmode)
2438         mode = word_mode;
2439
2440       type = (*lang_hooks.types.type_for_mode) (mode, 1);
2441       if (!type)
2442         abort ();
2443
2444       addr0 = gen_reg_rtx (Pmode);
2445       addr1 = gen_reg_rtx (Pmode);
2446       count = gen_reg_rtx (mode);
2447       blocks = gen_reg_rtx (mode);
2448
2449       convert_move (count, len, 1);
2450       emit_cmp_and_jump_insns (count, const0_rtx, 
2451                                EQ, NULL_RTX, mode, 1, end_label);
2452
2453       emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
2454       emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2455       op0 = change_address (op0, VOIDmode, addr0);
2456       op1 = change_address (op1, VOIDmode, addr1);
2457      
2458       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2459       if (temp != count)
2460         emit_move_insn (count, temp);
2461
2462       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2463       if (temp != blocks)
2464         emit_move_insn (blocks, temp);
2465
2466       expand_start_loop (1);
2467       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2468                                            make_tree (type, blocks),
2469                                            make_tree (type, const0_rtx)));
2470
2471       emit_insn ((*gen_short) (op0, op1, GEN_INT (255)));
2472       temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
2473       temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp, 
2474                         gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
2475       temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
2476       emit_jump_insn (temp);
2477
2478       s390_load_address (addr0, 
2479                          gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
2480       s390_load_address (addr1, 
2481                          gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
2482       
2483       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2484       if (temp != blocks)
2485         emit_move_insn (blocks, temp);
2486
2487       expand_end_loop ();
2488
2489       emit_insn ((*gen_short) (op0, op1, convert_to_mode (word_mode, count, 1)));
2490       emit_label (end_label);
2491
2492       emit_insn ((*gen_result) (target));
2493     }
2494 }
2495
2496 /* In the name of slightly smaller debug output, and to cater to
2497    general assembler losage, recognize various UNSPEC sequences
2498    and turn them back into a direct symbol reference.  */
2499
2500 rtx
2501 s390_simplify_dwarf_addr (orig_x)
2502      rtx orig_x;
2503 {
2504   rtx x = orig_x, y;
2505
2506   if (GET_CODE (x) != MEM)
2507     return orig_x;
2508
2509   x = XEXP (x, 0);
2510   if (GET_CODE (x) == PLUS
2511       && GET_CODE (XEXP (x, 1)) == CONST
2512       && GET_CODE (XEXP (x, 0)) == REG
2513       && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
2514     {
2515       y = XEXP (XEXP (x, 1), 0);
2516       if (GET_CODE (y) == UNSPEC
2517           && XINT (y, 1) == 110)
2518         return XVECEXP (y, 0, 0);
2519       return orig_x;
2520     }
2521
2522   if (GET_CODE (x) == CONST)
2523     {
2524       y = XEXP (x, 0);
2525       if (GET_CODE (y) == UNSPEC
2526           && XINT (y, 1) == 111)
2527         return XVECEXP (y, 0, 0);
2528       return orig_x;
2529     }
2530
2531   return orig_x;      
2532 }
2533
2534 /* Output symbolic constant X in assembler syntax to 
2535    stdio stream FILE.  */
2536
2537 void
2538 s390_output_symbolic_const (file, x)
2539      FILE *file;
2540      rtx x;
2541 {
2542   switch (GET_CODE (x))
2543     {
2544     case CONST:
2545     case ZERO_EXTEND:
2546     case SIGN_EXTEND:
2547       s390_output_symbolic_const (file, XEXP (x, 0));
2548       break;
2549
2550     case PLUS:
2551       s390_output_symbolic_const (file, XEXP (x, 0));
2552       fprintf (file, "+");
2553       s390_output_symbolic_const (file, XEXP (x, 1));
2554       break;
2555
2556     case MINUS:
2557       s390_output_symbolic_const (file, XEXP (x, 0));
2558       fprintf (file, "-");
2559       s390_output_symbolic_const (file, XEXP (x, 1));
2560       break;
2561
2562     case CONST_INT:
2563     case LABEL_REF:
2564     case CODE_LABEL:
2565     case SYMBOL_REF:
2566       output_addr_const (file, x);
2567       break;
2568
2569     case UNSPEC:
2570       if (XVECLEN (x, 0) != 1)
2571         output_operand_lossage ("invalid UNSPEC as operand (1)");
2572       switch (XINT (x, 1))
2573         {
2574         case 100:
2575         case 104:
2576           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2577           fprintf (file, "-.LT%d", current_function_funcdef_no);
2578           break;
2579         case 105:
2580           fprintf (file, ".LT%d-", current_function_funcdef_no);
2581           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2582           break;
2583         case 110:
2584           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2585           fprintf (file, "@GOT12");
2586           break;
2587         case 111:
2588           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2589           fprintf (file, "@GOTENT");
2590           break;
2591         case 112:
2592           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2593           fprintf (file, "@GOT");
2594           break;
2595         case 113:
2596           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2597           fprintf (file, "@PLT");
2598           break;
2599         case 114:
2600           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
2601           fprintf (file, "@PLT-.LT%d", current_function_funcdef_no);
2602           break;
2603         default:
2604           output_operand_lossage ("invalid UNSPEC as operand (2)");
2605           break;
2606         }
2607       break;
2608
2609     default:
2610       fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
2611       break;
2612     }
2613 }
2614
2615 /* Output address operand ADDR in assembler syntax to 
2616    stdio stream FILE.  */
2617
2618 void
2619 print_operand_address (file, addr)
2620      FILE *file;
2621      rtx addr;
2622 {
2623   struct s390_address ad;
2624
2625   if (!s390_decompose_address (addr, &ad)
2626       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2627       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
2628     output_operand_lossage ("Cannot decompose address.");
2629  
2630   if (ad.disp)
2631     s390_output_symbolic_const (file, ad.disp);
2632   else
2633     fprintf (file, "0");
2634
2635   if (ad.base && ad.indx)
2636     fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
2637                               reg_names[REGNO (ad.base)]);
2638   else if (ad.base)
2639     fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
2640 }
2641
2642 /* Output operand X in assembler syntax to stdio stream FILE.  
2643    CODE specified the format flag.  The following format flags 
2644    are recognized:
2645
2646     'C': print opcode suffix for branch condition.
2647     'D': print opcode suffix for inverse branch condition.
2648     'O': print only the displacement of a memory reference.
2649     'R': print only the base register of a memory reference.
2650     'N': print the second word of a DImode operand.
2651     'M': print the second word of a TImode operand.
2652
2653     'b': print integer X as if it's an unsigned byte.
2654     'x': print integer X as if it's an unsigned word.
2655     'h': print integer X as if it's a signed word.  */
2656
2657 void
2658 print_operand (file, x, code)
2659      FILE *file;
2660      rtx x;
2661      int code;
2662 {
2663   switch (code)
2664     {
2665     case 'C':
2666       fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
2667       return;
2668
2669     case 'D':
2670       fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
2671       return;
2672
2673     case 'O':
2674       {
2675         struct s390_address ad;
2676
2677         if (GET_CODE (x) != MEM
2678             || !s390_decompose_address (XEXP (x, 0), &ad)
2679             || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2680             || ad.indx)
2681           abort ();
2682
2683         if (ad.disp)
2684           s390_output_symbolic_const (file, ad.disp);
2685         else
2686           fprintf (file, "0");
2687       }
2688       return;
2689
2690     case 'R':
2691       {
2692         struct s390_address ad;
2693
2694         if (GET_CODE (x) != MEM
2695             || !s390_decompose_address (XEXP (x, 0), &ad)
2696             || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2697             || ad.indx)
2698           abort ();
2699
2700         if (ad.base)
2701           fprintf (file, "%s", reg_names[REGNO (ad.base)]);
2702         else
2703           fprintf (file, "0");
2704       }
2705       return;
2706
2707     case 'N':
2708       if (GET_CODE (x) == REG)
2709         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
2710       else if (GET_CODE (x) == MEM)
2711         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
2712       else
2713         abort ();
2714       break;
2715
2716     case 'M':
2717       if (GET_CODE (x) == REG)
2718         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
2719       else if (GET_CODE (x) == MEM)
2720         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
2721       else
2722         abort ();
2723       break;
2724     }
2725
2726   switch (GET_CODE (x))
2727     {
2728     case REG:
2729       fprintf (file, "%s", reg_names[REGNO (x)]);
2730       break;
2731
2732     case MEM:
2733       output_address (XEXP (x, 0));
2734       break;
2735
2736     case CONST:
2737     case CODE_LABEL:
2738     case LABEL_REF:
2739     case SYMBOL_REF:
2740       s390_output_symbolic_const (file, x);
2741       break;
2742
2743     case CONST_INT:
2744       if (code == 'b')
2745         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
2746       else if (code == 'x')
2747         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
2748       else if (code == 'h')
2749         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
2750       else
2751         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2752       break;
2753
2754     case CONST_DOUBLE:
2755       if (GET_MODE (x) != VOIDmode)
2756         abort ();
2757       if (code == 'b')
2758         fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
2759       else if (code == 'x')
2760         fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
2761       else if (code == 'h')
2762         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
2763       else
2764         abort ();
2765       break;
2766
2767     default:
2768       fatal_insn ("UNKNOWN in print_operand !?", x);
2769       break;
2770     }
2771 }
2772
2773 /* Target hook for assembling integer objects.  We need to define it
2774    here to work a round a bug in some versions of GAS, which couldn't
2775    handle values smaller than INT_MIN when printed in decimal.  */
2776
2777 static bool
2778 s390_assemble_integer (x, size, aligned_p)
2779      rtx x;
2780      unsigned int size;
2781      int aligned_p;
2782 {
2783   if (size == 8 && aligned_p
2784       && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
2785     {
2786       fputs ("\t.quad\t", asm_out_file);
2787       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
2788       putc ('\n', asm_out_file);
2789       return true;
2790     }
2791   return default_assemble_integer (x, size, aligned_p);
2792 }
2793
2794
2795 #define DEBUG_SCHED 0
2796
2797 /* Returns true if register REGNO is used  for forming 
2798    a memory address in expression X.  */
2799
2800 static int
2801 reg_used_in_mem_p (regno, x)
2802      int regno;
2803      rtx x;
2804 {
2805   enum rtx_code code = GET_CODE (x);
2806   int i, j;
2807   const char *fmt;
2808   
2809   if (code == MEM)
2810     {
2811       if (refers_to_regno_p (regno, regno+1,
2812                              XEXP (x, 0), 0))
2813         return 1;
2814     }
2815   else if (code == SET 
2816            && GET_CODE (SET_DEST (x)) == PC)
2817     {
2818       if (refers_to_regno_p (regno, regno+1,
2819                              SET_SRC (x), 0))
2820         return 1;
2821     }
2822
2823   fmt = GET_RTX_FORMAT (code);
2824   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2825     {
2826       if (fmt[i] == 'e'
2827           && reg_used_in_mem_p (regno, XEXP (x, i)))
2828         return 1;
2829       
2830       else if (fmt[i] == 'E')
2831         for (j = 0; j < XVECLEN (x, i); j++)
2832           if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
2833             return 1;
2834     }
2835   return 0;
2836 }
2837
2838 /* Returns true if expression DEP_RTX sets an address register
2839    used by instruction INSN to address memory.  */
2840
2841 static int 
2842 addr_generation_dependency_p (dep_rtx, insn)
2843      rtx dep_rtx; 
2844      rtx insn;
2845 {
2846   rtx target, pat;
2847
2848   if (GET_CODE (dep_rtx) == SET)
2849     {
2850       target = SET_DEST (dep_rtx);
2851       if (GET_CODE (target) == STRICT_LOW_PART)
2852         target = XEXP (target, 0);
2853       while (GET_CODE (target) == SUBREG)
2854         target = SUBREG_REG (target);
2855
2856       if (GET_CODE (target) == REG)
2857         {
2858           int regno = REGNO (target);
2859
2860           if (get_attr_type (insn) == TYPE_LA)
2861             {
2862               pat = PATTERN (insn);
2863               if (GET_CODE (pat) == PARALLEL)
2864                 {
2865                   if (XVECLEN (pat, 0) != 2)
2866                     abort();
2867                   pat = XVECEXP (pat, 0, 0);
2868                 }
2869               if (GET_CODE (pat) == SET)
2870                 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
2871               else
2872                 abort();
2873             }
2874           else if (get_attr_atype (insn) == ATYPE_MEM)
2875             return reg_used_in_mem_p (regno, PATTERN (insn));
2876         }
2877     }
2878   return 0;
2879 }
2880
2881
2882 /* Return the modified cost of the dependency of instruction INSN
2883    on instruction DEP_INSN through the link LINK.  COST is the 
2884    default cost of that dependency.
2885
2886    Data dependencies are all handled without delay.  However, if a
2887    register is modified and subsequently used as base or index 
2888    register of a memory reference, at least 4 cycles need to pass
2889    between setting and using the register to avoid pipeline stalls.  
2890    An exception is the LA instruction. An address generated by LA can
2891    be used by introducing only a one cycle stall on the pipeline.  */
2892
2893 static int
2894 s390_adjust_cost (insn, link, dep_insn, cost)
2895      rtx insn;
2896      rtx link;
2897      rtx dep_insn;
2898      int cost;
2899 {
2900   rtx dep_rtx;
2901   int i;
2902
2903   /* If the dependence is an anti-dependence, there is no cost.  For an
2904      output dependence, there is sometimes a cost, but it doesn't seem
2905      worth handling those few cases.  */
2906
2907   if (REG_NOTE_KIND (link) != 0)
2908     return 0;
2909
2910   /* If we can't recognize the insns, we can't really do anything.  */
2911   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2912     return cost;
2913
2914   dep_rtx = PATTERN (dep_insn);
2915
2916   if (GET_CODE (dep_rtx) == SET)
2917     {
2918       if (addr_generation_dependency_p (dep_rtx, insn))
2919         {
2920           cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;  
2921           if (DEBUG_SCHED)
2922             {
2923               fprintf (stderr, "\n\nAddress dependency detected: cost %d\n",
2924                        cost);
2925               debug_rtx (dep_insn);
2926               debug_rtx (insn);
2927             }
2928         }
2929     }
2930   else if (GET_CODE (dep_rtx) == PARALLEL)
2931     {
2932       for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
2933         {
2934           if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i),
2935                                             insn))
2936             {
2937               cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;  
2938               if (DEBUG_SCHED)
2939                 {
2940                   fprintf (stderr, "\n\nAddress dependency detected: cost %d\n"
2941                            ,cost);
2942                   debug_rtx (dep_insn);
2943                   debug_rtx (insn);
2944                 }
2945             }
2946         }
2947     }
2948
2949   return cost;
2950 }
2951
2952
2953 /* A C statement (sans semicolon) to update the integer scheduling priority
2954    INSN_PRIORITY (INSN).  Reduce the priority to execute the INSN earlier,
2955    increase the priority to execute INSN later.  Do not define this macro if
2956    you do not need to adjust the scheduling priorities of insns. 
2957
2958    A LA instruction maybe scheduled later, since the pipeline bypasses the
2959    calculated value.  */
2960
2961 static int
2962 s390_adjust_priority (insn, priority)
2963      rtx insn ATTRIBUTE_UNUSED;
2964      int priority;
2965 {
2966   if (! INSN_P (insn))
2967     return priority;
2968
2969   if (GET_CODE (PATTERN (insn)) == USE 
2970       || GET_CODE (PATTERN (insn)) == CLOBBER)
2971     return priority;
2972   
2973   switch (get_attr_type (insn))
2974     {
2975     default:
2976       break;
2977       
2978     case TYPE_LA:
2979       if (priority >= 0 && priority < 0x01000000)
2980         priority <<= 3;
2981       break;
2982     case TYPE_LM:
2983       /* LM in epilogue should never be scheduled. This
2984          is due to literal access done in function body.
2985          The usage of register 13 is not mentioned explicitly,
2986          leading to scheduling 'LM' accross this instructions.  
2987       */ 
2988       priority = 0x7fffffff;
2989       break;
2990     }
2991   
2992   return priority;
2993 }
2994
2995
2996 /* Split all branches that exceed the maximum distance.  
2997    Returns true if this created a new literal pool entry.  
2998
2999    Code generated by this routine is allowed to use
3000    TEMP_REG as temporary scratch register.  If this is
3001    done, TEMP_USED is set to true.  */
3002
3003 static int 
3004 s390_split_branches (temp_reg, temp_used)
3005      rtx temp_reg;
3006      bool *temp_used;
3007 {
3008   int new_literal = 0;
3009   rtx insn, pat, tmp, target;
3010   rtx *label;
3011
3012   /* We need correct insn addresses.  */
3013
3014   shorten_branches (get_insns ());
3015
3016   /* Find all branches that exceed 64KB, and split them.  */
3017
3018   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3019     {
3020       if (GET_CODE (insn) != JUMP_INSN)
3021         continue;
3022
3023       pat = PATTERN (insn);
3024       if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3025         pat = XVECEXP (pat, 0, 0);
3026       if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
3027         continue;
3028
3029       if (GET_CODE (SET_SRC (pat)) == LABEL_REF) 
3030         {
3031           label = &SET_SRC (pat);
3032         } 
3033       else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE) 
3034         {
3035           if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF) 
3036             label = &XEXP (SET_SRC (pat), 1);
3037           else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF) 
3038             label = &XEXP (SET_SRC (pat), 2);
3039           else
3040             continue;
3041         }
3042       else
3043         continue;
3044
3045       if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
3046         continue;
3047
3048       *temp_used = 1;
3049
3050       if (TARGET_64BIT)
3051         {
3052           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
3053           INSN_ADDRESSES_NEW (tmp, -1);
3054
3055           target = temp_reg;
3056         }
3057       else if (!flag_pic)
3058         {
3059           new_literal = 1;
3060           tmp = force_const_mem (Pmode, *label);
3061           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3062           INSN_ADDRESSES_NEW (tmp, -1);
3063
3064           target = temp_reg;
3065         }
3066       else
3067         {
3068           new_literal = 1;
3069           tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 104);
3070           tmp = gen_rtx_CONST (SImode, tmp);
3071           tmp = force_const_mem (SImode, tmp);
3072           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3073           INSN_ADDRESSES_NEW (tmp, -1);
3074
3075           target = gen_rtx_REG (Pmode, BASE_REGISTER);
3076           target = gen_rtx_PLUS (Pmode, target, temp_reg);
3077         }
3078
3079       if (!validate_change (insn, label, target, 0))
3080         abort ();
3081     }
3082
3083   return new_literal;
3084 }
3085
3086
3087 /* Find a literal pool symbol referenced in RTX X, and store 
3088    it at REF.  Will abort if X contains references to more than 
3089    one such pool symbol; multiple references to the same symbol
3090    are allowed, however. 
3091
3092    The rtx pointed to by REF must be initialized to NULL_RTX 
3093    by the caller before calling this routine.  */
3094
3095 static void
3096 find_constant_pool_ref (x, ref)
3097      rtx x;
3098      rtx *ref;
3099 {
3100   int i, j;
3101   const char *fmt;
3102
3103   if (GET_CODE (x) == SYMBOL_REF
3104       && CONSTANT_POOL_ADDRESS_P (x))
3105     {
3106       if (*ref == NULL_RTX)
3107         *ref = x;
3108       else if (*ref != x)
3109         abort();
3110     }
3111
3112   fmt = GET_RTX_FORMAT (GET_CODE (x));
3113   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3114     {
3115       if (fmt[i] == 'e')
3116         {
3117           find_constant_pool_ref (XEXP (x, i), ref);
3118         }
3119       else if (fmt[i] == 'E')
3120         {
3121           for (j = 0; j < XVECLEN (x, i); j++)
3122             find_constant_pool_ref (XVECEXP (x, i, j), ref);
3123         }
3124     }
3125 }
3126
3127 /* Replace every reference to the literal pool symbol REF
3128    in X by the address ADDR.  Fix up MEMs as required.  */
3129
3130 static void
3131 replace_constant_pool_ref (x, ref, addr)
3132      rtx *x;
3133      rtx ref;
3134      rtx addr;
3135 {
3136   int i, j;
3137   const char *fmt;
3138
3139   if (*x == ref)
3140     abort ();
3141
3142   /* Literal pool references can only occur inside a MEM ...  */
3143   if (GET_CODE (*x) == MEM)
3144     {
3145       rtx memref = XEXP (*x, 0);
3146
3147       if (memref == ref)
3148         {
3149           *x = replace_equiv_address (*x, addr);
3150           return;
3151         }
3152
3153       if (GET_CODE (memref) == CONST
3154           && GET_CODE (XEXP (memref, 0)) == PLUS
3155           && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
3156           && XEXP (XEXP (memref, 0), 0) == ref)
3157         {
3158           HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
3159           *x = replace_equiv_address (*x, plus_constant (addr, off));
3160           return;
3161         }
3162     }
3163
3164   /* ... or a load-address type pattern.  */
3165   if (GET_CODE (*x) == SET)
3166     {
3167       rtx addrref = SET_SRC (*x);
3168
3169       if (addrref == ref)
3170         {
3171           SET_SRC (*x) = addr;
3172           return;
3173         }
3174
3175       if (GET_CODE (addrref) == CONST
3176           && GET_CODE (XEXP (addrref, 0)) == PLUS
3177           && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
3178           && XEXP (XEXP (addrref, 0), 0) == ref)
3179         {
3180           HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
3181           SET_SRC (*x) = plus_constant (addr, off);
3182           return;
3183         }
3184     }
3185
3186   fmt = GET_RTX_FORMAT (GET_CODE (*x));
3187   for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
3188     {
3189       if (fmt[i] == 'e')
3190         {
3191           replace_constant_pool_ref (&XEXP (*x, i), ref, addr);
3192         }
3193       else if (fmt[i] == 'E')
3194         {
3195           for (j = 0; j < XVECLEN (*x, i); j++)
3196             replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, addr);
3197         }
3198     }
3199 }
3200
3201 /* Check whether ADDR is an address that uses the base register, 
3202    without actually constituting a literal pool access.  (This happens
3203    in 31-bit PIC mode, where the base register is used as anchor for
3204    relative addressing of local symbols.) 
3205
3206    Returns 1 if the base register occupies the base slot,
3207    returns 2 if the base register occupies the index slot,
3208    returns 0 if the address is not of this form.  */
3209
3210 static int
3211 find_base_register_in_addr (addr)
3212      struct s390_address *addr;
3213 {
3214   /* If DISP is complex, we might have a literal pool reference.  */
3215   if (addr->disp && GET_CODE (addr->disp) != CONST_INT)
3216     return 0;
3217
3218   if (addr->base && REG_P (addr->base) && REGNO (addr->base) == BASE_REGISTER)
3219     return 1;
3220
3221   if (addr->indx && REG_P (addr->indx) && REGNO (addr->indx) == BASE_REGISTER)
3222     return 2;
3223
3224   return 0;
3225 }
3226
3227 /* Return true if X contains an address that uses the base register, 
3228    without actually constituting a literal pool access.  */
3229
3230 static bool
3231 find_base_register_ref (x)
3232      rtx x;
3233 {
3234   bool retv = FALSE;
3235   struct s390_address addr;
3236   int i, j;
3237   const char *fmt;
3238
3239   /* Addresses can only occur inside a MEM ...  */
3240   if (GET_CODE (x) == MEM)
3241     {
3242       if (s390_decompose_address (XEXP (x, 0), &addr)
3243           && find_base_register_in_addr (&addr))
3244         return TRUE;
3245     }
3246
3247   /* ... or a load-address type pattern.  */
3248   if (GET_CODE (x) == SET && GET_CODE (SET_DEST (x)) == REG)
3249     {
3250       if (s390_decompose_address (SET_SRC (x), &addr)
3251           && find_base_register_in_addr (&addr))
3252         return TRUE;
3253     }
3254
3255   fmt = GET_RTX_FORMAT (GET_CODE (x));
3256   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3257     {
3258       if (fmt[i] == 'e')
3259         {
3260           retv |= find_base_register_ref (XEXP (x, i));
3261         }
3262       else if (fmt[i] == 'E')
3263         {
3264           for (j = 0; j < XVECLEN (x, i); j++)
3265             retv |= find_base_register_ref (XVECEXP (x, i, j));
3266         }
3267     }
3268
3269   return retv;
3270 }
3271
3272 /* If X contains an address that uses the base register,
3273    without actually constituting a literal pool access,
3274    replace the base register with REPL in all such cases.
3275
3276    Handles both MEMs and load address patterns.  */
3277
3278 static void
3279 replace_base_register_ref (x, repl)
3280      rtx *x;
3281      rtx repl;
3282 {
3283   struct s390_address addr;
3284   rtx new_addr;
3285   int i, j, pos;
3286   const char *fmt;
3287
3288   /* Addresses can only occur inside a MEM ...  */
3289   if (GET_CODE (*x) == MEM)
3290     {
3291       if (s390_decompose_address (XEXP (*x, 0), &addr)
3292           && (pos = find_base_register_in_addr (&addr)))
3293         {
3294           if (pos == 1)
3295             addr.base = repl;
3296           else
3297             addr.indx = repl;
3298
3299           new_addr = addr.base;
3300           if (addr.indx)
3301             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
3302           if (addr.disp)
3303             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
3304
3305           *x = replace_equiv_address (*x, new_addr);
3306           return;
3307         }
3308     }
3309
3310   /* ... or a load-address type pattern.  */
3311   if (GET_CODE (*x) == SET && GET_CODE (SET_DEST (*x)) == REG)
3312     {
3313       if (s390_decompose_address (SET_SRC (*x), &addr)
3314           && (pos = find_base_register_in_addr (&addr)))
3315         {
3316           if (pos == 1)
3317             addr.base = repl;
3318           else
3319             addr.indx = repl;
3320
3321           new_addr = addr.base;
3322           if (addr.indx)
3323             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
3324           if (addr.disp)
3325             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
3326
3327           SET_SRC (*x) = new_addr;
3328           return;
3329         }
3330     }
3331
3332   fmt = GET_RTX_FORMAT (GET_CODE (*x));
3333   for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
3334     {
3335       if (fmt[i] == 'e')
3336         {
3337           replace_base_register_ref (&XEXP (*x, i), repl);
3338         }
3339       else if (fmt[i] == 'E')
3340         {
3341           for (j = 0; j < XVECLEN (*x, i); j++)
3342             replace_base_register_ref (&XVECEXP (*x, i, j), repl);
3343         }
3344     }
3345 }
3346
3347
3348 /* We keep a list of constants we which we have to add to internal
3349    constant tables in the middle of large functions.  */
3350
3351 #define NR_C_MODES 6
3352 enum machine_mode constant_modes[NR_C_MODES] = 
3353 {
3354   DFmode, DImode,
3355   SFmode, SImode,
3356   HImode,
3357   QImode
3358 };
3359
3360 rtx (*gen_consttable[NR_C_MODES])(rtx) =
3361 {
3362   gen_consttable_df, gen_consttable_di,
3363   gen_consttable_sf, gen_consttable_si,
3364   gen_consttable_hi,
3365   gen_consttable_qi
3366 };
3367
3368 struct constant
3369 {
3370   struct constant *next;
3371   rtx value;
3372   rtx label;
3373 };
3374
3375 struct constant_pool
3376 {
3377   struct constant_pool *next;
3378   rtx first_insn;
3379   rtx pool_insn;
3380   bitmap insns;
3381
3382   struct constant *constants[NR_C_MODES];
3383   rtx label;
3384   int size;
3385   bool anchor;
3386 };
3387
3388 static struct constant_pool * s390_chunkify_start PARAMS ((rtx, bool *));
3389 static void s390_chunkify_finish PARAMS ((struct constant_pool *, rtx));
3390 static void s390_chunkify_cancel PARAMS ((struct constant_pool *));
3391
3392 static struct constant_pool *s390_start_pool PARAMS ((struct constant_pool **, rtx));
3393 static void s390_end_pool PARAMS ((struct constant_pool *, rtx));
3394 static void s390_add_pool_insn PARAMS ((struct constant_pool *, rtx));
3395 static struct constant_pool *s390_find_pool PARAMS ((struct constant_pool *, rtx));
3396 static void s390_add_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
3397 static rtx s390_find_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
3398 static void s390_add_anchor PARAMS ((struct constant_pool *));
3399 static rtx s390_dump_pool PARAMS ((struct constant_pool *));
3400 static void s390_free_pool PARAMS ((struct constant_pool *));
3401
3402 /* Create new constant pool covering instructions starting at INSN
3403    and chain it to the end of POOL_LIST.  */
3404
3405 static struct constant_pool *
3406 s390_start_pool (pool_list, insn)
3407      struct constant_pool **pool_list;
3408      rtx insn;
3409 {
3410   struct constant_pool *pool, **prev;
3411   int i;
3412
3413   pool = (struct constant_pool *) xmalloc (sizeof *pool);
3414   pool->next = NULL;
3415   for (i = 0; i < NR_C_MODES; i++)
3416     pool->constants[i] = NULL;
3417
3418   pool->label = gen_label_rtx ();
3419   pool->first_insn = insn;
3420   pool->pool_insn = NULL_RTX;
3421   pool->insns = BITMAP_XMALLOC ();
3422   pool->size = 0;
3423   pool->anchor = FALSE;
3424
3425   for (prev = pool_list; *prev; prev = &(*prev)->next)
3426     ;
3427   *prev = pool;
3428
3429   return pool;
3430 }
3431
3432 /* End range of instructions covered by POOL at INSN and emit
3433    placeholder insn representing the pool.  */
3434
3435 static void
3436 s390_end_pool (pool, insn)
3437      struct constant_pool *pool;
3438      rtx insn;
3439 {
3440   rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
3441
3442   if (!insn)
3443     insn = get_last_insn ();
3444
3445   pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
3446   INSN_ADDRESSES_NEW (pool->pool_insn, -1);
3447 }
3448
3449 /* Add INSN to the list of insns covered by POOL.  */
3450
3451 static void
3452 s390_add_pool_insn (pool, insn)
3453      struct constant_pool *pool;
3454      rtx insn;
3455 {
3456   bitmap_set_bit (pool->insns, INSN_UID (insn));
3457 }
3458
3459 /* Return pool out of POOL_LIST that covers INSN.  */
3460
3461 static struct constant_pool *
3462 s390_find_pool (pool_list, insn)
3463      struct constant_pool *pool_list;
3464      rtx insn;
3465 {
3466   struct constant_pool *pool;
3467
3468   for (pool = pool_list; pool; pool = pool->next)
3469     if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
3470       break;
3471
3472   return pool;
3473 }
3474
3475 /* Add constant VAL of mode MODE to the constant pool POOL.  */
3476
3477 static void
3478 s390_add_constant (pool, val, mode)
3479      struct constant_pool *pool;
3480      rtx val;
3481      enum machine_mode mode;
3482 {
3483   struct constant *c;
3484   int i;
3485
3486   for (i = 0; i < NR_C_MODES; i++)
3487     if (constant_modes[i] == mode)
3488       break;
3489   if (i == NR_C_MODES)
3490     abort ();
3491
3492   for (c = pool->constants[i]; c != NULL; c = c->next)
3493     if (rtx_equal_p (val, c->value))
3494       break;
3495
3496   if (c == NULL)
3497     {
3498       c = (struct constant *) xmalloc (sizeof *c);
3499       c->value = val;
3500       c->label = gen_label_rtx ();
3501       c->next = pool->constants[i];
3502       pool->constants[i] = c;
3503       pool->size += GET_MODE_SIZE (mode);
3504     }
3505 }
3506
3507 /* Find constant VAL of mode MODE in the constant pool POOL.
3508    Return an RTX describing the distance from the start of
3509    the pool to the location of the new constant.  */
3510  
3511 static rtx
3512 s390_find_constant (pool, val, mode)
3513      struct constant_pool *pool;
3514      rtx val;
3515      enum machine_mode mode;
3516 {
3517   struct constant *c;
3518   rtx offset;
3519   int i;
3520  
3521   for (i = 0; i < NR_C_MODES; i++)
3522     if (constant_modes[i] == mode)
3523       break;
3524   if (i == NR_C_MODES)
3525     abort ();
3526  
3527   for (c = pool->constants[i]; c != NULL; c = c->next)
3528     if (rtx_equal_p (val, c->value))
3529       break;
3530  
3531   if (c == NULL)
3532     abort ();
3533  
3534   offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
3535                                  gen_rtx_LABEL_REF (Pmode, pool->label));
3536   offset = gen_rtx_CONST (Pmode, offset);
3537   return offset;
3538 }
3539
3540 /* Set 'anchor' flag in POOL.  */
3541
3542 static void
3543 s390_add_anchor (pool)
3544      struct constant_pool *pool;
3545 {
3546   if (!pool->anchor)
3547     {
3548       pool->anchor = TRUE;
3549       pool->size += 4;
3550     }
3551 }
3552
3553 /* Dump out the constants in POOL.  */
3554
3555 static rtx
3556 s390_dump_pool (pool)
3557      struct constant_pool *pool;
3558 {
3559   struct constant *c;
3560   rtx insn;
3561   int i;
3562
3563   /* Pool start insn switches to proper section 
3564      and guarantees necessary alignment.  */
3565   if (TARGET_64BIT)
3566     insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
3567   else
3568     insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
3569   INSN_ADDRESSES_NEW (insn, -1);
3570
3571   insn = emit_label_after (pool->label, insn);
3572   INSN_ADDRESSES_NEW (insn, -1);
3573
3574   /* Emit anchor if we need one.  */
3575   if (pool->anchor)
3576     {
3577       rtx anchor = gen_rtx_LABEL_REF (VOIDmode, pool->label);
3578       anchor = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, anchor), 105);
3579       anchor = gen_rtx_CONST (VOIDmode, anchor);
3580       insn = emit_insn_after (gen_consttable_si (anchor), insn);
3581       INSN_ADDRESSES_NEW (insn, -1);
3582     }
3583
3584   /* Dump constants in descending alignment requirement order,
3585      ensuring proper alignment for every constant.  */
3586   for (i = 0; i < NR_C_MODES; i++)
3587     for (c = pool->constants[i]; c; c = c->next)
3588       {
3589         /* Convert 104 unspecs to pool-relative references.  */
3590         rtx value = c->value;
3591         if (GET_CODE (value) == CONST
3592             && GET_CODE (XEXP (value, 0)) == UNSPEC
3593             && XINT (XEXP (value, 0), 1) == 104
3594             && XVECLEN (XEXP (value, 0), 0) == 1)
3595           {
3596             value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
3597                                    gen_rtx_LABEL_REF (VOIDmode, pool->label));
3598             value = gen_rtx_CONST (VOIDmode, value);
3599           }
3600
3601         insn = emit_label_after (c->label, insn);
3602         INSN_ADDRESSES_NEW (insn, -1);
3603         insn = emit_insn_after (gen_consttable[i] (value), insn);
3604         INSN_ADDRESSES_NEW (insn, -1);
3605       }
3606
3607   /* Pool end insn switches back to previous section 
3608      and guarantees necessary alignment.  */
3609   if (TARGET_64BIT)
3610     insn = emit_insn_after (gen_pool_end_64 (), insn);
3611   else
3612     insn = emit_insn_after (gen_pool_end_31 (), insn);
3613   INSN_ADDRESSES_NEW (insn, -1);
3614
3615   insn = emit_barrier_after (insn);
3616   INSN_ADDRESSES_NEW (insn, -1);
3617
3618   /* Remove placeholder insn.  */
3619   remove_insn (pool->pool_insn);
3620
3621   return insn;
3622 }
3623
3624 /* Free all memory used by POOL.  */
3625
3626 static void
3627 s390_free_pool (pool)
3628      struct constant_pool *pool;
3629 {
3630   int i;
3631
3632   for (i = 0; i < NR_C_MODES; i++)
3633     {
3634       struct constant *c = pool->constants[i];
3635       while (c != NULL)
3636         {
3637           struct constant *next = c->next;
3638           free (c);
3639           c = next;
3640         }
3641     }
3642
3643   BITMAP_XFREE (pool->insns);
3644   free (pool);
3645
3646
3647
3648 /* Chunkify the literal pool if required.
3649
3650    Code generated by this routine is allowed to use
3651    TEMP_REG as temporary scratch register.  If this is
3652    done, TEMP_USED is set to true.  */
3653
3654 #define S390_POOL_CHUNK_MIN     0xc00
3655 #define S390_POOL_CHUNK_MAX     0xe00
3656
3657 static struct constant_pool * 
3658 s390_chunkify_start (temp_reg, temp_used)
3659      rtx temp_reg;
3660      bool *temp_used;
3661 {
3662   rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
3663
3664   struct constant_pool *curr_pool = NULL, *pool_list = NULL;
3665   int extra_size = 0;
3666   bitmap far_labels;
3667   rtx insn;
3668
3669   rtx (*gen_reload_base) PARAMS ((rtx, rtx)) =
3670     TARGET_64BIT? gen_reload_base_64 : gen_reload_base_31;
3671
3672
3673   /* Do we need to chunkify the literal pool?  */
3674
3675   if (get_pool_size () < S390_POOL_CHUNK_MAX)
3676     return NULL;
3677
3678   /* We need correct insn addresses.  */
3679
3680   shorten_branches (get_insns ());
3681
3682   /* Scan all insns and move literals to pool chunks.
3683      Also, emit anchor reload insns before every insn that uses 
3684      the literal pool base register as anchor pointer.  */
3685
3686   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3687     {
3688       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
3689         {
3690           rtx pool_ref = NULL_RTX;
3691           find_constant_pool_ref (PATTERN (insn), &pool_ref);
3692           if (pool_ref)
3693             {
3694               if (!curr_pool)
3695                 curr_pool = s390_start_pool (&pool_list, insn);
3696
3697               s390_add_constant (curr_pool, get_pool_constant (pool_ref), 
3698                                             get_pool_mode (pool_ref));
3699               s390_add_pool_insn (curr_pool, insn);
3700             }
3701
3702           else if (!TARGET_64BIT && flag_pic
3703                    && find_base_register_ref (PATTERN (insn)))
3704             {
3705               rtx new = gen_reload_anchor (temp_reg, base_reg);
3706               new = emit_insn_before (new, insn);
3707               INSN_ADDRESSES_NEW (new, INSN_ADDRESSES (INSN_UID (insn)));
3708               extra_size += 8;
3709               *temp_used = 1;
3710               
3711               if (!curr_pool)
3712                 curr_pool = s390_start_pool (&pool_list, new);
3713
3714               s390_add_anchor (curr_pool);
3715               s390_add_pool_insn (curr_pool, insn);
3716             }
3717         }
3718
3719       if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
3720         if (curr_pool)
3721           s390_add_pool_insn (curr_pool, insn);
3722
3723       if (!curr_pool 
3724           || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
3725           || INSN_ADDRESSES (INSN_UID (insn)) == -1)
3726         continue;
3727
3728       if (TARGET_64BIT)
3729         {
3730           if (curr_pool->size < S390_POOL_CHUNK_MAX)
3731             continue;
3732
3733           s390_end_pool (curr_pool, NULL_RTX);
3734           curr_pool = NULL;
3735         }
3736       else
3737         {
3738           int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
3739                            - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
3740                          + extra_size;
3741
3742           /* We will later have to insert base register reload insns.
3743              Those will have an effect on code size, which we need to
3744              consider here.  This calculation makes rather pessimistic
3745              worst-case assumptions.  */
3746           if (GET_CODE (insn) == CODE_LABEL)
3747             extra_size += 6;
3748
3749           if (chunk_size < S390_POOL_CHUNK_MIN
3750               && curr_pool->size < S390_POOL_CHUNK_MIN)
3751             continue;
3752
3753           /* Pool chunks can only be inserted after BARRIERs ...  */
3754           if (GET_CODE (insn) == BARRIER)
3755             {
3756               s390_end_pool (curr_pool, insn);
3757               curr_pool = NULL;
3758               extra_size = 0;
3759             }
3760
3761           /* ... so if we don't find one in time, create one.  */
3762           else if ((chunk_size > S390_POOL_CHUNK_MAX
3763                    || curr_pool->size > S390_POOL_CHUNK_MAX))
3764             {
3765               rtx label, jump, barrier;
3766
3767               /* We can insert the barrier only after a 'real' insn.  */
3768               if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
3769                 continue;
3770               if (get_attr_length (insn) == 0)
3771                 continue;
3772
3773               /* Don't separate insns created by s390_split_branches.  */
3774               if (GET_CODE (insn) == INSN 
3775                   && GET_CODE (PATTERN (insn)) == SET
3776                   && rtx_equal_p (SET_DEST (PATTERN (insn)), temp_reg))
3777                 continue;
3778
3779               label = gen_label_rtx ();
3780               jump = emit_jump_insn_after (gen_jump (label), insn);
3781               barrier = emit_barrier_after (jump);
3782               insn = emit_label_after (label, barrier);
3783               JUMP_LABEL (jump) = label;
3784               LABEL_NUSES (label) = 1;
3785
3786               INSN_ADDRESSES_NEW (jump, -1);
3787               INSN_ADDRESSES_NEW (barrier, -1);
3788               INSN_ADDRESSES_NEW (insn, -1);
3789
3790               s390_end_pool (curr_pool, barrier);
3791               curr_pool = NULL;
3792               extra_size = 0;
3793             }
3794         }
3795     }
3796
3797   if (curr_pool)
3798     s390_end_pool (curr_pool, NULL_RTX);
3799
3800
3801   /* Find all labels that are branched into 
3802      from an insn belonging to a different chunk.  */
3803
3804   far_labels = BITMAP_XMALLOC ();
3805
3806   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3807     {
3808       /* Labels marked with LABEL_PRESERVE_P can be target
3809          of non-local jumps, so we have to mark them.
3810          The same holds for named labels.
3811
3812          Don't do that, however, if it is the label before
3813          a jump table.  */
3814
3815       if (GET_CODE (insn) == CODE_LABEL 
3816           && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
3817         {
3818           rtx vec_insn = next_real_insn (insn);
3819           rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ? 
3820                         PATTERN (vec_insn) : NULL_RTX;
3821           if (!vec_pat
3822               || !(GET_CODE (vec_pat) == ADDR_VEC
3823                    || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
3824             bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
3825         }
3826
3827       /* If we have a direct jump (conditional or unconditional)
3828          or a casesi jump, check all potential targets.  */
3829       else if (GET_CODE (insn) == JUMP_INSN) 
3830         {
3831           rtx pat = PATTERN (insn);
3832           if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3833             pat = XVECEXP (pat, 0, 0);
3834
3835           if (GET_CODE (pat) == SET) 
3836             {
3837               rtx label = JUMP_LABEL (insn);
3838               if (label)
3839                 {
3840                   if (s390_find_pool (pool_list, label) 
3841                       != s390_find_pool (pool_list, insn))
3842                     bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
3843                 }
3844             } 
3845           else if (GET_CODE (pat) == PARALLEL
3846                    && XVECLEN (pat, 0) == 2
3847                    && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3848                    && GET_CODE (XVECEXP (pat, 0, 1)) == USE
3849                    && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
3850             {
3851               /* Find the jump table used by this casesi jump.  */
3852               rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
3853               rtx vec_insn = next_real_insn (vec_label);
3854               rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ? 
3855                             PATTERN (vec_insn) : NULL_RTX;
3856               if (vec_pat
3857                   && (GET_CODE (vec_pat) == ADDR_VEC
3858                       || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
3859                 {
3860                   int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
3861
3862                   for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
3863                     {
3864                       rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
3865
3866                       if (s390_find_pool (pool_list, label) 
3867                           != s390_find_pool (pool_list, insn))
3868                         bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
3869                     }
3870                 }
3871             }
3872         }
3873     }
3874
3875   /* Insert base register reload insns before every pool.  */
3876
3877   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
3878     {
3879       rtx new_insn = gen_reload_base (base_reg, curr_pool->label);
3880       rtx insn = curr_pool->first_insn;
3881       INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
3882     }
3883
3884   /* Insert base register reload insns at every far label.  */
3885
3886   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3887     if (GET_CODE (insn) == CODE_LABEL 
3888         && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
3889       {
3890         struct constant_pool *pool = s390_find_pool (pool_list, insn);
3891         if (pool)
3892           {
3893             rtx new_insn = gen_reload_base (base_reg, pool->label);
3894             INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
3895           }
3896       }
3897
3898
3899   BITMAP_XFREE (far_labels);
3900
3901
3902   /* Recompute insn addresses.  */
3903
3904   init_insn_lengths ();
3905   shorten_branches (get_insns ());
3906
3907   return pool_list;
3908 }
3909
3910 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
3911    After we have decided to use this list, finish implementing 
3912    all changes to the current function as required.
3913
3914    Code generated by this routine is allowed to use
3915    TEMP_REG as temporary scratch register.  */
3916  
3917 static void
3918 s390_chunkify_finish (pool_list, temp_reg)
3919      struct constant_pool *pool_list;
3920      rtx temp_reg;
3921 {
3922   rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
3923   struct constant_pool *curr_pool = NULL;
3924   rtx insn;
3925  
3926  
3927   /* Replace all literal pool references.  */
3928
3929   for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 
3930     {
3931       curr_pool = s390_find_pool (pool_list, insn);
3932       if (!curr_pool)
3933         continue;
3934
3935       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
3936         {
3937           rtx addr, pool_ref = NULL_RTX;
3938           find_constant_pool_ref (PATTERN (insn), &pool_ref);
3939           if (pool_ref)
3940             {
3941               addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
3942                                                     get_pool_mode (pool_ref));
3943               addr = gen_rtx_PLUS (Pmode, base_reg, addr);
3944               replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
3945               INSN_CODE (insn) = -1;
3946             }
3947
3948           else if (!TARGET_64BIT && flag_pic
3949                    && find_base_register_ref (PATTERN (insn)))
3950             {
3951               replace_base_register_ref (&PATTERN (insn), temp_reg);
3952             }
3953         }
3954     }
3955
3956   /* Dump out all literal pools.  */
3957  
3958   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
3959     s390_dump_pool (curr_pool);
3960  
3961   /* Free pool list.  */
3962
3963   while (pool_list)
3964     {
3965       struct constant_pool *next = pool_list->next;
3966       s390_free_pool (pool_list);
3967       pool_list = next;
3968     }
3969 }
3970
3971 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
3972    We have decided we cannot use this list, so revert all changes
3973    to the current function that were done by s390_chunkify_start.  */
3974  
3975 static void
3976 s390_chunkify_cancel (pool_list)
3977      struct constant_pool *pool_list;
3978 {
3979   struct constant_pool *curr_pool = NULL;
3980   rtx insn;
3981
3982   /* Remove all pool placeholder insns.  */
3983
3984   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
3985     {
3986       /* Did we insert an extra barrier?  Remove it.  */
3987       rtx barrier = PREV_INSN (curr_pool->pool_insn);
3988       rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
3989       rtx label = NEXT_INSN (curr_pool->pool_insn);
3990
3991       if (jump && GET_CODE (jump) == JUMP_INSN
3992           && barrier && GET_CODE (barrier) == BARRIER
3993           && label && GET_CODE (label) == CODE_LABEL
3994           && GET_CODE (PATTERN (jump)) == SET
3995           && SET_DEST (PATTERN (jump)) == pc_rtx
3996           && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
3997           && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
3998         {
3999           remove_insn (jump);
4000           remove_insn (barrier);
4001           remove_insn (label);
4002         }
4003
4004       remove_insn (curr_pool->pool_insn);
4005     }
4006
4007   /* Remove all base/anchor register reload insns.  */
4008
4009   for (insn = get_insns (); insn; )
4010     {
4011       rtx next_insn = NEXT_INSN (insn);
4012
4013       if (GET_CODE (insn) == INSN
4014           && GET_CODE (PATTERN (insn)) == SET
4015           && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
4016           && (XINT (SET_SRC (PATTERN (insn)), 1) == 210
4017               || XINT (SET_SRC (PATTERN (insn)), 1) == 211))
4018         remove_insn (insn);
4019
4020       insn = next_insn;
4021     }
4022
4023   /* Free pool list.  */
4024
4025   while (pool_list)
4026     {
4027       struct constant_pool *next = pool_list->next;
4028       s390_free_pool (pool_list);
4029       pool_list = next;
4030     }
4031 }
4032
4033
4034 /* Index of constant pool chunk that is currently being processed.
4035    Set to -1 before function output has started.  */
4036 int s390_pool_count = -1;
4037
4038 /* Number of elements of current constant pool.  */
4039 int s390_nr_constants;
4040
4041 /* Output main constant pool to stdio stream FILE.  */ 
4042
4043 void
4044 s390_output_constant_pool (file)
4045      FILE *file;
4046 {
4047   /* Output constant pool.  */
4048   if (s390_nr_constants)
4049     {
4050       if (TARGET_64BIT)
4051         {
4052           fprintf (file, "\tlarl\t%s,.LT%d\n", reg_names[BASE_REGISTER],
4053                    current_function_funcdef_no);
4054           readonly_data_section ();
4055           ASM_OUTPUT_ALIGN (file, 3);
4056         }
4057       else
4058         {
4059           fprintf (file, "\tbras\t%s,.LTN%d\n", reg_names[BASE_REGISTER],
4060                    current_function_funcdef_no);
4061         }
4062       fprintf (file, ".LT%d:\n", current_function_funcdef_no);
4063
4064       s390_pool_count = 0;
4065       output_constant_pool (current_function_name, current_function_decl);
4066       s390_pool_count = -1;
4067
4068       if (TARGET_64BIT)
4069         function_section (current_function_decl);
4070       else
4071         fprintf (file, ".LTN%d:\n", current_function_funcdef_no);
4072     }
4073
4074   /* If no pool required, at least output the anchor label.  */
4075   else if (!TARGET_64BIT && flag_pic)
4076     fprintf (file, ".LT%d:\n", current_function_funcdef_no);
4077 }
4078
4079
4080 /* Rework the prolog/epilog to avoid saving/restoring
4081    registers unnecessarily.  If TEMP_REGNO is nonnegative,
4082    it specifies the number of a caller-saved register used 
4083    as temporary scratch register by code emitted during 
4084    machine dependent reorg.  */
4085
4086 static void
4087 s390_optimize_prolog (temp_regno)
4088      int temp_regno;
4089 {
4090   int save_first, save_last, restore_first, restore_last;
4091   int i, j;
4092   rtx insn, new_insn, next_insn;
4093
4094   struct s390_frame frame;
4095   s390_frame_info (&frame);
4096
4097   /* Recompute regs_ever_live data for special registers.  */
4098   regs_ever_live[BASE_REGISTER] = 0;
4099   regs_ever_live[RETURN_REGNUM] = 0;
4100   regs_ever_live[STACK_POINTER_REGNUM] = frame.frame_size > 0;
4101
4102   /* If there is (possibly) any pool entry, we need to
4103      load the base register.  
4104      ??? FIXME: this should be more precise.  */
4105   if (get_pool_size ())
4106     regs_ever_live[BASE_REGISTER] = 1;
4107
4108   /* In non-leaf functions, the prolog/epilog code relies 
4109      on RETURN_REGNUM being saved in any case.  */
4110   if (!current_function_is_leaf)
4111     regs_ever_live[RETURN_REGNUM] = 1;
4112
4113   /* We need to save/restore the temporary register.  */
4114   if (temp_regno >= 0)
4115     regs_ever_live[temp_regno] = 1;
4116
4117
4118   /* Find first and last gpr to be saved.  */
4119   
4120   for (i = 6; i < 16; i++)
4121     if (regs_ever_live[i])
4122       break;
4123
4124   for (j = 15; j > i; j--)
4125     if (regs_ever_live[j])
4126       break;
4127
4128   if (i == 16)
4129     {
4130       /* Nothing to save/restore.  */
4131       save_first = restore_first = -1;
4132       save_last = restore_last = -1;
4133     }
4134   else
4135     {
4136       /* Save/restore from i to j.  */
4137       save_first = restore_first = i;
4138       save_last = restore_last = j;
4139     }
4140
4141   /* Varargs functions need to save gprs 2 to 6.  */
4142   if (current_function_stdarg)
4143     {
4144       save_first = 2;
4145       if (save_last < 6)
4146         save_last = 6;
4147     }
4148
4149
4150   /* If all special registers are in fact used, there's nothing we
4151      can do, so no point in walking the insn list.  */
4152   if (i <= BASE_REGISTER && j >= BASE_REGISTER
4153       && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
4154     return;
4155
4156
4157   /* Search for prolog/epilog insns and replace them.  */
4158
4159   for (insn = get_insns (); insn; insn = next_insn)
4160     {
4161       int first, last, off;
4162       rtx set, base, offset;
4163
4164       next_insn = NEXT_INSN (insn);
4165
4166       if (GET_CODE (insn) != INSN)
4167         continue;
4168       if (GET_CODE (PATTERN (insn)) != PARALLEL)
4169         continue;
4170
4171       if (store_multiple_operation (PATTERN (insn), VOIDmode))
4172         {
4173           set = XVECEXP (PATTERN (insn), 0, 0);
4174           first = REGNO (SET_SRC (set));
4175           last = first + XVECLEN (PATTERN (insn), 0) - 1;
4176           offset = const0_rtx;
4177           base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
4178           off = INTVAL (offset) - first * UNITS_PER_WORD;
4179
4180           if (GET_CODE (base) != REG || off < 0)
4181             continue;
4182           if (first > BASE_REGISTER && first > RETURN_REGNUM)
4183             continue;
4184           if (last < BASE_REGISTER && last < RETURN_REGNUM)
4185             continue;
4186
4187           if (save_first != -1)
4188             {
4189               new_insn = save_gprs (base, off, save_first, save_last);
4190               new_insn = emit_insn_before (new_insn, insn);
4191               INSN_ADDRESSES_NEW (new_insn, -1);
4192             }
4193
4194           remove_insn (insn);
4195         }
4196
4197       if (load_multiple_operation (PATTERN (insn), VOIDmode))
4198         {
4199           set = XVECEXP (PATTERN (insn), 0, 0);
4200           first = REGNO (SET_DEST (set));
4201           last = first + XVECLEN (PATTERN (insn), 0) - 1;
4202           offset = const0_rtx;
4203           base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
4204           off = INTVAL (offset) - first * UNITS_PER_WORD;
4205
4206           if (GET_CODE (base) != REG || off < 0)
4207             continue;
4208           if (first > BASE_REGISTER && first > RETURN_REGNUM)
4209             continue;
4210           if (last < BASE_REGISTER && last < RETURN_REGNUM)
4211             continue;
4212
4213           if (restore_first != -1)
4214             {
4215               new_insn = restore_gprs (base, off, restore_first, restore_last);
4216               new_insn = emit_insn_before (new_insn, insn);
4217               INSN_ADDRESSES_NEW (new_insn, -1);
4218             }
4219
4220           remove_insn (insn);
4221         }
4222     }
4223 }
4224
4225 /* Check whether any insn in the function makes use of the original
4226    value of RETURN_REG (e.g. for __builtin_return_address).
4227    If so, insert an insn reloading that value.
4228
4229    Return true if any such insn was found.  */
4230
4231 static bool
4232 s390_fixup_clobbered_return_reg (return_reg)
4233     rtx return_reg;
4234 {
4235   bool replacement_done = 0;
4236   rtx insn;
4237
4238   struct s390_frame frame;
4239   s390_frame_info (&frame);
4240
4241   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4242     {
4243       rtx reg, off, new_insn;
4244
4245       if (GET_CODE (insn) != INSN)
4246         continue;
4247       if (!reg_referenced_p (return_reg, PATTERN (insn)))
4248         continue;
4249       if (GET_CODE (PATTERN (insn)) == PARALLEL
4250           && store_multiple_operation (PATTERN (insn), VOIDmode))
4251         continue;
4252
4253       if (frame.frame_pointer_p)
4254         reg = hard_frame_pointer_rtx;
4255       else
4256         reg = stack_pointer_rtx;
4257
4258       off = GEN_INT (frame.frame_size + REGNO (return_reg) * UNITS_PER_WORD);
4259       if (INTVAL (off) >= 4096)
4260         {
4261           off = force_const_mem (Pmode, off);
4262           new_insn = gen_rtx_SET (Pmode, return_reg, off);
4263           new_insn = emit_insn_before (new_insn, insn);
4264           INSN_ADDRESSES_NEW (new_insn, -1);
4265           off = return_reg;
4266         }
4267
4268       new_insn = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, reg, off));
4269       new_insn = gen_rtx_SET (Pmode, return_reg, new_insn);
4270       new_insn = emit_insn_before (new_insn, insn);
4271       INSN_ADDRESSES_NEW (new_insn, -1);
4272
4273       replacement_done = 1;
4274     }
4275
4276   return replacement_done;
4277 }
4278
4279 /* Perform machine-dependent processing.  */
4280
4281 void
4282 s390_machine_dependent_reorg (first)
4283      rtx first ATTRIBUTE_UNUSED;
4284 {
4285   bool fixed_up_clobbered_return_reg = 0;
4286   rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
4287   bool temp_used = 0;
4288
4289   /* Make sure all splits have been performed; splits after
4290      machine_dependent_reorg might confuse insn length counts.  */
4291   split_all_insns_noflow ();
4292
4293
4294   /* There are two problematic situations we need to correct:
4295  
4296      - the literal pool might be > 4096 bytes in size, so that
4297        some of its elements cannot be directly accessed
4298  
4299      - a branch target might be > 64K away from the branch, so that
4300        it is not possible to use a PC-relative instruction.
4301  
4302      To fix those, we split the single literal pool into multiple
4303      pool chunks, reloading the pool base register at various
4304      points throughout the function to ensure it always points to
4305      the pool chunk the following code expects, and / or replace
4306      PC-relative branches by absolute branches.
4307  
4308      However, the two problems are interdependent: splitting the
4309      literal pool can move a branch further away from its target,
4310      causing the 64K limit to overflow, and on the other hand,
4311      replacing a PC-relative branch by an absolute branch means
4312      we need to put the branch target address into the literal
4313      pool, possibly causing it to overflow.
4314  
4315      So, we loop trying to fix up both problems until we manage
4316      to satisfy both conditions at the same time.  Note that the
4317      loop is guaranteed to terminate as every pass of the loop
4318      strictly decreases the total number of PC-relative branches
4319      in the function.  (This is not completely true as there
4320      might be branch-over-pool insns introduced by chunkify_start.
4321      Those never need to be split however.)  */
4322  
4323   for (;;)
4324     {
4325       struct constant_pool *pool_list;
4326  
4327       /* Try to chunkify the literal pool.  */
4328       pool_list = s390_chunkify_start (temp_reg, &temp_used);
4329
4330       /* Split out-of-range branches.  If this has created new
4331          literal pool entries, cancel current chunk list and
4332          recompute it.  */
4333       if (s390_split_branches (temp_reg, &temp_used))
4334         {
4335           if (pool_list)
4336             s390_chunkify_cancel (pool_list);
4337  
4338           continue;
4339         }
4340
4341       /* Check whether we have clobbered a use of the return
4342          register (e.g. for __builtin_return_address).  If so,
4343          add insns reloading the register where necessary.  */
4344       if (temp_used && !fixed_up_clobbered_return_reg
4345           && s390_fixup_clobbered_return_reg (temp_reg))
4346         {
4347           fixed_up_clobbered_return_reg = 1;
4348
4349           /* The fixup insns might have caused a jump to overflow.  */
4350           if (pool_list)
4351             s390_chunkify_cancel (pool_list);
4352
4353           continue;
4354         }
4355  
4356       /* If we made it up to here, both conditions are satisfied.
4357          Finish up pool chunkification if required.  */
4358       if (pool_list)
4359         s390_chunkify_finish (pool_list, temp_reg);
4360  
4361       break;
4362     }
4363  
4364   s390_optimize_prolog (temp_used? RETURN_REGNUM : -1);
4365 }
4366
4367
4368 /* Find first call clobbered register unsused in a function.
4369    This could be used as base register in a leaf function
4370    or for holding the return address before epilogue.  */
4371
4372 static int
4373 find_unused_clobbered_reg ()
4374 {
4375   int i;
4376   for (i = 0; i < 6; i++)
4377     if (!regs_ever_live[i])
4378       return i;
4379   return 0;
4380 }
4381
4382 /* Fill FRAME with info about frame of current function.  */
4383
4384 static void
4385 s390_frame_info (frame)
4386      struct s390_frame *frame;
4387 {
4388   char gprs_ever_live[16];
4389   int i, j;
4390   HOST_WIDE_INT fsize = get_frame_size ();
4391
4392   if (fsize > 0x7fff0000)
4393     fatal_error ("Total size of local variables exceeds architecture limit.");
4394
4395   /* fprs 8 - 15 are caller saved for 64 Bit ABI.  */
4396   frame->save_fprs_p = 0;
4397   if (TARGET_64BIT)
4398     for (i = 24; i < 32; i++) 
4399       if (regs_ever_live[i])
4400         {
4401           frame->save_fprs_p = 1;
4402           break;
4403         }
4404
4405   frame->frame_size = fsize + frame->save_fprs_p * 64;
4406
4407   /* Does function need to setup frame and save area.  */
4408   
4409   if (! current_function_is_leaf
4410       || frame->frame_size > 0
4411       || current_function_calls_alloca 
4412       || current_function_stdarg)
4413     frame->frame_size += STARTING_FRAME_OFFSET;
4414
4415   /* Frame pointer needed.   */
4416     
4417   frame->frame_pointer_p = frame_pointer_needed;
4418
4419   /* Find first and last gpr to be saved.  Note that at this point,
4420      we assume the return register and the base register always
4421      need to be saved.  This is done because the usage of these
4422      register might change even after the prolog was emitted.
4423      If it turns out later that we really don't need them, the
4424      prolog/epilog code is modified again.  */
4425
4426   for (i = 0; i < 16; i++)
4427     gprs_ever_live[i] = regs_ever_live[i];
4428
4429   gprs_ever_live[BASE_REGISTER] = 1;
4430   gprs_ever_live[RETURN_REGNUM] = 1;
4431   gprs_ever_live[STACK_POINTER_REGNUM] = frame->frame_size > 0;
4432   
4433   for (i = 6; i < 16; i++)
4434     if (gprs_ever_live[i])
4435       break;
4436
4437   for (j = 15; j > i; j--)
4438     if (gprs_ever_live[j])
4439       break;
4440
4441
4442   /* Save / Restore from gpr i to j.  */
4443   frame->first_save_gpr = i;
4444   frame->first_restore_gpr = i;
4445   frame->last_save_gpr  = j;
4446
4447   /* Varargs functions need to save gprs 2 to 6.  */
4448   if (current_function_stdarg)
4449     frame->first_save_gpr = 2;
4450 }
4451
4452 /* Return offset between argument pointer and frame pointer 
4453    initially after prologue.  */
4454
4455 int 
4456 s390_arg_frame_offset ()
4457 {
4458   struct s390_frame frame;
4459
4460   /* Compute frame_info.  */
4461
4462   s390_frame_info (&frame);
4463
4464   return frame.frame_size + STACK_POINTER_OFFSET;
4465 }
4466
4467 /* Emit insn to save fpr REGNUM at offset OFFSET relative
4468    to register BASE.  Return generated insn.  */ 
4469
4470 static rtx
4471 save_fpr (base, offset, regnum)
4472      rtx base;
4473      int offset;
4474      int regnum;     
4475 {
4476   rtx addr;
4477   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
4478   set_mem_alias_set (addr, s390_sr_alias_set);
4479
4480   return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
4481 }
4482
4483 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
4484    to register BASE.  Return generated insn.  */ 
4485
4486 static rtx
4487 restore_fpr (base, offset, regnum)
4488      rtx base;
4489      int offset;
4490      int regnum;
4491 {
4492   rtx addr;
4493   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
4494   set_mem_alias_set (addr, s390_sr_alias_set);
4495
4496   return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
4497 }
4498
4499 /* Generate insn to save registers FIRST to LAST into
4500    the register save area located at offset OFFSET 
4501    relative to register BASE.  */
4502
4503 static rtx
4504 save_gprs (base, offset, first, last)
4505      rtx base;
4506      int offset;
4507      int first;
4508      int last;
4509 {
4510   rtx addr, insn, note;
4511   int i;
4512
4513   addr = plus_constant (base, offset + first * UNITS_PER_WORD);
4514   addr = gen_rtx_MEM (Pmode, addr);
4515   set_mem_alias_set (addr, s390_sr_alias_set);
4516
4517   /* Special-case single register.  */
4518   if (first == last)
4519     {
4520       if (TARGET_64BIT)
4521         insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
4522       else
4523         insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
4524
4525       RTX_FRAME_RELATED_P (insn) = 1;
4526       return insn;
4527     }
4528
4529
4530   insn = gen_store_multiple (addr,
4531                              gen_rtx_REG (Pmode, first),
4532                              GEN_INT (last - first + 1));
4533
4534
4535   /* We need to set the FRAME_RELATED flag on all SETs
4536      inside the store-multiple pattern.
4537
4538      However, we must not emit DWARF records for registers 2..5
4539      if they are stored for use by variable arguments ...  
4540
4541      ??? Unfortunately, it is not enough to simply not the the
4542      FRAME_RELATED flags for those SETs, because the first SET
4543      of the PARALLEL is always treated as if it had the flag
4544      set, even if it does not.  Therefore we emit a new pattern
4545      without those registers as REG_FRAME_RELATED_EXPR note.  */
4546
4547   if (first >= 6)
4548     {
4549       rtx pat = PATTERN (insn);
4550
4551       for (i = 0; i < XVECLEN (pat, 0); i++)
4552         if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
4553           RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
4554
4555       RTX_FRAME_RELATED_P (insn) = 1;
4556     }
4557   else if (last >= 6)
4558     {
4559       addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
4560       note = gen_store_multiple (gen_rtx_MEM (Pmode, addr), 
4561                                  gen_rtx_REG (Pmode, 6),
4562                                  GEN_INT (last - 6 + 1));
4563       note = PATTERN (note);
4564
4565       REG_NOTES (insn) =
4566         gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, 
4567                            note, REG_NOTES (insn));
4568
4569       for (i = 0; i < XVECLEN (note, 0); i++)
4570         if (GET_CODE (XVECEXP (note, 0, i)) == SET)
4571           RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
4572
4573       RTX_FRAME_RELATED_P (insn) = 1;
4574     }
4575
4576   return insn;
4577 }
4578
4579 /* Generate insn to restore registers FIRST to LAST from
4580    the register save area located at offset OFFSET 
4581    relative to register BASE.  */
4582
4583 static rtx
4584 restore_gprs (base, offset, first, last)
4585      rtx base;
4586      int offset;
4587      int first;
4588      int last;
4589 {
4590   rtx addr, insn;
4591
4592   addr = plus_constant (base, offset + first * UNITS_PER_WORD);
4593   addr = gen_rtx_MEM (Pmode, addr);
4594   set_mem_alias_set (addr, s390_sr_alias_set);
4595
4596   /* Special-case single register.  */
4597   if (first == last)
4598     {
4599       if (TARGET_64BIT)
4600         insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
4601       else
4602         insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
4603
4604       return insn;
4605     }
4606
4607   insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
4608                             addr,
4609                             GEN_INT (last - first + 1));
4610   return insn;
4611 }
4612
4613 /* Expand the prologue into a bunch of separate insns.  */
4614
4615 void
4616 s390_emit_prologue ()
4617 {
4618   struct s390_frame frame;
4619   rtx insn, addr;
4620   rtx temp_reg;
4621   int i;
4622
4623   /* Compute frame_info.  */
4624
4625   s390_frame_info (&frame);
4626
4627   /* Choose best register to use for temp use within prologue.  */
4628   
4629   if (!current_function_is_leaf
4630       && !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
4631       && get_pool_size () < S390_POOL_CHUNK_MAX / 2)
4632     temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
4633   else
4634     temp_reg = gen_rtx_REG (Pmode, 1);
4635
4636   /* Save call saved gprs.  */
4637
4638   insn = save_gprs (stack_pointer_rtx, 0, 
4639                     frame.first_save_gpr, frame.last_save_gpr);
4640   emit_insn (insn);
4641
4642   /* Dump constant pool and set constant pool register (13).  */
4643  
4644   insn = emit_insn (gen_lit ());
4645   
4646   /* Save fprs for variable args.  */
4647
4648   if (current_function_stdarg)
4649     {
4650       /* Save fpr 0 and 2.  */ 
4651
4652       save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 32, 16); 
4653       save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 24, 17); 
4654       
4655       if (TARGET_64BIT)
4656         {
4657           /* Save fpr 4 and 6.  */
4658  
4659           save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18); 
4660           save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19); 
4661         }
4662     }
4663
4664   /* Save fprs 4 and 6 if used (31 bit ABI).  */
4665
4666   if (!TARGET_64BIT)
4667     {
4668       /* Save fpr 4 and 6.  */
4669       if (regs_ever_live[18])
4670         {
4671           insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
4672           RTX_FRAME_RELATED_P (insn) = 1;
4673         }
4674       if (regs_ever_live[19]) 
4675         {
4676           insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19); 
4677           RTX_FRAME_RELATED_P (insn) = 1;
4678         }
4679     }
4680
4681   /* Decrement stack pointer.  */
4682
4683   if (frame.frame_size > 0)
4684     {
4685       rtx frame_off = GEN_INT (-frame.frame_size);
4686
4687       /* Save incoming stack pointer into temp reg.  */
4688       
4689       if (TARGET_BACKCHAIN || frame.save_fprs_p)
4690         {
4691           insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
4692         }
4693       
4694       /* Substract frame size from stack pointer.  */
4695
4696       frame_off = GEN_INT (-frame.frame_size);
4697       if (!CONST_OK_FOR_LETTER_P (-frame.frame_size, 'K'))
4698         frame_off = force_const_mem (Pmode, frame_off);
4699
4700       insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
4701       RTX_FRAME_RELATED_P (insn) = 1;
4702       REG_NOTES (insn) = 
4703         gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4704                            gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4705                                    gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4706                                    GEN_INT (-frame.frame_size))),
4707                            REG_NOTES (insn));
4708
4709       /* Set backchain.  */
4710       
4711       if (TARGET_BACKCHAIN)
4712         {
4713           addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
4714           set_mem_alias_set (addr, s390_sr_alias_set);
4715           insn = emit_insn (gen_move_insn (addr, temp_reg));
4716         }
4717     }
4718
4719   /* Save fprs 8 - 15 (64 bit ABI).  */
4720   
4721   if (frame.save_fprs_p)
4722     {
4723       insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
4724
4725       for (i = 24; i < 32; i++)
4726         if (regs_ever_live[i])
4727           {
4728             rtx addr = plus_constant (stack_pointer_rtx, 
4729                                       frame.frame_size - 64 + (i-24)*8);
4730
4731             insn = save_fpr (temp_reg, (i-24)*8, i);
4732             RTX_FRAME_RELATED_P (insn) = 1;
4733             REG_NOTES (insn) = 
4734               gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4735                 gen_rtx_SET (VOIDmode, 
4736                              gen_rtx_MEM (DFmode, addr),
4737                              gen_rtx_REG (DFmode, i)),
4738                 REG_NOTES (insn));
4739           }
4740     }
4741             
4742   /* Set frame pointer, if needed.  */
4743   
4744   if (frame.frame_pointer_p)
4745     {
4746       insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
4747       RTX_FRAME_RELATED_P (insn) = 1;
4748     }
4749
4750   /* Set up got pointer, if needed.  */
4751   
4752   if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
4753     {
4754       rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
4755       SYMBOL_REF_FLAG (got_symbol) = 1;
4756
4757       if (TARGET_64BIT)
4758         {
4759           insn = emit_insn (gen_movdi (pic_offset_table_rtx,
4760                                        got_symbol));             
4761
4762           /* It can happen that the GOT pointer isn't really needed ...  */
4763           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
4764                                                REG_NOTES (insn));
4765         }
4766       else
4767         {
4768           got_symbol = gen_rtx_UNSPEC (VOIDmode, 
4769                                        gen_rtvec (1, got_symbol), 100);
4770           got_symbol = gen_rtx_CONST (VOIDmode, got_symbol);
4771           got_symbol = force_const_mem (Pmode, got_symbol);
4772           insn = emit_move_insn (pic_offset_table_rtx,
4773                                  got_symbol);            
4774           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
4775                                                REG_NOTES (insn));
4776
4777           insn = emit_insn (gen_add2_insn (pic_offset_table_rtx,
4778                                            gen_rtx_REG (Pmode, BASE_REGISTER)));
4779           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
4780                                                REG_NOTES (insn));
4781         }
4782     }      
4783 }
4784
4785 /* Expand the epilogue into a bunch of separate insns.  */
4786
4787 void
4788 s390_emit_epilogue ()
4789 {
4790   struct s390_frame frame;
4791   rtx frame_pointer, return_reg;
4792   int area_bottom, area_top, offset;
4793   rtvec p;
4794
4795   /* Compute frame_info.  */
4796  
4797   s390_frame_info (&frame);
4798
4799   /* Check whether to use frame or stack pointer for restore.  */
4800
4801   frame_pointer = frame.frame_pointer_p ? 
4802     hard_frame_pointer_rtx : stack_pointer_rtx;
4803
4804   /* Compute which parts of the save area we need to access.  */
4805
4806   if (frame.first_restore_gpr != -1)
4807     {
4808       area_bottom = frame.first_restore_gpr * UNITS_PER_WORD;
4809       area_top = (frame.last_save_gpr + 1) * UNITS_PER_WORD;
4810     }
4811   else
4812     {
4813       area_bottom = INT_MAX;
4814       area_top = INT_MIN;
4815     }
4816
4817   if (TARGET_64BIT)
4818     {
4819       if (frame.save_fprs_p)
4820         {
4821           if (area_bottom > -64)
4822             area_bottom = -64;
4823           if (area_top < 0)
4824             area_top = 0;
4825         }
4826     }
4827   else
4828     {
4829       if (regs_ever_live[18])
4830         {
4831           if (area_bottom > STACK_POINTER_OFFSET - 16)
4832             area_bottom = STACK_POINTER_OFFSET - 16;
4833           if (area_top < STACK_POINTER_OFFSET - 8)
4834             area_top = STACK_POINTER_OFFSET - 8;
4835         }
4836       if (regs_ever_live[19])
4837         {
4838           if (area_bottom > STACK_POINTER_OFFSET - 8)
4839             area_bottom = STACK_POINTER_OFFSET - 8;
4840           if (area_top < STACK_POINTER_OFFSET)
4841             area_top = STACK_POINTER_OFFSET;
4842         }
4843     }
4844
4845   /* Check whether we can access the register save area.  
4846      If not, increment the frame pointer as required.  */
4847
4848   if (area_top <= area_bottom)
4849     {
4850       /* Nothing to restore.  */
4851     }
4852   else if (frame.frame_size + area_bottom >= 0
4853            && frame.frame_size + area_top <= 4096)
4854     {
4855       /* Area is in range.  */
4856       offset = frame.frame_size;
4857     }
4858   else
4859     {
4860       rtx insn, frame_off;
4861
4862       offset = area_bottom < 0 ? -area_bottom : 0; 
4863       frame_off = GEN_INT (frame.frame_size - offset);
4864
4865       if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
4866         frame_off = force_const_mem (Pmode, frame_off);
4867
4868       insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
4869     }
4870
4871   /* Restore call saved fprs.  */
4872
4873   if (TARGET_64BIT)
4874     {
4875       int i;
4876
4877       if (frame.save_fprs_p)
4878         for (i = 24; i < 32; i++)
4879           if (regs_ever_live[i] && !global_regs[i])
4880             restore_fpr (frame_pointer, 
4881                          offset - 64 + (i-24) * 8, i);
4882     }
4883   else
4884     {
4885       if (regs_ever_live[18] && !global_regs[18])
4886         restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 16, 18);
4887       if (regs_ever_live[19] && !global_regs[19])
4888         restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 8, 19);
4889     }
4890
4891   /* Return register.  */
4892
4893   return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM); 
4894
4895   /* Restore call saved gprs.  */
4896
4897   if (frame.first_restore_gpr != -1)
4898     {
4899       rtx insn, addr;
4900       int i;
4901
4902       /* Check for global register and save them 
4903          to stack location from where they get restored.  */
4904
4905       for (i = frame.first_restore_gpr; 
4906            i <= frame.last_save_gpr;
4907            i++)
4908         {
4909           /* These registers are special and need to be 
4910              restored in any case.  */
4911           if (i == STACK_POINTER_REGNUM 
4912               || i == RETURN_REGNUM
4913               || i == BASE_REGISTER 
4914               || (flag_pic && i == PIC_OFFSET_TABLE_REGNUM))
4915             continue;
4916
4917           if (global_regs[i])
4918             {
4919               addr = plus_constant (frame_pointer, 
4920                      offset + i * UNITS_PER_WORD);
4921               addr = gen_rtx_MEM (Pmode, addr);
4922               set_mem_alias_set (addr, s390_sr_alias_set);
4923               emit_move_insn (addr, gen_rtx_REG (Pmode, i));
4924             }  
4925         }
4926
4927       /* Fetch return address from stack before load multiple,
4928          this will do good for scheduling.  */
4929
4930       if (!current_function_is_leaf)
4931         {
4932           int return_regnum = find_unused_clobbered_reg();
4933           if (!return_regnum)
4934             return_regnum = 4;
4935           return_reg = gen_rtx_REG (Pmode, return_regnum);
4936         
4937           addr = plus_constant (frame_pointer, 
4938                                 offset + RETURN_REGNUM * UNITS_PER_WORD); 
4939           addr = gen_rtx_MEM (Pmode, addr);
4940           set_mem_alias_set (addr, s390_sr_alias_set);
4941           emit_move_insn (return_reg, addr);
4942         }
4943
4944       /* ??? As references to the base register are not made
4945          explicit in insn RTX code, we have to add a barrier here
4946          to prevent incorrect scheduling.  */
4947
4948       emit_insn (gen_blockage());      
4949
4950       insn = restore_gprs (frame_pointer, offset, 
4951                            frame.first_restore_gpr, frame.last_save_gpr);
4952       emit_insn (insn);
4953     }
4954
4955   /* Return to caller.  */
4956
4957   p = rtvec_alloc (2);
4958   
4959   RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
4960   RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
4961   emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
4962 }
4963
4964
4965 /* Return the size in bytes of a function argument of 
4966    type TYPE and/or mode MODE.  At least one of TYPE or
4967    MODE must be specified.  */
4968
4969 static int
4970 s390_function_arg_size (mode, type)
4971      enum machine_mode mode;
4972      tree type;
4973 {
4974   if (type)
4975     return int_size_in_bytes (type);
4976
4977   /* No type info available for some library calls ...  */
4978   if (mode != BLKmode)
4979     return GET_MODE_SIZE (mode);
4980
4981   /* If we have neither type nor mode, abort */
4982   abort ();
4983 }
4984
4985 /* Return 1 if a function argument of type TYPE and mode MODE
4986    is to be passed by reference.  The ABI specifies that only
4987    structures of size 1, 2, 4, or 8 bytes are passed by value,
4988    all other structures (and complex numbers) are passed by
4989    reference.  */
4990
4991 int
4992 s390_function_arg_pass_by_reference (mode, type)
4993      enum machine_mode mode;
4994      tree type;
4995 {
4996   int size = s390_function_arg_size (mode, type);
4997
4998   if (type)
4999     {
5000       if (AGGREGATE_TYPE_P (type) &&
5001           size != 1 && size != 2 && size != 4 && size != 8)
5002         return 1;
5003
5004       if (TREE_CODE (type) == COMPLEX_TYPE)
5005         return 1;
5006     }
5007   return 0;
5008
5009 }
5010
5011 /* Update the data in CUM to advance over an argument of mode MODE and
5012    data type TYPE.  (TYPE is null for libcalls where that information
5013    may not be available.).  The boolean NAMED specifies whether the
5014    argument is a named argument (as opposed to an unnamed argument
5015    matching an ellipsis).  */
5016
5017 void
5018 s390_function_arg_advance (cum, mode, type, named)
5019      CUMULATIVE_ARGS *cum;
5020      enum machine_mode mode;
5021      tree type;
5022      int named ATTRIBUTE_UNUSED;
5023 {
5024   if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
5025     {
5026       cum->fprs++;
5027     }
5028   else if (s390_function_arg_pass_by_reference (mode, type))
5029     {
5030       cum->gprs += 1;
5031     }
5032   else
5033     {
5034       int size = s390_function_arg_size (mode, type);
5035       cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
5036     }
5037 }
5038
5039 /* Define where to put the arguments to a function.
5040    Value is zero to push the argument on the stack,
5041    or a hard register in which to store the argument.
5042
5043    MODE is the argument's machine mode.
5044    TYPE is the data type of the argument (as a tree).
5045     This is null for libcalls where that information may
5046     not be available.
5047    CUM is a variable of type CUMULATIVE_ARGS which gives info about
5048     the preceding args and about the function being called.
5049    NAMED is nonzero if this argument is a named parameter
5050     (otherwise it is an extra parameter matching an ellipsis).  
5051
5052    On S/390, we use general purpose registers 2 through 6 to
5053    pass integer, pointer, and certain structure arguments, and
5054    floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
5055    to pass floating point arguments.  All remaining arguments
5056    are pushed to the stack.  */
5057
5058 rtx
5059 s390_function_arg (cum, mode, type, named)
5060      CUMULATIVE_ARGS *cum;
5061      enum machine_mode mode;
5062      tree type;
5063      int named ATTRIBUTE_UNUSED;
5064 {
5065   if (s390_function_arg_pass_by_reference (mode, type))
5066       return 0;
5067
5068   if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
5069     {
5070       if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
5071         return 0;
5072       else
5073         return gen_rtx (REG, mode, cum->fprs + 16);
5074     }
5075   else
5076     {
5077       int size = s390_function_arg_size (mode, type);
5078       int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
5079
5080       if (cum->gprs + n_gprs > 5)
5081         return 0;
5082       else
5083         return gen_rtx (REG, mode, cum->gprs + 2);
5084     }
5085 }
5086
5087
5088 /* Create and return the va_list datatype.
5089
5090    On S/390, va_list is an array type equivalent to
5091
5092       typedef struct __va_list_tag
5093         {
5094             long __gpr;
5095             long __fpr;
5096             void *__overflow_arg_area;
5097             void *__reg_save_area;
5098             
5099         } va_list[1];
5100
5101    where __gpr and __fpr hold the number of general purpose
5102    or floating point arguments used up to now, respectively,
5103    __overflow_arg_area points to the stack location of the 
5104    next argument passed on the stack, and __reg_save_area
5105    always points to the start of the register area in the
5106    call frame of the current function.  The function prologue
5107    saves all registers used for argument passing into this
5108    area if the function uses variable arguments.  */
5109
5110 tree
5111 s390_build_va_list ()
5112 {
5113   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
5114
5115   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5116
5117   type_decl =
5118     build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5119
5120   f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"), 
5121                       long_integer_type_node);
5122   f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"), 
5123                       long_integer_type_node);
5124   f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
5125                       ptr_type_node);
5126   f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
5127                       ptr_type_node);
5128
5129   DECL_FIELD_CONTEXT (f_gpr) = record;
5130   DECL_FIELD_CONTEXT (f_fpr) = record;
5131   DECL_FIELD_CONTEXT (f_ovf) = record;
5132   DECL_FIELD_CONTEXT (f_sav) = record;
5133
5134   TREE_CHAIN (record) = type_decl;
5135   TYPE_NAME (record) = type_decl;
5136   TYPE_FIELDS (record) = f_gpr;
5137   TREE_CHAIN (f_gpr) = f_fpr;
5138   TREE_CHAIN (f_fpr) = f_ovf;
5139   TREE_CHAIN (f_ovf) = f_sav;
5140
5141   layout_type (record);
5142
5143   /* The correct type is an array type of one element.  */
5144   return build_array_type (record, build_index_type (size_zero_node));
5145 }
5146
5147 /* Implement va_start by filling the va_list structure VALIST.
5148    STDARG_P is always true, and ignored.
5149    NEXTARG points to the first anonymous stack argument.
5150
5151    The following global variables are used to initialize
5152    the va_list structure:
5153
5154      current_function_args_info:
5155        holds number of gprs and fprs used for named arguments.
5156      current_function_arg_offset_rtx:
5157        holds the offset of the first anonymous stack argument
5158        (relative to the virtual arg pointer).  */
5159
5160 void
5161 s390_va_start (valist, nextarg)
5162      tree valist;
5163      rtx nextarg ATTRIBUTE_UNUSED;
5164 {
5165   HOST_WIDE_INT n_gpr, n_fpr;
5166   int off;
5167   tree f_gpr, f_fpr, f_ovf, f_sav;
5168   tree gpr, fpr, ovf, sav, t;
5169
5170   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5171   f_fpr = TREE_CHAIN (f_gpr);
5172   f_ovf = TREE_CHAIN (f_fpr);
5173   f_sav = TREE_CHAIN (f_ovf);
5174
5175   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
5176   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
5177   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
5178   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
5179   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
5180
5181   /* Count number of gp and fp argument registers used.  */
5182
5183   n_gpr = current_function_args_info.gprs;
5184   n_fpr = current_function_args_info.fprs;
5185
5186   t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
5187   TREE_SIDE_EFFECTS (t) = 1;
5188   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5189
5190   t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
5191   TREE_SIDE_EFFECTS (t) = 1;
5192   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5193
5194   /* Find the overflow area.  */
5195   t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
5196
5197   off = INTVAL (current_function_arg_offset_rtx);
5198   off = off < 0 ? 0 : off;
5199   if (TARGET_DEBUG_ARG)
5200     fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
5201              (int)n_gpr, (int)n_fpr, off);
5202
5203   t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
5204
5205   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5206   TREE_SIDE_EFFECTS (t) = 1;
5207   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5208
5209   /* Find the register save area.  */
5210   t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
5211   t = build (PLUS_EXPR, TREE_TYPE (sav), t,
5212              build_int_2 (-STACK_POINTER_OFFSET, -1));
5213   t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
5214   TREE_SIDE_EFFECTS (t) = 1;
5215   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5216 }
5217
5218 /* Implement va_arg by updating the va_list structure 
5219    VALIST as required to retrieve an argument of type
5220    TYPE, and returning that argument. 
5221    
5222    Generates code equivalent to:
5223    
5224    if (integral value) {
5225      if (size  <= 4 && args.gpr < 5 ||
5226          size  > 4 && args.gpr < 4 ) 
5227        ret = args.reg_save_area[args.gpr+8]
5228      else
5229        ret = *args.overflow_arg_area++;
5230    } else if (float value) {
5231      if (args.fgpr < 2)
5232        ret = args.reg_save_area[args.fpr+64]
5233      else
5234        ret = *args.overflow_arg_area++;
5235    } else if (aggregate value) {
5236      if (args.gpr < 5)
5237        ret = *args.reg_save_area[args.gpr]
5238      else
5239        ret = **args.overflow_arg_area++;
5240    } */
5241
5242 rtx
5243 s390_va_arg (valist, type)
5244      tree valist;
5245      tree type;
5246 {
5247   tree f_gpr, f_fpr, f_ovf, f_sav;
5248   tree gpr, fpr, ovf, sav, reg, t, u;
5249   int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
5250   rtx lab_false, lab_over, addr_rtx, r;
5251
5252   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5253   f_fpr = TREE_CHAIN (f_gpr);
5254   f_ovf = TREE_CHAIN (f_fpr);
5255   f_sav = TREE_CHAIN (f_ovf);
5256
5257   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
5258   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
5259   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
5260   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
5261   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
5262
5263   size = int_size_in_bytes (type);
5264
5265   if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
5266     {
5267       if (TARGET_DEBUG_ARG)
5268         {
5269           fprintf (stderr, "va_arg: aggregate type");
5270           debug_tree (type);
5271         }
5272
5273       /* Aggregates are passed by reference.  */
5274       indirect_p = 1;
5275       reg = gpr;
5276       n_reg = 1;
5277       sav_ofs = 2 * UNITS_PER_WORD;
5278       sav_scale = UNITS_PER_WORD;
5279       size = UNITS_PER_WORD;
5280       max_reg = 4;
5281     }
5282   else if (FLOAT_TYPE_P (type) && ! TARGET_SOFT_FLOAT)
5283     {
5284       if (TARGET_DEBUG_ARG)
5285         {
5286           fprintf (stderr, "va_arg: float type");
5287           debug_tree (type);
5288         }
5289
5290       /* FP args go in FP registers, if present.  */
5291       indirect_p = 0;
5292       reg = fpr;
5293       n_reg = 1;
5294       sav_ofs = 16 * UNITS_PER_WORD;
5295       sav_scale = 8;
5296       /* TARGET_64BIT has up to 4 parameter in fprs */
5297       max_reg = TARGET_64BIT ? 3 : 1;
5298     }
5299   else
5300     {
5301       if (TARGET_DEBUG_ARG)
5302         {
5303           fprintf (stderr, "va_arg: other type");
5304           debug_tree (type);
5305         }
5306
5307       /* Otherwise into GP registers.  */
5308       indirect_p = 0;
5309       reg = gpr;
5310       n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5311       sav_ofs = 2 * UNITS_PER_WORD;
5312       if (TARGET_64BIT)
5313         sav_ofs += TYPE_MODE (type) == SImode ? 4 : 
5314                    TYPE_MODE (type) == HImode ? 6 : 
5315                    TYPE_MODE (type) == QImode ? 7 : 0;
5316       else
5317         sav_ofs += TYPE_MODE (type) == HImode ? 2 : 
5318                    TYPE_MODE (type) == QImode ? 3 : 0;
5319
5320       sav_scale = UNITS_PER_WORD;
5321       if (n_reg > 1)
5322         max_reg = 3;
5323       else
5324         max_reg = 4;
5325     }
5326
5327   /* Pull the value out of the saved registers ...  */
5328
5329   lab_false = gen_label_rtx ();
5330   lab_over = gen_label_rtx ();
5331   addr_rtx = gen_reg_rtx (Pmode);
5332
5333   emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
5334                            GEN_INT (max_reg),
5335                            GT, const1_rtx, Pmode, 0, lab_false);
5336
5337   if (sav_ofs)
5338     t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
5339   else
5340     t = sav;
5341
5342   u = build (MULT_EXPR, long_integer_type_node,
5343              reg, build_int_2 (sav_scale, 0));
5344   TREE_SIDE_EFFECTS (u) = 1;
5345
5346   t = build (PLUS_EXPR, ptr_type_node, t, u);
5347   TREE_SIDE_EFFECTS (t) = 1;
5348
5349   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
5350   if (r != addr_rtx)
5351     emit_move_insn (addr_rtx, r);
5352
5353
5354   emit_jump_insn (gen_jump (lab_over));
5355   emit_barrier ();
5356   emit_label (lab_false);
5357
5358   /* ... Otherwise out of the overflow area.  */
5359
5360   t = save_expr (ovf);
5361
5362
5363   /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated.  */
5364   if (size < UNITS_PER_WORD)
5365     {
5366       t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
5367       t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5368       TREE_SIDE_EFFECTS (t) = 1;
5369       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5370
5371       t = save_expr (ovf);
5372     }
5373
5374   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
5375   if (r != addr_rtx)
5376     emit_move_insn (addr_rtx, r);
5377
5378   t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
5379   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5380   TREE_SIDE_EFFECTS (t) = 1;
5381   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5382
5383   emit_label (lab_over);
5384
5385   /* If less than max_regs a registers are retrieved out 
5386      of register save area, increment.  */
5387
5388   u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg, 
5389              build_int_2 (n_reg, 0));
5390   TREE_SIDE_EFFECTS (u) = 1;
5391   expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
5392
5393   if (indirect_p)
5394     {
5395       r = gen_rtx_MEM (Pmode, addr_rtx);
5396       set_mem_alias_set (r, get_varargs_alias_set ());
5397       emit_move_insn (addr_rtx, r);
5398     }
5399
5400
5401   return addr_rtx;
5402 }
5403
5404
5405 /* Output assembly code for the trampoline template to
5406    stdio stream FILE.
5407
5408    On S/390, we use gpr 1 internally in the trampoline code;
5409    gpr 0 is used to hold the static chain.  */
5410
5411 void
5412 s390_trampoline_template (file)
5413      FILE *file;
5414 {
5415   if (TARGET_64BIT)
5416     {
5417       fprintf (file, "larl\t%s,0f\n", reg_names[1]);
5418       fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
5419       fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
5420       fprintf (file, "br\t%s\n", reg_names[1]);
5421       fprintf (file, "0:\t.quad\t0\n");
5422       fprintf (file, ".quad\t0\n");
5423     }
5424   else
5425     {
5426       fprintf (file, "basr\t%s,0\n", reg_names[1]);
5427       fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
5428       fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
5429       fprintf (file, "br\t%s\n", reg_names[1]);
5430       fprintf (file, ".long\t0\n");
5431       fprintf (file, ".long\t0\n");
5432     }
5433 }
5434
5435 /* Emit RTL insns to initialize the variable parts of a trampoline.
5436    FNADDR is an RTX for the address of the function's pure code.
5437    CXT is an RTX for the static chain value for the function.  */
5438
5439 void
5440 s390_initialize_trampoline (addr, fnaddr, cxt)
5441      rtx addr;
5442      rtx fnaddr;
5443      rtx cxt;
5444 {
5445   emit_move_insn (gen_rtx 
5446                   (MEM, Pmode,
5447                    memory_address (Pmode, 
5448                    plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
5449   emit_move_insn (gen_rtx
5450                   (MEM, Pmode,
5451                    memory_address (Pmode, 
5452                    plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
5453 }
5454
5455 /* Return rtx for 64-bit constant formed from the 32-bit subwords
5456    LOW and HIGH, independent of the host word size.  */
5457
5458 rtx
5459 s390_gen_rtx_const_DI (high, low)
5460      int high;
5461      int low;
5462 {
5463 #if HOST_BITS_PER_WIDE_INT >= 64
5464   HOST_WIDE_INT val;
5465   val = (HOST_WIDE_INT)high;
5466   val <<= 32;
5467   val |= (HOST_WIDE_INT)low;
5468   
5469   return GEN_INT (val);
5470 #else
5471 #if HOST_BITS_PER_WIDE_INT >= 32
5472   return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
5473 #else
5474   abort ();
5475 #endif
5476 #endif
5477
5478
5479 /* Output assembler code to FILE to increment profiler label # LABELNO
5480    for profiling a function entry.  */
5481
5482 void
5483 s390_function_profiler (file, labelno)
5484      FILE *file;
5485      int labelno;
5486 {
5487   rtx op[7];
5488
5489   char label[128];
5490   sprintf (label, "%sP%d", LPREFIX, labelno);
5491
5492   fprintf (file, "# function profiler \n");
5493
5494   op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
5495   op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
5496   op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
5497
5498   op[2] = gen_rtx_REG (Pmode, 1);
5499   op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
5500   SYMBOL_REF_FLAG (op[3]) = 1;
5501
5502   op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
5503   if (flag_pic)
5504     {
5505       op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), 113);
5506       op[4] = gen_rtx_CONST (Pmode, op[4]);
5507     }
5508
5509   if (TARGET_64BIT)
5510     {
5511       output_asm_insn ("stg\t%0,%1", op);
5512       output_asm_insn ("larl\t%2,%3", op);
5513       output_asm_insn ("brasl\t%0,%4", op);
5514       output_asm_insn ("lg\t%0,%1", op);
5515     }
5516   else if (!flag_pic)
5517     {
5518       op[6] = gen_label_rtx ();
5519
5520       output_asm_insn ("st\t%0,%1", op);
5521       output_asm_insn ("bras\t%2,%l6", op);
5522       output_asm_insn (".long\t%4", op);
5523       output_asm_insn (".long\t%3", op);
5524       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
5525       output_asm_insn ("l\t%0,0(%2)", op);
5526       output_asm_insn ("l\t%2,4(%2)", op);
5527       output_asm_insn ("basr\t%0,%0", op);
5528       output_asm_insn ("l\t%0,%1", op);
5529     }
5530   else
5531     {
5532       op[5] = gen_label_rtx ();
5533       op[6] = gen_label_rtx ();
5534
5535       output_asm_insn ("st\t%0,%1", op);
5536       output_asm_insn ("bras\t%2,%l6", op);
5537       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
5538       output_asm_insn (".long\t%4-%l5", op);
5539       output_asm_insn (".long\t%3-%l5", op);
5540       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
5541       output_asm_insn ("lr\t%0,%2", op);
5542       output_asm_insn ("a\t%0,0(%2)", op);
5543       output_asm_insn ("a\t%2,4(%2)", op);
5544       output_asm_insn ("basr\t%0,%0", op);
5545       output_asm_insn ("l\t%0,%1", op);
5546     }
5547 }
5548
5549 /* Select section for constant in constant pool.  In 32-bit mode,
5550    constants go in the function section; in 64-bit mode in .rodata.  */
5551
5552 static void
5553 s390_select_rtx_section (mode, x, align)
5554      enum machine_mode mode ATTRIBUTE_UNUSED;
5555      rtx x ATTRIBUTE_UNUSED;
5556      unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
5557 {
5558   if (TARGET_64BIT)
5559     readonly_data_section ();
5560   else
5561     function_section (current_function_decl);
5562 }
5563
5564 /* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we
5565    may access it directly in the GOT.  */
5566
5567 static void
5568 s390_encode_section_info (decl, first)
5569      tree decl;
5570      int first ATTRIBUTE_UNUSED;
5571 {
5572   if (flag_pic)
5573     {
5574       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
5575                  ? TREE_CST_RTL (decl) : DECL_RTL (decl));
5576
5577       if (GET_CODE (rtl) == MEM)
5578         {
5579           SYMBOL_REF_FLAG (XEXP (rtl, 0))
5580             = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
5581                || ! TREE_PUBLIC (decl));
5582         }
5583     }
5584 }