OSDN Git Service

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