OSDN Git Service

* config/s390/s390.c (s390_extra_constraint): New function.
[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, 2003 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 "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "except.h"
39 #include "function.h"
40 #include "recog.h"
41 #include "expr.h"
42 #include "reload.h"
43 #include "toplev.h"
44 #include "basic-block.h"
45 #include "integrate.h"
46 #include "ggc.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "debug.h"
50 #include "langhooks.h"
51 #include "optabs.h"
52
53 /* Machine-specific symbol_ref flags.  */
54 #define SYMBOL_FLAG_ALIGN1      (SYMBOL_FLAG_MACH_DEP << 0)
55
56
57 static bool s390_assemble_integer PARAMS ((rtx, unsigned int, int));
58 static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx, 
59                                              unsigned HOST_WIDE_INT));
60 static void s390_encode_section_info PARAMS ((tree, rtx, int));
61 static bool s390_cannot_force_const_mem PARAMS ((rtx));
62 static rtx s390_delegitimize_address PARAMS ((rtx));
63 static void s390_init_builtins PARAMS ((void));
64 static rtx s390_expand_builtin PARAMS ((tree, rtx, rtx, 
65                                         enum machine_mode, int));
66 static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
67                                           HOST_WIDE_INT, tree));
68 static enum attr_type s390_safe_attr_type PARAMS ((rtx));
69
70 static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
71 static int s390_adjust_priority PARAMS ((rtx, int));
72 static int s390_issue_rate PARAMS ((void));
73 static int s390_use_dfa_pipeline_interface PARAMS ((void));
74 static int s390_first_cycle_multipass_dfa_lookahead PARAMS ((void));
75 static int s390_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
76 static bool s390_rtx_costs PARAMS ((rtx, int, int, int *));
77 static int s390_address_cost PARAMS ((rtx));
78 static void s390_reorg PARAMS ((void));
79
80
81 #undef  TARGET_ASM_ALIGNED_HI_OP
82 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
83 #undef  TARGET_ASM_ALIGNED_DI_OP
84 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
85 #undef  TARGET_ASM_INTEGER
86 #define TARGET_ASM_INTEGER s390_assemble_integer
87
88 #undef  TARGET_ASM_OPEN_PAREN
89 #define TARGET_ASM_OPEN_PAREN ""
90
91 #undef  TARGET_ASM_CLOSE_PAREN
92 #define TARGET_ASM_CLOSE_PAREN ""
93
94 #undef  TARGET_ASM_SELECT_RTX_SECTION
95 #define TARGET_ASM_SELECT_RTX_SECTION  s390_select_rtx_section
96
97 #undef  TARGET_ENCODE_SECTION_INFO
98 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
99
100 #ifdef HAVE_AS_TLS
101 #undef TARGET_HAVE_TLS
102 #define TARGET_HAVE_TLS true
103 #endif
104 #undef TARGET_CANNOT_FORCE_CONST_MEM
105 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
106
107 #undef TARGET_DELEGITIMIZE_ADDRESS
108 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
109
110 #undef  TARGET_INIT_BUILTINS
111 #define TARGET_INIT_BUILTINS s390_init_builtins
112 #undef  TARGET_EXPAND_BUILTIN
113 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
114
115 #undef TARGET_ASM_OUTPUT_MI_THUNK
116 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
117 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
118 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
119
120 #undef  TARGET_SCHED_ADJUST_COST
121 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
122 #undef  TARGET_SCHED_ADJUST_PRIORITY
123 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
124 #undef TARGET_SCHED_ISSUE_RATE
125 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
126 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
127 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
128 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
129 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
130 #undef TARGET_SCHED_REORDER2
131 #define TARGET_SCHED_REORDER2 s390_sched_reorder2
132
133 #undef TARGET_RTX_COSTS
134 #define TARGET_RTX_COSTS s390_rtx_costs
135 #undef TARGET_ADDRESS_COST
136 #define TARGET_ADDRESS_COST s390_address_cost
137
138 #undef TARGET_MACHINE_DEPENDENT_REORG
139 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
140
141 struct gcc_target targetm = TARGET_INITIALIZER;
142
143 extern int reload_completed;
144
145 /* The alias set for prologue/epilogue register save/restore.  */
146 static int s390_sr_alias_set = 0;
147
148 /* Save information from a "cmpxx" operation until the branch or scc is
149    emitted.  */
150 rtx s390_compare_op0, s390_compare_op1;
151
152 /* Structure used to hold the components of a S/390 memory
153    address.  A legitimate address on S/390 is of the general
154    form
155           base + index + displacement
156    where any of the components is optional.
157
158    base and index are registers of the class ADDR_REGS,
159    displacement is an unsigned 12-bit immediate constant.  */
160
161 struct s390_address
162 {
163   rtx base;
164   rtx indx;
165   rtx disp;
166   int pointer;
167 };
168
169 /* Which cpu are we tuning for.  */
170 enum processor_type s390_tune;
171 enum processor_flags s390_tune_flags;
172 /* Which instruction set architecture to use.  */
173 enum processor_type s390_arch;
174 enum processor_flags s390_arch_flags;
175
176 /* Strings to hold which cpu and instruction set architecture  to use.  */
177 const char *s390_tune_string;           /* for -mtune=<xxx> */
178 const char *s390_arch_string;           /* for -march=<xxx> */
179
180 /* Define the structure for the machine field in struct function.  */
181
182 struct machine_function GTY(())
183 {
184   /* Label of start of initial literal pool.  */
185   rtx literal_pool_label;
186
187   /* Set, if some of the fprs 8-15 need to be saved (64 bit abi).  */
188   int save_fprs_p;
189
190   /* Number of first and last gpr to be saved, restored.  */
191   int first_save_gpr;
192   int first_restore_gpr;
193   int last_save_gpr;
194
195   /* Size of stack frame.  */
196   HOST_WIDE_INT frame_size;
197
198   /* Some local-dynamic TLS symbol name.  */
199   const char *some_ld_name;
200 };
201
202 static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
203 static int s390_branch_condition_mask PARAMS ((rtx));
204 static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
205 static int check_mode PARAMS ((rtx, enum machine_mode *));
206 static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
207 static int s390_short_displacement PARAMS ((rtx));
208 static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
209 static rtx get_thread_pointer PARAMS ((void));
210 static rtx legitimize_tls_address PARAMS ((rtx, rtx));
211 static const char *get_some_local_dynamic_name PARAMS ((void));
212 static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
213 static int reg_used_in_mem_p PARAMS ((int, rtx));
214 static int addr_generation_dependency_p PARAMS ((rtx, rtx));
215 static int s390_split_branches PARAMS ((rtx, bool *));
216 static void find_constant_pool_ref PARAMS ((rtx, rtx *));
217 static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
218 static int find_base_register_in_addr PARAMS ((struct s390_address *));
219 static bool find_base_register_ref PARAMS ((rtx));
220 static void replace_base_register_ref PARAMS ((rtx *, rtx));
221 static void s390_optimize_prolog PARAMS ((int));
222 static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
223 static int find_unused_clobbered_reg PARAMS ((void));
224 static void s390_frame_info PARAMS ((void));
225 static rtx save_fpr PARAMS ((rtx, int, int));
226 static rtx restore_fpr PARAMS ((rtx, int, int));
227 static rtx save_gprs PARAMS ((rtx, int, int, int));
228 static rtx restore_gprs PARAMS ((rtx, int, int, int));
229 static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
230 static bool s390_function_arg_float PARAMS ((enum machine_mode, tree));
231 static struct machine_function * s390_init_machine_status PARAMS ((void));
232
233 /* Check whether integer displacement is in range.  */
234 #define DISP_IN_RANGE(d) \
235   (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
236                            : ((d) >= 0 && (d) <= 4095))
237  
238 /* Return true if SET either doesn't set the CC register, or else
239    the source and destination have matching CC modes and that 
240    CC mode is at least as constrained as REQ_MODE.  */
241  
242 static int
243 s390_match_ccmode_set (set, req_mode)
244      rtx set;
245      enum machine_mode req_mode;
246 {
247   enum machine_mode set_mode;
248
249   if (GET_CODE (set) != SET)
250     abort ();
251
252   if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
253     return 1;
254
255   set_mode = GET_MODE (SET_DEST (set));
256   switch (set_mode)
257     {
258     case CCSmode:
259     case CCSRmode:
260     case CCUmode:
261     case CCURmode:
262     case CCLmode:
263     case CCL1mode:
264     case CCL2mode:
265     case CCT1mode:
266     case CCT2mode:
267     case CCT3mode:
268       if (req_mode != set_mode)
269         return 0;
270       break;
271
272     case CCZmode:
273       if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
274           && req_mode != CCSRmode && req_mode != CCURmode)
275         return 0;
276       break;
277
278     case CCAPmode:
279     case CCANmode:
280       if (req_mode != CCAmode)
281         return 0;
282       break;
283  
284     default:
285       abort ();
286     }
287  
288   return (GET_MODE (SET_SRC (set)) == set_mode);
289 }
290
291 /* Return true if every SET in INSN that sets the CC register 
292    has source and destination with matching CC modes and that 
293    CC mode is at least as constrained as REQ_MODE.  
294    If REQ_MODE is VOIDmode, always return false.  */
295  
296 int
297 s390_match_ccmode (insn, req_mode)
298      rtx insn;
299      enum machine_mode req_mode;
300 {
301   int i;
302
303   /* s390_tm_ccmode returns VOIDmode to indicate failure.  */
304   if (req_mode == VOIDmode)
305     return 0;
306
307   if (GET_CODE (PATTERN (insn)) == SET)
308     return s390_match_ccmode_set (PATTERN (insn), req_mode);
309
310   if (GET_CODE (PATTERN (insn)) == PARALLEL)
311       for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
312         {
313           rtx set = XVECEXP (PATTERN (insn), 0, i);
314           if (GET_CODE (set) == SET)
315             if (!s390_match_ccmode_set (set, req_mode))
316               return 0;
317         }
318
319   return 1;
320 }
321
322 /* If a test-under-mask instruction can be used to implement 
323    (compare (and ... OP1) OP2), return the CC mode required
324    to do that.  Otherwise, return VOIDmode.  
325    MIXED is true if the instruction can distinguish between
326    CC1 and CC2 for mixed selected bits (TMxx), it is false
327    if the instruction cannot (TM).  */
328
329 enum machine_mode
330 s390_tm_ccmode (op1, op2, mixed)
331      rtx op1;
332      rtx op2;
333      int mixed;
334 {
335   int bit0, bit1;
336
337   /* ??? Fixme: should work on CONST_DOUBLE as well.  */
338   if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
339     return VOIDmode;
340
341   /* Selected bits all zero: CC0.  */
342   if (INTVAL (op2) == 0)
343     return CCTmode;
344
345   /* Selected bits all one: CC3.  */
346   if (INTVAL (op2) == INTVAL (op1))
347     return CCT3mode;
348
349   /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2.  */
350   if (mixed)
351     {
352       bit1 = exact_log2 (INTVAL (op2));
353       bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
354       if (bit0 != -1 && bit1 != -1)
355         return bit0 > bit1 ? CCT1mode : CCT2mode;
356     }
357
358   return VOIDmode;
359 }
360
361 /* Given a comparison code OP (EQ, NE, etc.) and the operands 
362    OP0 and OP1 of a COMPARE, return the mode to be used for the 
363    comparison.  */
364
365 enum machine_mode
366 s390_select_ccmode (code, op0, op1) 
367      enum rtx_code code;
368      rtx op0;
369      rtx op1;
370 {
371   switch (code)
372     {
373       case EQ:
374       case NE:
375         if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
376             && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K')) 
377           return CCAPmode;
378         if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
379             || GET_CODE (op1) == NEG)
380           return CCLmode;
381
382         if (GET_CODE (op0) == AND)
383           {
384             /* Check whether we can potentially do it via TM.  */
385             enum machine_mode ccmode;
386             ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
387             if (ccmode != VOIDmode)
388               {
389                 /* Relax CCTmode to CCZmode to allow fall-back to AND
390                    if that turns out to be beneficial.  */
391                 return ccmode == CCTmode ? CCZmode : ccmode;
392               }
393           }
394
395         if (register_operand (op0, HImode) 
396             && GET_CODE (op1) == CONST_INT
397             && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
398           return CCT3mode;
399         if (register_operand (op0, QImode) 
400             && GET_CODE (op1) == CONST_INT
401             && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
402           return CCT3mode;
403
404         return CCZmode;
405
406       case LE:
407       case LT:
408       case GE:
409       case GT:
410           if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
411               && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K')) 
412             {
413               if (INTVAL (XEXP((op0), 1)) < 0)
414                 return CCANmode;
415               else
416                 return CCAPmode;
417             }
418       case UNORDERED:
419       case ORDERED:
420       case UNEQ:
421       case UNLE:
422       case UNLT:
423       case UNGE:
424       case UNGT:
425       case LTGT:
426         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
427             && GET_CODE (op1) != CONST_INT)
428           return CCSRmode;
429         return CCSmode;
430
431       case LTU:
432       case GEU:
433         if (GET_CODE (op0) == PLUS)
434           return CCL1mode;
435
436         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
437             && GET_CODE (op1) != CONST_INT)
438           return CCURmode;
439         return CCUmode;
440
441       case LEU:
442       case GTU:
443         if (GET_CODE (op0) == MINUS)
444           return CCL2mode;
445
446         if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
447             && GET_CODE (op1) != CONST_INT)
448           return CCURmode;
449         return CCUmode;
450
451       default:
452         abort ();
453     }
454 }
455
456 /* Return branch condition mask to implement a branch 
457    specified by CODE.  */
458
459 static int
460 s390_branch_condition_mask (code)
461     rtx code;
462
463   const int CC0 = 1 << 3;
464   const int CC1 = 1 << 2;
465   const int CC2 = 1 << 1;
466   const int CC3 = 1 << 0;
467
468   if (GET_CODE (XEXP (code, 0)) != REG
469       || REGNO (XEXP (code, 0)) != CC_REGNUM
470       || XEXP (code, 1) != const0_rtx)
471     abort ();
472
473   switch (GET_MODE (XEXP (code, 0)))
474     {
475     case CCZmode:
476       switch (GET_CODE (code))
477         {
478         case EQ:        return CC0;
479         case NE:        return CC1 | CC2 | CC3;
480         default:
481           abort ();
482         }
483       break;
484
485     case CCT1mode:
486       switch (GET_CODE (code))
487         {
488         case EQ:        return CC1;
489         case NE:        return CC0 | CC2 | CC3;
490         default:
491           abort ();
492         }
493       break;
494
495     case CCT2mode:
496       switch (GET_CODE (code))
497         {
498         case EQ:        return CC2;
499         case NE:        return CC0 | CC1 | CC3;
500         default:
501           abort ();
502         }
503       break;
504
505     case CCT3mode:
506       switch (GET_CODE (code))
507         {
508         case EQ:        return CC3;
509         case NE:        return CC0 | CC1 | CC2;
510         default:
511           abort ();
512         }
513       break;
514
515     case CCLmode:
516       switch (GET_CODE (code))
517         {
518         case EQ:        return CC0 | CC2;
519         case NE:        return CC1 | CC3;
520         default:
521           abort ();
522         }
523       break;
524
525     case CCL1mode:
526       switch (GET_CODE (code))
527         {
528         case LTU:       return CC2 | CC3;  /* carry */
529         case GEU:       return CC0 | CC1;  /* no carry */
530         default:
531           abort ();
532         }
533       break;
534
535     case CCL2mode:
536       switch (GET_CODE (code))
537         {
538         case GTU:       return CC0 | CC1;  /* borrow */
539         case LEU:       return CC2 | CC3;  /* no borrow */
540         default:
541           abort ();
542         }
543       break;
544
545     case CCUmode:
546       switch (GET_CODE (code))
547         {
548         case EQ:        return CC0;
549         case NE:        return CC1 | CC2 | CC3;
550         case LTU:       return CC1;
551         case GTU:       return CC2;
552         case LEU:       return CC0 | CC1;
553         case GEU:       return CC0 | CC2;
554         default:
555           abort ();
556         }
557       break;
558
559     case CCURmode:
560       switch (GET_CODE (code))
561         {
562         case EQ:        return CC0;
563         case NE:        return CC2 | CC1 | CC3;
564         case LTU:       return CC2;
565         case GTU:       return CC1;
566         case LEU:       return CC0 | CC2;
567         case GEU:       return CC0 | CC1;
568         default:
569           abort ();
570         }
571       break;
572
573     case CCAPmode:
574       switch (GET_CODE (code))
575         {
576         case EQ:        return CC0;
577         case NE:        return CC1 | CC2 | CC3;
578         case LT:        return CC1 | CC3;
579         case GT:        return CC2;
580         case LE:        return CC0 | CC1 | CC3;
581         case GE:        return CC0 | CC2;
582         default:
583           abort ();
584         }
585       break;
586
587     case CCANmode:
588       switch (GET_CODE (code))
589         {
590         case EQ:        return CC0;
591         case NE:        return CC1 | CC2 | CC3;
592         case LT:        return CC1;
593         case GT:        return CC2 | CC3;
594         case LE:        return CC0 | CC1;
595         case GE:        return CC0 | CC2 | CC3;
596         default:
597           abort ();
598         }
599       break;
600
601     case CCSmode:
602       switch (GET_CODE (code))
603         {
604         case EQ:        return CC0;
605         case NE:        return CC1 | CC2 | CC3;
606         case LT:        return CC1;
607         case GT:        return CC2;
608         case LE:        return CC0 | CC1;
609         case GE:        return CC0 | CC2;
610         case UNORDERED: return CC3;
611         case ORDERED:   return CC0 | CC1 | CC2;
612         case UNEQ:      return CC0 | CC3;
613         case UNLT:      return CC1 | CC3;
614         case UNGT:      return CC2 | CC3;
615         case UNLE:      return CC0 | CC1 | CC3;
616         case UNGE:      return CC0 | CC2 | CC3;
617         case LTGT:      return CC1 | CC2;
618         default:
619           abort ();
620         }
621       break;
622
623     case CCSRmode:
624       switch (GET_CODE (code))
625         {
626         case EQ:        return CC0;
627         case NE:        return CC2 | CC1 | CC3;
628         case LT:        return CC2;
629         case GT:        return CC1;
630         case LE:        return CC0 | CC2;
631         case GE:        return CC0 | CC1;
632         case UNORDERED: return CC3;
633         case ORDERED:   return CC0 | CC2 | CC1;
634         case UNEQ:      return CC0 | CC3;
635         case UNLT:      return CC2 | CC3;
636         case UNGT:      return CC1 | CC3;
637         case UNLE:      return CC0 | CC2 | CC3;
638         case UNGE:      return CC0 | CC1 | CC3;
639         case LTGT:      return CC2 | CC1;
640         default:
641           abort ();
642         }
643       break;
644
645     default:
646       abort ();
647     }
648 }
649
650 /* If INV is false, return assembler mnemonic string to implement 
651    a branch specified by CODE.  If INV is true, return mnemonic 
652    for the corresponding inverted branch.  */
653
654 static const char *
655 s390_branch_condition_mnemonic (code, inv)
656      rtx code;
657      int inv;
658 {
659   static const char *const mnemonic[16] =
660     {
661       NULL, "o", "h", "nle",
662       "l", "nhe", "lh", "ne",
663       "e", "nlh", "he", "nl",
664       "le", "nh", "no", NULL
665     };
666
667   int mask = s390_branch_condition_mask (code);
668
669   if (inv)
670     mask ^= 15;
671
672   if (mask < 1 || mask > 14)
673     abort ();
674
675   return mnemonic[mask];
676 }
677
678 /* If OP is an integer constant of mode MODE with exactly one
679    HImode subpart unequal to DEF, return the number of that 
680    subpart.  As a special case, all HImode subparts of OP are
681    equal to DEF, return zero.  Otherwise, return -1.  */
682
683 int
684 s390_single_hi (op, mode, def)
685      rtx op;
686      enum machine_mode mode;
687      int def;
688 {
689   if (GET_CODE (op) == CONST_INT)
690     {
691       unsigned HOST_WIDE_INT value = 0;
692       int n_parts = GET_MODE_SIZE (mode) / 2;
693       int i, part = -1;
694
695       for (i = 0; i < n_parts; i++)
696         {
697           if (i == 0)
698             value = (unsigned HOST_WIDE_INT) INTVAL (op);
699           else
700             value >>= 16;
701
702           if ((value & 0xffff) != (unsigned)(def & 0xffff))
703             {
704               if (part != -1)
705                 return -1;
706               else
707                 part = i;
708             }
709         }
710
711       return part == -1 ? 0 : (n_parts - 1 - part);
712     }
713
714   else if (GET_CODE (op) == CONST_DOUBLE
715            && GET_MODE (op) == VOIDmode)
716     {
717       unsigned HOST_WIDE_INT value = 0;
718       int n_parts = GET_MODE_SIZE (mode) / 2;
719       int i, part = -1;
720
721       for (i = 0; i < n_parts; i++)
722         {
723           if (i == 0)
724             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
725           else if (i == HOST_BITS_PER_WIDE_INT / 16)
726             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
727           else
728             value >>= 16;
729
730           if ((value & 0xffff) != (unsigned)(def & 0xffff))
731             {
732               if (part != -1)
733                 return -1;
734               else
735                 part = i;
736             }
737         }
738
739       return part == -1 ? 0 : (n_parts - 1 - part);
740     }
741
742   return -1;      
743 }
744
745 /* Extract the HImode part number PART from integer 
746    constant OP of mode MODE.  */
747
748 int
749 s390_extract_hi (op, mode, part)
750     rtx op;
751     enum machine_mode mode;
752     int part;
753 {
754   int n_parts = GET_MODE_SIZE (mode) / 2;
755   if (part < 0 || part >= n_parts)
756     abort();
757   else
758     part = n_parts - 1 - part;
759
760   if (GET_CODE (op) == CONST_INT)
761     {
762       unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
763       return ((value >> (16 * part)) & 0xffff);
764     }
765   else if (GET_CODE (op) == CONST_DOUBLE
766            && GET_MODE (op) == VOIDmode)
767     {
768       unsigned HOST_WIDE_INT value;
769       if (part < HOST_BITS_PER_WIDE_INT / 16)
770         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
771       else
772         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
773         part -= HOST_BITS_PER_WIDE_INT / 16;
774
775       return ((value >> (16 * part)) & 0xffff); 
776     }
777
778   abort ();
779 }
780
781 /* If OP is an integer constant of mode MODE with exactly one
782    QImode subpart unequal to DEF, return the number of that 
783    subpart.  As a special case, all QImode subparts of OP are
784    equal to DEF, return zero.  Otherwise, return -1.  */
785
786 int
787 s390_single_qi (op, mode, def)
788      rtx op;
789      enum machine_mode mode;
790      int def;
791 {
792   if (GET_CODE (op) == CONST_INT)
793     {
794       unsigned HOST_WIDE_INT value = 0;
795       int n_parts = GET_MODE_SIZE (mode);
796       int i, part = -1;
797
798       for (i = 0; i < n_parts; i++)
799         {
800           if (i == 0)
801             value = (unsigned HOST_WIDE_INT) INTVAL (op);
802           else
803             value >>= 8;
804
805           if ((value & 0xff) != (unsigned)(def & 0xff))
806             {
807               if (part != -1)
808                 return -1;
809               else
810                 part = i;
811             }
812         }
813
814       return part == -1 ? 0 : (n_parts - 1 - part);
815     }
816
817   else if (GET_CODE (op) == CONST_DOUBLE
818            && GET_MODE (op) == VOIDmode)
819     {
820       unsigned HOST_WIDE_INT value = 0;
821       int n_parts = GET_MODE_SIZE (mode);
822       int i, part = -1;
823
824       for (i = 0; i < n_parts; i++)
825         {
826           if (i == 0)
827             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
828           else if (i == HOST_BITS_PER_WIDE_INT / 8)
829             value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
830           else
831             value >>= 8;
832
833           if ((value & 0xff) != (unsigned)(def & 0xff))
834             {
835               if (part != -1)
836                 return -1;
837               else
838                 part = i;
839             }
840         }
841
842       return part == -1 ? 0 : (n_parts - 1 - part);
843     }
844
845   return -1;      
846 }
847
848 /* Extract the QImode part number PART from integer 
849    constant OP of mode MODE.  */
850
851 int
852 s390_extract_qi (op, mode, part)
853     rtx op;
854     enum machine_mode mode;
855     int part;
856 {
857   int n_parts = GET_MODE_SIZE (mode);
858   if (part < 0 || part >= n_parts)
859     abort();
860   else
861     part = n_parts - 1 - part;
862
863   if (GET_CODE (op) == CONST_INT)
864     {
865       unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
866       return ((value >> (8 * part)) & 0xff);
867     }
868   else if (GET_CODE (op) == CONST_DOUBLE
869            && GET_MODE (op) == VOIDmode)
870     {
871       unsigned HOST_WIDE_INT value;
872       if (part < HOST_BITS_PER_WIDE_INT / 8)
873         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
874       else
875         value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
876         part -= HOST_BITS_PER_WIDE_INT / 8;
877
878       return ((value >> (8 * part)) & 0xff); 
879     }
880
881   abort ();
882 }
883
884 /* Check whether we can (and want to) split a double-word 
885    move in mode MODE from SRC to DST into two single-word 
886    moves, moving the subword FIRST_SUBWORD first.  */
887
888 bool
889 s390_split_ok_p (dst, src, mode, first_subword)
890      rtx dst;
891      rtx src;
892      enum machine_mode mode;
893      int first_subword;
894 {
895   /* Floating point registers cannot be split.  */
896   if (FP_REG_P (src) || FP_REG_P (dst))
897     return false;
898
899   /* We don't need to split if operands are directly accessable.  */
900   if (s_operand (src, mode) || s_operand (dst, mode))
901     return false;
902
903   /* Non-offsettable memory references cannot be split.  */
904   if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
905       || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
906     return false;
907
908   /* Moving the first subword must not clobber a register
909      needed to move the second subword.  */
910   if (register_operand (dst, mode))
911     {
912       rtx subreg = operand_subword (dst, first_subword, 0, mode);
913       if (reg_overlap_mentioned_p (subreg, src))
914         return false;
915     }
916
917   return true;
918 }
919
920
921 /* Change optimizations to be performed, depending on the 
922    optimization level.
923
924    LEVEL is the optimization level specified; 2 if `-O2' is
925    specified, 1 if `-O' is specified, and 0 if neither is specified.
926
927    SIZE is nonzero if `-Os' is specified and zero otherwise.  */
928
929 void
930 optimization_options (level, size)
931      int level ATTRIBUTE_UNUSED;
932      int size ATTRIBUTE_UNUSED;
933 {
934   /* ??? There are apparently still problems with -fcaller-saves.  */
935   flag_caller_saves = 0;
936
937   /* By default, always emit DWARF-2 unwind info.  This allows debugging
938      without maintaining a stack frame back-chain.  */
939   flag_asynchronous_unwind_tables = 1;
940 }
941
942 void
943 override_options ()
944 {
945   int i;
946   static struct pta
947     {
948       const char *const name;           /* processor name or nickname.  */
949       const enum processor_type processor;
950       const enum processor_flags flags;
951     }
952   const processor_alias_table[] =
953     {
954       {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
955       {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
956       {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
957       {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH 
958                                     | PF_LONG_DISPLACEMENT},
959     };
960
961   int const pta_size = ARRAY_SIZE (processor_alias_table);
962
963   /* Acquire a unique set number for our register saves and restores.  */
964   s390_sr_alias_set = new_alias_set ();
965
966   /* Set up function hooks.  */
967   init_machine_status = s390_init_machine_status;
968
969   /* Architecture mode defaults according to ABI.  */
970   if (!(target_flags_explicit & MASK_ZARCH))
971     {
972       if (TARGET_64BIT)
973         target_flags |= MASK_ZARCH;
974       else
975         target_flags &= ~MASK_ZARCH;
976     }
977
978   /* Determine processor architectural level.  */
979   if (!s390_arch_string)
980     s390_arch_string = TARGET_ZARCH? "z900" : "g5";
981
982   for (i = 0; i < pta_size; i++)
983     if (! strcmp (s390_arch_string, processor_alias_table[i].name))
984       {
985         s390_arch = processor_alias_table[i].processor;
986         s390_arch_flags = processor_alias_table[i].flags;
987         break;
988       }
989   if (i == pta_size)
990     error ("Unknown cpu used in -march=%s.", s390_arch_string);
991
992   /* Determine processor to tune for.  */
993   if (!s390_tune_string)
994     {
995       s390_tune = s390_arch;
996       s390_tune_flags = s390_arch_flags;
997       s390_tune_string = s390_arch_string;
998     }
999   else
1000     {
1001       for (i = 0; i < pta_size; i++)
1002         if (! strcmp (s390_tune_string, processor_alias_table[i].name))
1003           {
1004             s390_tune = processor_alias_table[i].processor;
1005             s390_tune_flags = processor_alias_table[i].flags;
1006             break;
1007           }
1008       if (i == pta_size)
1009         error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
1010     }
1011
1012   /* Sanity checks.  */
1013   if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1014     error ("z/Architecture mode not supported on %s.", s390_arch_string);
1015   if (TARGET_64BIT && !TARGET_ZARCH)
1016     error ("64-bit ABI not supported in ESA/390 mode.");
1017 }
1018
1019 /* Map for smallest class containing reg regno.  */
1020
1021 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1022 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1023   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1024   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1025   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1026   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1027   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1028   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1029   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1030   ADDR_REGS,    NO_REGS,   ADDR_REGS 
1031 };
1032
1033 /* Return attribute type of insn.  */
1034
1035 static enum attr_type
1036 s390_safe_attr_type (insn)
1037      rtx insn;
1038 {
1039   if (recog_memoized (insn) >= 0)
1040     return get_attr_type (insn);
1041   else
1042     return TYPE_NONE;
1043 }
1044
1045 /* Return true if OP a (const_int 0) operand.
1046    OP is the current operation.
1047    MODE is the current operation mode.  */
1048  
1049 int
1050 const0_operand (op, mode)
1051      register rtx op;
1052      enum machine_mode mode;
1053 {
1054   return op == CONST0_RTX (mode);
1055 }
1056
1057 /* Return true if OP is constant.
1058    OP is the current operation.
1059    MODE is the current operation mode.  */
1060
1061 int
1062 consttable_operand (op, mode)
1063      rtx op;
1064      enum machine_mode mode ATTRIBUTE_UNUSED;
1065 {
1066   return CONSTANT_P (op);
1067 }
1068
1069 /* Return true if the mode of operand OP matches MODE.
1070    If MODE is set to VOIDmode, set it to the mode of OP.  */ 
1071
1072 static int
1073 check_mode (op, mode)
1074      register rtx op;
1075      enum machine_mode *mode;
1076 {
1077   if (*mode == VOIDmode)
1078       *mode = GET_MODE (op);
1079   else
1080   {
1081     if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1082        return 0;
1083   }
1084   return 1;
1085 }
1086
1087 /* Return true if OP a valid operand for the LARL instruction.
1088    OP is the current operation.
1089    MODE is the current operation mode.  */
1090
1091 int
1092 larl_operand (op, mode)
1093      register rtx op;
1094      enum machine_mode mode;
1095 {
1096   if (! check_mode (op, &mode))
1097     return 0;
1098
1099   /* Allow labels and local symbols.  */
1100   if (GET_CODE (op) == LABEL_REF)
1101     return 1;
1102   if (GET_CODE (op) == SYMBOL_REF)
1103     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1104             && SYMBOL_REF_TLS_MODEL (op) == 0
1105             && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1106
1107   /* Everything else must have a CONST, so strip it.  */
1108   if (GET_CODE (op) != CONST)
1109     return 0;
1110   op = XEXP (op, 0);
1111
1112   /* Allow adding *even* in-range constants.  */
1113   if (GET_CODE (op) == PLUS)
1114     {
1115       if (GET_CODE (XEXP (op, 1)) != CONST_INT
1116           || (INTVAL (XEXP (op, 1)) & 1) != 0)
1117         return 0;
1118 #if HOST_BITS_PER_WIDE_INT > 32
1119       if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1120           || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1121         return 0;
1122 #endif  
1123       op = XEXP (op, 0);
1124     }
1125
1126   /* Labels and local symbols allowed here as well.  */
1127   if (GET_CODE (op) == LABEL_REF)
1128     return 1;
1129   if (GET_CODE (op) == SYMBOL_REF)
1130     return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1131             && SYMBOL_REF_TLS_MODEL (op) == 0
1132             && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1133
1134   /* Now we must have a @GOTENT offset or @PLT stub
1135      or an @INDNTPOFF TLS offset.  */
1136   if (GET_CODE (op) == UNSPEC
1137       && XINT (op, 1) == 111)
1138     return 1;
1139   if (GET_CODE (op) == UNSPEC
1140       && XINT (op, 1) == 113)
1141     return 1;
1142   if (GET_CODE (op) == UNSPEC
1143       && XINT (op, 1) == UNSPEC_INDNTPOFF)
1144     return 1;
1145
1146   return 0;
1147 }
1148
1149 /* Helper routine to implement s_operand and s_imm_operand.
1150    OP is the current operation.
1151    MODE is the current operation mode.
1152    ALLOW_IMMEDIATE specifies whether immediate operands should
1153    be accepted or not.  */
1154
1155 static int
1156 general_s_operand (op, mode, allow_immediate)
1157      register rtx op;
1158      enum machine_mode mode;
1159      int allow_immediate;
1160 {
1161   struct s390_address addr;
1162
1163   /* Call general_operand first, so that we don't have to
1164      check for many special cases.  */
1165   if (!general_operand (op, mode))
1166     return 0;
1167
1168   /* Just like memory_operand, allow (subreg (mem ...))
1169      after reload.  */
1170   if (reload_completed 
1171       && GET_CODE (op) == SUBREG 
1172       && GET_CODE (SUBREG_REG (op)) == MEM)
1173     op = SUBREG_REG (op);
1174
1175   switch (GET_CODE (op))
1176     {
1177       /* Constants that we are sure will be forced to the
1178          literal pool in reload are OK as s-operand.  Note
1179          that we cannot call s390_preferred_reload_class here
1180          because it might not be known yet at this point 
1181          whether the current function is a leaf or not.  */
1182       case CONST_INT:
1183       case CONST_DOUBLE:
1184         if (!allow_immediate || reload_completed)
1185           break;
1186         if (!legitimate_reload_constant_p (op))
1187           return 1;
1188         if (!TARGET_64BIT)
1189           return 1;
1190         break;
1191
1192       /* Memory operands are OK unless they already use an
1193          index register.  */
1194       case MEM:
1195         if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
1196           return 1;
1197         if (s390_decompose_address (XEXP (op, 0), &addr) 
1198             && !addr.indx)
1199           return 1;
1200         break;
1201
1202       default:
1203         break;
1204     }
1205
1206   return 0;
1207 }
1208
1209 /* Return true if OP is a valid S-type operand.
1210    OP is the current operation.
1211    MODE is the current operation mode.  */
1212
1213 int
1214 s_operand (op, mode)
1215      register rtx op;
1216      enum machine_mode mode;
1217 {
1218   return general_s_operand (op, mode, 0);
1219 }
1220
1221 /* Return true if OP is a valid S-type operand or an immediate 
1222    operand that can be addressed as S-type operand by forcing 
1223    it into the literal pool.
1224    OP is the current operation.
1225    MODE is the current operation mode.  */
1226
1227 int
1228 s_imm_operand (op, mode)
1229      register rtx op;
1230      enum machine_mode mode;
1231 {
1232   return general_s_operand (op, mode, 1);
1233 }
1234
1235 /* Return true if DISP is a valid short displacement.  */
1236
1237 static int
1238 s390_short_displacement (disp)
1239      rtx disp;
1240 {
1241   /* No displacement is OK.  */
1242   if (!disp)
1243     return 1;
1244
1245   /* Integer displacement in range.  */
1246   if (GET_CODE (disp) == CONST_INT)
1247     return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1248
1249   /* GOT offset is not OK, the GOT can be large.  */
1250   if (GET_CODE (disp) == CONST
1251       && GET_CODE (XEXP (disp, 0)) == UNSPEC
1252       && XINT (XEXP (disp, 0), 1) == 110)
1253     return 0;
1254
1255   /* All other symbolic constants are literal pool references,
1256      which are OK as the literal pool must be small.  */
1257   if (GET_CODE (disp) == CONST)
1258     return 1;
1259
1260   return 0;
1261 }
1262
1263 /* Return true if OP is a valid operand for a C constraint.  */
1264
1265 int
1266 s390_extra_constraint (op, c)
1267      rtx op;
1268      int c;
1269 {
1270   struct s390_address addr;
1271
1272   switch (c)
1273     {
1274     case 'Q':
1275       if (GET_CODE (op) != MEM)
1276         return 0;
1277       if (!s390_decompose_address (XEXP (op, 0), &addr))
1278         return 0;
1279       if (addr.indx)
1280         return 0;
1281
1282       if (TARGET_LONG_DISPLACEMENT)
1283         {
1284           if (!s390_short_displacement (addr.disp))
1285             return 0;
1286         }
1287       break;
1288
1289     case 'R':
1290       if (GET_CODE (op) != MEM)
1291         return 0;
1292
1293       if (TARGET_LONG_DISPLACEMENT)
1294         {
1295           if (!s390_decompose_address (XEXP (op, 0), &addr))
1296             return 0;
1297           if (!s390_short_displacement (addr.disp))
1298             return 0;
1299         }
1300       break;
1301
1302     case 'S':
1303       if (!TARGET_LONG_DISPLACEMENT)
1304         return 0;
1305       if (GET_CODE (op) != MEM)
1306         return 0;
1307       if (!s390_decompose_address (XEXP (op, 0), &addr))
1308         return 0;
1309       if (addr.indx)
1310         return 0;
1311       if (s390_short_displacement (addr.disp))
1312         return 0;
1313       break;
1314
1315     case 'T':
1316       if (!TARGET_LONG_DISPLACEMENT)
1317         return 0;
1318       if (GET_CODE (op) != MEM)
1319         return 0;
1320       /* Any invalid address here will be fixed up by reload,
1321          so accept it for the most generic constraint.  */
1322       if (s390_decompose_address (XEXP (op, 0), &addr)
1323           && s390_short_displacement (addr.disp))
1324         return 0;
1325       break;
1326
1327     case 'U':
1328       if (TARGET_LONG_DISPLACEMENT)
1329         {
1330           if (!s390_decompose_address (op, &addr))
1331             return 0;
1332           if (!s390_short_displacement (addr.disp))
1333             return 0;
1334         }
1335       break;
1336
1337     case 'W':
1338       if (!TARGET_LONG_DISPLACEMENT)
1339         return 0;
1340       /* Any invalid address here will be fixed up by reload,
1341          so accept it for the most generic constraint.  */
1342       if (s390_decompose_address (op, &addr)
1343           && s390_short_displacement (addr.disp))
1344         return 0;
1345       break;
1346
1347     default:
1348       return 0;
1349     }
1350
1351   return 1;
1352 }
1353
1354 /* Compute a (partial) cost for rtx X.  Return true if the complete
1355    cost has been computed, and false if subexpressions should be
1356    scanned.  In either case, *TOTAL contains the cost result.  */
1357
1358 static bool
1359 s390_rtx_costs (x, code, outer_code, total)
1360      rtx x;
1361      int code, outer_code;
1362      int *total;
1363 {
1364   switch (code)
1365     {
1366     case CONST:
1367       if (GET_CODE (XEXP (x, 0)) == MINUS
1368           && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1369         *total = 1000;
1370       else
1371         *total = 0;
1372       return true;
1373
1374     case CONST_INT:
1375       /* Force_const_mem does not work out of reload, because the
1376          saveable_obstack is set to reload_obstack, which does not
1377          live long enough.  Because of this we cannot use force_const_mem
1378          in addsi3.  This leads to problems with gen_add2_insn with a
1379          constant greater than a short. Because of that we give an
1380          addition of greater constants a cost of 3 (reload1.c 10096).  */
1381       /* ??? saveable_obstack no longer exists.  */
1382       if (outer_code == PLUS
1383           && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1384         *total = COSTS_N_INSNS (3);
1385       else
1386         *total = 0;
1387       return true;
1388
1389     case LABEL_REF:
1390     case SYMBOL_REF:
1391     case CONST_DOUBLE:
1392       *total = 0;
1393       return true;
1394
1395     case ASHIFT:
1396     case ASHIFTRT:
1397     case LSHIFTRT:
1398     case PLUS:
1399     case AND:
1400     case IOR:
1401     case XOR:
1402     case MINUS:
1403     case NEG:
1404     case NOT:
1405       *total = COSTS_N_INSNS (1);
1406       return true;
1407
1408     case MULT:
1409       if (GET_MODE (XEXP (x, 0)) == DImode)
1410         *total = COSTS_N_INSNS (40);
1411       else
1412         *total = COSTS_N_INSNS (7);
1413       return true;
1414
1415     case DIV:
1416     case UDIV:
1417     case MOD:
1418     case UMOD:
1419       *total = COSTS_N_INSNS (33);
1420       return true;
1421
1422     default:
1423       return false;
1424     }
1425 }
1426
1427 /* Return the cost of an address rtx ADDR.  */
1428
1429 static int
1430 s390_address_cost (addr)
1431      rtx addr;
1432 {
1433   struct s390_address ad;
1434   if (!s390_decompose_address (addr, &ad))
1435     return 1000;
1436
1437   return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1438 }
1439
1440 /* Return true if OP is a valid operand for the BRAS instruction.
1441    OP is the current operation.
1442    MODE is the current operation mode.  */
1443
1444 int
1445 bras_sym_operand (op, mode)
1446      register rtx op;
1447      enum machine_mode mode ATTRIBUTE_UNUSED;
1448 {
1449   register enum rtx_code code = GET_CODE (op);
1450
1451   /* Allow SYMBOL_REFs.  */
1452   if (code == SYMBOL_REF)
1453     return 1;
1454
1455   /* Allow @PLT stubs.  */
1456   if (code == CONST
1457       && GET_CODE (XEXP (op, 0)) == UNSPEC
1458       && XINT (XEXP (op, 0), 1) == 113)
1459     return 1;
1460   return 0;
1461 }
1462
1463 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1464    otherwise return 0.  */
1465
1466 int
1467 tls_symbolic_operand (op)
1468      register rtx op;
1469 {
1470   if (GET_CODE (op) != SYMBOL_REF)
1471     return 0;
1472   return SYMBOL_REF_TLS_MODEL (op);
1473 }
1474 \f
1475 /* Return true if OP is a load multiple operation.  It is known to be a
1476    PARALLEL and the first section will be tested. 
1477    OP is the current operation.
1478    MODE is the current operation mode.  */
1479
1480 int
1481 load_multiple_operation (op, mode)
1482      rtx op;
1483      enum machine_mode mode ATTRIBUTE_UNUSED;
1484 {
1485   int count = XVECLEN (op, 0);
1486   unsigned int dest_regno;
1487   rtx src_addr;
1488   int i, off;
1489
1490
1491   /* Perform a quick check so we don't blow up below.  */
1492   if (count <= 1
1493       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1494       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1495       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1496     return 0;
1497
1498   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1499   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1500
1501   /* Check, is base, or base + displacement.  */
1502
1503   if (GET_CODE (src_addr) == REG)
1504     off = 0;
1505   else if (GET_CODE (src_addr) == PLUS
1506            && GET_CODE (XEXP (src_addr, 0)) == REG 
1507            && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1508     {
1509       off = INTVAL (XEXP (src_addr, 1));
1510       src_addr = XEXP (src_addr, 0);
1511     }
1512   else
1513     return 0;
1514
1515   if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
1516     return 0;
1517
1518   for (i = 1; i < count; i++)
1519     {
1520       rtx elt = XVECEXP (op, 0, i);
1521
1522       if (GET_CODE (elt) != SET
1523           || GET_CODE (SET_DEST (elt)) != REG
1524           || GET_MODE (SET_DEST (elt)) != Pmode
1525           || REGNO (SET_DEST (elt)) != dest_regno + i
1526           || GET_CODE (SET_SRC (elt)) != MEM
1527           || GET_MODE (SET_SRC (elt)) != Pmode
1528           || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1529           || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1530           || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1531           || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1532              != off + i * UNITS_PER_WORD)
1533         return 0;
1534     }
1535
1536   return 1;
1537 }
1538
1539 /* Return true if OP is a store multiple operation.  It is known to be a
1540    PARALLEL and the first section will be tested. 
1541    OP is the current operation.
1542    MODE is the current operation mode.  */
1543
1544 int
1545 store_multiple_operation (op, mode)
1546      rtx op;
1547      enum machine_mode mode ATTRIBUTE_UNUSED;
1548 {
1549   int count = XVECLEN (op, 0);
1550   unsigned int src_regno;
1551   rtx dest_addr;
1552   int i, off;
1553
1554   /* Perform a quick check so we don't blow up below.  */
1555   if (count <= 1
1556       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1557       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1558       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1559     return 0;
1560
1561   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1562   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1563
1564   /* Check, is base, or base + displacement.  */
1565
1566   if (GET_CODE (dest_addr) == REG)
1567     off = 0;
1568   else if (GET_CODE (dest_addr) == PLUS
1569            && GET_CODE (XEXP (dest_addr, 0)) == REG 
1570            && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1571     {
1572       off = INTVAL (XEXP (dest_addr, 1));
1573       dest_addr = XEXP (dest_addr, 0);
1574     }
1575   else
1576     return 0;
1577
1578   if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
1579     return 0;
1580
1581   for (i = 1; i < count; i++)
1582     {
1583       rtx elt = XVECEXP (op, 0, i);
1584
1585       if (GET_CODE (elt) != SET
1586           || GET_CODE (SET_SRC (elt)) != REG
1587           || GET_MODE (SET_SRC (elt)) != Pmode
1588           || REGNO (SET_SRC (elt)) != src_regno + i
1589           || GET_CODE (SET_DEST (elt)) != MEM
1590           || GET_MODE (SET_DEST (elt)) != Pmode
1591           || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1592           || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1593           || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1594           || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1595              != off + i * UNITS_PER_WORD)
1596         return 0;
1597     }
1598   return 1;
1599 }
1600
1601
1602 /* Return true if OP contains a symbol reference */
1603
1604 int
1605 symbolic_reference_mentioned_p (op)
1606      rtx op;
1607 {
1608   register const char *fmt;
1609   register int i;
1610
1611   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1612     return 1;
1613
1614   fmt = GET_RTX_FORMAT (GET_CODE (op));
1615   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1616     {
1617       if (fmt[i] == 'E')
1618         {
1619           register int j;
1620
1621           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1622             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1623               return 1;
1624         }
1625
1626       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1627         return 1;
1628     }
1629
1630   return 0;
1631 }
1632
1633 /* Return true if OP contains a reference to a thread-local symbol.  */
1634
1635 int
1636 tls_symbolic_reference_mentioned_p (op)
1637      rtx op;
1638 {
1639   register const char *fmt;
1640   register int i;
1641
1642   if (GET_CODE (op) == SYMBOL_REF)
1643     return tls_symbolic_operand (op);
1644
1645   fmt = GET_RTX_FORMAT (GET_CODE (op));
1646   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1647     {
1648       if (fmt[i] == 'E')
1649         {
1650           register int j;
1651
1652           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1653             if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1654               return 1;
1655         }
1656
1657       else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1658         return 1;
1659     }
1660
1661   return 0;
1662 }
1663
1664
1665 /* Return true if OP is a legitimate general operand when 
1666    generating PIC code.  It is given that flag_pic is on 
1667    and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1668
1669 int
1670 legitimate_pic_operand_p (op)
1671      register rtx op;
1672 {
1673   /* Accept all non-symbolic constants.  */
1674   if (!SYMBOLIC_CONST (op))
1675     return 1;
1676
1677   /* Reject everything else; must be handled 
1678      via emit_symbolic_move.  */
1679   return 0;
1680 }
1681
1682 /* Returns true if the constant value OP is a legitimate general operand.
1683    It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1684
1685 int
1686 legitimate_constant_p (op)
1687      register rtx op;
1688 {
1689   /* Accept all non-symbolic constants.  */
1690   if (!SYMBOLIC_CONST (op))
1691     return 1;
1692
1693   /* Accept immediate LARL operands.  */
1694   if (TARGET_64BIT && larl_operand (op, VOIDmode))
1695     return 1;
1696
1697   /* Thread-local symbols are never legal constants.  This is
1698      so that emit_call knows that computing such addresses
1699      might require a function call.  */
1700   if (TLS_SYMBOLIC_CONST (op))
1701     return 0;
1702
1703   /* In the PIC case, symbolic constants must *not* be
1704      forced into the literal pool.  We accept them here,
1705      so that they will be handled by emit_symbolic_move.  */
1706   if (flag_pic)
1707     return 1;
1708
1709   /* All remaining non-PIC symbolic constants are
1710      forced into the literal pool.  */
1711   return 0;
1712 }
1713
1714 /* Determine if it's legal to put X into the constant pool.  This
1715    is not possible if X contains the address of a symbol that is
1716    not constant (TLS) or not known at final link time (PIC).  */
1717
1718 static bool
1719 s390_cannot_force_const_mem (x)
1720      rtx x;
1721 {
1722   switch (GET_CODE (x))
1723     {
1724     case CONST_INT:
1725     case CONST_DOUBLE:
1726       /* Accept all non-symbolic constants.  */
1727       return false;
1728
1729     case LABEL_REF:
1730       /* Labels are OK iff we are non-PIC.  */
1731       return flag_pic != 0;
1732
1733     case SYMBOL_REF:
1734       /* 'Naked' TLS symbol references are never OK,
1735          non-TLS symbols are OK iff we are non-PIC.  */
1736       if (tls_symbolic_operand (x))
1737         return true;
1738       else
1739         return flag_pic != 0;
1740
1741     case CONST:
1742       return s390_cannot_force_const_mem (XEXP (x, 0));
1743     case PLUS:
1744     case MINUS:
1745       return s390_cannot_force_const_mem (XEXP (x, 0))
1746              || s390_cannot_force_const_mem (XEXP (x, 1));
1747
1748     case UNSPEC:
1749       switch (XINT (x, 1))
1750         {
1751         /* Only lt-relative or GOT-relative UNSPECs are OK.  */
1752         case 100:
1753         case 104:
1754         case 112:
1755         case 114:
1756         case UNSPEC_TLSGD:
1757         case UNSPEC_TLSLDM:
1758         case UNSPEC_NTPOFF:
1759         case UNSPEC_DTPOFF:
1760         case UNSPEC_GOTNTPOFF:
1761         case UNSPEC_INDNTPOFF:
1762           return false;
1763
1764         default:
1765           return true;
1766         }
1767       break;
1768
1769     default:
1770       abort ();
1771     }
1772 }
1773
1774 /* Returns true if the constant value OP is a legitimate general
1775    operand during and after reload.  The difference to 
1776    legitimate_constant_p is that this function will not accept
1777    a constant that would need to be forced to the literal pool
1778    before it can be used as operand.  */
1779
1780 int
1781 legitimate_reload_constant_p (op)
1782      register rtx op;
1783 {
1784   /* Accept la(y) operands.  */
1785   if (GET_CODE (op) == CONST_INT 
1786       && DISP_IN_RANGE (INTVAL (op)))
1787     return 1;
1788
1789   /* Accept l(g)hi operands.  */
1790   if (GET_CODE (op) == CONST_INT
1791       && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
1792     return 1;
1793
1794   /* Accept lliXX operands.  */
1795   if (TARGET_64BIT
1796       && s390_single_hi (op, DImode, 0) >= 0)
1797   return 1;
1798
1799   /* Accept larl operands.  */
1800   if (TARGET_64BIT
1801       && larl_operand (op, VOIDmode))
1802     return 1;
1803
1804   /* Everything else cannot be handled without reload.  */
1805   return 0;
1806 }
1807
1808 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1809    return the class of reg to actually use.  */
1810
1811 enum reg_class
1812 s390_preferred_reload_class (op, class)
1813      rtx op;
1814      enum reg_class class;
1815 {
1816   /* This can happen if a floating point constant is being
1817      reloaded into an integer register.  Leave well alone.  */
1818   if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1819       && class != FP_REGS)
1820     return class;
1821
1822   switch (GET_CODE (op))
1823     {
1824       /* Constants we cannot reload must be forced into the
1825          literal pool.  */
1826
1827       case CONST_DOUBLE:
1828       case CONST_INT:
1829         if (legitimate_reload_constant_p (op))
1830           return class;
1831         else
1832           return NO_REGS;
1833
1834       /* If a symbolic constant or a PLUS is reloaded,
1835          it is most likely being used as an address, so
1836          prefer ADDR_REGS.  If 'class' is not a superset
1837          of ADDR_REGS, e.g. FP_REGS, reject this reload.  */
1838       case PLUS:
1839       case LABEL_REF:
1840       case SYMBOL_REF:
1841       case CONST:
1842         if (reg_class_subset_p (ADDR_REGS, class))
1843           return ADDR_REGS;
1844         else
1845           return NO_REGS;
1846
1847       default:
1848         break;
1849     }
1850
1851   return class;
1852 }
1853
1854 /* Return the register class of a scratch register needed to
1855    load IN into a register of class CLASS in MODE.
1856
1857    We need a temporary when loading a PLUS expression which
1858    is not a legitimate operand of the LOAD ADDRESS instruction.  */
1859
1860 enum reg_class
1861 s390_secondary_input_reload_class (class, mode, in)
1862      enum reg_class class ATTRIBUTE_UNUSED;
1863      enum machine_mode mode;
1864      rtx in;
1865 {
1866   if (s390_plus_operand (in, mode))
1867     return ADDR_REGS;
1868
1869   return NO_REGS;
1870 }
1871
1872 /* Return the register class of a scratch register needed to
1873    store a register of class CLASS in MODE into OUT:
1874
1875    We need a temporary when storing a double-word to a 
1876    non-offsettable memory address.  */
1877
1878 enum reg_class
1879 s390_secondary_output_reload_class (class, mode, out)
1880      enum reg_class class;
1881      enum machine_mode mode;
1882      rtx out;
1883 {
1884   if ((TARGET_64BIT ? mode == TImode
1885                     : (mode == DImode || mode == DFmode))
1886       && reg_classes_intersect_p (GENERAL_REGS, class)
1887       && GET_CODE (out) == MEM
1888       && !offsettable_memref_p (out)
1889       && !s_operand (out, VOIDmode))
1890     return ADDR_REGS;
1891
1892   return NO_REGS;
1893 }
1894
1895 /* Return true if OP is a PLUS that is not a legitimate
1896    operand for the LA instruction. 
1897    OP is the current operation.
1898    MODE is the current operation mode.  */
1899
1900 int
1901 s390_plus_operand (op, mode)
1902      register rtx op;
1903      enum machine_mode mode;
1904 {
1905   if (!check_mode (op, &mode) || mode != Pmode)
1906     return FALSE;
1907
1908   if (GET_CODE (op) != PLUS)
1909     return FALSE;
1910
1911   if (legitimate_la_operand_p (op))
1912     return FALSE;
1913
1914   return TRUE;
1915 }
1916
1917 /* Generate code to load SRC, which is PLUS that is not a
1918    legitimate operand for the LA instruction, into TARGET.
1919    SCRATCH may be used as scratch register.  */
1920
1921 void
1922 s390_expand_plus_operand (target, src, scratch)
1923      register rtx target;
1924      register rtx src;
1925      register rtx scratch;
1926 {
1927   rtx sum1, sum2;
1928   struct s390_address ad;
1929
1930   /* src must be a PLUS; get its two operands.  */
1931   if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
1932     abort ();
1933
1934   /* Check if any of the two operands is already scheduled
1935      for replacement by reload.  This can happen e.g. when
1936      float registers occur in an address.  */
1937   sum1 = find_replacement (&XEXP (src, 0));
1938   sum2 = find_replacement (&XEXP (src, 1));
1939   src = gen_rtx_PLUS (Pmode, sum1, sum2);
1940
1941   /* If the address is already strictly valid, there's nothing to do.  */
1942   if (!s390_decompose_address (src, &ad)
1943       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1944       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
1945     {
1946       /* Otherwise, one of the operands cannot be an address register;
1947          we reload its value into the scratch register.  */
1948       if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
1949         {
1950           emit_move_insn (scratch, sum1);
1951           sum1 = scratch;
1952         }
1953       if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
1954         {
1955           emit_move_insn (scratch, sum2);
1956           sum2 = scratch;
1957         }
1958
1959       /* According to the way these invalid addresses are generated
1960          in reload.c, it should never happen (at least on s390) that
1961          *neither* of the PLUS components, after find_replacements
1962          was applied, is an address register.  */
1963       if (sum1 == scratch && sum2 == scratch)
1964         {
1965           debug_rtx (src);
1966           abort ();
1967         }
1968
1969       src = gen_rtx_PLUS (Pmode, sum1, sum2);
1970     }
1971
1972   /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
1973      is only ever performed on addresses, so we can mark the
1974      sum as legitimate for LA in any case.  */
1975   s390_load_address (target, src);
1976 }
1977
1978
1979 /* Decompose a RTL expression ADDR for a memory address into
1980    its components, returned in OUT.
1981
1982    Returns 0 if ADDR is not a valid memory address, nonzero
1983    otherwise.  If OUT is NULL, don't return the components,
1984    but check for validity only.
1985
1986    Note: Only addresses in canonical form are recognized.
1987    LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1988    canonical form so that they will be recognized.  */
1989
1990 static int
1991 s390_decompose_address (addr, out)
1992      register rtx addr;
1993      struct s390_address *out;
1994 {
1995   rtx base = NULL_RTX;
1996   rtx indx = NULL_RTX;
1997   rtx disp = NULL_RTX;
1998   int pointer = FALSE;
1999
2000   /* Decompose address into base + index + displacement.  */
2001
2002   if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2003     base = addr;
2004
2005   else if (GET_CODE (addr) == PLUS)
2006     {
2007       rtx op0 = XEXP (addr, 0);
2008       rtx op1 = XEXP (addr, 1);
2009       enum rtx_code code0 = GET_CODE (op0);
2010       enum rtx_code code1 = GET_CODE (op1);
2011
2012       if (code0 == REG || code0 == UNSPEC)
2013         {
2014           if (code1 == REG || code1 == UNSPEC)
2015             {
2016               indx = op0;       /* index + base */
2017               base = op1;
2018             }
2019
2020           else
2021             {
2022               base = op0;       /* base + displacement */
2023               disp = op1;
2024             }
2025         }
2026
2027       else if (code0 == PLUS)
2028         {
2029           indx = XEXP (op0, 0); /* index + base + disp */
2030           base = XEXP (op0, 1);
2031           disp = op1;
2032         }
2033
2034       else
2035         {
2036           return FALSE;
2037         }
2038     }
2039
2040   else
2041     disp = addr;                /* displacement */
2042
2043
2044   /* Prefer to use pointer as base, not index.  */
2045   if (base && indx)
2046     {
2047       int base_ptr = GET_CODE (base) == UNSPEC
2048                      || (REG_P (base) && REG_POINTER (base));
2049       int indx_ptr = GET_CODE (indx) == UNSPEC
2050                      || (REG_P (indx) && REG_POINTER (indx));
2051
2052       if (!base_ptr && indx_ptr)
2053         {
2054           rtx tmp = base;
2055           base = indx;
2056           indx = tmp;
2057         }
2058     }
2059
2060   /* Validate base register.  */
2061   if (base)
2062     {
2063       if (GET_CODE (base) == UNSPEC)
2064         {
2065           if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
2066               return FALSE;
2067           base = XVECEXP (base, 0, 0);
2068           pointer = TRUE;
2069         }
2070
2071       if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2072           return FALSE;
2073
2074       if (REGNO (base) == BASE_REGISTER
2075           || REGNO (base) == STACK_POINTER_REGNUM
2076           || REGNO (base) == FRAME_POINTER_REGNUM
2077           || ((reload_completed || reload_in_progress)
2078               && frame_pointer_needed
2079               && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2080           || REGNO (base) == ARG_POINTER_REGNUM
2081           || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
2082               && REGNO (base) <= LAST_VIRTUAL_REGISTER)
2083           || (flag_pic
2084               && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2085         pointer = TRUE;
2086     }
2087
2088   /* Validate index register.  */
2089   if (indx)
2090     {
2091       if (GET_CODE (indx) == UNSPEC)
2092         {
2093           if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
2094               return FALSE;
2095           indx = XVECEXP (indx, 0, 0);
2096           pointer = TRUE;
2097         }
2098
2099       if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2100           return FALSE;
2101
2102       if (REGNO (indx) == BASE_REGISTER
2103           || REGNO (indx) == STACK_POINTER_REGNUM
2104           || REGNO (indx) == FRAME_POINTER_REGNUM
2105           || ((reload_completed || reload_in_progress)
2106               && frame_pointer_needed
2107               && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2108           || REGNO (indx) == ARG_POINTER_REGNUM
2109           || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
2110               && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
2111           || (flag_pic
2112               && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2113         pointer = TRUE;
2114     }
2115
2116   /* Validate displacement.  */
2117   if (disp)
2118     {
2119       /* Allow integer constant in range.  */
2120       if (GET_CODE (disp) == CONST_INT)
2121         {
2122           /* If the argument pointer is involved, the displacement will change
2123              later anyway as the argument pointer gets eliminated.  This could
2124              make a valid displacement invalid, but it is more likely to make
2125              an invalid displacement valid, because we sometimes access the
2126              register save area via negative offsets to the arg pointer.
2127              Thus we don't check the displacement for validity here.  If after
2128              elimination the displacement turns out to be invalid after all,
2129              this is fixed up by reload in any case.  */
2130           if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
2131             {
2132               if (!DISP_IN_RANGE (INTVAL (disp)))
2133                 return FALSE;
2134             }
2135         }
2136
2137       /* In the small-PIC case, the linker converts @GOT12 
2138          and @GOTNTPOFF offsets to possible displacements.  */
2139       else if (GET_CODE (disp) == CONST
2140                && GET_CODE (XEXP (disp, 0)) == UNSPEC
2141                && (XINT (XEXP (disp, 0), 1) == 110
2142                    || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
2143         {
2144           if (flag_pic != 1)
2145             return FALSE;
2146
2147           pointer = TRUE;
2148         }
2149
2150       /* Accept chunkfied literal pool symbol references.  */
2151       else if (GET_CODE (disp) == CONST
2152                && GET_CODE (XEXP (disp, 0)) == MINUS
2153                && GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF
2154                && GET_CODE (XEXP (XEXP (disp, 0), 1)) == LABEL_REF)
2155         {
2156           pointer = TRUE;
2157         }
2158  
2159       /* Likewise if a constant offset is present.  */
2160       else if (GET_CODE (disp) == CONST
2161                && GET_CODE (XEXP (disp, 0)) == PLUS
2162                && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
2163                && GET_CODE (XEXP (XEXP (disp, 0), 0)) == MINUS
2164                && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 0)) == LABEL_REF
2165                && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 1)) == LABEL_REF)
2166         {
2167           pointer = TRUE;
2168         }
2169
2170       /* We can convert literal pool addresses to 
2171          displacements by basing them off the base register.  */
2172       else
2173         {
2174           /* In some cases, we can accept an additional
2175              small constant offset.  Split these off here.  */
2176
2177           unsigned int offset = 0;
2178
2179           if (GET_CODE (disp) == CONST
2180               && GET_CODE (XEXP (disp, 0)) == PLUS
2181               && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2182             {
2183               offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2184               disp = XEXP (XEXP (disp, 0), 0);
2185             }
2186
2187           /* Now we must have a literal pool address.  */
2188           if (GET_CODE (disp) != SYMBOL_REF
2189               || !CONSTANT_POOL_ADDRESS_P (disp))
2190             return FALSE;
2191
2192           /* If we have an offset, make sure it does not
2193              exceed the size of the constant pool entry.  */
2194           if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
2195             return FALSE;
2196
2197           /* Either base or index must be free to 
2198              hold the base register.  */
2199           if (base && indx)
2200             return FALSE;
2201
2202           /* Convert the address.  */
2203           if (base)
2204             indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2205           else
2206             base = gen_rtx_REG (Pmode, BASE_REGISTER);
2207
2208           disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
2209           disp = gen_rtx_CONST (Pmode, disp);
2210
2211           if (offset)
2212             disp = plus_constant (disp, offset);
2213
2214           pointer = TRUE;
2215         }
2216     }
2217
2218   if (!base && !indx)
2219     pointer = TRUE;
2220    
2221   if (out)
2222     {
2223       out->base = base;
2224       out->indx = indx;
2225       out->disp = disp;
2226       out->pointer = pointer;
2227     }
2228
2229   return TRUE;
2230 }
2231
2232 /* Return nonzero if ADDR is a valid memory address.
2233    STRICT specifies whether strict register checking applies.  */
2234
2235 int
2236 legitimate_address_p (mode, addr, strict)
2237      enum machine_mode mode ATTRIBUTE_UNUSED;
2238      register rtx addr;
2239      int strict;
2240 {
2241   struct s390_address ad;
2242   if (!s390_decompose_address (addr, &ad))
2243     return FALSE;
2244
2245   if (strict)
2246     {
2247       if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2248         return FALSE;
2249       if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2250         return FALSE;
2251     }
2252   else
2253     {
2254       if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2255         return FALSE;
2256       if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2257         return FALSE;
2258     }
2259
2260   return TRUE;
2261 }
2262
2263 /* Return 1 if OP is a valid operand for the LA instruction.
2264    In 31-bit, we need to prove that the result is used as an
2265    address, as LA performs only a 31-bit addition.  */
2266
2267 int
2268 legitimate_la_operand_p (op)
2269      register rtx op;
2270 {
2271   struct s390_address addr;
2272   if (!s390_decompose_address (op, &addr))
2273     return FALSE;
2274
2275   if (TARGET_64BIT || addr.pointer)
2276     return TRUE;
2277
2278   return FALSE;
2279 }
2280
2281 /* Return 1 if OP is a valid operand for the LA instruction,
2282    and we prefer to use LA over addition to compute it.  */
2283    
2284 int
2285 preferred_la_operand_p (op)
2286      register rtx op;
2287 {
2288   struct s390_address addr;
2289   if (!s390_decompose_address (op, &addr))
2290     return FALSE;
2291
2292   if (!TARGET_64BIT && !addr.pointer)
2293     return FALSE;
2294
2295   if (addr.pointer)
2296     return TRUE;
2297
2298   if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2299       || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2300     return TRUE;
2301
2302   return FALSE;
2303 }
2304
2305 /* Emit a forced load-address operation to load SRC into DST.
2306    This will use the LOAD ADDRESS instruction even in situations
2307    where legitimate_la_operand_p (SRC) returns false.  */
2308
2309 void
2310 s390_load_address (dst, src)
2311      rtx dst;
2312      rtx src;
2313 {
2314   if (TARGET_64BIT)
2315     emit_move_insn (dst, src);
2316   else
2317     emit_insn (gen_force_la_31 (dst, src));
2318 }
2319
2320 /* Return a legitimate reference for ORIG (an address) using the
2321    register REG.  If REG is 0, a new pseudo is generated.
2322
2323    There are two types of references that must be handled:
2324
2325    1. Global data references must load the address from the GOT, via
2326       the PIC reg.  An insn is emitted to do this load, and the reg is
2327       returned.
2328
2329    2. Static data references, constant pool addresses, and code labels
2330       compute the address as an offset from the GOT, whose base is in
2331       the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
2332       differentiate them from global data objects.  The returned
2333       address is the PIC reg + an unspec constant.
2334
2335    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2336    reg also appears in the address.  */
2337
2338 rtx
2339 legitimize_pic_address (orig, reg)
2340      rtx orig;
2341      rtx reg;
2342 {
2343   rtx addr = orig;
2344   rtx new = orig;
2345   rtx base;
2346
2347   if (GET_CODE (addr) == LABEL_REF
2348       || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2349     {
2350       /* This is a local symbol.  */
2351       if (TARGET_64BIT && larl_operand (addr, VOIDmode))
2352         {
2353           /* Access local symbols PC-relative via LARL.  
2354              This is the same as in the non-PIC case, so it is 
2355              handled automatically ...  */
2356         }
2357       else
2358         {
2359           /* Access local symbols relative to the literal pool.  */
2360
2361           rtx temp = reg? reg : gen_reg_rtx (Pmode);
2362
2363           addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 100);
2364           addr = gen_rtx_CONST (Pmode, addr);
2365           addr = force_const_mem (Pmode, addr);
2366           emit_move_insn (temp, addr);
2367
2368           base = gen_rtx_REG (Pmode, BASE_REGISTER);
2369           base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
2370           new = gen_rtx_PLUS (Pmode, base, temp);
2371
2372           if (reg != 0)
2373             {
2374               emit_move_insn (reg, new);
2375               new = reg;
2376             }
2377         }
2378     }
2379   else if (GET_CODE (addr) == SYMBOL_REF)
2380     {
2381       if (reg == 0)
2382         reg = gen_reg_rtx (Pmode);
2383
2384       if (flag_pic == 1)
2385         {
2386           /* Assume GOT offset < 4k.  This is handled the same way
2387              in both 31- and 64-bit code (@GOT12).  */
2388
2389           if (reload_in_progress || reload_completed)
2390             regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2391
2392           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
2393           new = gen_rtx_CONST (Pmode, new);
2394           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2395           new = gen_rtx_MEM (Pmode, new);
2396           RTX_UNCHANGING_P (new) = 1;
2397           emit_move_insn (reg, new);
2398           new = reg;
2399         }
2400       else if (TARGET_64BIT)
2401         {
2402           /* If the GOT offset might be >= 4k, we determine the position
2403              of the GOT entry via a PC-relative LARL (@GOTENT).  */
2404
2405           rtx temp = gen_reg_rtx (Pmode);
2406
2407           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
2408           new = gen_rtx_CONST (Pmode, new);
2409           emit_move_insn (temp, new);
2410
2411           new = gen_rtx_MEM (Pmode, temp);
2412           RTX_UNCHANGING_P (new) = 1;
2413           emit_move_insn (reg, new);
2414           new = reg;
2415         }
2416       else
2417         {
2418           /* If the GOT offset might be >= 4k, we have to load it 
2419              from the literal pool (@GOT).  */
2420
2421           rtx temp = gen_reg_rtx (Pmode);
2422
2423           if (reload_in_progress || reload_completed)
2424             regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2425
2426           addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 112);
2427           addr = gen_rtx_CONST (Pmode, addr);
2428           addr = force_const_mem (Pmode, addr);
2429           emit_move_insn (temp, addr);
2430
2431           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2432           new = gen_rtx_MEM (Pmode, new);
2433           RTX_UNCHANGING_P (new) = 1;
2434           emit_move_insn (reg, new);
2435           new = reg;
2436         }
2437     }      
2438   else
2439     {
2440       if (GET_CODE (addr) == CONST)
2441         {
2442           addr = XEXP (addr, 0);
2443           if (GET_CODE (addr) == UNSPEC)
2444             {
2445               if (XVECLEN (addr, 0) != 1)
2446                 abort ();
2447               switch (XINT (addr, 1))
2448                 {
2449                   /* If someone moved an @GOT or lt-relative UNSPEC
2450                      out of the literal pool, force them back in.  */
2451                   case 100:
2452                   case 112:
2453                   case 114:
2454                     new = force_const_mem (Pmode, orig);
2455                     break;
2456
2457                   /* @GOTENT is OK as is.  */
2458                   case 111:
2459                     break;
2460
2461                   /* @PLT is OK as is on 64-bit, must be converted to
2462                      lt-relative PLT on 31-bit.  */
2463                   case 113:
2464                     if (!TARGET_64BIT)
2465                       {
2466                         rtx temp = reg? reg : gen_reg_rtx (Pmode);
2467
2468                         addr = XVECEXP (addr, 0, 0);
2469                         addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 114);
2470                         addr = gen_rtx_CONST (Pmode, addr);
2471                         addr = force_const_mem (Pmode, addr);
2472                         emit_move_insn (temp, addr);
2473
2474                         base = gen_rtx_REG (Pmode, BASE_REGISTER);
2475                         base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
2476                         new = gen_rtx_PLUS (Pmode, base, temp);
2477
2478                         if (reg != 0)
2479                           {
2480                             emit_move_insn (reg, new);
2481                             new = reg;
2482                           }
2483                       }
2484                     break;
2485
2486                   /* Everything else cannot happen.  */
2487                   default:
2488                     abort ();
2489                 }
2490             }
2491           else if (GET_CODE (addr) != PLUS)
2492             abort ();
2493         }
2494       if (GET_CODE (addr) == PLUS)
2495         {
2496           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2497           /* Check first to see if this is a constant offset 
2498              from a local symbol reference.  */
2499           if ((GET_CODE (op0) == LABEL_REF
2500                 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2501               && GET_CODE (op1) == CONST_INT)
2502             {
2503               if (TARGET_64BIT && larl_operand (op0, VOIDmode))
2504                 {
2505                   if (INTVAL (op1) & 1)
2506                     {
2507                       /* LARL can't handle odd offsets, so emit a 
2508                          pair of LARL and LA.  */
2509                       rtx temp = reg? reg : gen_reg_rtx (Pmode);
2510
2511                       if (!DISP_IN_RANGE (INTVAL (op1)))
2512                         {
2513                           int even = INTVAL (op1) - 1;
2514                           op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2515                           op0 = gen_rtx_CONST (Pmode, op0);
2516                           op1 = GEN_INT (1);
2517                         }
2518
2519                       emit_move_insn (temp, op0);
2520                       new = gen_rtx_PLUS (Pmode, temp, op1);
2521
2522                       if (reg != 0)
2523                         {
2524                           emit_move_insn (reg, new);
2525                           new = reg;
2526                         }
2527                     }
2528                   else
2529                     {
2530                       /* If the offset is even, we can just use LARL.
2531                          This will happen automatically.  */
2532                     }
2533                 }
2534               else
2535                 {
2536                   /* Access local symbols relative to the literal pool.  */
2537
2538                   rtx temp = reg? reg : gen_reg_rtx (Pmode);
2539
2540                   addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 100);
2541                   addr = gen_rtx_PLUS (Pmode, addr, op1);
2542                   addr = gen_rtx_CONST (Pmode, addr);
2543                   addr = force_const_mem (Pmode, addr);
2544                   emit_move_insn (temp, addr);
2545
2546                   base = gen_rtx_REG (Pmode, BASE_REGISTER);
2547                   base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
2548                   new = gen_rtx_PLUS (Pmode, base, temp);
2549
2550                   if (reg != 0)
2551                     {
2552                       emit_move_insn (reg, new);
2553                       new = reg;
2554                     }
2555                 }
2556             }
2557
2558           /* Now, check whether it is an LT-relative symbol plus offset
2559              that was pulled out of the literal pool.  Force it back in.  */
2560
2561           else if (GET_CODE (op0) == UNSPEC
2562                    && GET_CODE (op1) == CONST_INT)
2563             {
2564               if (XVECLEN (op0, 0) != 1)
2565                 abort ();
2566               if (XINT (op0, 1) != 100)
2567                 abort ();
2568
2569               new = force_const_mem (Pmode, orig);
2570             }
2571
2572           /* Otherwise, compute the sum.  */
2573           else
2574             {
2575               base = legitimize_pic_address (XEXP (addr, 0), reg);
2576               new  = legitimize_pic_address (XEXP (addr, 1),
2577                                              base == reg ? NULL_RTX : reg);
2578               if (GET_CODE (new) == CONST_INT)
2579                 new = plus_constant (base, INTVAL (new));
2580               else
2581                 {
2582                   if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2583                     {
2584                       base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2585                       new = XEXP (new, 1);
2586                     }
2587                   new = gen_rtx_PLUS (Pmode, base, new);
2588                 }
2589
2590               if (GET_CODE (new) == CONST)
2591                 new = XEXP (new, 0);
2592               new = force_operand (new, 0);
2593             }
2594         }
2595     }
2596   return new;
2597 }
2598
2599 /* Load the thread pointer into a register.  */
2600
2601 static rtx
2602 get_thread_pointer ()
2603 {
2604   rtx tp;
2605
2606   tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2607   tp = force_reg (Pmode, tp);
2608   mark_reg_pointer (tp, BITS_PER_WORD);
2609
2610   return tp;
2611 }
2612
2613 /* Construct the SYMBOL_REF for the tls_get_offset function.  */
2614
2615 static GTY(()) rtx s390_tls_symbol;
2616 rtx
2617 s390_tls_get_offset ()
2618 {
2619   if (!s390_tls_symbol)
2620     s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2621
2622   return s390_tls_symbol;
2623 }
2624
2625 /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
2626    this (thread-local) address.  REG may be used as temporary.  */
2627
2628 static rtx
2629 legitimize_tls_address (addr, reg)
2630      rtx addr;
2631      rtx reg;
2632 {
2633   rtx new, tls_call, temp, base, r2, insn;
2634
2635   if (GET_CODE (addr) == SYMBOL_REF)
2636     switch (tls_symbolic_operand (addr))
2637       {
2638       case TLS_MODEL_GLOBAL_DYNAMIC:
2639         start_sequence ();
2640         r2 = gen_rtx_REG (Pmode, 2);
2641         tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2642         new = gen_rtx_CONST (Pmode, tls_call);
2643         new = force_const_mem (Pmode, new);
2644         emit_move_insn (r2, new);
2645         emit_call_insn (gen_call_value_tls (r2, tls_call));
2646         insn = get_insns ();
2647         end_sequence ();
2648
2649         new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2650         temp = gen_reg_rtx (Pmode);
2651         emit_libcall_block (insn, temp, r2, new);
2652
2653         new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2654         if (reg != 0)
2655           {
2656             s390_load_address (reg, new);
2657             new = reg;
2658           }
2659         break;
2660
2661       case TLS_MODEL_LOCAL_DYNAMIC:
2662         start_sequence ();
2663         r2 = gen_rtx_REG (Pmode, 2);
2664         tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2665         new = gen_rtx_CONST (Pmode, tls_call);
2666         new = force_const_mem (Pmode, new);
2667         emit_move_insn (r2, new);
2668         emit_call_insn (gen_call_value_tls (r2, tls_call));
2669         insn = get_insns ();
2670         end_sequence ();
2671
2672         new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2673         temp = gen_reg_rtx (Pmode);
2674         emit_libcall_block (insn, temp, r2, new);
2675
2676         new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2677         base = gen_reg_rtx (Pmode);
2678         s390_load_address (base, new);
2679
2680         new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2681         new = gen_rtx_CONST (Pmode, new);
2682         new = force_const_mem (Pmode, new);
2683         temp = gen_reg_rtx (Pmode);
2684         emit_move_insn (temp, new);
2685
2686         new = gen_rtx_PLUS (Pmode, base, temp);
2687         if (reg != 0)
2688           {
2689             s390_load_address (reg, new);
2690             new = reg;
2691           }
2692         break;
2693
2694       case TLS_MODEL_INITIAL_EXEC:
2695         if (flag_pic == 1)
2696           {
2697             /* Assume GOT offset < 4k.  This is handled the same way
2698                in both 31- and 64-bit code.  */
2699
2700             if (reload_in_progress || reload_completed)
2701               regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2702
2703             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2704             new = gen_rtx_CONST (Pmode, new);
2705             new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2706             new = gen_rtx_MEM (Pmode, new);
2707             RTX_UNCHANGING_P (new) = 1;
2708             temp = gen_reg_rtx (Pmode);
2709             emit_move_insn (temp, new);
2710           }
2711         else if (TARGET_64BIT)
2712           {
2713             /* If the GOT offset might be >= 4k, we determine the position
2714                of the GOT entry via a PC-relative LARL.  */
2715
2716             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2717             new = gen_rtx_CONST (Pmode, new);
2718             temp = gen_reg_rtx (Pmode);
2719             emit_move_insn (temp, new);
2720
2721             new = gen_rtx_MEM (Pmode, temp);
2722             RTX_UNCHANGING_P (new) = 1;
2723             temp = gen_reg_rtx (Pmode);
2724             emit_move_insn (temp, new);
2725           }
2726         else if (flag_pic)
2727           {
2728             /* If the GOT offset might be >= 4k, we have to load it 
2729                from the literal pool.  */
2730
2731             if (reload_in_progress || reload_completed)
2732               regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2733
2734             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2735             new = gen_rtx_CONST (Pmode, new);
2736             new = force_const_mem (Pmode, new);
2737             temp = gen_reg_rtx (Pmode);
2738             emit_move_insn (temp, new);
2739
2740             new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2741             new = gen_rtx_MEM (Pmode, new);
2742             RTX_UNCHANGING_P (new) = 1;
2743
2744             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2745             temp = gen_reg_rtx (Pmode);
2746             emit_insn (gen_rtx_SET (Pmode, temp, new));
2747           }
2748         else
2749           {
2750             /* In position-dependent code, load the absolute address of
2751                the GOT entry from the literal pool.  */
2752
2753             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2754             new = gen_rtx_CONST (Pmode, new);
2755             new = force_const_mem (Pmode, new);
2756             temp = gen_reg_rtx (Pmode);
2757             emit_move_insn (temp, new);
2758
2759             new = temp;
2760             new = gen_rtx_MEM (Pmode, new);
2761             RTX_UNCHANGING_P (new) = 1;
2762
2763             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2764             temp = gen_reg_rtx (Pmode);
2765             emit_insn (gen_rtx_SET (Pmode, temp, new));
2766           }
2767
2768         new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2769         if (reg != 0)
2770           {
2771             s390_load_address (reg, new);
2772             new = reg;
2773           }
2774         break;
2775
2776       case TLS_MODEL_LOCAL_EXEC:
2777         new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2778         new = gen_rtx_CONST (Pmode, new);
2779         new = force_const_mem (Pmode, new);
2780         temp = gen_reg_rtx (Pmode);
2781         emit_move_insn (temp, new);
2782
2783         new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2784         if (reg != 0)
2785           {
2786             s390_load_address (reg, new);
2787             new = reg;
2788           }
2789         break;
2790
2791       default:
2792         abort ();
2793       }
2794
2795   else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
2796     {
2797       switch (XINT (XEXP (addr, 0), 1))
2798         {
2799         case UNSPEC_INDNTPOFF:
2800           if (TARGET_64BIT)
2801             new = addr;
2802           else
2803             abort ();
2804           break;
2805
2806         default:
2807           abort ();
2808         }
2809     }
2810
2811   else
2812     abort ();  /* for now ... */
2813
2814   return new;
2815 }
2816
2817 /* Emit insns to move operands[1] into operands[0].  */
2818
2819 void
2820 emit_symbolic_move (operands)
2821      rtx *operands;
2822 {
2823   rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2824
2825   if (GET_CODE (operands[0]) == MEM)
2826     operands[1] = force_reg (Pmode, operands[1]);
2827   else if (TLS_SYMBOLIC_CONST (operands[1]))
2828     operands[1] = legitimize_tls_address (operands[1], temp);
2829   else if (flag_pic)
2830     operands[1] = legitimize_pic_address (operands[1], temp);
2831 }
2832
2833 /* Try machine-dependent ways of modifying an illegitimate address X
2834    to be legitimate.  If we find one, return the new, valid address.
2835
2836    OLDX is the address as it was before break_out_memory_refs was called.
2837    In some cases it is useful to look at this to decide what needs to be done.
2838
2839    MODE is the mode of the operand pointed to by X.
2840
2841    When -fpic is used, special handling is needed for symbolic references.
2842    See comments by legitimize_pic_address for details.  */
2843
2844 rtx
2845 legitimize_address (x, oldx, mode)
2846      register rtx x;
2847      register rtx oldx ATTRIBUTE_UNUSED;
2848      enum machine_mode mode ATTRIBUTE_UNUSED;
2849 {
2850   rtx constant_term = const0_rtx;
2851
2852   if (TLS_SYMBOLIC_CONST (x))
2853     {
2854       x = legitimize_tls_address (x, 0);
2855
2856       if (legitimate_address_p (mode, x, FALSE))
2857         return x;
2858     }
2859   else if (flag_pic)
2860     {
2861       if (SYMBOLIC_CONST (x)
2862           || (GET_CODE (x) == PLUS 
2863               && (SYMBOLIC_CONST (XEXP (x, 0)) 
2864                   || SYMBOLIC_CONST (XEXP (x, 1)))))
2865           x = legitimize_pic_address (x, 0);
2866
2867       if (legitimate_address_p (mode, x, FALSE))
2868         return x;
2869     }
2870
2871   x = eliminate_constant_term (x, &constant_term);
2872
2873   /* Optimize loading of large displacements by splitting them
2874      into the multiple of 4K and the rest; this allows the
2875      former to be CSE'd if possible. 
2876
2877      Don't do this if the displacement is added to a register
2878      pointing into the stack frame, as the offsets will
2879      change later anyway.  */
2880
2881   if (GET_CODE (constant_term) == CONST_INT
2882       && !TARGET_LONG_DISPLACEMENT
2883       && !DISP_IN_RANGE (INTVAL (constant_term))
2884       && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
2885     {
2886       HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
2887       HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
2888
2889       rtx temp = gen_reg_rtx (Pmode);
2890       rtx val  = force_operand (GEN_INT (upper), temp);
2891       if (val != temp)
2892         emit_move_insn (temp, val);
2893
2894       x = gen_rtx_PLUS (Pmode, x, temp);
2895       constant_term = GEN_INT (lower);
2896     }
2897
2898   if (GET_CODE (x) == PLUS)
2899     {
2900       if (GET_CODE (XEXP (x, 0)) == REG)
2901         {
2902           register rtx temp = gen_reg_rtx (Pmode);
2903           register rtx val  = force_operand (XEXP (x, 1), temp);
2904           if (val != temp)
2905             emit_move_insn (temp, val);
2906
2907           x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
2908         }
2909
2910       else if (GET_CODE (XEXP (x, 1)) == REG)
2911         {
2912           register rtx temp = gen_reg_rtx (Pmode);
2913           register rtx val  = force_operand (XEXP (x, 0), temp);
2914           if (val != temp)
2915             emit_move_insn (temp, val);
2916
2917           x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
2918         }
2919     }
2920
2921   if (constant_term != const0_rtx)
2922     x = gen_rtx_PLUS (Pmode, x, constant_term);
2923
2924   return x;
2925 }
2926
2927 /* Emit code to move LEN bytes from DST to SRC.  */
2928
2929 void
2930 s390_expand_movstr (dst, src, len)
2931      rtx dst;
2932      rtx src;
2933      rtx len;
2934 {
2935   rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) = 
2936     TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
2937   rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) = 
2938     TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
2939
2940
2941   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2942     {
2943       if (INTVAL (len) > 0)
2944         emit_insn ((*gen_short) (dst, src, GEN_INT (INTVAL (len) - 1)));
2945     }
2946
2947   else if (TARGET_MVCLE)
2948     {
2949       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2950       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2951       rtx reg0 = gen_reg_rtx (double_mode);
2952       rtx reg1 = gen_reg_rtx (double_mode);
2953
2954       emit_move_insn (gen_highpart (single_mode, reg0), 
2955                       force_operand (XEXP (dst, 0), NULL_RTX));
2956       emit_move_insn (gen_highpart (single_mode, reg1), 
2957                       force_operand (XEXP (src, 0), NULL_RTX));
2958
2959       convert_move (gen_lowpart (single_mode, reg0), len, 1);
2960       convert_move (gen_lowpart (single_mode, reg1), len, 1);
2961
2962       emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
2963     }
2964
2965   else
2966     {
2967       rtx dst_addr, src_addr, count, blocks, temp;
2968       rtx end_label = gen_label_rtx ();
2969       enum machine_mode mode;
2970       tree type;
2971
2972       mode = GET_MODE (len);
2973       if (mode == VOIDmode)
2974         mode = word_mode;
2975
2976       type = (*lang_hooks.types.type_for_mode) (mode, 1);
2977       if (!type)
2978         abort ();
2979
2980       dst_addr = gen_reg_rtx (Pmode);
2981       src_addr = gen_reg_rtx (Pmode);
2982       count = gen_reg_rtx (mode);
2983       blocks = gen_reg_rtx (mode);
2984
2985       convert_move (count, len, 1);
2986       emit_cmp_and_jump_insns (count, const0_rtx, 
2987                                EQ, NULL_RTX, mode, 1, end_label);
2988
2989       emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2990       emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
2991       dst = change_address (dst, VOIDmode, dst_addr);
2992       src = change_address (src, VOIDmode, src_addr);
2993      
2994       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2995       if (temp != count)
2996         emit_move_insn (count, temp);
2997
2998       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2999       if (temp != blocks)
3000         emit_move_insn (blocks, temp);
3001
3002       expand_start_loop (1);
3003       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3004                                            make_tree (type, blocks),
3005                                            make_tree (type, const0_rtx)));
3006
3007       emit_insn ((*gen_short) (dst, src, GEN_INT (255)));
3008       s390_load_address (dst_addr, 
3009                          gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3010       s390_load_address (src_addr, 
3011                          gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3012       
3013       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3014       if (temp != blocks)
3015         emit_move_insn (blocks, temp);
3016
3017       expand_end_loop ();
3018
3019       emit_insn ((*gen_short) (dst, src, convert_to_mode (word_mode, count, 1)));
3020       emit_label (end_label);
3021     }
3022 }
3023
3024 /* Emit code to clear LEN bytes at DST.  */
3025
3026 void
3027 s390_expand_clrstr (dst, len)
3028      rtx dst;
3029      rtx len;
3030 {
3031   rtx (*gen_short) PARAMS ((rtx, rtx)) = 
3032     TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
3033   rtx (*gen_long) PARAMS ((rtx, rtx, rtx)) = 
3034     TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
3035
3036
3037   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3038     {
3039       if (INTVAL (len) > 0)
3040         emit_insn ((*gen_short) (dst, GEN_INT (INTVAL (len) - 1)));
3041     }
3042
3043   else if (TARGET_MVCLE)
3044     {
3045       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
3046       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
3047       rtx reg0 = gen_reg_rtx (double_mode);
3048       rtx reg1 = gen_reg_rtx (double_mode);
3049
3050       emit_move_insn (gen_highpart (single_mode, reg0), 
3051                       force_operand (XEXP (dst, 0), NULL_RTX));
3052       convert_move (gen_lowpart (single_mode, reg0), len, 1);
3053
3054       emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
3055       emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
3056
3057       emit_insn ((*gen_long) (reg0, reg1, reg0));
3058     }
3059
3060   else
3061     {
3062       rtx dst_addr, src_addr, count, blocks, temp;
3063       rtx end_label = gen_label_rtx ();
3064       enum machine_mode mode;
3065       tree type;
3066
3067       mode = GET_MODE (len);
3068       if (mode == VOIDmode)
3069         mode = word_mode;
3070
3071       type = (*lang_hooks.types.type_for_mode) (mode, 1);
3072       if (!type)
3073         abort ();
3074
3075       dst_addr = gen_reg_rtx (Pmode);
3076       src_addr = gen_reg_rtx (Pmode);
3077       count = gen_reg_rtx (mode);
3078       blocks = gen_reg_rtx (mode);
3079
3080       convert_move (count, len, 1);
3081       emit_cmp_and_jump_insns (count, const0_rtx, 
3082                                EQ, NULL_RTX, mode, 1, end_label);
3083
3084       emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3085       dst = change_address (dst, VOIDmode, dst_addr);
3086      
3087       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3088       if (temp != count)
3089         emit_move_insn (count, temp);
3090
3091       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3092       if (temp != blocks)
3093         emit_move_insn (blocks, temp);
3094
3095       expand_start_loop (1);
3096       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3097                                            make_tree (type, blocks),
3098                                            make_tree (type, const0_rtx)));
3099
3100       emit_insn ((*gen_short) (dst, GEN_INT (255)));
3101       s390_load_address (dst_addr, 
3102                          gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3103       
3104       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3105       if (temp != blocks)
3106         emit_move_insn (blocks, temp);
3107
3108       expand_end_loop ();
3109
3110       emit_insn ((*gen_short) (dst, convert_to_mode (word_mode, count, 1)));
3111       emit_label (end_label);
3112     }
3113 }
3114
3115 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3116    and return the result in TARGET.  */
3117
3118 void
3119 s390_expand_cmpstr (target, op0, op1, len)
3120      rtx target;
3121      rtx op0;
3122      rtx op1;
3123      rtx len;
3124 {
3125   rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) = 
3126     TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31;
3127   rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) = 
3128     TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31;
3129   rtx (*gen_result) PARAMS ((rtx)) =
3130     GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3131
3132   op0 = protect_from_queue (op0, 0);
3133   op1 = protect_from_queue (op1, 0);
3134   len = protect_from_queue (len, 0);
3135
3136   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3137     {
3138       if (INTVAL (len) > 0)
3139         {
3140           emit_insn ((*gen_short) (op0, op1, GEN_INT (INTVAL (len) - 1)));
3141           emit_insn ((*gen_result) (target));
3142         }
3143       else
3144         emit_move_insn (target, const0_rtx);
3145     }
3146
3147   else /* if (TARGET_MVCLE) */
3148     {
3149       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
3150       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
3151       rtx reg0 = gen_reg_rtx (double_mode);
3152       rtx reg1 = gen_reg_rtx (double_mode);
3153
3154       emit_move_insn (gen_highpart (single_mode, reg0), 
3155                       force_operand (XEXP (op0, 0), NULL_RTX));
3156       emit_move_insn (gen_highpart (single_mode, reg1), 
3157                       force_operand (XEXP (op1, 0), NULL_RTX));
3158
3159       convert_move (gen_lowpart (single_mode, reg0), len, 1);
3160       convert_move (gen_lowpart (single_mode, reg1), len, 1);
3161
3162       emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
3163       emit_insn ((*gen_result) (target));
3164     }
3165
3166 #if 0
3167   /* Deactivate for now as profile code cannot cope with
3168      CC being live across basic block boundaries.  */
3169   else
3170     {
3171       rtx addr0, addr1, count, blocks, temp;
3172       rtx end_label = gen_label_rtx ();
3173       enum machine_mode mode;
3174       tree type;
3175
3176       mode = GET_MODE (len);
3177       if (mode == VOIDmode)
3178         mode = word_mode;
3179
3180       type = (*lang_hooks.types.type_for_mode) (mode, 1);
3181       if (!type)
3182         abort ();
3183
3184       addr0 = gen_reg_rtx (Pmode);
3185       addr1 = gen_reg_rtx (Pmode);
3186       count = gen_reg_rtx (mode);
3187       blocks = gen_reg_rtx (mode);
3188
3189       convert_move (count, len, 1);
3190       emit_cmp_and_jump_insns (count, const0_rtx, 
3191                                EQ, NULL_RTX, mode, 1, end_label);
3192
3193       emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3194       emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3195       op0 = change_address (op0, VOIDmode, addr0);
3196       op1 = change_address (op1, VOIDmode, addr1);
3197      
3198       temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3199       if (temp != count)
3200         emit_move_insn (count, temp);
3201
3202       temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3203       if (temp != blocks)
3204         emit_move_insn (blocks, temp);
3205
3206       expand_start_loop (1);
3207       expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3208                                            make_tree (type, blocks),
3209                                            make_tree (type, const0_rtx)));
3210
3211       emit_insn ((*gen_short) (op0, op1, GEN_INT (255)));
3212       temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3213       temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp, 
3214                         gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3215       temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3216       emit_jump_insn (temp);
3217
3218       s390_load_address (addr0, 
3219                          gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3220       s390_load_address (addr1, 
3221                          gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3222       
3223       temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3224       if (temp != blocks)
3225         emit_move_insn (blocks, temp);
3226
3227       expand_end_loop ();
3228
3229       emit_insn ((*gen_short) (op0, op1, convert_to_mode (word_mode, count, 1)));
3230       emit_label (end_label);
3231
3232       emit_insn ((*gen_result) (target));
3233     }
3234 #endif
3235 }
3236
3237 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3238    We need to emit DTP-relative relocations.  */
3239
3240 void
3241 s390_output_dwarf_dtprel (file, size, x)
3242      FILE *file;
3243      int size;
3244      rtx x;
3245 {
3246   switch (size)
3247     {
3248     case 4:
3249       fputs ("\t.long\t", file);
3250       break;
3251     case 8:
3252       fputs ("\t.quad\t", file);
3253       break;
3254     default:
3255       abort ();
3256     }
3257   output_addr_const (file, x);
3258   fputs ("@DTPOFF", file);
3259 }
3260
3261 /* In the name of slightly smaller debug output, and to cater to
3262    general assembler losage, recognize various UNSPEC sequences
3263    and turn them back into a direct symbol reference.  */
3264
3265 static rtx
3266 s390_delegitimize_address (orig_x)
3267      rtx orig_x;
3268 {
3269   rtx x = orig_x, y;
3270
3271   if (GET_CODE (x) != MEM)
3272     return orig_x;
3273
3274   x = XEXP (x, 0);
3275   if (GET_CODE (x) == PLUS
3276       && GET_CODE (XEXP (x, 1)) == CONST
3277       && GET_CODE (XEXP (x, 0)) == REG
3278       && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3279     {
3280       y = XEXP (XEXP (x, 1), 0);
3281       if (GET_CODE (y) == UNSPEC
3282           && XINT (y, 1) == 110)
3283         return XVECEXP (y, 0, 0);
3284       return orig_x;
3285     }
3286
3287   if (GET_CODE (x) == CONST)
3288     {
3289       y = XEXP (x, 0);
3290       if (GET_CODE (y) == UNSPEC
3291           && XINT (y, 1) == 111)
3292         return XVECEXP (y, 0, 0);
3293       return orig_x;
3294     }
3295
3296   return orig_x;      
3297 }
3298
3299 /* Locate some local-dynamic symbol still in use by this function
3300    so that we can print its name in local-dynamic base patterns.  */
3301
3302 static const char *
3303 get_some_local_dynamic_name ()
3304 {
3305   rtx insn;
3306
3307   if (cfun->machine->some_ld_name)
3308     return cfun->machine->some_ld_name;
3309
3310   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3311     if (INSN_P (insn)
3312         && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3313       return cfun->machine->some_ld_name;
3314
3315   abort ();
3316 }
3317
3318 static int
3319 get_some_local_dynamic_name_1 (px, data)
3320      rtx *px;
3321      void *data ATTRIBUTE_UNUSED;
3322 {
3323   rtx x = *px;
3324
3325   if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3326     {
3327       x = get_pool_constant (x);
3328       return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3329     }
3330
3331   if (GET_CODE (x) == SYMBOL_REF
3332       && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3333     {
3334       cfun->machine->some_ld_name = XSTR (x, 0);
3335       return 1;
3336     }
3337
3338   return 0;
3339 }
3340
3341 /* Output symbolic constant X in assembler syntax to 
3342    stdio stream FILE.  */
3343
3344 void
3345 s390_output_symbolic_const (file, x)
3346      FILE *file;
3347      rtx x;
3348 {
3349   switch (GET_CODE (x))
3350     {
3351     case CONST:
3352     case ZERO_EXTEND:
3353     case SIGN_EXTEND:
3354       s390_output_symbolic_const (file, XEXP (x, 0));
3355       break;
3356
3357     case PLUS:
3358       s390_output_symbolic_const (file, XEXP (x, 0));
3359       fprintf (file, "+");
3360       s390_output_symbolic_const (file, XEXP (x, 1));
3361       break;
3362
3363     case MINUS:
3364       s390_output_symbolic_const (file, XEXP (x, 0));
3365       fprintf (file, "-");
3366       s390_output_symbolic_const (file, XEXP (x, 1));
3367       break;
3368
3369     case CONST_INT:
3370     case LABEL_REF:
3371     case CODE_LABEL:
3372     case SYMBOL_REF:
3373       output_addr_const (file, x);
3374       break;
3375
3376     case UNSPEC:
3377       if (XVECLEN (x, 0) != 1)
3378         output_operand_lossage ("invalid UNSPEC as operand (1)");
3379       switch (XINT (x, 1))
3380         {
3381         case 100:
3382         case 104:
3383           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3384           fprintf (file, "-");  
3385           s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
3386           break;
3387         case 105:
3388           s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
3389           fprintf (file, "-");
3390           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3391           break;
3392         case 110:
3393           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3394           fprintf (file, "@GOT12");
3395           break;
3396         case 111:
3397           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3398           fprintf (file, "@GOTENT");
3399           break;
3400         case 112:
3401           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3402           fprintf (file, "@GOT");
3403           break;
3404         case 113:
3405           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3406           fprintf (file, "@PLT");
3407           break;
3408         case 114:
3409           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3410           fprintf (file, "@PLT-");
3411           s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
3412           break;
3413         case UNSPEC_TLSGD:
3414           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3415           fprintf (file, "@TLSGD");
3416           break;
3417         case UNSPEC_TLSLDM:
3418           assemble_name (file, get_some_local_dynamic_name ());
3419           fprintf (file, "@TLSLDM");
3420           break;
3421         case UNSPEC_DTPOFF:
3422           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3423           fprintf (file, "@DTPOFF");
3424           break;
3425         case UNSPEC_NTPOFF:
3426           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3427           fprintf (file, "@NTPOFF");
3428           break;
3429         case UNSPEC_GOTNTPOFF:
3430           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3431           fprintf (file, "@GOTNTPOFF");
3432           break;
3433         case UNSPEC_INDNTPOFF:
3434           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3435           fprintf (file, "@INDNTPOFF");
3436           break;
3437         default:
3438           output_operand_lossage ("invalid UNSPEC as operand (2)");
3439           break;
3440         }
3441       break;
3442
3443     default:
3444       fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
3445       break;
3446     }
3447 }
3448
3449 /* Output address operand ADDR in assembler syntax to 
3450    stdio stream FILE.  */
3451
3452 void
3453 print_operand_address (file, addr)
3454      FILE *file;
3455      rtx addr;
3456 {
3457   struct s390_address ad;
3458
3459   if (!s390_decompose_address (addr, &ad)
3460       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3461       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3462     output_operand_lossage ("Cannot decompose address.");
3463  
3464   if (ad.disp)
3465     s390_output_symbolic_const (file, ad.disp);
3466   else
3467     fprintf (file, "0");
3468
3469   if (ad.base && ad.indx)
3470     fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3471                               reg_names[REGNO (ad.base)]);
3472   else if (ad.base)
3473     fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3474 }
3475
3476 /* Output operand X in assembler syntax to stdio stream FILE.  
3477    CODE specified the format flag.  The following format flags 
3478    are recognized:
3479
3480     'C': print opcode suffix for branch condition.
3481     'D': print opcode suffix for inverse branch condition.
3482     'J': print tls_load/tls_gdcall/tls_ldcall suffix
3483     'O': print only the displacement of a memory reference.
3484     'R': print only the base register of a memory reference.
3485     'N': print the second word of a DImode operand.
3486     'M': print the second word of a TImode operand.
3487
3488     'b': print integer X as if it's an unsigned byte.
3489     'x': print integer X as if it's an unsigned word.
3490     'h': print integer X as if it's a signed word.  */
3491
3492 void
3493 print_operand (file, x, code)
3494      FILE *file;
3495      rtx x;
3496      int code;
3497 {
3498   switch (code)
3499     {
3500     case 'C':
3501       fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3502       return;
3503
3504     case 'D':
3505       fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3506       return;
3507
3508     case 'J':
3509       if (GET_CODE (x) == SYMBOL_REF)
3510         {
3511           fprintf (file, "%s", ":tls_load:");
3512           output_addr_const (file, x);
3513         }
3514       else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3515         {
3516           fprintf (file, "%s", ":tls_gdcall:");
3517           output_addr_const (file, XVECEXP (x, 0, 0));
3518         }
3519       else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3520         {
3521           fprintf (file, "%s", ":tls_ldcall:");
3522           assemble_name (file, get_some_local_dynamic_name ());
3523         }
3524       else
3525         abort ();
3526       return;
3527
3528     case 'O':
3529       {
3530         struct s390_address ad;
3531
3532         if (GET_CODE (x) != MEM
3533             || !s390_decompose_address (XEXP (x, 0), &ad)
3534             || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3535             || ad.indx)
3536           abort ();
3537
3538         if (ad.disp)
3539           s390_output_symbolic_const (file, ad.disp);
3540         else
3541           fprintf (file, "0");
3542       }
3543       return;
3544
3545     case 'R':
3546       {
3547         struct s390_address ad;
3548
3549         if (GET_CODE (x) != MEM
3550             || !s390_decompose_address (XEXP (x, 0), &ad)
3551             || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3552             || ad.indx)
3553           abort ();
3554
3555         if (ad.base)
3556           fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3557         else
3558           fprintf (file, "0");
3559       }
3560       return;
3561
3562     case 'N':
3563       if (GET_CODE (x) == REG)
3564         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3565       else if (GET_CODE (x) == MEM)
3566         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3567       else
3568         abort ();
3569       break;
3570
3571     case 'M':
3572       if (GET_CODE (x) == REG)
3573         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3574       else if (GET_CODE (x) == MEM)
3575         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3576       else
3577         abort ();
3578       break;
3579     }
3580
3581   switch (GET_CODE (x))
3582     {
3583     case REG:
3584       fprintf (file, "%s", reg_names[REGNO (x)]);
3585       break;
3586
3587     case MEM:
3588       output_address (XEXP (x, 0));
3589       break;
3590
3591     case CONST:
3592     case CODE_LABEL:
3593     case LABEL_REF:
3594     case SYMBOL_REF:
3595       s390_output_symbolic_const (file, x);
3596       break;
3597
3598     case CONST_INT:
3599       if (code == 'b')
3600         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3601       else if (code == 'x')
3602         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3603       else if (code == 'h')
3604         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3605       else
3606         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3607       break;
3608
3609     case CONST_DOUBLE:
3610       if (GET_MODE (x) != VOIDmode)
3611         abort ();
3612       if (code == 'b')
3613         fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3614       else if (code == 'x')
3615         fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3616       else if (code == 'h')
3617         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3618       else
3619         abort ();
3620       break;
3621
3622     default:
3623       fatal_insn ("UNKNOWN in print_operand !?", x);
3624       break;
3625     }
3626 }
3627
3628 /* Target hook for assembling integer objects.  We need to define it
3629    here to work a round a bug in some versions of GAS, which couldn't
3630    handle values smaller than INT_MIN when printed in decimal.  */
3631
3632 static bool
3633 s390_assemble_integer (x, size, aligned_p)
3634      rtx x;
3635      unsigned int size;
3636      int aligned_p;
3637 {
3638   if (size == 8 && aligned_p
3639       && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3640     {
3641       fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3642                INTVAL (x));
3643       return true;
3644     }
3645   return default_assemble_integer (x, size, aligned_p);
3646 }
3647
3648 /* Returns true if register REGNO is used  for forming 
3649    a memory address in expression X.  */
3650
3651 static int
3652 reg_used_in_mem_p (regno, x)
3653      int regno;
3654      rtx x;
3655 {
3656   enum rtx_code code = GET_CODE (x);
3657   int i, j;
3658   const char *fmt;
3659   
3660   if (code == MEM)
3661     {
3662       if (refers_to_regno_p (regno, regno+1,
3663                              XEXP (x, 0), 0))
3664         return 1;
3665     }
3666   else if (code == SET 
3667            && GET_CODE (SET_DEST (x)) == PC)
3668     {
3669       if (refers_to_regno_p (regno, regno+1,
3670                              SET_SRC (x), 0))
3671         return 1;
3672     }
3673
3674   fmt = GET_RTX_FORMAT (code);
3675   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3676     {
3677       if (fmt[i] == 'e'
3678           && reg_used_in_mem_p (regno, XEXP (x, i)))
3679         return 1;
3680       
3681       else if (fmt[i] == 'E')
3682         for (j = 0; j < XVECLEN (x, i); j++)
3683           if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
3684             return 1;
3685     }
3686   return 0;
3687 }
3688
3689 /* Returns true if expression DEP_RTX sets an address register
3690    used by instruction INSN to address memory.  */
3691
3692 static int 
3693 addr_generation_dependency_p (dep_rtx, insn)
3694      rtx dep_rtx; 
3695      rtx insn;
3696 {
3697   rtx target, pat;
3698
3699   if (GET_CODE (dep_rtx) == INSN)
3700       dep_rtx = PATTERN (dep_rtx);
3701
3702   if (GET_CODE (dep_rtx) == SET)
3703     {
3704       target = SET_DEST (dep_rtx);
3705       if (GET_CODE (target) == STRICT_LOW_PART)
3706         target = XEXP (target, 0);
3707       while (GET_CODE (target) == SUBREG)
3708         target = SUBREG_REG (target);
3709
3710       if (GET_CODE (target) == REG)
3711         {
3712           int regno = REGNO (target);
3713
3714           if (s390_safe_attr_type (insn) == TYPE_LA)
3715             {
3716               pat = PATTERN (insn);
3717               if (GET_CODE (pat) == PARALLEL)
3718                 {
3719                   if (XVECLEN (pat, 0) != 2)
3720                     abort();
3721                   pat = XVECEXP (pat, 0, 0);
3722                 }
3723               if (GET_CODE (pat) == SET)
3724                 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
3725               else
3726                 abort();
3727             }
3728           else if (get_attr_atype (insn) == ATYPE_AGEN)
3729             return reg_used_in_mem_p (regno, PATTERN (insn));
3730         }
3731     }
3732   return 0;
3733 }
3734
3735 /* Return 1, if dep_insn sets register used in insn in the agen unit.  */
3736
3737 int 
3738 s390_agen_dep_p(dep_insn, insn)
3739      rtx dep_insn;
3740      rtx insn;
3741
3742   rtx dep_rtx = PATTERN (dep_insn);
3743   int i;
3744   
3745   if (GET_CODE (dep_rtx) == SET  
3746       && addr_generation_dependency_p (dep_rtx, insn))
3747     return 1;
3748   else if (GET_CODE (dep_rtx) == PARALLEL)
3749     {
3750       for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3751         {
3752           if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3753             return 1;
3754         }
3755     }
3756   return 0;
3757 }
3758
3759 /* Return the modified cost of the dependency of instruction INSN
3760    on instruction DEP_INSN through the link LINK.  COST is the 
3761    default cost of that dependency.
3762
3763    Data dependencies are all handled without delay.  However, if a
3764    register is modified and subsequently used as base or index 
3765    register of a memory reference, at least 4 cycles need to pass
3766    between setting and using the register to avoid pipeline stalls.  
3767    An exception is the LA instruction. An address generated by LA can
3768    be used by introducing only a one cycle stall on the pipeline.  */
3769
3770 static int
3771 s390_adjust_cost (insn, link, dep_insn, cost)
3772      rtx insn;
3773      rtx link;
3774      rtx dep_insn;
3775      int cost;
3776 {
3777   rtx dep_rtx;
3778   int i;
3779
3780   /* If the dependence is an anti-dependence, there is no cost.  For an
3781      output dependence, there is sometimes a cost, but it doesn't seem
3782      worth handling those few cases.  */
3783
3784   if (REG_NOTE_KIND (link) != 0)
3785     return 0;
3786
3787   /* If we can't recognize the insns, we can't really do anything.  */
3788   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3789     return cost;
3790
3791   /* DFA based scheduling checks address dependency in md file.  */
3792   if (s390_use_dfa_pipeline_interface ())
3793   {
3794     /* Operand forward in case of lr, load and la.  */ 
3795     if (s390_tune == PROCESSOR_2084_Z990
3796         && cost == 1
3797         && (s390_safe_attr_type (dep_insn) == TYPE_LA
3798             || s390_safe_attr_type (dep_insn) == TYPE_LR
3799             || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
3800       return 0;
3801     return cost;
3802   }
3803
3804   dep_rtx = PATTERN (dep_insn);
3805
3806   if (GET_CODE (dep_rtx) == SET 
3807       && addr_generation_dependency_p (dep_rtx, insn))
3808     cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;  
3809   else if (GET_CODE (dep_rtx) == PARALLEL)
3810     {
3811       for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3812         {
3813           if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3814             cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;  
3815         }
3816     }
3817
3818   return cost;
3819 }
3820 /* A C statement (sans semicolon) to update the integer scheduling priority
3821    INSN_PRIORITY (INSN).  Increase the priority to execute the INSN earlier,
3822    reduce the priority to execute INSN later.  Do not define this macro if
3823    you do not need to adjust the scheduling priorities of insns. 
3824
3825    A STD instruction should be scheduled earlier, 
3826    in order to use the bypass.  */
3827
3828 static int
3829 s390_adjust_priority (insn, priority)
3830      rtx insn ATTRIBUTE_UNUSED;
3831      int priority;
3832 {
3833   if (! INSN_P (insn))
3834     return priority;
3835
3836   if (s390_tune != PROCESSOR_2084_Z990)
3837     return priority;
3838
3839   switch (s390_safe_attr_type (insn))
3840     {
3841       case TYPE_FSTORED:
3842       case TYPE_FSTORES:
3843         priority = priority << 3;
3844         break;
3845       case TYPE_STORE:
3846         priority = priority << 1;
3847         break;
3848       default:
3849         break;
3850     }
3851   return priority;
3852 }
3853
3854 /* The number of instructions that can be issued per cycle.  */
3855
3856 static int
3857 s390_issue_rate ()
3858 {
3859   if (s390_tune == PROCESSOR_2084_Z990) 
3860     return 3;
3861   return 1;
3862 }
3863
3864 /* If the following function returns TRUE, we will use the the DFA
3865    insn scheduler.  */
3866
3867 static int
3868 s390_use_dfa_pipeline_interface ()
3869 {
3870   if (s390_tune == PROCESSOR_2064_Z900
3871       || s390_tune == PROCESSOR_2084_Z990)
3872     return 1;
3873
3874   return 0;
3875 }
3876
3877 static int
3878 s390_first_cycle_multipass_dfa_lookahead ()
3879 {
3880   return s390_use_dfa_pipeline_interface () ? 4 : 0;
3881 }
3882
3883 /* Called after issuing each insn.
3884    Triggers default sort algorithm to better slot instructions.  */
3885
3886 static int
3887 s390_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
3888      FILE *dump ATTRIBUTE_UNUSED;
3889      int sched_verbose ATTRIBUTE_UNUSED;
3890      rtx *ready ATTRIBUTE_UNUSED;
3891      int *pn_ready ATTRIBUTE_UNUSED;
3892      int clock_var ATTRIBUTE_UNUSED;
3893 {
3894     return s390_issue_rate();
3895 }
3896
3897
3898 /* Split all branches that exceed the maximum distance.  
3899    Returns true if this created a new literal pool entry.  
3900
3901    Code generated by this routine is allowed to use
3902    TEMP_REG as temporary scratch register.  If this is
3903    done, TEMP_USED is set to true.  */
3904
3905 static int 
3906 s390_split_branches (temp_reg, temp_used)
3907      rtx temp_reg;
3908      bool *temp_used;
3909 {
3910   int new_literal = 0;
3911   rtx insn, pat, tmp, target;
3912   rtx *label;
3913
3914   /* We need correct insn addresses.  */
3915
3916   shorten_branches (get_insns ());
3917
3918   /* Find all branches that exceed 64KB, and split them.  */
3919
3920   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3921     {
3922       if (GET_CODE (insn) != JUMP_INSN)
3923         continue;
3924
3925       pat = PATTERN (insn);
3926       if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3927         pat = XVECEXP (pat, 0, 0);
3928       if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
3929         continue;
3930
3931       if (GET_CODE (SET_SRC (pat)) == LABEL_REF) 
3932         {
3933           label = &SET_SRC (pat);
3934         } 
3935       else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE) 
3936         {
3937           if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF) 
3938             label = &XEXP (SET_SRC (pat), 1);
3939           else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF) 
3940             label = &XEXP (SET_SRC (pat), 2);
3941           else
3942             continue;
3943         }
3944       else
3945         continue;
3946
3947       if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
3948         continue;
3949
3950       *temp_used = 1;
3951
3952       if (TARGET_64BIT)
3953         {
3954           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
3955           INSN_ADDRESSES_NEW (tmp, -1);
3956
3957           target = temp_reg;
3958         }
3959       else if (!flag_pic)
3960         {
3961           new_literal = 1;
3962           tmp = force_const_mem (Pmode, *label);
3963           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3964           INSN_ADDRESSES_NEW (tmp, -1);
3965
3966           target = temp_reg;
3967         }
3968       else
3969         {
3970           new_literal = 1;
3971           tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 104);
3972           tmp = gen_rtx_CONST (SImode, tmp);
3973           tmp = force_const_mem (SImode, tmp);
3974           tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3975           INSN_ADDRESSES_NEW (tmp, -1);
3976
3977           target = gen_rtx_REG (Pmode, BASE_REGISTER);
3978           target = gen_rtx_PLUS (Pmode, target, temp_reg);
3979         }
3980
3981       if (!validate_change (insn, label, target, 0))
3982         abort ();
3983     }
3984
3985   return new_literal;
3986 }
3987
3988
3989 /* Find a literal pool symbol referenced in RTX X, and store 
3990    it at REF.  Will abort if X contains references to more than 
3991    one such pool symbol; multiple references to the same symbol
3992    are allowed, however. 
3993
3994    The rtx pointed to by REF must be initialized to NULL_RTX 
3995    by the caller before calling this routine.  */
3996
3997 static void
3998 find_constant_pool_ref (x, ref)
3999      rtx x;
4000      rtx *ref;
4001 {
4002   int i, j;
4003   const char *fmt;
4004
4005   if (GET_CODE (x) == SYMBOL_REF
4006       && CONSTANT_POOL_ADDRESS_P (x))
4007     {
4008       if (*ref == NULL_RTX)
4009         *ref = x;
4010       else if (*ref != x)
4011         abort();
4012     }
4013
4014   fmt = GET_RTX_FORMAT (GET_CODE (x));
4015   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4016     {
4017       if (fmt[i] == 'e')
4018         {
4019           find_constant_pool_ref (XEXP (x, i), ref);
4020         }
4021       else if (fmt[i] == 'E')
4022         {
4023           for (j = 0; j < XVECLEN (x, i); j++)
4024             find_constant_pool_ref (XVECEXP (x, i, j), ref);
4025         }
4026     }
4027 }
4028
4029 /* Replace every reference to the literal pool symbol REF
4030    in X by the address ADDR.  Fix up MEMs as required.  */
4031
4032 static void
4033 replace_constant_pool_ref (x, ref, addr)
4034      rtx *x;
4035      rtx ref;
4036      rtx addr;
4037 {
4038   int i, j;
4039   const char *fmt;
4040
4041   if (*x == ref)
4042     abort ();
4043
4044   /* Literal pool references can only occur inside a MEM ...  */
4045   if (GET_CODE (*x) == MEM)
4046     {
4047       rtx memref = XEXP (*x, 0);
4048
4049       if (memref == ref)
4050         {
4051           *x = replace_equiv_address (*x, addr);
4052           return;
4053         }
4054
4055       if (GET_CODE (memref) == CONST
4056           && GET_CODE (XEXP (memref, 0)) == PLUS
4057           && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4058           && XEXP (XEXP (memref, 0), 0) == ref)
4059         {
4060           HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4061           *x = replace_equiv_address (*x, plus_constant (addr, off));
4062           return;
4063         }
4064     }
4065
4066   /* ... or a load-address type pattern.  */
4067   if (GET_CODE (*x) == SET)
4068     {
4069       rtx addrref = SET_SRC (*x);
4070
4071       if (addrref == ref)
4072         {
4073           SET_SRC (*x) = addr;
4074           return;
4075         }
4076
4077       if (GET_CODE (addrref) == CONST
4078           && GET_CODE (XEXP (addrref, 0)) == PLUS
4079           && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4080           && XEXP (XEXP (addrref, 0), 0) == ref)
4081         {
4082           HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4083           SET_SRC (*x) = plus_constant (addr, off);
4084           return;
4085         }
4086     }
4087
4088   fmt = GET_RTX_FORMAT (GET_CODE (*x));
4089   for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4090     {
4091       if (fmt[i] == 'e')
4092         {
4093           replace_constant_pool_ref (&XEXP (*x, i), ref, addr);
4094         }
4095       else if (fmt[i] == 'E')
4096         {
4097           for (j = 0; j < XVECLEN (*x, i); j++)
4098             replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, addr);
4099         }
4100     }
4101 }
4102
4103 /* Check whether ADDR is an address that uses the base register, 
4104    without actually constituting a literal pool access.  (This happens
4105    in 31-bit PIC mode, where the base register is used as anchor for
4106    relative addressing of local symbols.) 
4107
4108    Returns 1 if the base register occupies the base slot,
4109    returns 2 if the base register occupies the index slot,
4110    returns 0 if the address is not of this form.  */
4111
4112 static int
4113 find_base_register_in_addr (addr)
4114      struct s390_address *addr;
4115 {
4116   /* If DISP is complex, we might have a literal pool reference.  */
4117   if (addr->disp && GET_CODE (addr->disp) != CONST_INT)
4118     return 0;
4119
4120   if (addr->base && REG_P (addr->base) && REGNO (addr->base) == BASE_REGISTER)
4121     return 1;
4122
4123   if (addr->indx && REG_P (addr->indx) && REGNO (addr->indx) == BASE_REGISTER)
4124     return 2;
4125
4126   return 0;
4127 }
4128
4129 /* Return true if X contains an address that uses the base register, 
4130    without actually constituting a literal pool access.  */
4131
4132 static bool
4133 find_base_register_ref (x)
4134      rtx x;
4135 {
4136   bool retv = FALSE;
4137   struct s390_address addr;
4138   int i, j;
4139   const char *fmt;
4140
4141   /* Addresses can only occur inside a MEM ...  */
4142   if (GET_CODE (x) == MEM)
4143     {
4144       if (s390_decompose_address (XEXP (x, 0), &addr)
4145           && find_base_register_in_addr (&addr))
4146         return TRUE;
4147     }
4148
4149   /* ... or a load-address type pattern.  */
4150   if (GET_CODE (x) == SET && GET_CODE (SET_DEST (x)) == REG)
4151     {
4152       if (s390_decompose_address (SET_SRC (x), &addr)
4153           && find_base_register_in_addr (&addr))
4154         return TRUE;
4155     }
4156
4157   fmt = GET_RTX_FORMAT (GET_CODE (x));
4158   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4159     {
4160       if (fmt[i] == 'e')
4161         {
4162           retv |= find_base_register_ref (XEXP (x, i));
4163         }
4164       else if (fmt[i] == 'E')
4165         {
4166           for (j = 0; j < XVECLEN (x, i); j++)
4167             retv |= find_base_register_ref (XVECEXP (x, i, j));
4168         }
4169     }
4170
4171   return retv;
4172 }
4173
4174 /* If X contains an address that uses the base register,
4175    without actually constituting a literal pool access,
4176    replace the base register with REPL in all such cases.
4177
4178    Handles both MEMs and load address patterns.  */
4179
4180 static void
4181 replace_base_register_ref (x, repl)
4182      rtx *x;
4183      rtx repl;
4184 {
4185   struct s390_address addr;
4186   rtx new_addr;
4187   int i, j, pos;
4188   const char *fmt;
4189
4190   /* Addresses can only occur inside a MEM ...  */
4191   if (GET_CODE (*x) == MEM)
4192     {
4193       if (s390_decompose_address (XEXP (*x, 0), &addr)
4194           && (pos = find_base_register_in_addr (&addr)))
4195         {
4196           if (pos == 1)
4197             addr.base = repl;
4198           else
4199             addr.indx = repl;
4200
4201           new_addr = addr.base;
4202           if (addr.indx)
4203             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
4204           if (addr.disp)
4205             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
4206
4207           *x = replace_equiv_address (*x, new_addr);
4208           return;
4209         }
4210     }
4211
4212   /* ... or a load-address type pattern.  */
4213   if (GET_CODE (*x) == SET && GET_CODE (SET_DEST (*x)) == REG)
4214     {
4215       if (s390_decompose_address (SET_SRC (*x), &addr)
4216           && (pos = find_base_register_in_addr (&addr)))
4217         {
4218           if (pos == 1)
4219             addr.base = repl;
4220           else
4221             addr.indx = repl;
4222
4223           new_addr = addr.base;
4224           if (addr.indx)
4225             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
4226           if (addr.disp)
4227             new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
4228
4229           SET_SRC (*x) = new_addr;
4230           return;
4231         }
4232     }
4233
4234   fmt = GET_RTX_FORMAT (GET_CODE (*x));
4235   for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4236     {
4237       if (fmt[i] == 'e')
4238         {
4239           replace_base_register_ref (&XEXP (*x, i), repl);
4240         }
4241       else if (fmt[i] == 'E')
4242         {
4243           for (j = 0; j < XVECLEN (*x, i); j++)
4244             replace_base_register_ref (&XVECEXP (*x, i, j), repl);
4245         }
4246     }
4247 }
4248
4249
4250 /* We keep a list of constants we which we have to add to internal
4251    constant tables in the middle of large functions.  */
4252
4253 #define NR_C_MODES 6
4254 enum machine_mode constant_modes[NR_C_MODES] = 
4255 {
4256   DFmode, DImode,
4257   SFmode, SImode,
4258   HImode,
4259   QImode
4260 };
4261
4262 rtx (*gen_consttable[NR_C_MODES])(rtx) =
4263 {
4264   gen_consttable_df, gen_consttable_di,
4265   gen_consttable_sf, gen_consttable_si,
4266   gen_consttable_hi,
4267   gen_consttable_qi
4268 };
4269
4270 struct constant
4271 {
4272   struct constant *next;
4273   rtx value;
4274   rtx label;
4275 };
4276
4277 struct constant_pool
4278 {
4279   struct constant_pool *next;
4280   rtx first_insn;
4281   rtx pool_insn;
4282   bitmap insns;
4283
4284   struct constant *constants[NR_C_MODES];
4285   rtx label;
4286   int size;
4287   bool anchor;
4288 };
4289
4290 static struct constant_pool * s390_chunkify_start PARAMS ((rtx, bool *));
4291 static void s390_chunkify_finish PARAMS ((struct constant_pool *, rtx));
4292 static void s390_chunkify_cancel PARAMS ((struct constant_pool *));
4293
4294 static struct constant_pool *s390_start_pool PARAMS ((struct constant_pool **, rtx));
4295 static void s390_end_pool PARAMS ((struct constant_pool *, rtx));
4296 static void s390_add_pool_insn PARAMS ((struct constant_pool *, rtx));
4297 static struct constant_pool *s390_find_pool PARAMS ((struct constant_pool *, rtx));
4298 static void s390_add_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
4299 static rtx s390_find_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
4300 static void s390_add_anchor PARAMS ((struct constant_pool *));
4301 static rtx s390_dump_pool PARAMS ((struct constant_pool *));
4302 static void s390_free_pool PARAMS ((struct constant_pool *));
4303
4304 /* Create new constant pool covering instructions starting at INSN
4305    and chain it to the end of POOL_LIST.  */
4306
4307 static struct constant_pool *
4308 s390_start_pool (pool_list, insn)
4309      struct constant_pool **pool_list;
4310      rtx insn;
4311 {
4312   struct constant_pool *pool, **prev;
4313   int i;
4314
4315   pool = (struct constant_pool *) xmalloc (sizeof *pool);
4316   pool->next = NULL;
4317   for (i = 0; i < NR_C_MODES; i++)
4318     pool->constants[i] = NULL;
4319
4320   pool->label = gen_label_rtx ();
4321   pool->first_insn = insn;
4322   pool->pool_insn = NULL_RTX;
4323   pool->insns = BITMAP_XMALLOC ();
4324   pool->size = 0;
4325   pool->anchor = FALSE;
4326
4327   for (prev = pool_list; *prev; prev = &(*prev)->next)
4328     ;
4329   *prev = pool;
4330
4331   return pool;
4332 }
4333
4334 /* End range of instructions covered by POOL at INSN and emit
4335    placeholder insn representing the pool.  */
4336
4337 static void
4338 s390_end_pool (pool, insn)
4339      struct constant_pool *pool;
4340      rtx insn;
4341 {
4342   rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4343
4344   if (!insn)
4345     insn = get_last_insn ();
4346
4347   pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4348   INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4349 }
4350
4351 /* Add INSN to the list of insns covered by POOL.  */
4352
4353 static void
4354 s390_add_pool_insn (pool, insn)
4355      struct constant_pool *pool;
4356      rtx insn;
4357 {
4358   bitmap_set_bit (pool->insns, INSN_UID (insn));
4359 }
4360
4361 /* Return pool out of POOL_LIST that covers INSN.  */
4362
4363 static struct constant_pool *
4364 s390_find_pool (pool_list, insn)
4365      struct constant_pool *pool_list;
4366      rtx insn;
4367 {
4368   struct constant_pool *pool;
4369
4370   for (pool = pool_list; pool; pool = pool->next)
4371     if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4372       break;
4373
4374   return pool;
4375 }
4376
4377 /* Add constant VAL of mode MODE to the constant pool POOL.  */
4378
4379 static void
4380 s390_add_constant (pool, val, mode)
4381      struct constant_pool *pool;
4382      rtx val;
4383      enum machine_mode mode;
4384 {
4385   struct constant *c;
4386   int i;
4387
4388   for (i = 0; i < NR_C_MODES; i++)
4389     if (constant_modes[i] == mode)
4390       break;
4391   if (i == NR_C_MODES)
4392     abort ();
4393
4394   for (c = pool->constants[i]; c != NULL; c = c->next)
4395     if (rtx_equal_p (val, c->value))
4396       break;
4397
4398   if (c == NULL)
4399     {
4400       c = (struct constant *) xmalloc (sizeof *c);
4401       c->value = val;
4402       c->label = gen_label_rtx ();
4403       c->next = pool->constants[i];
4404       pool->constants[i] = c;
4405       pool->size += GET_MODE_SIZE (mode);
4406     }
4407 }
4408
4409 /* Find constant VAL of mode MODE in the constant pool POOL.
4410    Return an RTX describing the distance from the start of
4411    the pool to the location of the new constant.  */
4412  
4413 static rtx
4414 s390_find_constant (pool, val, mode)
4415      struct constant_pool *pool;
4416      rtx val;
4417      enum machine_mode mode;
4418 {
4419   struct constant *c;
4420   rtx offset;
4421   int i;
4422  
4423   for (i = 0; i < NR_C_MODES; i++)
4424     if (constant_modes[i] == mode)
4425       break;
4426   if (i == NR_C_MODES)
4427     abort ();
4428  
4429   for (c = pool->constants[i]; c != NULL; c = c->next)
4430     if (rtx_equal_p (val, c->value))
4431       break;
4432  
4433   if (c == NULL)
4434     abort ();
4435  
4436   offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4437                                  gen_rtx_LABEL_REF (Pmode, pool->label));
4438   offset = gen_rtx_CONST (Pmode, offset);
4439   return offset;
4440 }
4441
4442 /* Set 'anchor' flag in POOL.  */
4443
4444 static void
4445 s390_add_anchor (pool)
4446      struct constant_pool *pool;
4447 {
4448   if (!pool->anchor)
4449     {
4450       pool->anchor = TRUE;
4451       pool->size += 4;
4452     }
4453 }
4454
4455 /* Dump out the constants in POOL.  */
4456
4457 static rtx
4458 s390_dump_pool (pool)
4459      struct constant_pool *pool;
4460 {
4461   struct constant *c;
4462   rtx insn;
4463   int i;
4464
4465   /* Pool start insn switches to proper section 
4466      and guarantees necessary alignment.  */
4467   if (TARGET_64BIT)
4468     insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4469   else
4470     insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4471   INSN_ADDRESSES_NEW (insn, -1);
4472
4473   insn = emit_label_after (pool->label, insn);
4474   INSN_ADDRESSES_NEW (insn, -1);
4475
4476   /* Emit anchor if we need one.  */
4477   if (pool->anchor)
4478     {
4479       rtx anchor = gen_rtx_LABEL_REF (VOIDmode, pool->label);
4480       anchor = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, anchor), 105);
4481       anchor = gen_rtx_CONST (VOIDmode, anchor);
4482       insn = emit_insn_after (gen_consttable_si (anchor), insn);
4483       INSN_ADDRESSES_NEW (insn, -1);
4484     }
4485
4486   /* Dump constants in descending alignment requirement order,
4487      ensuring proper alignment for every constant.  */
4488   for (i = 0; i < NR_C_MODES; i++)
4489     for (c = pool->constants[i]; c; c = c->next)
4490       {
4491         /* Convert 104 unspecs to pool-relative references.  */
4492         rtx value = c->value;
4493         if (GET_CODE (value) == CONST
4494             && GET_CODE (XEXP (value, 0)) == UNSPEC
4495             && XINT (XEXP (value, 0), 1) == 104
4496             && XVECLEN (XEXP (value, 0), 0) == 1)
4497           {
4498             value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4499                                    gen_rtx_LABEL_REF (VOIDmode, pool->label));
4500             value = gen_rtx_CONST (VOIDmode, value);
4501           }
4502
4503         insn = emit_label_after (c->label, insn);
4504         INSN_ADDRESSES_NEW (insn, -1);
4505         insn = emit_insn_after (gen_consttable[i] (value), insn);
4506         INSN_ADDRESSES_NEW (insn, -1);
4507       }
4508
4509   /* Pool end insn switches back to previous section 
4510      and guarantees necessary alignment.  */
4511   if (TARGET_64BIT)
4512     insn = emit_insn_after (gen_pool_end_64 (), insn);
4513   else
4514     insn = emit_insn_after (gen_pool_end_31 (), insn);
4515   INSN_ADDRESSES_NEW (insn, -1);
4516
4517   insn = emit_barrier_after (insn);
4518   INSN_ADDRESSES_NEW (insn, -1);
4519
4520   /* Remove placeholder insn.  */
4521   remove_insn (pool->pool_insn);
4522
4523   return insn;
4524 }
4525
4526 /* Free all memory used by POOL.  */
4527
4528 static void
4529 s390_free_pool (pool)
4530      struct constant_pool *pool;
4531 {
4532   int i;
4533
4534   for (i = 0; i < NR_C_MODES; i++)
4535     {
4536       struct constant *c = pool->constants[i];
4537       while (c != NULL)
4538         {
4539           struct constant *next = c->next;
4540           free (c);
4541           c = next;
4542         }
4543     }
4544
4545   BITMAP_XFREE (pool->insns);
4546   free (pool);
4547
4548
4549
4550 /* Chunkify the literal pool if required.
4551
4552    Code generated by this routine is allowed to use
4553    TEMP_REG as temporary scratch register.  If this is
4554    done, TEMP_USED is set to true.  */
4555
4556 #define S390_POOL_CHUNK_MIN     0xc00
4557 #define S390_POOL_CHUNK_MAX     0xe00
4558
4559 static struct constant_pool * 
4560 s390_chunkify_start (temp_reg, temp_used)
4561      rtx temp_reg;
4562      bool *temp_used;
4563 {
4564   rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
4565
4566   struct constant_pool *curr_pool = NULL, *pool_list = NULL;
4567   int extra_size = 0;
4568   bitmap far_labels;
4569   rtx insn;
4570
4571   rtx (*gen_reload_base) PARAMS ((rtx, rtx)) =
4572     TARGET_64BIT? gen_reload_base_64 : gen_reload_base_31;
4573
4574
4575   /* Do we need to chunkify the literal pool?  */
4576
4577   if (get_pool_size () < S390_POOL_CHUNK_MAX)
4578     return NULL;
4579
4580   /* We need correct insn addresses.  */
4581
4582   shorten_branches (get_insns ());
4583
4584   /* Scan all insns and move literals to pool chunks.
4585      Also, emit anchor reload insns before every insn that uses 
4586      the literal pool base register as anchor pointer.  */
4587
4588   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4589     {
4590       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4591         {
4592           rtx pool_ref = NULL_RTX;
4593           find_constant_pool_ref (PATTERN (insn), &pool_ref);
4594           if (pool_ref)
4595             {
4596               if (!curr_pool)
4597                 curr_pool = s390_start_pool (&pool_list, insn);
4598
4599               s390_add_constant (curr_pool, get_pool_constant (pool_ref), 
4600                                             get_pool_mode (pool_ref));
4601               s390_add_pool_insn (curr_pool, insn);
4602             }
4603
4604           else if (!TARGET_64BIT && flag_pic
4605                    && find_base_register_ref (PATTERN (insn)))
4606             {
4607               rtx new = gen_reload_anchor (temp_reg, base_reg);
4608               new = emit_insn_before (new, insn);
4609               INSN_ADDRESSES_NEW (new, INSN_ADDRESSES (INSN_UID (insn)));
4610               extra_size += 8;
4611               *temp_used = 1;
4612               
4613               if (!curr_pool)
4614                 curr_pool = s390_start_pool (&pool_list, new);
4615
4616               s390_add_anchor (curr_pool);
4617               s390_add_pool_insn (curr_pool, insn);
4618             }
4619         }
4620
4621       if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
4622         if (curr_pool)
4623           s390_add_pool_insn (curr_pool, insn);
4624
4625       if (!curr_pool 
4626           || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
4627           || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4628         continue;
4629
4630       if (TARGET_64BIT)
4631         {
4632           if (curr_pool->size < S390_POOL_CHUNK_MAX)
4633             continue;
4634
4635           s390_end_pool (curr_pool, NULL_RTX);
4636           curr_pool = NULL;
4637         }
4638       else
4639         {
4640           int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
4641                            - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
4642                          + extra_size;
4643
4644           /* We will later have to insert base register reload insns.
4645              Those will have an effect on code size, which we need to
4646              consider here.  This calculation makes rather pessimistic
4647              worst-case assumptions.  */
4648           if (GET_CODE (insn) == CODE_LABEL)
4649             extra_size += 6;
4650
4651           if (chunk_size < S390_POOL_CHUNK_MIN
4652               && curr_pool->size < S390_POOL_CHUNK_MIN)
4653             continue;
4654
4655           /* Pool chunks can only be inserted after BARRIERs ...  */
4656           if (GET_CODE (insn) == BARRIER)
4657             {
4658               s390_end_pool (curr_pool, insn);
4659               curr_pool = NULL;
4660               extra_size = 0;
4661             }
4662
4663           /* ... so if we don't find one in time, create one.  */
4664           else if ((chunk_size > S390_POOL_CHUNK_MAX
4665                    || curr_pool->size > S390_POOL_CHUNK_MAX))
4666             {
4667               rtx label, jump, barrier;
4668
4669               /* We can insert the barrier only after a 'real' insn.  */
4670               if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
4671                 continue;
4672               if (get_attr_length (insn) == 0)
4673                 continue;
4674
4675               /* Don't separate insns created by s390_split_branches.  */
4676               if (GET_CODE (insn) == INSN 
4677                   && GET_CODE (PATTERN (insn)) == SET
4678                   && rtx_equal_p (SET_DEST (PATTERN (insn)), temp_reg))
4679                 continue;
4680
4681               label = gen_label_rtx ();
4682               jump = emit_jump_insn_after (gen_jump (label), insn);
4683               barrier = emit_barrier_after (jump);
4684               insn = emit_label_after (label, barrier);
4685               JUMP_LABEL (jump) = label;
4686               LABEL_NUSES (label) = 1;
4687
4688               INSN_ADDRESSES_NEW (jump, -1);
4689               INSN_ADDRESSES_NEW (barrier, -1);
4690               INSN_ADDRESSES_NEW (insn, -1);
4691
4692               s390_end_pool (curr_pool, barrier);
4693               curr_pool = NULL;
4694               extra_size = 0;
4695             }
4696         }
4697     }
4698
4699   if (curr_pool)
4700     s390_end_pool (curr_pool, NULL_RTX);
4701
4702
4703   /* Find all labels that are branched into 
4704      from an insn belonging to a different chunk.  */
4705
4706   far_labels = BITMAP_XMALLOC ();
4707
4708   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4709     {
4710       /* Labels marked with LABEL_PRESERVE_P can be target
4711          of non-local jumps, so we have to mark them.
4712          The same holds for named labels.
4713
4714          Don't do that, however, if it is the label before
4715          a jump table.  */
4716
4717       if (GET_CODE (insn) == CODE_LABEL 
4718           && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
4719         {
4720           rtx vec_insn = next_real_insn (insn);
4721           rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ? 
4722                         PATTERN (vec_insn) : NULL_RTX;
4723           if (!vec_pat
4724               || !(GET_CODE (vec_pat) == ADDR_VEC
4725                    || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4726             bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
4727         }
4728
4729       /* If we have a direct jump (conditional or unconditional)
4730          or a casesi jump, check all potential targets.  */
4731       else if (GET_CODE (insn) == JUMP_INSN) 
4732         {
4733           rtx pat = PATTERN (insn);
4734           if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4735             pat = XVECEXP (pat, 0, 0);
4736
4737           if (GET_CODE (pat) == SET) 
4738             {
4739               rtx label = JUMP_LABEL (insn);
4740               if (label)
4741                 {
4742                   if (s390_find_pool (pool_list, label) 
4743                       != s390_find_pool (pool_list, insn))
4744                     bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4745                 }
4746             } 
4747           else if (GET_CODE (pat) == PARALLEL
4748                    && XVECLEN (pat, 0) == 2
4749                    && GET_CODE (XVECEXP (pat, 0, 0)) == SET
4750                    && GET_CODE (XVECEXP (pat, 0, 1)) == USE
4751                    && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
4752             {
4753               /* Find the jump table used by this casesi jump.  */
4754               rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
4755               rtx vec_insn = next_real_insn (vec_label);
4756               rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ? 
4757                             PATTERN (vec_insn) : NULL_RTX;
4758               if (vec_pat
4759                   && (GET_CODE (vec_pat) == ADDR_VEC
4760                       || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4761                 {
4762                   int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
4763
4764                   for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
4765                     {
4766                       rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
4767
4768                       if (s390_find_pool (pool_list, label) 
4769                           != s390_find_pool (pool_list, insn))
4770                         bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4771                     }
4772                 }
4773             }
4774         }
4775     }
4776
4777   /* Insert base register reload insns before every pool.  */
4778
4779   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4780     {
4781       rtx new_insn = gen_reload_base (base_reg, curr_pool->label);
4782       rtx insn = curr_pool->first_insn;
4783       INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
4784     }
4785
4786   /* Insert base register reload insns at every far label.  */
4787
4788   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4789     if (GET_CODE (insn) == CODE_LABEL 
4790         && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
4791       {
4792         struct constant_pool *pool = s390_find_pool (pool_list, insn);
4793         if (pool)
4794           {
4795             rtx new_insn = gen_reload_base (base_reg, pool->label);
4796             INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
4797           }
4798       }
4799
4800
4801   BITMAP_XFREE (far_labels);
4802
4803
4804   /* Recompute insn addresses.  */
4805
4806   init_insn_lengths ();
4807   shorten_branches (get_insns ());
4808
4809   return pool_list;
4810 }
4811
4812 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4813    After we have decided to use this list, finish implementing 
4814    all changes to the current function as required.
4815
4816    Code generated by this routine is allowed to use
4817    TEMP_REG as temporary scratch register.  */
4818  
4819 static void
4820 s390_chunkify_finish (pool_list, temp_reg)
4821      struct constant_pool *pool_list;
4822      rtx temp_reg;
4823 {
4824   rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
4825   struct constant_pool *curr_pool = NULL;
4826   rtx insn;
4827  
4828  
4829   /* Replace all literal pool references.  */
4830
4831   for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 
4832     {
4833       curr_pool = s390_find_pool (pool_list, insn);
4834       if (!curr_pool)
4835         continue;
4836
4837       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4838         {
4839           rtx addr, pool_ref = NULL_RTX;
4840           find_constant_pool_ref (PATTERN (insn), &pool_ref);
4841           if (pool_ref)
4842             {
4843               addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
4844                                                     get_pool_mode (pool_ref));
4845               addr = gen_rtx_PLUS (Pmode, base_reg, addr);
4846               replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4847               INSN_CODE (insn) = -1;
4848             }
4849
4850           else if (!TARGET_64BIT && flag_pic
4851                    && find_base_register_ref (PATTERN (insn)))
4852             {
4853               replace_base_register_ref (&PATTERN (insn), temp_reg);
4854             }
4855         }
4856     }
4857
4858   /* Dump out all literal pools.  */
4859  
4860   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4861     s390_dump_pool (curr_pool);
4862  
4863   /* Free pool list.  */
4864
4865   while (pool_list)
4866     {
4867       struct constant_pool *next = pool_list->next;
4868       s390_free_pool (pool_list);
4869       pool_list = next;
4870     }
4871 }
4872
4873 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4874    We have decided we cannot use this list, so revert all changes
4875    to the current function that were done by s390_chunkify_start.  */
4876  
4877 static void
4878 s390_chunkify_cancel (pool_list)
4879      struct constant_pool *pool_list;
4880 {
4881   struct constant_pool *curr_pool = NULL;
4882   rtx insn;
4883
4884   /* Remove all pool placeholder insns.  */
4885
4886   for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4887     {
4888       /* Did we insert an extra barrier?  Remove it.  */
4889       rtx barrier = PREV_INSN (curr_pool->pool_insn);
4890       rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
4891       rtx label = NEXT_INSN (curr_pool->pool_insn);
4892
4893       if (jump && GET_CODE (jump) == JUMP_INSN
4894           && barrier && GET_CODE (barrier) == BARRIER
4895           && label && GET_CODE (label) == CODE_LABEL
4896           && GET_CODE (PATTERN (jump)) == SET
4897           && SET_DEST (PATTERN (jump)) == pc_rtx
4898           && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
4899           && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
4900         {
4901           remove_insn (jump);
4902           remove_insn (barrier);
4903           remove_insn (label);
4904         }
4905
4906       remove_insn (curr_pool->pool_insn);
4907     }
4908
4909   /* Remove all base/anchor register reload insns.  */
4910
4911   for (insn = get_insns (); insn; )
4912     {
4913       rtx next_insn = NEXT_INSN (insn);
4914
4915       if (GET_CODE (insn) == INSN
4916           && GET_CODE (PATTERN (insn)) == SET
4917           && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
4918           && (XINT (SET_SRC (PATTERN (insn)), 1) == 210
4919               || XINT (SET_SRC (PATTERN (insn)), 1) == 211))
4920         remove_insn (insn);
4921
4922       insn = next_insn;
4923     }
4924
4925   /* Free pool list.  */
4926
4927   while (pool_list)
4928     {
4929       struct constant_pool *next = pool_list->next;
4930       s390_free_pool (pool_list);
4931       pool_list = next;
4932     }
4933 }
4934
4935
4936 /* Index of constant pool chunk that is currently being processed.
4937    Set to -1 before function output has started.  */
4938 int s390_pool_count = -1;
4939
4940 /* Number of elements of current constant pool.  */
4941 int s390_nr_constants;
4942
4943 /* Output main constant pool to stdio stream FILE.  */ 
4944
4945 void
4946 s390_output_constant_pool (start_label, end_label)
4947      rtx start_label;
4948      rtx end_label;
4949 {
4950   if (TARGET_64BIT) 
4951     {
4952       readonly_data_section ();
4953       ASM_OUTPUT_ALIGN (asm_out_file, 3);
4954       (*targetm.asm_out.internal_label) (asm_out_file, "L", 
4955                                          CODE_LABEL_NUMBER (start_label));
4956     } 
4957   else 
4958     {
4959       (*targetm.asm_out.internal_label) (asm_out_file, "L",
4960                                          CODE_LABEL_NUMBER (start_label));
4961       ASM_OUTPUT_ALIGN (asm_out_file, 2);      
4962     }
4963
4964   s390_pool_count = 0;
4965   output_constant_pool (current_function_name, current_function_decl);
4966   s390_pool_count = -1;
4967   if (TARGET_64BIT)
4968     function_section (current_function_decl);
4969   else
4970     {
4971       ASM_OUTPUT_ALIGN (asm_out_file, 1);
4972       (*targetm.asm_out.internal_label) (asm_out_file, "L", 
4973                                          CODE_LABEL_NUMBER (end_label));
4974     }
4975 }
4976
4977 /* Rework the prolog/epilog to avoid saving/restoring
4978    registers unnecessarily.  If TEMP_REGNO is nonnegative,
4979    it specifies the number of a caller-saved register used 
4980    as temporary scratch register by code emitted during 
4981    machine dependent reorg.  */
4982
4983 static void
4984 s390_optimize_prolog (temp_regno)
4985      int temp_regno;
4986 {
4987   int save_first, save_last, restore_first, restore_last;
4988   int i, j;
4989   rtx insn, new_insn, next_insn;
4990
4991   /* Recompute regs_ever_live data for special registers.  */
4992   regs_ever_live[BASE_REGISTER] = 0;
4993   regs_ever_live[RETURN_REGNUM] = 0;
4994   regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
4995
4996   /* If there is (possibly) any pool entry, we need to
4997      load the base register.  
4998      ??? FIXME: this should be more precise.  */
4999   if (get_pool_size ())
5000     regs_ever_live[BASE_REGISTER] = 1;
5001
5002   /* In non-leaf functions, the prolog/epilog code relies 
5003      on RETURN_REGNUM being saved in any case.  */
5004   if (!current_function_is_leaf)
5005     regs_ever_live[RETURN_REGNUM] = 1;
5006
5007   /* We need to save/restore the temporary register.  */
5008   if (temp_regno >= 0)
5009     regs_ever_live[temp_regno] = 1;
5010
5011
5012   /* Find first and last gpr to be saved.  */
5013   
5014   for (i = 6; i < 16; i++)
5015     if (regs_ever_live[i])
5016       if (!global_regs[i]
5017           || i == STACK_POINTER_REGNUM 
5018           || i == RETURN_REGNUM
5019           || i == BASE_REGISTER 
5020           || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5021         break;
5022
5023   for (j = 15; j > i; j--)
5024     if (regs_ever_live[j])
5025       if (!global_regs[j]
5026           || j == STACK_POINTER_REGNUM 
5027           || j == RETURN_REGNUM
5028           || j == BASE_REGISTER 
5029           || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
5030         break;
5031
5032   if (i == 16)
5033     {
5034       /* Nothing to save/restore.  */
5035       save_first = restore_first = -1;
5036       save_last = restore_last = -1;
5037     }
5038   else
5039     {
5040       /* Save/restore from i to j.  */
5041       save_first = restore_first = i;
5042       save_last = restore_last = j;
5043     }
5044
5045   /* Varargs functions need to save gprs 2 to 6.  */
5046   if (current_function_stdarg)
5047     {
5048       save_first = 2;
5049       if (save_last < 6)
5050         save_last = 6;
5051     }
5052
5053
5054   /* If all special registers are in fact used, there's nothing we
5055      can do, so no point in walking the insn list.  */
5056   if (i <= BASE_REGISTER && j >= BASE_REGISTER
5057       && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
5058     return;
5059
5060
5061   /* Search for prolog/epilog insns and replace them.  */
5062
5063   for (insn = get_insns (); insn; insn = next_insn)
5064     {
5065       int first, last, off;
5066       rtx set, base, offset;
5067
5068       next_insn = NEXT_INSN (insn);
5069
5070       if (GET_CODE (insn) != INSN)
5071         continue;
5072       if (GET_CODE (PATTERN (insn)) != PARALLEL)
5073         continue;
5074
5075       if (store_multiple_operation (PATTERN (insn), VOIDmode))
5076         {
5077           set = XVECEXP (PATTERN (insn), 0, 0);
5078           first = REGNO (SET_SRC (set));
5079           last = first + XVECLEN (PATTERN (insn), 0) - 1;
5080           offset = const0_rtx;
5081           base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5082           off = INTVAL (offset) - first * UNITS_PER_WORD;
5083
5084           if (GET_CODE (base) != REG || off < 0)
5085             continue;
5086           if (first > BASE_REGISTER && first > RETURN_REGNUM)
5087             continue;
5088           if (last < BASE_REGISTER && last < RETURN_REGNUM)
5089             continue;
5090
5091           if (save_first != -1)
5092             {
5093               new_insn = save_gprs (base, off, save_first, save_last);
5094               new_insn = emit_insn_before (new_insn, insn);
5095               INSN_ADDRESSES_NEW (new_insn, -1);
5096             }
5097
5098           remove_insn (insn);
5099         }
5100
5101       if (load_multiple_operation (PATTERN (insn), VOIDmode))
5102         {
5103           set = XVECEXP (PATTERN (insn), 0, 0);
5104           first = REGNO (SET_DEST (set));
5105           last = first + XVECLEN (PATTERN (insn), 0) - 1;
5106           offset = const0_rtx;
5107           base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5108           off = INTVAL (offset) - first * UNITS_PER_WORD;
5109
5110           if (GET_CODE (base) != REG || off < 0)
5111             continue;
5112           if (first > BASE_REGISTER && first > RETURN_REGNUM)
5113             continue;
5114           if (last < BASE_REGISTER && last < RETURN_REGNUM)
5115             continue;
5116
5117           if (restore_first != -1)
5118             {
5119               new_insn = restore_gprs (base, off, restore_first, restore_last);
5120               new_insn = emit_insn_before (new_insn, insn);
5121               INSN_ADDRESSES_NEW (new_insn, -1);
5122             }
5123
5124           remove_insn (insn);
5125         }
5126     }
5127 }
5128
5129 /* Check whether any insn in the function makes use of the original
5130    value of RETURN_REG (e.g. for __builtin_return_address).
5131    If so, insert an insn reloading that value.
5132
5133    Return true if any such insn was found.  */
5134
5135 static bool
5136 s390_fixup_clobbered_return_reg (return_reg)
5137     rtx return_reg;
5138 {
5139   bool replacement_done = 0;
5140   rtx insn;
5141
5142   /* If we never called __builtin_return_address, register 14
5143      might have been used as temp during the prolog; we do
5144      not want to touch those uses.  */
5145   if (!has_hard_reg_initial_val (Pmode, REGNO (return_reg)))
5146     return false;
5147
5148   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5149     {
5150       rtx reg, off, new_insn;
5151
5152       if (GET_CODE (insn) != INSN)
5153         continue;
5154       if (!reg_referenced_p (return_reg, PATTERN (insn)))
5155         continue;
5156       if (GET_CODE (PATTERN (insn)) == PARALLEL
5157           && store_multiple_operation (PATTERN (insn), VOIDmode))
5158         continue;
5159
5160       if (frame_pointer_needed)
5161         reg = hard_frame_pointer_rtx;
5162       else
5163         reg = stack_pointer_rtx;
5164
5165       off = GEN_INT (cfun->machine->frame_size + REGNO (return_reg) * UNITS_PER_WORD);
5166       if (!DISP_IN_RANGE (INTVAL (off)))
5167         {
5168           off = force_const_mem (Pmode, off);
5169           new_insn = gen_rtx_SET (Pmode, return_reg, off);
5170           new_insn = emit_insn_before (new_insn, insn);
5171           INSN_ADDRESSES_NEW (new_insn, -1);
5172           off = return_reg;
5173         }
5174
5175       new_insn = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, reg, off));
5176       new_insn = gen_rtx_SET (Pmode, return_reg, new_insn);
5177       new_insn = emit_insn_before (new_insn, insn);
5178       INSN_ADDRESSES_NEW (new_insn, -1);
5179
5180       replacement_done = 1;
5181     }
5182
5183   return replacement_done;
5184 }
5185
5186 /* Perform machine-dependent processing.  */
5187
5188 static void
5189 s390_reorg ()
5190 {
5191   bool fixed_up_clobbered_return_reg = 0;
5192   rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5193   bool temp_used = 0;
5194
5195   /* Make sure all splits have been performed; splits after
5196      machine_dependent_reorg might confuse insn length counts.  */
5197   split_all_insns_noflow ();
5198
5199
5200   /* There are two problematic situations we need to correct:
5201  
5202      - the literal pool might be > 4096 bytes in size, so that
5203        some of its elements cannot be directly accessed
5204  
5205      - a branch target might be > 64K away from the branch, so that
5206        it is not possible to use a PC-relative instruction.
5207  
5208      To fix those, we split the single literal pool into multiple
5209      pool chunks, reloading the pool base register at various
5210      points throughout the function to ensure it always points to
5211      the pool chunk the following code expects, and / or replace
5212      PC-relative branches by absolute branches.
5213  
5214      However, the two problems are interdependent: splitting the
5215      literal pool can move a branch further away from its target,
5216      causing the 64K limit to overflow, and on the other hand,
5217      replacing a PC-relative branch by an absolute branch means
5218      we need to put the branch target address into the literal
5219      pool, possibly causing it to overflow.
5220  
5221      So, we loop trying to fix up both problems until we manage
5222      to satisfy both conditions at the same time.  Note that the
5223      loop is guaranteed to terminate as every pass of the loop
5224      strictly decreases the total number of PC-relative branches
5225      in the function.  (This is not completely true as there
5226      might be branch-over-pool insns introduced by chunkify_start.
5227      Those never need to be split however.)  */
5228  
5229   for (;;)
5230     {
5231       struct constant_pool *pool_list;
5232  
5233       /* Try to chunkify the literal pool.  */
5234       pool_list = s390_chunkify_start (temp_reg, &temp_used);
5235
5236       /* Split out-of-range branches.  If this has created new
5237          literal pool entries, cancel current chunk list and
5238          recompute it.  */
5239       if (s390_split_branches (temp_reg, &temp_used))
5240         {
5241           if (pool_list)
5242             s390_chunkify_cancel (pool_list);
5243  
5244           continue;
5245         }
5246
5247       /* Check whether we have clobbered a use of the return
5248          register (e.g. for __builtin_return_address).  If so,
5249          add insns reloading the register where necessary.  */
5250       if (temp_used && !fixed_up_clobbered_return_reg
5251           && s390_fixup_clobbered_return_reg (temp_reg))
5252         {
5253           fixed_up_clobbered_return_reg = 1;
5254
5255           /* The fixup insns might have caused a jump to overflow.  */
5256           if (pool_list)
5257             s390_chunkify_cancel (pool_list);
5258
5259           continue;
5260         }
5261  
5262       /* If we made it up to here, both conditions are satisfied.
5263          Finish up pool chunkification if required.  */
5264       if (pool_list)
5265         s390_chunkify_finish (pool_list, temp_reg);
5266  
5267       break;
5268     }
5269  
5270   s390_optimize_prolog (temp_used? RETURN_REGNUM : -1);
5271 }
5272
5273
5274 /* Return an RTL expression representing the value of the return address
5275    for the frame COUNT steps up from the current frame.  FRAME is the
5276    frame pointer of that frame.  */
5277
5278 rtx
5279 s390_return_addr_rtx (count, frame)
5280      int count;
5281      rtx frame;
5282 {
5283   rtx addr;
5284
5285   /* For the current frame, we use the initial value of RETURN_REGNUM.
5286      This works both in leaf and non-leaf functions.  */
5287
5288   if (count == 0)
5289     return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
5290
5291   /* For frames farther back, we read the stack slot where the
5292      corresponding RETURN_REGNUM value was saved.  */
5293
5294   addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
5295   addr = memory_address (Pmode, addr);
5296   return gen_rtx_MEM (Pmode, addr);
5297
5298
5299 /* Find first call clobbered register unsused in a function.
5300    This could be used as base register in a leaf function
5301    or for holding the return address before epilogue.  */
5302
5303 static int
5304 find_unused_clobbered_reg ()
5305 {
5306   int i;
5307   for (i = 0; i < 6; i++)
5308     if (!regs_ever_live[i])
5309       return i;
5310   return 0;
5311 }
5312
5313 /* Fill FRAME with info about frame of current function.  */
5314
5315 static void
5316 s390_frame_info ()
5317 {
5318   char gprs_ever_live[16];
5319   int i, j;
5320   HOST_WIDE_INT fsize = get_frame_size ();
5321
5322   if (fsize > 0x7fff0000)
5323     fatal_error ("Total size of local variables exceeds architecture limit.");
5324
5325   /* fprs 8 - 15 are caller saved for 64 Bit ABI.  */
5326   cfun->machine->save_fprs_p = 0;
5327   if (TARGET_64BIT)
5328     for (i = 24; i < 32; i++) 
5329       if (regs_ever_live[i] && !global_regs[i])
5330         {
5331           cfun->machine->save_fprs_p = 1;
5332           break;
5333         }
5334
5335   cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
5336
5337   /* Does function need to setup frame and save area.  */
5338   
5339   if (! current_function_is_leaf
5340       || cfun->machine->frame_size > 0
5341       || current_function_calls_alloca 
5342       || current_function_stdarg)
5343     cfun->machine->frame_size += STARTING_FRAME_OFFSET;
5344
5345   /* Find first and last gpr to be saved.  Note that at this point,
5346      we assume the return register and the base register always
5347      need to be saved.  This is done because the usage of these
5348      register might change even after the prolog was emitted.
5349      If it turns out later that we really don't need them, the
5350      prolog/epilog code is modified again.  */
5351
5352   for (i = 0; i < 16; i++)
5353     gprs_ever_live[i] = regs_ever_live[i] && !global_regs[i];
5354
5355   if (flag_pic)
5356     gprs_ever_live[PIC_OFFSET_TABLE_REGNUM] =
5357     regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
5358   gprs_ever_live[BASE_REGISTER] = 1;
5359   gprs_ever_live[RETURN_REGNUM] = 1;
5360   gprs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
5361   
5362   for (i = 6; i < 16; i++)
5363     if (gprs_ever_live[i])
5364       break;
5365
5366   for (j = 15; j > i; j--)
5367     if (gprs_ever_live[j])
5368       break;
5369
5370
5371   /* Save / Restore from gpr i to j.  */
5372   cfun->machine->first_save_gpr = i;
5373   cfun->machine->first_restore_gpr = i;
5374   cfun->machine->last_save_gpr  = j;
5375
5376   /* Varargs functions need to save gprs 2 to 6.  */
5377   if (current_function_stdarg)
5378     cfun->machine->first_save_gpr = 2;
5379 }
5380
5381 /* Return offset between argument pointer and frame pointer 
5382    initially after prologue.  */
5383
5384 int 
5385 s390_arg_frame_offset ()
5386 {
5387   HOST_WIDE_INT fsize = get_frame_size ();
5388   int save_fprs_p, i;
5389
5390   /* fprs 8 - 15 are caller saved for 64 Bit ABI.  */
5391   save_fprs_p = 0;
5392   if (TARGET_64BIT)
5393     for (i = 24; i < 32; i++) 
5394       if (regs_ever_live[i] && !global_regs[i])
5395         {
5396           save_fprs_p = 1;
5397           break;
5398         }
5399
5400   fsize = fsize + save_fprs_p * 64;
5401
5402   /* Does function need to setup frame and save area.  */
5403   
5404   if (! current_function_is_leaf
5405       || fsize > 0
5406       || current_function_calls_alloca 
5407       || current_function_stdarg)
5408     fsize += STARTING_FRAME_OFFSET;
5409   return fsize + STACK_POINTER_OFFSET;
5410 }
5411
5412 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5413    to register BASE.  Return generated insn.  */ 
5414
5415 static rtx
5416 save_fpr (base, offset, regnum)
5417      rtx base;
5418      int offset;
5419      int regnum;     
5420 {
5421   rtx addr;
5422   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5423   set_mem_alias_set (addr, s390_sr_alias_set);
5424
5425   return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
5426 }
5427
5428 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5429    to register BASE.  Return generated insn.  */ 
5430
5431 static rtx
5432 restore_fpr (base, offset, regnum)
5433      rtx base;
5434      int offset;
5435      int regnum;
5436 {
5437   rtx addr;
5438   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5439   set_mem_alias_set (addr, s390_sr_alias_set);
5440
5441   return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
5442 }
5443
5444 /* Generate insn to save registers FIRST to LAST into
5445    the register save area located at offset OFFSET 
5446    relative to register BASE.  */
5447
5448 static rtx
5449 save_gprs (base, offset, first, last)
5450      rtx base;
5451      int offset;
5452      int first;
5453      int last;
5454 {
5455   rtx addr, insn, note;
5456   int i;
5457
5458   addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5459   addr = gen_rtx_MEM (Pmode, addr);
5460   set_mem_alias_set (addr, s390_sr_alias_set);
5461
5462   /* Special-case single register.  */
5463   if (first == last)
5464     {
5465       if (TARGET_64BIT)
5466         insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
5467       else
5468         insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
5469
5470       RTX_FRAME_RELATED_P (insn) = 1;
5471       return insn;
5472     }
5473
5474
5475   insn = gen_store_multiple (addr,
5476                              gen_rtx_REG (Pmode, first),
5477                              GEN_INT (last - first + 1));
5478
5479
5480   /* We need to set the FRAME_RELATED flag on all SETs
5481      inside the store-multiple pattern.
5482
5483      However, we must not emit DWARF records for registers 2..5
5484      if they are stored for use by variable arguments ...  
5485
5486      ??? Unfortunately, it is not enough to simply not the the
5487      FRAME_RELATED flags for those SETs, because the first SET
5488      of the PARALLEL is always treated as if it had the flag
5489      set, even if it does not.  Therefore we emit a new pattern
5490      without those registers as REG_FRAME_RELATED_EXPR note.  */
5491
5492   if (first >= 6)
5493     {
5494       rtx pat = PATTERN (insn);
5495
5496       for (i = 0; i < XVECLEN (pat, 0); i++)
5497         if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
5498           RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
5499
5500       RTX_FRAME_RELATED_P (insn) = 1;
5501     }
5502   else if (last >= 6)
5503     {
5504       addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
5505       note = gen_store_multiple (gen_rtx_MEM (Pmode, addr), 
5506                                  gen_rtx_REG (Pmode, 6),
5507                                  GEN_INT (last - 6 + 1));
5508       note = PATTERN (note);
5509
5510       REG_NOTES (insn) =
5511         gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, 
5512                            note, REG_NOTES (insn));
5513
5514       for (i = 0; i < XVECLEN (note, 0); i++)
5515         if (GET_CODE (XVECEXP (note, 0, i)) == SET)
5516           RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
5517
5518       RTX_FRAME_RELATED_P (insn) = 1;
5519     }
5520
5521   return insn;
5522 }
5523
5524 /* Generate insn to restore registers FIRST to LAST from
5525    the register save area located at offset OFFSET 
5526    relative to register BASE.  */
5527
5528 static rtx
5529 restore_gprs (base, offset, first, last)
5530      rtx base;
5531      int offset;
5532      int first;
5533      int last;
5534 {
5535   rtx addr, insn;
5536
5537   addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5538   addr = gen_rtx_MEM (Pmode, addr);
5539   set_mem_alias_set (addr, s390_sr_alias_set);
5540
5541   /* Special-case single register.  */
5542   if (first == last)
5543     {
5544       if (TARGET_64BIT)
5545         insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
5546       else
5547         insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
5548
5549       return insn;
5550     }
5551
5552   insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
5553                             addr,
5554                             GEN_INT (last - first + 1));
5555   return insn;
5556 }
5557
5558 /* Expand the prologue into a bunch of separate insns.  */
5559
5560 void
5561 s390_emit_prologue ()
5562 {
5563   rtx insn, addr;
5564   rtx temp_reg;
5565   rtx pool_start_label, pool_end_label;
5566   int i;
5567
5568   /* Compute frame_info.  */
5569
5570   s390_frame_info ();
5571
5572   /* Choose best register to use for temp use within prologue.  */
5573   
5574   if (!current_function_is_leaf
5575       && !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
5576       && get_pool_size () < S390_POOL_CHUNK_MAX / 2)
5577     temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5578   else
5579     temp_reg = gen_rtx_REG (Pmode, 1);
5580
5581   /* Save call saved gprs.  */
5582
5583   insn = save_gprs (stack_pointer_rtx, 0, 
5584                     cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
5585   emit_insn (insn);
5586
5587   /* Dump constant pool and set constant pool register.  */
5588
5589   pool_start_label = gen_label_rtx();
5590   pool_end_label = gen_label_rtx();
5591   cfun->machine->literal_pool_label = pool_start_label;
5592   
5593   if (TARGET_64BIT)
5594     insn = emit_insn (gen_literal_pool_64 (gen_rtx_REG (Pmode, BASE_REGISTER),
5595                                            pool_start_label, pool_end_label));
5596   else
5597     insn = emit_insn (gen_literal_pool_31 (gen_rtx_REG (Pmode, BASE_REGISTER),
5598                                              pool_start_label, pool_end_label));  
5599   
5600   /* Save fprs for variable args.  */
5601
5602   if (current_function_stdarg)
5603     {
5604       /* Save fpr 0 and 2.  */ 
5605
5606       save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 32, 16); 
5607       save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 24, 17); 
5608       
5609       if (TARGET_64BIT)
5610         {
5611           /* Save fpr 4 and 6.  */
5612  
5613           save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18); 
5614           save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19); 
5615         }
5616     }
5617
5618   /* Save fprs 4 and 6 if used (31 bit ABI).  */
5619
5620   if (!TARGET_64BIT)
5621     {
5622       /* Save fpr 4 and 6.  */
5623       if (regs_ever_live[18] && !global_regs[18])
5624         {
5625           insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
5626           RTX_FRAME_RELATED_P (insn) = 1;
5627         }
5628       if (regs_ever_live[19] && !global_regs[19])
5629         {
5630           insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19); 
5631           RTX_FRAME_RELATED_P (insn) = 1;
5632         }
5633     }
5634
5635   /* Decrement stack pointer.  */
5636
5637   if (cfun->machine->frame_size > 0)
5638     {
5639       rtx frame_off = GEN_INT (-cfun->machine->frame_size);
5640
5641       /* Save incoming stack pointer into temp reg.  */
5642       
5643       if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
5644         {
5645           insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
5646         }
5647       
5648       /* Substract frame size from stack pointer.  */
5649
5650       if (DISP_IN_RANGE (INTVAL (frame_off)))
5651         {
5652           insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx, 
5653                               gen_rtx_PLUS (Pmode, stack_pointer_rtx, 
5654                                             frame_off));
5655           insn = emit_insn (insn);
5656         }
5657       else
5658         {
5659           if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
5660             frame_off = force_const_mem (Pmode, frame_off);
5661
5662           insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
5663         }
5664
5665       RTX_FRAME_RELATED_P (insn) = 1;
5666       REG_NOTES (insn) = 
5667         gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5668                            gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5669                                    gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5670                                    GEN_INT (-cfun->machine->frame_size))),
5671                            REG_NOTES (insn));
5672
5673       /* Set backchain.  */
5674       
5675       if (TARGET_BACKCHAIN)
5676         {
5677           addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
5678           set_mem_alias_set (addr, s390_sr_alias_set);
5679           insn = emit_insn (gen_move_insn (addr, temp_reg));
5680         }
5681
5682       /* If we support asynchronous exceptions (e.g. for Java),
5683          we need to make sure the backchain pointer is set up
5684          before any possibly trapping memory access.  */
5685
5686       if (TARGET_BACKCHAIN && flag_non_call_exceptions)
5687         {
5688           addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
5689           emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
5690         }
5691     }
5692
5693   /* Save fprs 8 - 15 (64 bit ABI).  */
5694   
5695   if (cfun->machine->save_fprs_p)
5696     {
5697       insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
5698
5699       for (i = 24; i < 32; i++)
5700         if (regs_ever_live[i] && !global_regs[i])
5701           {
5702             rtx addr = plus_constant (stack_pointer_rtx, 
5703                                       cfun->machine->frame_size - 64 + (i-24)*8);
5704
5705             insn = save_fpr (temp_reg, (i-24)*8, i);
5706             RTX_FRAME_RELATED_P (insn) = 1;
5707             REG_NOTES (insn) = 
5708               gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5709                 gen_rtx_SET (VOIDmode, 
5710                              gen_rtx_MEM (DFmode, addr),
5711                              gen_rtx_REG (DFmode, i)),
5712                 REG_NOTES (insn));
5713           }
5714     }
5715             
5716   /* Set frame pointer, if needed.  */
5717   
5718   if (frame_pointer_needed)
5719     {
5720       insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
5721       RTX_FRAME_RELATED_P (insn) = 1;
5722     }
5723
5724   /* Set up got pointer, if needed.  */
5725   
5726   if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5727     {
5728       rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5729       SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
5730
5731       if (TARGET_64BIT)
5732         {
5733           insn = emit_insn (gen_movdi (pic_offset_table_rtx,
5734                                        got_symbol));             
5735
5736           /* It can happen that the GOT pointer isn't really needed ...  */
5737           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5738                                                REG_NOTES (insn));
5739         }
5740       else
5741         {
5742           got_symbol = gen_rtx_UNSPEC (VOIDmode, 
5743                                        gen_rtvec (1, got_symbol), 100);
5744           got_symbol = gen_rtx_CONST (VOIDmode, got_symbol);
5745           got_symbol = force_const_mem (Pmode, got_symbol);
5746           insn = emit_move_insn (pic_offset_table_rtx,
5747                                  got_symbol);            
5748           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5749                                                REG_NOTES (insn));
5750
5751           got_symbol = gen_rtx_REG (Pmode, BASE_REGISTER);
5752           got_symbol = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol), 101);
5753           got_symbol = gen_rtx_PLUS (Pmode, got_symbol, pic_offset_table_rtx);
5754           insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
5755           REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5756                                                REG_NOTES (insn));
5757         }
5758     }      
5759 }
5760
5761 /* Expand the epilogue into a bunch of separate insns.  */
5762
5763 void
5764 s390_emit_epilogue ()
5765 {
5766   rtx frame_pointer, return_reg;
5767   int area_bottom, area_top, offset = 0;
5768   rtvec p;
5769
5770   /* Check whether to use frame or stack pointer for restore.  */
5771
5772   frame_pointer = frame_pointer_needed ? 
5773     hard_frame_pointer_rtx : stack_pointer_rtx;
5774
5775   /* Compute which parts of the save area we need to access.  */
5776
5777   if (cfun->machine->first_restore_gpr != -1)
5778     {
5779       area_bottom = cfun->machine->first_restore_gpr * UNITS_PER_WORD;
5780       area_top = (cfun->machine->last_save_gpr + 1) * UNITS_PER_WORD;
5781     }
5782   else
5783     {
5784       area_bottom = INT_MAX;
5785       area_top = INT_MIN;
5786     }
5787
5788   if (TARGET_64BIT)
5789     {
5790       if (cfun->machine->save_fprs_p)
5791         {
5792           if (area_bottom > -64)
5793             area_bottom = -64;
5794           if (area_top < 0)
5795             area_top = 0;
5796         }
5797     }
5798   else
5799     {
5800       if (regs_ever_live[18] && !global_regs[18])
5801         {
5802           if (area_bottom > STACK_POINTER_OFFSET - 16)
5803             area_bottom = STACK_POINTER_OFFSET - 16;
5804           if (area_top < STACK_POINTER_OFFSET - 8)
5805             area_top = STACK_POINTER_OFFSET - 8;
5806         }
5807       if (regs_ever_live[19] && !global_regs[19])
5808         {
5809           if (area_bottom > STACK_POINTER_OFFSET - 8)
5810             area_bottom = STACK_POINTER_OFFSET - 8;
5811           if (area_top < STACK_POINTER_OFFSET)
5812             area_top = STACK_POINTER_OFFSET;
5813         }
5814     }
5815
5816   /* Check whether we can access the register save area.  
5817      If not, increment the frame pointer as required.  */
5818
5819   if (area_top <= area_bottom)
5820     {
5821       /* Nothing to restore.  */
5822     }
5823   else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
5824            && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
5825     {
5826       /* Area is in range.  */
5827       offset = cfun->machine->frame_size;
5828     }
5829   else
5830     {
5831       rtx insn, frame_off;
5832
5833       offset = area_bottom < 0 ? -area_bottom : 0; 
5834       frame_off = GEN_INT (cfun->machine->frame_size - offset);
5835
5836       if (DISP_IN_RANGE (INTVAL (frame_off)))
5837         {
5838           insn = gen_rtx_SET (VOIDmode, frame_pointer, 
5839                               gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
5840           insn = emit_insn (insn);
5841         }
5842       else
5843         {
5844           if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
5845             frame_off = force_const_mem (Pmode, frame_off);
5846
5847           insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
5848         }
5849     }
5850
5851   /* Restore call saved fprs.  */
5852
5853   if (TARGET_64BIT)
5854     {
5855       int i;
5856
5857       if (cfun->machine->save_fprs_p)
5858         for (i = 24; i < 32; i++)
5859           if (regs_ever_live[i] && !global_regs[i])
5860             restore_fpr (frame_pointer, 
5861                          offset - 64 + (i-24) * 8, i);
5862     }
5863   else
5864     {
5865       if (regs_ever_live[18] && !global_regs[18])
5866         restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 16, 18);
5867       if (regs_ever_live[19] && !global_regs[19])
5868         restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 8, 19);
5869     }
5870
5871   /* Return register.  */
5872
5873   return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM); 
5874
5875   /* Restore call saved gprs.  */
5876
5877   if (cfun->machine->first_restore_gpr != -1)
5878     {
5879       rtx insn, addr;
5880       int i;
5881
5882       /* Check for global register and save them 
5883          to stack location from where they get restored.  */
5884
5885       for (i = cfun->machine->first_restore_gpr; 
5886            i <= cfun->machine->last_save_gpr;
5887            i++)
5888         {
5889           /* These registers are special and need to be 
5890              restored in any case.  */
5891           if (i == STACK_POINTER_REGNUM 
5892               || i == RETURN_REGNUM
5893               || i == BASE_REGISTER 
5894               || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5895             continue;
5896
5897           if (global_regs[i])
5898             {
5899               addr = plus_constant (frame_pointer, 
5900                      offset + i * UNITS_PER_WORD);
5901               addr = gen_rtx_MEM (Pmode, addr);
5902               set_mem_alias_set (addr, s390_sr_alias_set);
5903               emit_move_insn (addr, gen_rtx_REG (Pmode, i));
5904             }  
5905         }
5906
5907       /* Fetch return address from stack before load multiple,
5908          this will do good for scheduling.  */
5909
5910       if (!current_function_is_leaf)
5911         {
5912           int return_regnum = find_unused_clobbered_reg();
5913           if (!return_regnum)
5914             return_regnum = 4;
5915           return_reg = gen_rtx_REG (Pmode, return_regnum);
5916         
5917           addr = plus_constant (frame_pointer, 
5918                                 offset + RETURN_REGNUM * UNITS_PER_WORD); 
5919           addr = gen_rtx_MEM (Pmode, addr);
5920           set_mem_alias_set (addr, s390_sr_alias_set);
5921           emit_move_insn (return_reg, addr);
5922         }
5923
5924       /* ??? As references to the base register are not made
5925          explicit in insn RTX code, we have to add a barrier here
5926          to prevent incorrect scheduling.  */
5927
5928       emit_insn (gen_blockage());      
5929
5930       insn = restore_gprs (frame_pointer, offset, 
5931                            cfun->machine->first_restore_gpr, 
5932                            cfun->machine->last_save_gpr);
5933       emit_insn (insn);
5934     }
5935
5936   /* Return to caller.  */
5937
5938   p = rtvec_alloc (2);
5939   
5940   RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
5941   RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
5942   emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
5943 }
5944
5945
5946 /* Return the size in bytes of a function argument of 
5947    type TYPE and/or mode MODE.  At least one of TYPE or
5948    MODE must be specified.  */
5949
5950 static int
5951 s390_function_arg_size (mode, type)
5952      enum machine_mode mode;
5953      tree type;
5954 {
5955   if (type)
5956     return int_size_in_bytes (type);
5957
5958   /* No type info available for some library calls ...  */
5959   if (mode != BLKmode)
5960     return GET_MODE_SIZE (mode);
5961
5962   /* If we have neither type nor mode, abort */
5963   abort ();
5964 }
5965
5966 /* Return true if a function argument of type TYPE and mode MODE
5967    is to be passed in a floating-point register, if available.  */
5968
5969 static bool
5970 s390_function_arg_float (mode, type)
5971      enum machine_mode mode;
5972      tree type;
5973 {
5974   /* Soft-float changes the ABI: no floating-point registers are used.  */
5975   if (TARGET_SOFT_FLOAT)
5976     return false;
5977
5978   /* No type info available for some library calls ...  */
5979   if (!type)
5980     return mode == SFmode || mode == DFmode;
5981
5982   /* The ABI says that record types with a single member are treated
5983      just like that member would be.  */
5984   while (TREE_CODE (type) == RECORD_TYPE)
5985     {
5986       tree field, single = NULL_TREE;
5987
5988       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
5989         {
5990           if (TREE_CODE (field) != FIELD_DECL)
5991             continue;
5992
5993           if (single == NULL_TREE)
5994             single = TREE_TYPE (field);
5995           else
5996             return false;
5997         }
5998
5999       if (single == NULL_TREE)
6000         return false;
6001       else
6002         type = single;
6003     }
6004
6005   return TREE_CODE (type) == REAL_TYPE;
6006 }
6007
6008 /* Return 1 if a function argument of type TYPE and mode MODE
6009    is to be passed by reference.  The ABI specifies that only
6010    structures of size 1, 2, 4, or 8 bytes are passed by value,
6011    all other structures (and complex numbers) are passed by
6012    reference.  */
6013
6014 int
6015 s390_function_arg_pass_by_reference (mode, type)
6016      enum machine_mode mode;
6017      tree type;
6018 {
6019   int size = s390_function_arg_size (mode, type);
6020
6021   if (type)
6022     {
6023       if (AGGREGATE_TYPE_P (type) &&
6024           size != 1 && size != 2 && size != 4 && size != 8
6025           && !s390_function_arg_float (mode, type))
6026         return 1;
6027
6028       if (TREE_CODE (type) == COMPLEX_TYPE)
6029         return 1;
6030     }
6031     
6032   return 0;
6033 }
6034
6035 /* Update the data in CUM to advance over an argument of mode MODE and
6036    data type TYPE.  (TYPE is null for libcalls where that information
6037    may not be available.).  The boolean NAMED specifies whether the
6038    argument is a named argument (as opposed to an unnamed argument
6039    matching an ellipsis).  */
6040
6041 void
6042 s390_function_arg_advance (cum, mode, type, named)
6043      CUMULATIVE_ARGS *cum;
6044      enum machine_mode mode;
6045      tree type;
6046      int named ATTRIBUTE_UNUSED;
6047 {
6048   if (s390_function_arg_pass_by_reference (mode, type))
6049     {
6050       cum->gprs += 1;
6051     }
6052   else if (s390_function_arg_float (mode, type))
6053     {
6054       cum->fprs += 1;
6055     }
6056   else
6057     {
6058       int size = s390_function_arg_size (mode, type);
6059       cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6060     }
6061 }
6062
6063 /* Define where to put the arguments to a function.
6064    Value is zero to push the argument on the stack,
6065    or a hard register in which to store the argument.
6066
6067    MODE is the argument's machine mode.
6068    TYPE is the data type of the argument (as a tree).
6069     This is null for libcalls where that information may
6070     not be available.
6071    CUM is a variable of type CUMULATIVE_ARGS which gives info about
6072     the preceding args and about the function being called.
6073    NAMED is nonzero if this argument is a named parameter
6074     (otherwise it is an extra parameter matching an ellipsis).  
6075
6076    On S/390, we use general purpose registers 2 through 6 to
6077    pass integer, pointer, and certain structure arguments, and
6078    floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6079    to pass floating point arguments.  All remaining arguments
6080    are pushed to the stack.  */
6081
6082 rtx
6083 s390_function_arg (cum, mode, type, named)
6084      CUMULATIVE_ARGS *cum;
6085      enum machine_mode mode;
6086      tree type;
6087      int named ATTRIBUTE_UNUSED;
6088 {
6089   if (s390_function_arg_pass_by_reference (mode, type))
6090       return 0;
6091
6092   if (s390_function_arg_float (mode, type))
6093     {
6094       if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
6095         return 0;
6096       else
6097         return gen_rtx (REG, mode, cum->fprs + 16);
6098     }
6099   else
6100     {
6101       int size = s390_function_arg_size (mode, type);
6102       int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6103
6104       if (cum->gprs + n_gprs > 5)
6105         return 0;
6106       else
6107         return gen_rtx (REG, mode, cum->gprs + 2);
6108     }
6109 }
6110
6111
6112 /* Create and return the va_list datatype.
6113
6114    On S/390, va_list is an array type equivalent to
6115
6116       typedef struct __va_list_tag
6117         {
6118             long __gpr;
6119             long __fpr;
6120             void *__overflow_arg_area;
6121             void *__reg_save_area;
6122             
6123         } va_list[1];
6124
6125    where __gpr and __fpr hold the number of general purpose
6126    or floating point arguments used up to now, respectively,
6127    __overflow_arg_area points to the stack location of the 
6128    next argument passed on the stack, and __reg_save_area
6129    always points to the start of the register area in the
6130    call frame of the current function.  The function prologue
6131    saves all registers used for argument passing into this
6132    area if the function uses variable arguments.  */
6133
6134 tree
6135 s390_build_va_list ()
6136 {
6137   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6138
6139   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
6140
6141   type_decl =
6142     build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6143
6144   f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"), 
6145                       long_integer_type_node);
6146   f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"), 
6147                       long_integer_type_node);
6148   f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6149                       ptr_type_node);
6150   f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6151                       ptr_type_node);
6152
6153   DECL_FIELD_CONTEXT (f_gpr) = record;
6154   DECL_FIELD_CONTEXT (f_fpr) = record;
6155   DECL_FIELD_CONTEXT (f_ovf) = record;
6156   DECL_FIELD_CONTEXT (f_sav) = record;
6157
6158   TREE_CHAIN (record) = type_decl;
6159   TYPE_NAME (record) = type_decl;
6160   TYPE_FIELDS (record) = f_gpr;
6161   TREE_CHAIN (f_gpr) = f_fpr;
6162   TREE_CHAIN (f_fpr) = f_ovf;
6163   TREE_CHAIN (f_ovf) = f_sav;
6164
6165   layout_type (record);
6166
6167   /* The correct type is an array type of one element.  */
6168   return build_array_type (record, build_index_type (size_zero_node));
6169 }
6170
6171 /* Implement va_start by filling the va_list structure VALIST.
6172    STDARG_P is always true, and ignored.
6173    NEXTARG points to the first anonymous stack argument.
6174
6175    The following global variables are used to initialize
6176    the va_list structure:
6177
6178      current_function_args_info:
6179        holds number of gprs and fprs used for named arguments.
6180      current_function_arg_offset_rtx:
6181        holds the offset of the first anonymous stack argument
6182        (relative to the virtual arg pointer).  */
6183
6184 void
6185 s390_va_start (valist, nextarg)
6186      tree valist;
6187      rtx nextarg ATTRIBUTE_UNUSED;
6188 {
6189   HOST_WIDE_INT n_gpr, n_fpr;
6190   int off;
6191   tree f_gpr, f_fpr, f_ovf, f_sav;
6192   tree gpr, fpr, ovf, sav, t;
6193
6194   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6195   f_fpr = TREE_CHAIN (f_gpr);
6196   f_ovf = TREE_CHAIN (f_fpr);
6197   f_sav = TREE_CHAIN (f_ovf);
6198
6199   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6200   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6201   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6202   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6203   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6204
6205   /* Count number of gp and fp argument registers used.  */
6206
6207   n_gpr = current_function_args_info.gprs;
6208   n_fpr = current_function_args_info.fprs;
6209
6210   t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
6211   TREE_SIDE_EFFECTS (t) = 1;
6212   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6213
6214   t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
6215   TREE_SIDE_EFFECTS (t) = 1;
6216   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6217
6218   /* Find the overflow area.  */
6219   t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6220
6221   off = INTVAL (current_function_arg_offset_rtx);
6222   off = off < 0 ? 0 : off;
6223   if (TARGET_DEBUG_ARG)
6224     fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6225              (int)n_gpr, (int)n_fpr, off);
6226
6227   t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
6228
6229   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6230   TREE_SIDE_EFFECTS (t) = 1;
6231   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6232
6233   /* Find the register save area.  */
6234   t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
6235   t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6236              build_int_2 (-STACK_POINTER_OFFSET, -1));
6237   t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6238   TREE_SIDE_EFFECTS (t) = 1;
6239   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6240 }
6241
6242 /* Implement va_arg by updating the va_list structure 
6243    VALIST as required to retrieve an argument of type
6244    TYPE, and returning that argument. 
6245    
6246    Generates code equivalent to:
6247    
6248    if (integral value) {
6249      if (size  <= 4 && args.gpr < 5 ||
6250          size  > 4 && args.gpr < 4 ) 
6251        ret = args.reg_save_area[args.gpr+8]
6252      else
6253        ret = *args.overflow_arg_area++;
6254    } else if (float value) {
6255      if (args.fgpr < 2)
6256        ret = args.reg_save_area[args.fpr+64]
6257      else
6258        ret = *args.overflow_arg_area++;
6259    } else if (aggregate value) {
6260      if (args.gpr < 5)
6261        ret = *args.reg_save_area[args.gpr]
6262      else
6263        ret = **args.overflow_arg_area++;
6264    } */
6265
6266 rtx
6267 s390_va_arg (valist, type)
6268      tree valist;
6269      tree type;
6270 {
6271   tree f_gpr, f_fpr, f_ovf, f_sav;
6272   tree gpr, fpr, ovf, sav, reg, t, u;
6273   int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
6274   rtx lab_false, lab_over, addr_rtx, r;
6275
6276   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6277   f_fpr = TREE_CHAIN (f_gpr);
6278   f_ovf = TREE_CHAIN (f_fpr);
6279   f_sav = TREE_CHAIN (f_ovf);
6280
6281   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6282   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6283   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6284   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6285   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6286
6287   size = int_size_in_bytes (type);
6288
6289   if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
6290     {
6291       if (TARGET_DEBUG_ARG)
6292         {
6293           fprintf (stderr, "va_arg: aggregate type");
6294           debug_tree (type);
6295         }
6296
6297       /* Aggregates are passed by reference.  */
6298       indirect_p = 1;
6299       reg = gpr;
6300       n_reg = 1;
6301       sav_ofs = 2 * UNITS_PER_WORD;
6302       sav_scale = UNITS_PER_WORD;
6303       size = UNITS_PER_WORD;
6304       max_reg = 4;
6305     }
6306   else if (s390_function_arg_float (TYPE_MODE (type), type))
6307     {
6308       if (TARGET_DEBUG_ARG)
6309         {
6310           fprintf (stderr, "va_arg: float type");
6311           debug_tree (type);
6312         }
6313
6314       /* FP args go in FP registers, if present.  */
6315       indirect_p = 0;
6316       reg = fpr;
6317       n_reg = 1;
6318       sav_ofs = 16 * UNITS_PER_WORD;
6319       sav_scale = 8;
6320       /* TARGET_64BIT has up to 4 parameter in fprs */
6321       max_reg = TARGET_64BIT ? 3 : 1;
6322     }
6323   else
6324     {
6325       if (TARGET_DEBUG_ARG)
6326         {
6327           fprintf (stderr, "va_arg: other type");
6328           debug_tree (type);
6329         }
6330
6331       /* Otherwise into GP registers.  */
6332       indirect_p = 0;
6333       reg = gpr;
6334       n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6335       sav_ofs = 2 * UNITS_PER_WORD;
6336       if (size < UNITS_PER_WORD)
6337         sav_ofs += UNITS_PER_WORD - size;
6338
6339       sav_scale = UNITS_PER_WORD;
6340       if (n_reg > 1)
6341         max_reg = 3;
6342       else
6343         max_reg = 4;
6344     }
6345
6346   /* Pull the value out of the saved registers ...  */
6347
6348   lab_false = gen_label_rtx ();
6349   lab_over = gen_label_rtx ();
6350   addr_rtx = gen_reg_rtx (Pmode);
6351
6352   emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
6353                            GEN_INT (max_reg),
6354                            GT, const1_rtx, Pmode, 0, lab_false);
6355
6356   if (sav_ofs)
6357     t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
6358   else
6359     t = sav;
6360
6361   u = build (MULT_EXPR, long_integer_type_node,
6362              reg, build_int_2 (sav_scale, 0));
6363   TREE_SIDE_EFFECTS (u) = 1;
6364
6365   t = build (PLUS_EXPR, ptr_type_node, t, u);
6366   TREE_SIDE_EFFECTS (t) = 1;
6367
6368   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6369   if (r != addr_rtx)
6370     emit_move_insn (addr_rtx, r);
6371
6372
6373   emit_jump_insn (gen_jump (lab_over));
6374   emit_barrier ();
6375   emit_label (lab_false);
6376
6377   /* ... Otherwise out of the overflow area.  */
6378
6379   t = save_expr (ovf);
6380
6381
6382   /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated.  */
6383   if (size < UNITS_PER_WORD)
6384     {
6385       t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
6386       t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6387       TREE_SIDE_EFFECTS (t) = 1;
6388       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6389
6390       t = save_expr (ovf);
6391     }
6392
6393   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6394   if (r != addr_rtx)
6395     emit_move_insn (addr_rtx, r);
6396
6397   t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
6398   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6399   TREE_SIDE_EFFECTS (t) = 1;
6400   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6401
6402   emit_label (lab_over);
6403
6404   /* If less than max_regs a registers are retrieved out 
6405      of register save area, increment.  */
6406
6407   u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg, 
6408              build_int_2 (n_reg, 0));
6409   TREE_SIDE_EFFECTS (u) = 1;
6410   expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
6411
6412   if (indirect_p)
6413     {
6414       r = gen_rtx_MEM (Pmode, addr_rtx);
6415       set_mem_alias_set (r, get_varargs_alias_set ());
6416       emit_move_insn (addr_rtx, r);
6417     }
6418
6419
6420   return addr_rtx;
6421 }
6422
6423
6424 /* Builtins.  */
6425
6426 enum s390_builtin
6427 {
6428   S390_BUILTIN_THREAD_POINTER,
6429   S390_BUILTIN_SET_THREAD_POINTER,
6430
6431   S390_BUILTIN_max
6432 };
6433
6434 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
6435   CODE_FOR_get_tp_64,
6436   CODE_FOR_set_tp_64
6437 };
6438
6439 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
6440   CODE_FOR_get_tp_31,
6441   CODE_FOR_set_tp_31
6442 };
6443
6444 static void
6445 s390_init_builtins ()
6446 {
6447   tree ftype;
6448
6449   ftype = build_function_type (ptr_type_node, void_list_node);
6450   builtin_function ("__builtin_thread_pointer", ftype,
6451                     S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6452                     NULL, NULL_TREE);
6453
6454   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6455   builtin_function ("__builtin_set_thread_pointer", ftype,
6456                     S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6457                     NULL, NULL_TREE);
6458 }
6459
6460 /* Expand an expression EXP that calls a built-in function,
6461    with result going to TARGET if that's convenient
6462    (and in mode MODE if that's convenient).
6463    SUBTARGET may be used as the target for computing one of EXP's operands.
6464    IGNORE is nonzero if the value is to be ignored.  */
6465
6466 static rtx
6467 s390_expand_builtin (exp, target, subtarget, mode, ignore)
6468      tree exp;
6469      rtx target;
6470      rtx subtarget ATTRIBUTE_UNUSED;
6471      enum machine_mode mode ATTRIBUTE_UNUSED;
6472      int ignore ATTRIBUTE_UNUSED;
6473 {
6474 #define MAX_ARGS 2
6475
6476   unsigned int const *code_for_builtin = 
6477     TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
6478
6479   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6480   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6481   tree arglist = TREE_OPERAND (exp, 1);
6482   enum insn_code icode;
6483   rtx op[MAX_ARGS], pat;
6484   int arity;
6485   bool nonvoid;
6486
6487   if (fcode >= S390_BUILTIN_max)
6488     internal_error ("bad builtin fcode");
6489   icode = code_for_builtin[fcode];
6490   if (icode == 0)
6491     internal_error ("bad builtin fcode");
6492
6493   nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6494
6495   for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6496        arglist;
6497        arglist = TREE_CHAIN (arglist), arity++)
6498     {
6499       const struct insn_operand_data *insn_op;
6500
6501       tree arg = TREE_VALUE (arglist);
6502       if (arg == error_mark_node)
6503         return NULL_RTX;
6504       if (arity > MAX_ARGS)
6505         return NULL_RTX;
6506
6507       insn_op = &insn_data[icode].operand[arity + nonvoid];
6508
6509       op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6510
6511       if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6512         op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6513     }
6514
6515   if (nonvoid)
6516     {
6517       enum machine_mode tmode = insn_data[icode].operand[0].mode;
6518       if (!target
6519           || GET_MODE (target) != tmode
6520           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6521         target = gen_reg_rtx (tmode);
6522     }
6523
6524   switch (arity)
6525     {
6526     case 0:
6527       pat = GEN_FCN (icode) (target);
6528       break;
6529     case 1:
6530       if (nonvoid)
6531         pat = GEN_FCN (icode) (target, op[0]);
6532       else
6533         pat = GEN_FCN (icode) (op[0]);
6534       break;
6535     case 2:
6536       pat = GEN_FCN (icode) (target, op[0], op[1]);
6537       break;
6538     default:
6539       abort ();
6540     }
6541   if (!pat)
6542     return NULL_RTX;
6543   emit_insn (pat);
6544
6545   if (nonvoid)
6546     return target;
6547   else
6548     return const0_rtx;
6549 }
6550
6551
6552 /* Output assembly code for the trampoline template to
6553    stdio stream FILE.
6554
6555    On S/390, we use gpr 1 internally in the trampoline code;
6556    gpr 0 is used to hold the static chain.  */
6557
6558 void
6559 s390_trampoline_template (file)
6560      FILE *file;
6561 {
6562   if (TARGET_64BIT)
6563     {
6564       fprintf (file, "larl\t%s,0f\n", reg_names[1]);
6565       fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
6566       fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
6567       fprintf (file, "br\t%s\n", reg_names[1]);
6568       fprintf (file, "0:\t.quad\t0\n");
6569       fprintf (file, ".quad\t0\n");
6570     }
6571   else
6572     {
6573       fprintf (file, "basr\t%s,0\n", reg_names[1]);
6574       fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
6575       fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
6576       fprintf (file, "br\t%s\n", reg_names[1]);
6577       fprintf (file, ".long\t0\n");
6578       fprintf (file, ".long\t0\n");
6579     }
6580 }
6581
6582 /* Emit RTL insns to initialize the variable parts of a trampoline.
6583    FNADDR is an RTX for the address of the function's pure code.
6584    CXT is an RTX for the static chain value for the function.  */
6585
6586 void
6587 s390_initialize_trampoline (addr, fnaddr, cxt)
6588      rtx addr;
6589      rtx fnaddr;
6590      rtx cxt;
6591 {
6592   emit_move_insn (gen_rtx 
6593                   (MEM, Pmode,
6594                    memory_address (Pmode, 
6595                    plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
6596   emit_move_insn (gen_rtx
6597                   (MEM, Pmode,
6598                    memory_address (Pmode, 
6599                    plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
6600 }
6601
6602 /* Return rtx for 64-bit constant formed from the 32-bit subwords
6603    LOW and HIGH, independent of the host word size.  */
6604
6605 rtx
6606 s390_gen_rtx_const_DI (high, low)
6607      int high;
6608      int low;
6609 {
6610 #if HOST_BITS_PER_WIDE_INT >= 64
6611   HOST_WIDE_INT val;
6612   val = (HOST_WIDE_INT)high;
6613   val <<= 32;
6614   val |= (HOST_WIDE_INT)low;
6615   
6616   return GEN_INT (val);
6617 #else
6618 #if HOST_BITS_PER_WIDE_INT >= 32
6619   return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
6620 #else
6621   abort ();
6622 #endif
6623 #endif
6624
6625
6626 /* Output assembler code to FILE to increment profiler label # LABELNO
6627    for profiling a function entry.  */
6628
6629 void
6630 s390_function_profiler (file, labelno)
6631      FILE *file;
6632      int labelno;
6633 {
6634   rtx op[7];
6635
6636   char label[128];
6637   ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
6638
6639   fprintf (file, "# function profiler \n");
6640
6641   op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
6642   op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
6643   op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
6644
6645   op[2] = gen_rtx_REG (Pmode, 1);
6646   op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
6647   SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
6648
6649   op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
6650   if (flag_pic)
6651     {
6652       op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), 113);
6653       op[4] = gen_rtx_CONST (Pmode, op[4]);
6654     }
6655
6656   if (TARGET_64BIT)
6657     {
6658       output_asm_insn ("stg\t%0,%1", op);
6659       output_asm_insn ("larl\t%2,%3", op);
6660       output_asm_insn ("brasl\t%0,%4", op);
6661       output_asm_insn ("lg\t%0,%1", op);
6662     }
6663   else if (!flag_pic)
6664     {
6665       op[6] = gen_label_rtx ();
6666
6667       output_asm_insn ("st\t%0,%1", op);
6668       output_asm_insn ("bras\t%2,%l6", op);
6669       output_asm_insn (".long\t%4", op);
6670       output_asm_insn (".long\t%3", op);
6671       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[6]));
6672       output_asm_insn ("l\t%0,0(%2)", op);
6673       output_asm_insn ("l\t%2,4(%2)", op);
6674       output_asm_insn ("basr\t%0,%0", op);
6675       output_asm_insn ("l\t%0,%1", op);
6676     }
6677   else
6678     {
6679       op[5] = gen_label_rtx ();
6680       op[6] = gen_label_rtx ();
6681
6682       output_asm_insn ("st\t%0,%1", op);
6683       output_asm_insn ("bras\t%2,%l6", op);
6684       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[5]));
6685       output_asm_insn (".long\t%4-%l5", op);
6686       output_asm_insn (".long\t%3-%l5", op);
6687       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[6]));
6688       output_asm_insn ("lr\t%0,%2", op);
6689       output_asm_insn ("a\t%0,0(%2)", op);
6690       output_asm_insn ("a\t%2,4(%2)", op);
6691       output_asm_insn ("basr\t%0,%0", op);
6692       output_asm_insn ("l\t%0,%1", op);
6693     }
6694 }
6695
6696 /* Select section for constant in constant pool.  In 32-bit mode,
6697    constants go in the function section; in 64-bit mode in .rodata.  */
6698
6699 static void
6700 s390_select_rtx_section (mode, x, align)
6701      enum machine_mode mode ATTRIBUTE_UNUSED;
6702      rtx x ATTRIBUTE_UNUSED;
6703      unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
6704 {
6705   if (TARGET_64BIT)
6706     readonly_data_section ();
6707   else
6708     function_section (current_function_decl);
6709 }
6710
6711 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
6712    into its SYMBOL_REF_FLAGS.  */
6713
6714 static void
6715 s390_encode_section_info (decl, rtl, first)
6716      tree decl;
6717      rtx rtl;
6718      int first;
6719 {
6720   default_encode_section_info (decl, rtl, first);
6721
6722   /* If a variable has a forced alignment to < 2 bytes, mark it with
6723      SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand.  */
6724   if (TREE_CODE (decl) == VAR_DECL 
6725       && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
6726     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
6727 }
6728
6729 /* Output thunk to FILE that implements a C++ virtual function call (with
6730    multiple inheritance) to FUNCTION.  The thunk adjusts the this pointer 
6731    by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
6732    stored at VCALL_OFFSET in the vtable whose address is located at offset 0
6733    relative to the resulting this pointer.  */
6734
6735 static void
6736 s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
6737      FILE *file;
6738      tree thunk ATTRIBUTE_UNUSED;
6739      HOST_WIDE_INT delta;
6740      HOST_WIDE_INT vcall_offset;
6741      tree function;
6742 {
6743   rtx op[10];
6744   int nonlocal = 0;
6745
6746   /* Operand 0 is the target function.  */
6747   op[0] = XEXP (DECL_RTL (function), 0);
6748   if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
6749     {
6750       nonlocal = 1;
6751       op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
6752                               TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
6753       op[0] = gen_rtx_CONST (Pmode, op[0]);
6754     }
6755
6756   /* Operand 1 is the 'this' pointer.  */
6757   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
6758     op[1] = gen_rtx_REG (Pmode, 3);
6759   else
6760     op[1] = gen_rtx_REG (Pmode, 2);
6761
6762   /* Operand 2 is the delta.  */
6763   op[2] = GEN_INT (delta);
6764
6765   /* Operand 3 is the vcall_offset.  */
6766   op[3] = GEN_INT (vcall_offset);
6767
6768   /* Operand 4 is the temporary register.  */
6769   op[4] = gen_rtx_REG (Pmode, 1);
6770
6771   /* Operands 5 to 8 can be used as labels.  */
6772   op[5] = NULL_RTX;
6773   op[6] = NULL_RTX;
6774   op[7] = NULL_RTX;
6775   op[8] = NULL_RTX;
6776
6777   /* Operand 9 can be used for temporary register.  */
6778   op[9] = NULL_RTX;
6779
6780   /* Generate code.  */
6781   if (TARGET_64BIT)
6782     {
6783       /* Setup literal pool pointer if required.  */
6784       if ((!DISP_IN_RANGE (delta) 
6785            && !CONST_OK_FOR_LETTER_P (delta, 'K'))
6786           || (!DISP_IN_RANGE (vcall_offset) 
6787               && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
6788         {
6789           op[5] = gen_label_rtx ();
6790           output_asm_insn ("larl\t%4,%5", op);
6791         }
6792
6793       /* Add DELTA to this pointer.  */
6794       if (delta)
6795         {
6796           if (CONST_OK_FOR_LETTER_P (delta, 'J'))
6797             output_asm_insn ("la\t%1,%2(%1)", op);
6798           else if (DISP_IN_RANGE (delta))
6799             output_asm_insn ("lay\t%1,%2(%1)", op);
6800           else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
6801             output_asm_insn ("aghi\t%1,%2", op);
6802           else
6803             {
6804               op[6] = gen_label_rtx ();
6805               output_asm_insn ("agf\t%1,%6-%5(%4)", op);
6806             }
6807         }
6808
6809       /* Perform vcall adjustment.  */
6810       if (vcall_offset)
6811         {
6812           if (DISP_IN_RANGE (vcall_offset))
6813             {
6814               output_asm_insn ("lg\t%4,0(%1)", op);
6815               output_asm_insn ("ag\t%1,%3(%4)", op);
6816             }
6817           else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
6818             {
6819               output_asm_insn ("lghi\t%4,%3", op);
6820               output_asm_insn ("ag\t%4,0(%1)", op);
6821               output_asm_insn ("ag\t%1,0(%4)", op);
6822             }
6823           else
6824             {
6825               op[7] = gen_label_rtx ();
6826               output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
6827               output_asm_insn ("ag\t%4,0(%1)", op);
6828               output_asm_insn ("ag\t%1,0(%4)", op);
6829             }
6830         }
6831         
6832       /* Jump to target.  */
6833       output_asm_insn ("jg\t%0", op);
6834
6835       /* Output literal pool if required.  */
6836       if (op[5])
6837         {
6838           output_asm_insn (".align\t4", op);
6839           (*targetm.asm_out.internal_label) (file, "L",
6840                                              CODE_LABEL_NUMBER (op[5]));
6841         }
6842       if (op[6])
6843         {
6844           (*targetm.asm_out.internal_label) (file, "L",
6845                                              CODE_LABEL_NUMBER (op[6]));
6846           output_asm_insn (".long\t%2", op);
6847         }
6848       if (op[7])
6849         {
6850           (*targetm.asm_out.internal_label) (file, "L",
6851                                              CODE_LABEL_NUMBER (op[7]));
6852           output_asm_insn (".long\t%3", op);
6853         }
6854     }
6855   else
6856     {
6857       /* Setup base pointer if required.  */
6858       if (!vcall_offset
6859           || (!DISP_IN_RANGE (delta)
6860               && !CONST_OK_FOR_LETTER_P (delta, 'K'))
6861           || (!DISP_IN_RANGE (delta)
6862               && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
6863         {
6864           op[5] = gen_label_rtx ();
6865           output_asm_insn ("basr\t%4,0", op);
6866           (*targetm.asm_out.internal_label) (file, "L",
6867                                              CODE_LABEL_NUMBER (op[5]));
6868         }
6869
6870       /* Add DELTA to this pointer.  */
6871       if (delta)
6872         {
6873           if (CONST_OK_FOR_LETTER_P (delta, 'J'))
6874             output_asm_insn ("la\t%1,%2(%1)", op);
6875           else if (DISP_IN_RANGE (delta))
6876             output_asm_insn ("lay\t%1,%2(%1)", op);
6877           else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
6878             output_asm_insn ("ahi\t%1,%2", op);
6879           else
6880             {
6881               op[6] = gen_label_rtx ();
6882               output_asm_insn ("a\t%1,%6-%5(%4)", op);
6883             }
6884         }
6885
6886       /* Perform vcall adjustment.  */
6887       if (vcall_offset)
6888         {
6889           if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
6890             {
6891               output_asm_insn ("lg\t%4,0(%1)", op);
6892               output_asm_insn ("a\t%1,%3(%4)", op);
6893             }
6894           else if (DISP_IN_RANGE (vcall_offset))
6895             {
6896               output_asm_insn ("lg\t%4,0(%1)", op);
6897               output_asm_insn ("ay\t%1,%3(%4)", op);
6898             }
6899           else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
6900             {
6901               output_asm_insn ("lhi\t%4,%3", op);
6902               output_asm_insn ("a\t%4,0(%1)", op);
6903               output_asm_insn ("a\t%1,0(%4)", op);
6904             }
6905           else
6906             {
6907               op[7] = gen_label_rtx ();
6908               output_asm_insn ("l\t%4,%7-%5(%4)", op);
6909               output_asm_insn ("a\t%4,0(%1)", op);
6910               output_asm_insn ("a\t%1,0(%4)", op);
6911             }
6912
6913           /* We had to clobber the base pointer register.
6914              Re-setup the base pointer (with a different base).  */
6915           op[5] = gen_label_rtx ();
6916           output_asm_insn ("basr\t%4,0", op);
6917           (*targetm.asm_out.internal_label) (file, "L",
6918                                              CODE_LABEL_NUMBER (op[5]));
6919         }
6920
6921       /* Jump to target.  */
6922       op[8] = gen_label_rtx ();
6923
6924       if (!flag_pic)
6925         output_asm_insn ("l\t%4,%8-%5(%4)", op);
6926       else if (!nonlocal)
6927         output_asm_insn ("a\t%4,%8-%5(%4)", op);
6928       /* We cannot call through .plt, since .plt requires %r12 loaded.  */
6929       else if (flag_pic == 1)
6930         {
6931           output_asm_insn ("a\t%4,%8-%5(%4)", op);
6932           output_asm_insn ("l\t%4,%0(%4)", op);
6933         }
6934       else if (flag_pic == 2)
6935         {
6936           op[9] = gen_rtx_REG (Pmode, 0);
6937           output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
6938           output_asm_insn ("a\t%4,%8-%5(%4)", op);
6939           output_asm_insn ("ar\t%4,%9", op);
6940           output_asm_insn ("l\t%4,0(%4)", op);
6941         }
6942
6943       output_asm_insn ("br\t%4", op);
6944
6945       /* Output literal pool.  */
6946       output_asm_insn (".align\t4", op);
6947
6948       if (nonlocal && flag_pic == 2)
6949         output_asm_insn (".long\t%0", op);
6950       if (nonlocal)
6951         {
6952           op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6953           SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
6954         }
6955
6956       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[8]));
6957       if (!flag_pic)
6958         output_asm_insn (".long\t%0", op);
6959       else
6960         output_asm_insn (".long\t%0-%5", op);
6961
6962       if (op[6])
6963         {
6964           (*targetm.asm_out.internal_label) (file, "L",
6965                                              CODE_LABEL_NUMBER (op[6]));
6966           output_asm_insn (".long\t%2", op);
6967         }
6968       if (op[7])
6969         {
6970           (*targetm.asm_out.internal_label) (file, "L",
6971                                              CODE_LABEL_NUMBER (op[7]));
6972           output_asm_insn (".long\t%3", op);
6973         }
6974     }
6975 }
6976
6977 /* How to allocate a 'struct machine_function'.  */
6978
6979 static struct machine_function *
6980 s390_init_machine_status ()
6981 {
6982   return ggc_alloc_cleared (sizeof (struct machine_function));
6983 }
6984
6985 #include "gt-s390.h"