OSDN Git Service

Fixed HOST_WIDE_INT type mismatch.
[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 Free Software Foundation, Inc.
3    Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4                   Ulrich Weigand (uweigand@de.ibm.com).
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "tm_p.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "except.h"
37 #include "function.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "toplev.h"
41 #include "basic-block.h"
42 #include "ggc.h"
43 #include "target.h"
44 #include "target-def.h"
45
46
47
48
49 #undef  TARGET_ASM_FUNCTION_PROLOGUE 
50 #define TARGET_ASM_FUNCTION_PROLOGUE s390_function_prologue
51
52 #undef  TARGET_ASM_FUNCTION_EPILOGUE 
53 #define TARGET_ASM_FUNCTION_EPILOGUE s390_function_epilogue
54
55 #undef  TARGET_ASM_OPEN_PAREN
56 #define TARGET_ASM_OPEN_PAREN ""
57
58 #undef  TARGET_ASM_CLOSE_PAREN
59 #define TARGET_ASM_CLOSE_PAREN ""
60
61 struct gcc_target targetm = TARGET_INITIALIZER;
62
63 extern int reload_completed;
64
65 /* Function count for creating unique internal labels in a compile unit.  */
66 int  s390_function_count = 0;
67
68 /* Save information from a "cmpxx" operation until the branch or scc is
69    emitted.  */
70 rtx s390_compare_op0, s390_compare_op1;
71
72 /* Structure used to hold the components of a S/390 memory
73    address.  A legitimate address on S/390 is of the general
74    form
75           base + index + displacement
76    where any of the components is optional.
77
78    base and index are registers of the class ADDR_REGS,
79    displacement is an unsigned 12-bit immediate constant.  */
80
81 struct s390_address
82 {
83   rtx base;
84   rtx indx;
85   rtx disp;
86 };
87
88 static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
89 static int base_n_index_p PARAMS ((rtx));
90 static int check_mode PARAMS ((rtx, enum machine_mode *));
91 static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int));
92 static void output_branch_condition PARAMS ((FILE *, rtx));
93 static void output_inverse_branch_condition PARAMS ((FILE *, rtx));
94 static int reg_used_in_mem_p PARAMS ((int, rtx));
95 static int addr_generation_dependency_p PARAMS ((rtx, rtx));
96 static int other_chunk PARAMS ((int *, int, int));
97 static int far_away PARAMS ((int, int));
98 static rtx check_and_change_labels PARAMS ((rtx, int *));
99 static void s390_final_chunkify PARAMS ((int));
100 static int save_fprs_p PARAMS ((void));
101 static int cur_is_leaf_function PARAMS ((void));
102 static int save_fprs PARAMS ((FILE *, long, int));
103 static int restore_fprs PARAMS ((FILE *, long, int));
104 static void s390_output_constant_pool PARAMS ((FILE *));
105 static rtx s390_force_const_mem_late PARAMS ((rtx));
106 static rtx s390_force_const_mem_symbol PARAMS ((const char *, int, int));
107 static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
108
109  
110 /* Return true if SET either doesn't set the CC register, or else
111    the source and destination have matching CC modes and that 
112    CC mode is at least as constrained as REQ_MODE.  */
113  
114 static int
115 s390_match_ccmode_set (set, req_mode)
116      rtx set;
117      enum machine_mode req_mode;
118 {
119   enum machine_mode set_mode;
120
121   if (GET_CODE (set) != SET)
122     abort ();
123
124   if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
125     return 1;
126
127   set_mode = GET_MODE (SET_DEST (set));
128   switch (set_mode)
129     {
130     case CCmode:
131       return 0;
132
133     case CCSmode:
134       if (req_mode != CCSmode)
135         return 0;
136       break;
137     case CCUmode:
138       if (req_mode != CCUmode)
139         return 0;
140       break;
141     case CCZmode:
142       if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode)
143         return 0;
144       break;
145  
146     default:
147       abort ();
148     }
149  
150   return (GET_MODE (SET_SRC (set)) == set_mode);
151 }
152
153 /* Return true if every SET in INSN that sets the CC register 
154    has source and destination with matching CC modes and that 
155    CC mode is at least as constrained as REQ_MODE.  */
156  
157 int
158 s390_match_ccmode (insn, req_mode)
159      rtx insn;
160      enum machine_mode req_mode;
161 {
162   int i;
163
164   if (GET_CODE (PATTERN (insn)) == SET)
165     return s390_match_ccmode_set (PATTERN (insn), req_mode);
166
167   if (GET_CODE (PATTERN (insn)) == PARALLEL)
168       for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
169         {
170           rtx set = XVECEXP (PATTERN (insn), 0, i);
171           if (GET_CODE (set) == SET)
172             if (!s390_match_ccmode_set (set, req_mode))
173               return 0;
174         }
175
176   return 1;
177 }
178
179 /* Change optimizations to be performed, depending on the 
180    optimization level.
181
182    LEVEL is the optimization level specified; 2 if `-O2' is
183    specified, 1 if `-O' is specified, and 0 if neither is specified.
184
185    SIZE is non-zero if `-Os' is specified and zero otherwise. */
186
187 void
188 optimization_options (level, size)
189      int level ATTRIBUTE_UNUSED;
190      int size ATTRIBUTE_UNUSED;
191 {
192 #ifdef HAVE_decrement_and_branch_on_count
193   /* When optimizing, enable use of BRCT instruction.  */
194   if (level >= 1)
195       flag_branch_on_count_reg = 1;
196 #endif
197 }
198
199
200 /* Map for smallest class containing reg regno.  */
201
202 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
203 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
204   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
205   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
206   ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
207   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
208   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
209   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
210   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
211   ADDR_REGS,    NO_REGS 
212 };
213
214
215 /* Return true if OP a (const_int 0) operand.
216    OP is the current operation.
217    MODE is the current operation mode.  */
218  
219 int
220 const0_operand (op, mode)
221      register rtx op;
222      enum machine_mode mode;
223 {
224   return op == CONST0_RTX (mode);
225 }
226
227 /* Return true if OP a (const_int 1) operand.
228    OP is the current operation.
229    MODE is the current operation mode.  */
230  
231 int
232 const1_operand (op, mode)
233      register rtx op;
234      enum machine_mode mode;
235 {
236   return op == CONST1_RTX (mode);
237 }
238
239 /* Return true if OP needs base and index register.  */
240
241 static int 
242 base_n_index_p (op)
243      register rtx op;
244 {
245   if ((GET_CODE (op) == PLUS) &&
246       (GET_CODE (XEXP (op, 0)) == PLUS ||
247        GET_CODE (XEXP (op, 1)) == PLUS ||
248        GET_CODE (XEXP (op, 1)) == REG ))
249     return 1;
250   return 0;
251 }
252
253 /* Return true if the mode of operand OP matches MODE.
254    If MODE is set to VOIDmode, set it to the mode of OP.  */ 
255
256 static int
257 check_mode (op, mode)
258      register rtx op;
259      enum machine_mode *mode;
260 {
261   if (*mode == VOIDmode)
262       *mode = GET_MODE (op);
263   else
264   {
265     if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
266        return 0;
267   }
268   return 1;
269 }
270
271 /* Return true if OP a valid operand for the LARL instruction.
272    OP is the current operation.
273    MODE is the current operation mode.  */
274
275 int
276 larl_operand (op, mode)
277      register rtx op;
278      enum machine_mode mode;
279 {
280   if (! check_mode (op, &mode))
281     return 0;
282
283   /* Allow labels and local symbols.  */
284   if (GET_CODE (op) == LABEL_REF)
285     return 1;
286   if (GET_CODE (op) == SYMBOL_REF
287       && (!flag_pic || SYMBOL_REF_FLAG (op) 
288           || CONSTANT_POOL_ADDRESS_P (op)))
289     return 1;
290
291   /* Everything else must have a CONST, so strip it.  */
292   if (GET_CODE (op) != CONST)
293     return 0;
294   op = XEXP (op, 0);
295
296   /* Allow adding *even* constants.  */
297   if (GET_CODE (op) == PLUS)
298     {
299       if (GET_CODE (XEXP (op, 1)) != CONST_INT
300           || (INTVAL (XEXP (op, 1)) & 1) != 0)
301         return 0;
302       op = XEXP (op, 0);
303     }
304
305   /* Labels and local symbols allowed here as well.  */
306   if (GET_CODE (op) == LABEL_REF)
307     return 1;
308   if (GET_CODE (op) == SYMBOL_REF
309       && (!flag_pic || SYMBOL_REF_FLAG (op)
310           || CONSTANT_POOL_ADDRESS_P (op)))
311     return 1;
312
313   /* Now we must have a @GOTENT offset or @PLT stub.  */
314   if (GET_CODE (op) == UNSPEC
315       && XINT (op, 1) == 111)
316     return 1;
317   if (GET_CODE (op) == UNSPEC
318       && XINT (op, 1) == 113)
319     return 1;
320
321   return 0;
322 }
323
324 /* Return true if OP is a valid FP-Register.
325    OP is the current operation.
326    MODE is the current operation mode.  */
327
328 int
329 fp_operand (op, mode)
330      register rtx op;
331      enum machine_mode mode;
332 {
333   register enum rtx_code code = GET_CODE (op);
334   if (! check_mode (op, &mode))
335     return 0;
336   if (code == REG && REGNO_OK_FOR_FP_P (REGNO (op)))
337     return 1;
338   else
339     return 0;
340 }
341
342 /* Return true if OP is a valid S operand for an RS, SI or SS type instruction.
343    OP is the current operation.
344    MODE is the current operation mode.  */
345
346 int
347 s_operand (op, mode)
348      register rtx op;
349      enum machine_mode mode;
350 {
351   register enum rtx_code code = GET_CODE (op);
352
353   if (! check_mode (op,&mode))
354     return 0;
355
356   if (code == MEM) {
357     if (base_n_index_p (XEXP (op, 0)))
358       return 0;
359   }
360
361   return memory_operand (op, mode);
362 }
363
364 /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
365    instruction.
366    OP is the current operation.
367    MODE is the current operation mode.  */
368
369 int
370 r_or_s_operand (op, mode)
371      register rtx op;
372      enum machine_mode mode;
373 {
374   register enum rtx_code code = GET_CODE (op);
375
376   if (!general_operand (op, mode))
377     return 0;
378
379   if (code == MEM) {
380     if (base_n_index_p (XEXP (op, 0)))
381       return 0;
382     else
383       return memory_operand (op, mode);
384   }
385   return register_operand (op, mode);
386 }
387
388 /* Return true if OP is a valid R or S or immediate operand for 
389    RS, SI or SS type instruction.
390    OP is the current operation.
391    MODE is the current operation mode.  */
392
393 int
394 r_or_s_or_im8_operand (op, mode)
395      register rtx op;
396      enum machine_mode mode;
397 {
398   register enum rtx_code code = GET_CODE (op);
399
400   if (!general_operand (op, mode))
401     return 0;
402
403   if (code == MEM) {
404     if (base_n_index_p (XEXP (op, 0)))
405       return 0;
406     else
407       return memory_operand (op, mode);
408   }
409   return register_operand (op, mode) || immediate_operand (op, mode);
410 }
411
412 /* Return true if OP is a valid R or X or 16 bit immediate operand for 
413    RX, RR or RI type instruction.
414    OP is the current operation.
415    MODE is the current operation mode.  */
416
417 int
418 r_or_x_or_im16_operand (op, mode)
419      register rtx op;
420      enum machine_mode mode;
421 {
422
423   if (! general_operand (op, mode))
424     return 0;
425
426   if (GET_CODE (op) == CONST_INT)
427     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'));
428   return register_operand (op, mode) || memory_operand (op, mode);
429 }
430
431 /* Return true if OP is a valid R or 8 bit immediate operand.
432    OP is the current operation.
433    MODE is the current operation mode.  */
434
435 int
436 r_or_im8_operand (op, mode)
437      register rtx op;
438      enum machine_mode mode;
439 {
440
441   if (!general_operand (op, mode))
442     return 0;
443
444   if (GET_CODE (op) == CONST_INT)
445     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'J'));
446   return register_operand (op, mode) || memory_operand (op, mode);
447 }
448
449 /* Return true if OP is a valid operand for the 'test under mask'
450    instruction with 16 bit immediate.  
451    The value should only have set bits in one halfword.
452    OP is the current operation.
453    MODE is the current operation mode.  */
454
455 int
456 tmxx_operand (op, mode)
457      register rtx op;
458      enum machine_mode mode ATTRIBUTE_UNUSED;
459 {
460   rtx con;
461   if (GET_CODE (op) == CONST_INT)
462     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
463   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == SYMBOL_REF &&
464       CONSTANT_POOL_ADDRESS_P (XEXP (op, 0))) 
465     {
466       con = get_pool_constant (XEXP (op, 0));
467
468       if (GET_CODE (con) == CONST_INT)
469         {
470           unsigned HOST_WIDEST_INT c;
471           
472           c = (unsigned HOST_WIDEST_INT) INTVAL (con);
473           
474           return ((c & 0xffff) ? ((c & 0xffffffffffff0000ULL)==0) : 
475                   (c & 0xffff0000U) ? ((c & 0xffffffff0000ffffULL)==0) :
476                   (c & 0xffff00000000ULL) ? ((c & 0xffff0000ffffffffULL)==0) :
477                   (c & 0xffff000000000000ULL) ? ((c & 0xffffffffffffULL)==0) : 1);
478                   
479         }
480     }
481   return 0;
482 }
483
484 /* Return true if OP is a valid operand for the BRAS instruction.
485    OP is the current operation.
486    MODE is the current operation mode.  */
487
488 int
489 bras_sym_operand (op, mode)
490      register rtx op;
491      enum machine_mode mode ATTRIBUTE_UNUSED;
492 {
493   register enum rtx_code code = GET_CODE (op);
494
495   /* Allow SYMBOL_REFs.  */
496   if (code == SYMBOL_REF)
497     return 1;
498
499   /* Allow @PLT stubs.  */
500   if (code == CONST
501       && GET_CODE (XEXP (op, 0)) == UNSPEC
502       && XINT (XEXP (op, 0), 1) == 113)
503     return 1;
504   return 0;
505 }
506
507 \f
508 /* Return true if OP is a load multiple operation.  It is known to be a
509    PARALLEL and the first section will be tested. 
510    OP is the current operation.
511    MODE is the current operation mode.  */
512
513 int
514 load_multiple_operation (op, mode)
515      rtx op;
516      enum machine_mode mode ATTRIBUTE_UNUSED;
517 {
518   int count = XVECLEN (op, 0);
519   unsigned int dest_regno;
520   rtx src_addr;
521   int i;
522
523
524   /* Perform a quick check so we don't blow up below.  */
525   if (count <= 1
526       || GET_CODE (XVECEXP (op, 0, 0)) != SET
527       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
528       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
529     return 0;
530
531   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
532   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
533
534   for (i = 1; i < count; i++)
535     {
536       rtx elt = XVECEXP (op, 0, i);
537
538       if (GET_CODE (elt) != SET
539           || GET_CODE (SET_DEST (elt)) != REG
540           || GET_MODE (SET_DEST (elt)) != Pmode
541           || REGNO (SET_DEST (elt)) != dest_regno + i
542           || GET_CODE (SET_SRC (elt)) != MEM
543           || GET_MODE (SET_SRC (elt)) != Pmode
544           || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
545           || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
546           || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
547           || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
548         return 0;
549     }
550
551   return 1;
552 }
553
554 /* Return true if OP is a store multiple operation.  It is known to be a
555    PARALLEL and the first section will be tested. 
556    OP is the current operation.
557    MODE is the current operation mode.  */
558
559 int
560 store_multiple_operation (op, mode)
561      rtx op;
562      enum machine_mode mode ATTRIBUTE_UNUSED;
563 {
564   int count = XVECLEN (op, 0) - 1;
565   unsigned int src_regno;
566   rtx dest_addr;
567   int i;
568
569   /* Perform a quick check so we don't blow up below.  */
570   if (count <= 1
571       || GET_CODE (XVECEXP (op, 0, 0)) != SET
572       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
573       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
574     return 0;
575
576   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
577   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
578
579   for (i = 1; i < count; i++)
580     {
581       rtx elt = XVECEXP (op, 0, i);
582
583       if (GET_CODE (elt) != SET
584           || GET_CODE (SET_SRC (elt)) != REG
585           || GET_MODE (SET_SRC (elt)) != Pmode
586           || REGNO (SET_SRC (elt)) != src_regno + i
587           || GET_CODE (SET_DEST (elt)) != MEM
588           || GET_MODE (SET_DEST (elt)) != Pmode
589           || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
590           || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
591           || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
592           || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
593         return 0;
594     }
595   return 1;
596 }
597
598
599 /* Return true if OP contains a symbol reference */
600
601 int
602 symbolic_reference_mentioned_p (op)
603      rtx op;
604 {
605   register const char *fmt;
606   register int i;
607
608   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
609     return 1;
610
611   fmt = GET_RTX_FORMAT (GET_CODE (op));
612   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
613     {
614       if (fmt[i] == 'E')
615         {
616           register int j;
617
618           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
619             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
620               return 1;
621         }
622
623       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
624         return 1;
625     }
626
627   return 0;
628 }
629
630
631 /* Return true if OP is a legitimate general operand when 
632    generating PIC code.  It is given that flag_pic is on 
633    and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
634
635 int
636 legitimate_pic_operand_p (op)
637      register rtx op;
638 {
639   /* All non-symbolic constants that made it 
640      up to here are fine.  */
641   if (!SYMBOLIC_CONST (op))
642     return 1;
643
644   /* Accept immediate LARL operands.  */
645   if (TARGET_64BIT)
646     return larl_operand (op, VOIDmode);
647
648   /* Reject everything else; must be handled 
649      via emit_pic_move.  */
650   return 0;
651 }
652
653 /* Returns true if the constant value OP is a legitimate general operand.
654    It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
655
656 int
657 legitimate_constant_p (op)
658      register rtx op;
659 {
660   /* Reject doubles and integers out of range.  */
661   if (GET_CODE (op) == CONST_DOUBLE ||
662       (GET_CODE (op) == CONST_INT &&
663        (INTVAL (op) < -32768 || INTVAL (op) > 32767)))
664     return 0;
665
666   /* Accept all other non-symbolic constants.  */
667   if (!SYMBOLIC_CONST (op))
668     return 1;
669
670   /* In the PIC case, symbolic constants must *not* be
671      forced into the literal pool.  We accept them here,
672      so that they will be handled by emit_pic_move.  */
673   if (flag_pic)
674     return 1;
675
676   /* Even in the non-PIC case, we can accept immediate
677      LARL operands here.  */
678   if (TARGET_64BIT)
679     return larl_operand (op, VOIDmode);
680
681   /* All remaining non-PIC symbolic constants are
682      forced into the literal pool.  */
683   return 0;
684 }
685
686
687 /* Decompose a RTL expression ADDR for a memory address into
688    its components, returned in OUT.  The boolean STRICT 
689    specifies whether strict register checking applies.
690    Returns 0 if ADDR is not a valid memory address, nonzero
691    otherwise.  If OUT is NULL, don't return the components,
692    but check for validity only.
693
694    Note: Only addresses in canonical form are recognized.
695    LEGITIMIZE_ADDRESS should convert non-canonical forms to the
696    canonical form so that they will be recognized.  */
697
698 static int
699 s390_decompose_address (addr, out, strict)
700      register rtx addr;
701      struct s390_address *out;
702      int strict;
703 {
704   rtx base = NULL_RTX;
705   rtx indx = NULL_RTX;
706   rtx disp = NULL_RTX;
707
708   /* Decompose address into base + index + displacement.  */
709
710   if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
711     base = addr;
712
713   else if (GET_CODE (addr) == PLUS)
714     {
715       rtx op0 = XEXP (addr, 0);
716       rtx op1 = XEXP (addr, 1);
717       enum rtx_code code0 = GET_CODE (op0);
718       enum rtx_code code1 = GET_CODE (op1);
719
720       if (code0 == REG || code0 == UNSPEC)
721         {
722           if (code1 == REG || code1 == UNSPEC)
723             {
724               indx = op0;       /* index + base */
725               base = op1;
726             }
727
728           else
729             {
730               base = op0;       /* base + displacement */
731               disp = op1;
732             }
733         }
734
735       else if (code0 == PLUS)
736         {
737           indx = XEXP (op0, 0); /* index + base + disp */
738           base = XEXP (op0, 1);
739           disp = op1;
740         }
741
742       else
743         {
744           return FALSE;
745         }
746     }
747
748   else
749     disp = addr;                /* displacement */
750
751
752   /* Validate base register.  */
753   if (base)
754     {
755       if (GET_CODE (base) == UNSPEC)
756         {
757           if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
758               return FALSE;
759           base = XVECEXP (base, 0, 0);
760         }
761
762       if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
763           return FALSE;
764
765       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
766           || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
767           return FALSE;
768     }
769
770   /* Validate index register.  */
771   if (indx)
772     {
773       if (GET_CODE (indx) == UNSPEC)
774         {
775           if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
776               return FALSE;
777           indx = XVECEXP (indx, 0, 0);
778         }
779
780       if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
781           return FALSE;
782
783       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (indx))
784           || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (indx)))
785           return FALSE;
786     }
787
788   /* Validate displacement.  */
789   if (disp)
790     {
791       /* Allow integer constant in range.  */
792       if (GET_CODE (disp) == CONST_INT)
793         {
794           if (INTVAL (disp) < 0 || INTVAL (disp) >= 4096)
795               return FALSE;
796         }
797
798       /* In the small-PIC case, the linker converts @GOT12 
799          offsets to possible displacements.  */
800       else if (GET_CODE (disp) == CONST
801                && GET_CODE (XEXP (disp, 0)) == UNSPEC
802                && XINT (XEXP (disp, 0), 1) == 110)
803         {
804           if (flag_pic != 1)
805             return FALSE;
806         }
807
808       /* We can convert literal pool addresses to 
809          displacements by basing them off the base register.  */
810       else
811         {
812           /* In some cases, we can accept an additional
813              small constant offset.  Split these off here.  */
814
815           unsigned int offset = 0;
816
817           if (GET_CODE (disp) == CONST
818               && GET_CODE (XEXP (disp, 0)) == PLUS
819               && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
820             {
821               offset = INTVAL (XEXP (XEXP (disp, 0), 1));
822               disp = XEXP (XEXP (disp, 0), 0);
823             }
824
825           /* Now we must have a literal pool address.  */
826           if (GET_CODE (disp) != SYMBOL_REF
827               || !CONSTANT_POOL_ADDRESS_P (disp))
828             return FALSE;
829
830           /* In 64-bit PIC mode we cannot accept symbolic 
831              constants in the constant pool.  */
832           if (TARGET_64BIT && flag_pic
833               && SYMBOLIC_CONST (get_pool_constant (disp)))
834             return FALSE;
835
836           /* If we have an offset, make sure it does not
837              exceed the size of the constant pool entry.  */
838           if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
839             return FALSE;
840
841           /* Either base or index must be free to 
842              hold the base register.  */
843           if (base && indx)
844             return FALSE;
845
846           /* Convert the address.  */
847           if (base)
848             indx = gen_rtx_REG (Pmode, BASE_REGISTER);
849           else
850             base = gen_rtx_REG (Pmode, BASE_REGISTER);
851
852           disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
853           disp = gen_rtx_CONST (Pmode, disp);
854
855           if (offset)
856             disp = plus_constant (disp, offset);
857         }
858     }
859
860   if (out)
861     {
862       out->base = base;
863       out->indx = indx;
864       out->disp = disp;
865     }
866
867   return TRUE;
868 }
869
870 /* Return nonzero if ADDR is a valid memory address.
871    STRICT specifies whether strict register checking applies.  */
872
873 int
874 legitimate_address_p (mode, addr, strict)
875      enum machine_mode mode ATTRIBUTE_UNUSED;
876      register rtx addr;
877      int strict;
878 {
879   return s390_decompose_address (addr, NULL, strict);
880 }
881
882 /* Return a legitimate reference for ORIG (an address) using the
883    register REG.  If REG is 0, a new pseudo is generated.
884
885    There are two types of references that must be handled:
886
887    1. Global data references must load the address from the GOT, via
888       the PIC reg.  An insn is emitted to do this load, and the reg is
889       returned.
890
891    2. Static data references, constant pool addresses, and code labels
892       compute the address as an offset from the GOT, whose base is in
893       the PIC reg.  Static data objects have SYMBOL_REF_FLAG set to
894       differentiate them from global data objects.  The returned
895       address is the PIC reg + an unspec constant.
896
897    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
898    reg also appears in the address.  */
899
900 rtx
901 legitimize_pic_address (orig, reg)
902      rtx orig;
903      rtx reg;
904 {
905   rtx addr = orig;
906   rtx new = orig;
907   rtx base;
908
909   if (GET_CODE (addr) == LABEL_REF
910       || (GET_CODE (addr) == SYMBOL_REF
911           && (SYMBOL_REF_FLAG (addr) 
912               || CONSTANT_POOL_ADDRESS_P (addr))))
913     {
914       /* This is a local symbol.  */
915       if (TARGET_64BIT)
916         {
917           /* Access local symbols PC-relative via LARL.  
918              This is the same as in the non-PIC case, so it is 
919              handled automatically ... */
920         }
921       else
922         {
923           /* Access local symbols relative to the literal pool.  */
924
925           rtx temp = reg? reg : gen_reg_rtx (Pmode);
926
927           addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 100);
928           addr = gen_rtx_CONST (SImode, addr);
929           addr = force_const_mem (SImode, addr);
930           emit_move_insn (temp, addr);
931
932           base = gen_rtx_REG (Pmode, BASE_REGISTER);
933           base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
934           new = gen_rtx_PLUS (Pmode, base, temp);
935
936           if (reg != 0)
937             {
938               emit_move_insn (reg, new);
939               new = reg;
940             }
941         }
942     }
943   else if (GET_CODE (addr) == SYMBOL_REF)
944     {
945       if (reg == 0)
946         reg = gen_reg_rtx (Pmode);
947
948       if (flag_pic == 1)
949         {
950           /* Assume GOT offset < 4k.  This is handled the same way
951              in both 31- and 64-bit code (@GOT12).  */
952
953           current_function_uses_pic_offset_table = 1;
954
955           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
956           new = gen_rtx_CONST (Pmode, new);
957           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
958           new = gen_rtx_MEM (Pmode, new);
959           RTX_UNCHANGING_P (new) = 1;
960           emit_move_insn (reg, new);
961           new = reg;
962         }
963       else if (TARGET_64BIT)
964         {
965           /* If the GOT offset might be >= 4k, we determine the position
966              of the GOT entry via a PC-relative LARL (@GOTENT).  */
967
968           rtx temp = gen_reg_rtx (Pmode);
969
970           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
971           new = gen_rtx_CONST (Pmode, new);
972           emit_move_insn (temp, new);
973
974           new = gen_rtx_MEM (Pmode, temp);
975           RTX_UNCHANGING_P (new) = 1;
976           emit_move_insn (reg, new);
977           new = reg;
978         }
979       else
980         {
981           /* If the GOT offset might be >= 4k, we have to load it 
982              from the literal pool (@GOT).  */
983
984           rtx temp = gen_reg_rtx (Pmode);
985
986           current_function_uses_pic_offset_table = 1;
987
988           addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 112);
989           addr = gen_rtx_CONST (SImode, addr);
990           addr = force_const_mem (SImode, addr);
991           emit_move_insn (temp, addr);
992
993           new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
994           new = gen_rtx_MEM (Pmode, new);
995           RTX_UNCHANGING_P (new) = 1;
996           emit_move_insn (reg, new);
997           new = reg;
998         }
999     }      
1000   else
1001     {
1002       if (GET_CODE (addr) == CONST)
1003         {
1004           addr = XEXP (addr, 0);
1005           if (GET_CODE (addr) == UNSPEC)
1006             {
1007               if (XVECLEN (addr, 0) != 1)
1008                 abort ();
1009               switch (XINT (addr, 1))
1010                 {
1011                   /* If someone moved an @GOT or lt-relative UNSPEC
1012                      out of the literal pool, force them back in.  */
1013                   case 100:
1014                   case 112:
1015                   case 114:
1016                     new = force_const_mem (SImode, orig);
1017                     break;
1018
1019                   /* @GOTENT is OK as is.  */
1020                   case 111:
1021                     break;
1022
1023                   /* @PLT is OK as is on 64-bit, must be converted to
1024                      lt-relative PLT on 31-bit.  */
1025                   case 113:
1026                     if (!TARGET_64BIT)
1027                       {
1028                         rtx temp = reg? reg : gen_reg_rtx (Pmode);
1029
1030                         addr = XVECEXP (addr, 0, 0);
1031                         addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 114);
1032                         addr = gen_rtx_CONST (SImode, addr);
1033                         addr = force_const_mem (SImode, addr);
1034                         emit_move_insn (temp, addr);
1035
1036                         base = gen_rtx_REG (Pmode, BASE_REGISTER);
1037                         base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
1038                         new = gen_rtx_PLUS (Pmode, base, temp);
1039
1040                         if (reg != 0)
1041                           {
1042                             emit_move_insn (reg, new);
1043                             new = reg;
1044                           }
1045                       }
1046                     break;
1047
1048                   /* Everything else cannot happen.  */
1049                   default:
1050                     abort ();
1051                 }
1052             }
1053           else if (GET_CODE (addr) != PLUS)
1054             abort ();
1055         }
1056       if (GET_CODE (addr) == PLUS)
1057         {
1058           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
1059           /* Check first to see if this is a constant offset 
1060              from a local symbol reference.  */
1061           if ((GET_CODE (op0) == LABEL_REF
1062                 || (GET_CODE (op0) == SYMBOL_REF
1063                     && (SYMBOL_REF_FLAG (op0)
1064                         || CONSTANT_POOL_ADDRESS_P (op0))))
1065               && GET_CODE (op1) == CONST_INT)
1066             {
1067               if (TARGET_64BIT)
1068                 {
1069                   if (INTVAL (op1) & 1)
1070                     {
1071                       /* LARL can't handle odd offsets, so emit a 
1072                          pair of LARL and LA.  */
1073                       rtx temp = reg? reg : gen_reg_rtx (Pmode);
1074
1075                       if (INTVAL (op1) < 0 || INTVAL (op1) >= 4096)
1076                         {
1077                           int even = INTVAL (op1) - 1;
1078                           op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
1079                           op1 = GEN_INT (1);
1080                         }
1081
1082                       emit_move_insn (temp, op0);
1083                       new = gen_rtx_PLUS (Pmode, temp, op1);
1084
1085                       if (reg != 0)
1086                         {
1087                           emit_move_insn (reg, new);
1088                           new = reg;
1089                         }
1090                     }
1091                   else
1092                     {
1093                       /* If the offset is even, we can just use LARL.
1094                          This will happen automatically.  */
1095                     }
1096                 }
1097               else
1098                 {
1099                   /* Access local symbols relative to the literal pool.  */
1100
1101                   rtx temp = reg? reg : gen_reg_rtx (Pmode);
1102
1103                   addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), 100);
1104                   addr = gen_rtx_PLUS (SImode, addr, op1);
1105                   addr = gen_rtx_CONST (SImode, addr);
1106                   addr = force_const_mem (SImode, addr);
1107                   emit_move_insn (temp, addr);
1108
1109                   base = gen_rtx_REG (Pmode, BASE_REGISTER);
1110                   base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
1111                   new = gen_rtx_PLUS (Pmode, base, temp);
1112
1113                   if (reg != 0)
1114                     {
1115                       emit_move_insn (reg, new);
1116                       new = reg;
1117                     }
1118                 }
1119             }
1120
1121           /* Now, check whether it is an LT-relative symbol plus offset
1122              that was pulled out of the literal pool.  Force it back in.  */
1123
1124           else if (GET_CODE (op0) == UNSPEC
1125                    && GET_CODE (op1) == CONST_INT)
1126             {
1127               if (XVECLEN (op0, 0) != 1)
1128                 abort ();
1129               if (XINT (op0, 1) != 100)
1130                 abort ();
1131
1132               new = force_const_mem (SImode, orig);
1133             }
1134
1135           /* Otherwise, compute the sum.  */
1136           else
1137             {
1138               base = legitimize_pic_address (XEXP (addr, 0), reg);
1139               new  = legitimize_pic_address (XEXP (addr, 1),
1140                                              base == reg ? NULL_RTX : reg);
1141               if (GET_CODE (new) == CONST_INT)
1142                 new = plus_constant (base, INTVAL (new));
1143               else
1144                 {
1145                   if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
1146                     {
1147                       base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
1148                       new = XEXP (new, 1);
1149                     }
1150                   new = gen_rtx_PLUS (Pmode, base, new);
1151                 }
1152
1153               if (GET_CODE (new) == CONST)
1154                 new = XEXP (new, 0);
1155               new = force_operand (new, 0);
1156             }
1157         }
1158     }
1159   return new;
1160 }
1161
1162 /* Emit insns to move operands[1] into operands[0].  */
1163
1164 void
1165 emit_pic_move (operands, mode)
1166      rtx *operands;
1167      enum machine_mode mode ATTRIBUTE_UNUSED;
1168 {
1169   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
1170
1171   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
1172     operands[1] = force_reg (Pmode, operands[1]);
1173   else
1174     operands[1] = legitimize_pic_address (operands[1], temp);
1175 }
1176
1177 /* Try machine-dependent ways of modifying an illegitimate address X
1178    to be legitimate.  If we find one, return the new, valid address.
1179
1180    OLDX is the address as it was before break_out_memory_refs was called.
1181    In some cases it is useful to look at this to decide what needs to be done.
1182
1183    MODE is the mode of the operand pointed to by X.
1184
1185    When -fpic is used, special handling is needed for symbolic references.
1186    See comments by legitimize_pic_address for details.  */
1187
1188 rtx
1189 legitimize_address (x, oldx, mode)
1190      register rtx x;
1191      register rtx oldx ATTRIBUTE_UNUSED;
1192      enum machine_mode mode ATTRIBUTE_UNUSED;
1193 {
1194   if (flag_pic && SYMBOLIC_CONST (x))
1195     return legitimize_pic_address (x, 0);
1196
1197   return x;
1198 }
1199
1200
1201 /* Output branch condition code of CODE in assembler
1202    syntax to stdio stream FILE.  */
1203
1204 static void
1205 output_branch_condition (file, code)
1206      FILE *file;
1207      rtx code;
1208 {
1209   switch (GET_CODE (code)) 
1210     {
1211     case EQ:
1212       fprintf (file, "e");
1213       break;
1214     case NE:
1215       fprintf (file, "ne");
1216       break;
1217     case GT:
1218     case GTU:
1219       fprintf (file, "h");
1220       break;
1221     case LT:
1222     case LTU:
1223       fprintf (file, "l");
1224       break;
1225     case GE:
1226     case GEU:
1227       fprintf (file, "he");
1228       break;
1229     case LE:
1230     case LEU:
1231       fprintf (file, "le");
1232       break;
1233     default:
1234       fatal_insn ("Unknown CC code", code);
1235     }
1236 }
1237
1238 /* Output the inverse of the branch condition code of CODE 
1239    in assembler syntax to stdio stream FILE.  */
1240
1241 static void
1242 output_inverse_branch_condition (file, code)
1243      FILE *file;
1244      rtx code;
1245 {
1246   switch (GET_CODE (code)) 
1247     {
1248     case EQ:
1249       fprintf (file, "ne");
1250       break;
1251     case NE:
1252       fprintf (file, "e");
1253       break;
1254     case GT:
1255     case GTU:
1256       fprintf (file, "nh");
1257       break;
1258     case LT:
1259     case LTU:
1260       fprintf (file, "nl");
1261       break;
1262     case GE:
1263     case GEU:
1264       fprintf (file, "nhe");
1265       break;
1266     case LE:
1267     case LEU:
1268       fprintf (file, "nle");
1269       break;
1270     default:
1271       fatal_insn ("Unknown CC code", code);
1272     }
1273 }
1274
1275 /* Output symbolic constant X in assembler syntax to 
1276    stdio stream FILE.  */
1277
1278 void
1279 s390_output_symbolic_const (file, x)
1280      FILE *file;
1281      rtx x;
1282 {
1283   switch (GET_CODE (x))
1284     {
1285     case CONST:
1286     case ZERO_EXTEND:
1287     case SIGN_EXTEND:
1288       s390_output_symbolic_const (file, XEXP (x, 0));
1289       break;
1290
1291     case PLUS:
1292       s390_output_symbolic_const (file, XEXP (x, 0));
1293       fprintf (file, "+");
1294       s390_output_symbolic_const (file, XEXP (x, 1));
1295       break;
1296
1297     case MINUS:
1298       s390_output_symbolic_const (file, XEXP (x, 0));
1299       fprintf (file, "-");
1300       s390_output_symbolic_const (file, XEXP (x, 1));
1301       break;
1302
1303     case CONST_INT:
1304       output_addr_const (file, x);
1305       break;
1306
1307     case LABEL_REF:
1308     case CODE_LABEL:
1309       output_addr_const (file, x);
1310       break;
1311
1312     case SYMBOL_REF:
1313       output_addr_const (file, x);
1314       if (CONSTANT_POOL_ADDRESS_P (x) && s390_pool_count != 0)
1315         fprintf (file, "_%X", s390_pool_count);
1316       break;
1317
1318     case UNSPEC:
1319       if (XVECLEN (x, 0) != 1)
1320         output_operand_lossage ("invalid UNSPEC as operand (1)");
1321       switch (XINT (x, 1))
1322         {
1323         case 100:
1324           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1325           fprintf (file, "-.LT%X_%X", 
1326                    s390_function_count, s390_pool_count);
1327           break;
1328         case 110:
1329           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1330           fprintf (file, "@GOT12");
1331           break;
1332         case 111:
1333           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1334           fprintf (file, "@GOTENT");
1335           break;
1336         case 112:
1337           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1338           fprintf (file, "@GOT");
1339           break;
1340         case 113:
1341           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1342           fprintf (file, "@PLT");
1343           break;
1344         case 114:
1345           s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
1346           fprintf (file, "@PLT-.LT%X_%X",
1347                    s390_function_count, s390_pool_count);
1348           break;
1349         default:
1350           output_operand_lossage ("invalid UNSPEC as operand (2)");
1351           break;
1352         }
1353       break;
1354
1355     default:
1356       fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
1357       break;
1358     }
1359 }
1360
1361 /* Output address operand ADDR in assembler syntax to 
1362    stdio stream FILE.  */
1363
1364 void
1365 print_operand_address (file, addr)
1366      FILE *file;
1367      rtx addr;
1368 {
1369   struct s390_address ad;
1370
1371   if (!s390_decompose_address (addr, &ad, TRUE))
1372     output_operand_lossage ("Cannot decompose address.\n");
1373  
1374   if (ad.disp)
1375     s390_output_symbolic_const (file, ad.disp);
1376   else
1377     fprintf (file, "0");
1378
1379   if (ad.base && ad.indx)
1380     fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
1381                               reg_names[REGNO (ad.base)]);
1382   else if (ad.base)
1383     fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
1384 }
1385
1386 /* Output operand X in assembler syntax to stdio stream FILE.  
1387    CODE specified the format flag.  The following format flags 
1388    are recognized:
1389
1390     'C': print opcode suffix for branch condition.
1391     'D': print opcode suffix for inverse branch condition.
1392     'Y': print current constant pool address (pc-relative).
1393     'y': print current constant pool address (absolute).
1394     'O': print only the displacement of a memory reference.
1395     'R': print only the base register of a memory reference.
1396     'N': print the second word of a DImode operand.
1397     'M': print the second word of a TImode operand.
1398
1399     'b': print integer X as if it's a unsigned byte.
1400     'x': print integer X as if it's a unsigned word.
1401     'h': print integer X as if it's a signed word.  */
1402
1403 void
1404 print_operand (file, x, code)
1405      FILE *file;
1406      rtx x;
1407      int code;
1408 {
1409   switch (code)
1410     {
1411     case 'C':
1412       output_branch_condition (file, x);
1413       return;
1414
1415     case 'D':
1416       output_inverse_branch_condition (file, x);
1417       return;
1418
1419     case 'Y':
1420       fprintf (file, ".LT%X_%X-.", s390_function_count, s390_pool_count);
1421       return;
1422
1423     case 'y':
1424       fprintf (file, ".LT%X_%X", s390_function_count, s390_pool_count);
1425       return;
1426
1427     case 'O':
1428       {
1429         struct s390_address ad;
1430
1431         if (GET_CODE (x) != MEM
1432             || !s390_decompose_address (XEXP (x, 0), &ad, TRUE)
1433             || ad.indx)
1434           abort ();
1435
1436         if (ad.disp)
1437           s390_output_symbolic_const (file, ad.disp);
1438         else
1439           fprintf (file, "0");
1440       }
1441       return;
1442
1443     case 'R':
1444       {
1445         struct s390_address ad;
1446
1447         if (GET_CODE (x) != MEM
1448             || !s390_decompose_address (XEXP (x, 0), &ad, TRUE)
1449             || ad.indx)
1450           abort ();
1451
1452         if (ad.base)
1453           fprintf (file, "%s", reg_names[REGNO (ad.base)]);
1454         else
1455           fprintf (file, "0");
1456       }
1457       return;
1458
1459     case 'N':
1460       if (GET_CODE (x) == REG)
1461         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
1462       else if (GET_CODE (x) == MEM)
1463         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
1464       else
1465         abort ();
1466       break;
1467
1468     case 'M':
1469       if (GET_CODE (x) == REG)
1470         x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
1471       else if (GET_CODE (x) == MEM)
1472         x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
1473       else
1474         abort ();
1475       break;
1476     }
1477
1478   switch (GET_CODE (x))
1479     {
1480     case REG:
1481       fprintf (file, "%s", reg_names[REGNO (x)]);
1482       break;
1483
1484     case MEM:
1485       output_address (XEXP (x, 0));
1486       break;
1487
1488     case CONST:
1489     case CODE_LABEL:
1490     case LABEL_REF:
1491     case SYMBOL_REF:
1492       s390_output_symbolic_const (file, x);
1493       break;
1494
1495     case CONST_INT:
1496       if (code == 'b')
1497         fprintf (file, "%d", (int)(INTVAL (x) & 0xff));
1498       else if (code == 'X')
1499         fprintf (file, "%d", (int)(INTVAL (x) & 0xff));
1500       else if (code == 'x')
1501         fprintf (file, "0x%x", (int)(INTVAL (x) & 0xffff));
1502       else if (code == 'h')
1503         fprintf (file, "%d", (int)(INTVAL (x) << 16) >> 16);
1504       else
1505         fprintf (file, "%d", (int)INTVAL (x));
1506       break;
1507
1508     default:
1509       fatal_insn ("UNKNOWN in print_operand !?", x);
1510       break;
1511     }
1512 }
1513
1514 #define DEBUG_SCHED 0
1515
1516 /* Returns true if register REGNO is used  for forming 
1517    a memory address in expression X.  */
1518
1519 static int
1520 reg_used_in_mem_p (regno, x)
1521      int regno;
1522      rtx x;
1523 {
1524   enum rtx_code code = GET_CODE (x);
1525   int i, j;
1526   const char *fmt;
1527   
1528   if (code == MEM)
1529     {
1530       if (refers_to_regno_p (regno, regno+1,
1531                              XEXP (x, 0), 0))
1532         return 1;
1533     }
1534
1535   fmt = GET_RTX_FORMAT (code);
1536   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1537     {
1538       if (fmt[i] == 'e'
1539           && reg_used_in_mem_p (regno, XEXP (x, i)))
1540         return 1;
1541       
1542       else if (fmt[i] == 'E')
1543         for (j = 0; j < XVECLEN (x, i); j++)
1544           if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
1545             return 1;
1546     }
1547   return 0;
1548 }
1549
1550 /* Returns true if expression DEP_RTX sets a address register
1551    used by instruction INSN to address memory.  */
1552
1553 static int 
1554 addr_generation_dependency_p (dep_rtx, insn)
1555      rtx dep_rtx; 
1556      rtx insn;
1557 {
1558   rtx target;
1559
1560   if (GET_CODE (dep_rtx) == SET)
1561     {
1562       target = SET_DEST (dep_rtx);
1563       
1564       if (GET_CODE (target) == REG)
1565         {
1566           int regno = REGNO (target);
1567
1568           if (get_attr_type (insn) == TYPE_LA)
1569             return refers_to_regno_p (regno, regno+1,
1570                                       SET_SRC (PATTERN (insn)), 0);
1571           else if (get_attr_atype (insn) == ATYPE_MEM)
1572             return reg_used_in_mem_p (regno, PATTERN (insn));
1573         }
1574     }
1575   return 0;
1576 }
1577
1578
1579 /* Return the modified cost of the dependency of instruction INSN
1580    on instruction DEP_INSN through the link LINK.  COST is the 
1581    default cost of that dependency.
1582
1583    Data dependencies are all handled without delay.  However, if a
1584    register is modified and subsequently used as base or index 
1585    register of a memory reference, at least 4 cycles need to pass
1586    between setting and using the register to avoid pipeline stalls.  */
1587
1588 int
1589 s390_adjust_cost (insn, link, dep_insn, cost)
1590      rtx insn;
1591      rtx link;
1592      rtx dep_insn;
1593      int cost;
1594 {
1595   rtx dep_rtx;
1596   int i;
1597
1598   /* If the dependence is an anti-dependence, there is no cost.  For an
1599      output dependence, there is sometimes a cost, but it doesn't seem
1600      worth handling those few cases.  */
1601
1602   if (REG_NOTE_KIND (link) != 0)
1603     return 0;
1604
1605   /* If we can't recognize the insns, we can't really do anything.  */
1606   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
1607     return cost;
1608
1609   /* If cost equal 1 nothing needs to be checked. */
1610
1611   if (cost == 1)
1612     {
1613       return cost;
1614     }
1615
1616   dep_rtx = PATTERN (dep_insn);
1617
1618   if (GET_CODE (dep_rtx) == SET)
1619     {
1620       if (addr_generation_dependency_p (dep_rtx, insn))
1621         {
1622           if (DEBUG_SCHED)
1623             {
1624               fprintf (stderr, "\n\nAddress dependency detected: cost %d\n",
1625                        cost);
1626               debug_rtx (dep_insn);
1627               debug_rtx (insn);
1628             }
1629           return cost;
1630         }
1631     }
1632
1633   else if (GET_CODE (dep_rtx) == PARALLEL)
1634     {
1635       for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
1636         {
1637           if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i),
1638                                             insn))
1639             {
1640               if (DEBUG_SCHED)
1641                 {
1642                   fprintf (stderr, "\n\nAddress dependency detected: cost %d\n"
1643                            ,cost);
1644                   debug_rtx (dep_insn);
1645                   debug_rtx (insn);
1646                 }
1647               return cost;
1648             }
1649         }
1650     }
1651
1652   /* default cost.  */
1653   return 1;
1654 }
1655
1656 /* Pool concept for Linux 390:
1657    - Function prologue saves used register 
1658    - literal pool is dumped in prologue and  jump across with bras
1659    - If function has more than 4 k literals, at about every 
1660      S390_CHUNK_MAX offset in the function a literal pool will be
1661      dumped
1662      - in this case, a branch from one chunk to other chunk needs
1663        a reload of base register at the code label branched to.  */
1664
1665 /* Index of constant pool chunk that is currently being processed.
1666    Set to -1 before function output has started.  */
1667 int s390_pool_count = -1;
1668
1669 /* First insn using the constant pool chunk that is currently being
1670    processed.  */
1671 rtx s390_pool_start_insn = NULL_RTX;
1672
1673 /* UID of last insn using the constant pool chunk that is currently 
1674    being processed.  */
1675 static int pool_stop_uid;
1676
1677 /* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to 
1678    prepare for printing a literal pool chunk to stdio stream FILE.  
1679
1680    FNAME and FNDECL specify the name and type of the current function.
1681    SIZE is the size in bytes of the current literal pool.  */
1682  
1683 void 
1684 s390_asm_output_pool_prologue (file, fname, fndecl, size)
1685      FILE *file;
1686      const char *fname ATTRIBUTE_UNUSED;
1687      tree fndecl;
1688      int size ATTRIBUTE_UNUSED;
1689 {
1690
1691   if (s390_pool_count>0) {
1692     /*
1693      * We are in an internal pool, branch over
1694      */
1695     if (TARGET_64BIT)
1696       {
1697         fprintf (file, "\tlarl\t%s,.LT%X_%X\n", 
1698                  reg_names[BASE_REGISTER],
1699                  s390_function_count, s390_pool_count);
1700         readonly_data_section ();
1701         ASM_OUTPUT_ALIGN (file, floor_log2 (3));
1702         fprintf (file, ".LT%X_%X:\t# Pool %d\n",
1703                  s390_function_count, s390_pool_count, s390_pool_count);
1704       }
1705     else
1706     fprintf (file,"\t.align 4\n\tbras\t%s,0f\n.LT%X_%X:\t# Pool %d \n",
1707              reg_names[BASE_REGISTER],
1708              s390_function_count, s390_pool_count, s390_pool_count);
1709   }
1710   if (!TARGET_64BIT)
1711     function_section (fndecl);
1712 }
1713
1714 /* Return true if OTHER_ADDR is in different chunk than MY_ADDR.
1715    LTORG points to a list of all literal pools inserted
1716    into the current function.  */
1717
1718 static int
1719 other_chunk (ltorg, my_addr, other_addr)
1720      int *ltorg;
1721      int my_addr;
1722      int other_addr;
1723 {
1724   int ad, i=0, j=0;
1725
1726   while ((ad = ltorg[i++])) {
1727     if (INSN_ADDRESSES (ad) >= my_addr)
1728       break;
1729   }
1730
1731   while ((ad = ltorg[j++])) {
1732     if (INSN_ADDRESSES (ad) > other_addr)
1733       break;
1734   }
1735   
1736   if (i==j)
1737     return 0;
1738
1739   return 1;
1740 }
1741
1742 /* Return true if OTHER_ADDR is too far away from MY_ADDR
1743    to use a relative branch instruction.  */
1744
1745 static int 
1746 far_away (my_addr, other_addr)
1747      int my_addr;
1748      int other_addr;
1749 {
1750   /* In 64 bit mode we can jump +- 4GB.  */
1751   if (TARGET_64BIT)
1752     return 0;
1753   if (abs (my_addr - other_addr) > S390_REL_MAX)
1754     return 1;
1755   return 0;
1756 }
1757
1758 /* Go through all insns in the current function (starting
1759    at INSN), replacing branch insn if necessary.  A branch
1760    needs to be modified if either the distance to the 
1761    target is too far to use a relative branch, or if the
1762    target uses a different literal pool than the origin.
1763    LTORG_UIDS points to a list of all literal pool insns
1764    that have been inserted.  */
1765
1766 static rtx 
1767 check_and_change_labels (insn, ltorg_uids)
1768      rtx insn;
1769      int *ltorg_uids;
1770 {
1771   rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
1772   rtx target, jump;
1773   rtx pattern, tmp, body, label1;
1774   int addr0, addr1;
1775
1776   if (GET_CODE (insn) != JUMP_INSN) 
1777     return insn;
1778
1779   pattern = PATTERN (insn);
1780   
1781   addr0 = INSN_ADDRESSES (INSN_UID (insn));
1782   if (GET_CODE (pattern) == SET) 
1783     {
1784       body = XEXP (pattern, 1);
1785       if (GET_CODE (body) == LABEL_REF) 
1786         {
1787           addr1 = INSN_ADDRESSES (INSN_UID (XEXP (body, 0)));
1788           
1789           if (other_chunk (ltorg_uids, addr0, addr1)) 
1790             {
1791               SYMBOL_REF_USED (XEXP (body, 0)) = 1;
1792             } 
1793           if (far_away (addr0, addr1)) 
1794             {
1795               if (flag_pic) 
1796                 {
1797                   target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, body), 100);
1798                   target = gen_rtx_CONST (SImode, target);
1799                   target = force_const_mem (SImode, target);
1800                   jump = gen_rtx_REG (Pmode, BASE_REGISTER);
1801                   jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
1802                 } 
1803               else 
1804                 {
1805                   target = force_const_mem (Pmode, body);
1806                   jump = temp_reg;
1807                 }
1808               
1809               emit_insn_before (gen_movsi (temp_reg, target), insn);
1810               tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
1811               remove_insn (insn);
1812               INSN_ADDRESSES_NEW (tmp, -1);
1813               return tmp;
1814             }
1815         } 
1816       else if (GET_CODE (body) == IF_THEN_ELSE) 
1817         {
1818           if (GET_CODE (XEXP (body, 1)) == LABEL_REF) 
1819             {
1820               addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body, 1), 0)));
1821               
1822               if (other_chunk (ltorg_uids, addr0, addr1)) 
1823                 {
1824                   SYMBOL_REF_USED (XEXP (XEXP (body, 1), 0)) = 1;
1825                 } 
1826               
1827               if (far_away (addr0, addr1)) 
1828                 {
1829                   if (flag_pic) 
1830                     {
1831                       target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, XEXP (body, 1)), 100);
1832                       target = gen_rtx_CONST (SImode, target);
1833                       target = force_const_mem (SImode, target);
1834                       jump = gen_rtx_REG (Pmode, BASE_REGISTER);
1835                       jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
1836                     } 
1837                   else 
1838                     {
1839                       target = force_const_mem (Pmode, XEXP (body, 1));
1840                       jump = temp_reg;
1841                     }
1842                   
1843                   label1 = gen_label_rtx ();
1844                   emit_jump_insn_before (gen_icjump (label1, XEXP (body, 0)), insn);
1845                   emit_insn_before (gen_movsi (temp_reg, target), insn);
1846                   tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
1847                   INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
1848                   remove_insn (insn);
1849                   return tmp;
1850                 }
1851             }
1852           else if (GET_CODE (XEXP (body, 2)) == LABEL_REF) 
1853             {
1854               addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XEXP (body, 2), 0)));
1855               
1856               if (other_chunk (ltorg_uids, addr0, addr1)) 
1857                 {
1858                   SYMBOL_REF_USED (XEXP (XEXP (body, 2), 0)) = 1;
1859                 } 
1860               
1861               if (far_away (addr0, addr1)) 
1862                 {
1863                   if (flag_pic) 
1864                     {
1865                       target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, XEXP (body, 2)), 100);
1866                       target = gen_rtx_CONST (SImode, target);
1867                       target = force_const_mem (SImode, target);
1868                       jump = gen_rtx_REG (Pmode, BASE_REGISTER);
1869                       jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
1870                     } 
1871                   else 
1872                     {
1873                       target = force_const_mem (Pmode, XEXP (body, 2));
1874                       jump = temp_reg;
1875                     }
1876                   
1877                   label1 = gen_label_rtx ();
1878                   emit_jump_insn_before (gen_cjump (label1, XEXP (body, 0)), insn);
1879                   emit_insn_before (gen_movsi (temp_reg, target), insn);
1880                   tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
1881                   INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
1882                   remove_insn (insn);
1883                   return tmp;
1884                 }
1885             }
1886         }
1887     } 
1888   else if (GET_CODE (pattern) == ADDR_VEC || 
1889            GET_CODE (pattern) == ADDR_DIFF_VEC) 
1890     {
1891       int i, diff_vec_p = GET_CODE (pattern) == ADDR_DIFF_VEC;
1892       int len = XVECLEN (pattern, diff_vec_p);
1893       
1894       for (i = 0; i < len; i++) 
1895         {
1896           addr1 = INSN_ADDRESSES (INSN_UID (XEXP (XVECEXP (pattern, diff_vec_p, i), 0)));
1897           if (other_chunk (ltorg_uids, addr0, addr1)) 
1898             {
1899               SYMBOL_REF_USED (XEXP (XVECEXP (pattern, diff_vec_p, i), 0)) = 1;
1900             } 
1901         }
1902     }
1903   return insn;
1904 }
1905
1906 /* Called from s390_function_prologue to make final adjustments
1907    before outputting code.  CHUNKIFY specifies whether we need
1908    to use multiple literal pools (because the total size of the
1909    literals exceeds 4K).  */
1910
1911 static void
1912 s390_final_chunkify (chunkify)
1913      int chunkify;
1914 {
1915   rtx insn, ninsn, tmp;
1916   int addr, naddr = 0, uids;
1917   int chunk_max = 0;
1918
1919   const char *asms;
1920
1921   int size = insn_current_address;
1922
1923   int *ltorg_uids;
1924   int max_ltorg=0;
1925
1926   ltorg_uids = alloca (size / 1024 + 1024);
1927   memset (ltorg_uids, 0, size / 1024 + 1024);
1928
1929   if (chunkify == 1) 
1930     {
1931       chunk_max = size * 2048 / get_pool_size ();
1932       chunk_max = chunk_max > S390_CHUNK_MAX 
1933         ? S390_CHUNK_MAX : chunk_max;
1934     } 
1935   
1936   for (insn=get_insns (); insn;insn = next_real_insn (insn)) 
1937     {
1938       if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
1939         continue;
1940       
1941       addr = INSN_ADDRESSES (INSN_UID (insn));
1942       if ((ninsn = next_real_insn (insn))) 
1943         {
1944           naddr = INSN_ADDRESSES (INSN_UID (ninsn));
1945         }
1946       
1947       if (chunkify && (addr / chunk_max != naddr / chunk_max)) 
1948         {
1949           for (tmp = insn; tmp; tmp = NEXT_INSN (tmp)) 
1950             {
1951               if (GET_CODE (tmp) == CODE_LABEL && 
1952                   GET_CODE (NEXT_INSN (tmp)) != JUMP_INSN) 
1953                 {
1954                   ltorg_uids[max_ltorg++] = INSN_UID (prev_real_insn (tmp));
1955                   break;
1956                 } 
1957               if (GET_CODE (tmp) == CALL_INSN) 
1958                 {
1959                   ltorg_uids[max_ltorg++] = INSN_UID (tmp);
1960                   break;
1961                 } 
1962               if (INSN_ADDRESSES (INSN_UID (tmp)) - naddr > S390_CHUNK_OV) 
1963                 {
1964                   debug_rtx (insn);
1965                   debug_rtx (tmp);
1966                   fprintf (stderr, "s390 multiple literalpool support:"
1967                            "\n No code label between this insn %X %X",
1968                            naddr, INSN_ADDRESSES (INSN_UID (tmp)));
1969                   abort ();
1970                 }
1971             }
1972           if (tmp == NULL) 
1973             {
1974               warning ("no code label found");
1975             }
1976         } 
1977       else if (GET_CODE (PATTERN (insn)) == ASM_INPUT && !TARGET_64BIT) 
1978         {
1979           asms = XSTR (PATTERN (insn),0);
1980           
1981           if ((memcmp (asms,".section",8) == 0) ||
1982               (memcmp (asms,".text",5) == 0)    ||
1983               (memcmp (asms,"\t.section",9) == 0) ||
1984               (memcmp (asms,"\t.text",6) == 0))  {
1985             ltorg_uids[max_ltorg++] = INSN_UID (insn);
1986             INSN_ADDRESSES_NEW (emit_insn_before (gen_rtx_ASM_INPUT (VOIDmode,
1987                                            ".align 4"), insn), -1);
1988           }
1989         }
1990     }
1991   ltorg_uids[max_ltorg] = 0;
1992   for (insn=get_insns (),uids=0; insn;insn = next_real_insn (insn)) 
1993     {
1994       if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
1995         continue;
1996       if (INSN_UID (insn) == ltorg_uids[uids]) 
1997         {
1998           INSN_ADDRESSES_NEW (emit_insn_after (gen_ltorg (
1999                               gen_rtx_CONST_INT (Pmode, ltorg_uids[++uids])),
2000                                                insn), -1);
2001         } 
2002       if (GET_CODE (insn) == JUMP_INSN) 
2003         {
2004           insn = check_and_change_labels (insn, ltorg_uids);
2005         }
2006     }
2007   if (chunkify) 
2008     {
2009     for (insn=get_insns (); insn;insn = next_insn (insn)) 
2010       {
2011       if (GET_CODE (insn) == CODE_LABEL) 
2012         {
2013         if (SYMBOL_REF_USED (insn)) 
2014           {
2015             INSN_ADDRESSES_NEW (emit_insn_after (gen_reload_base (
2016                                                                   gen_rtx_LABEL_REF (Pmode, XEXP (insn, 0))), insn), -1);
2017           }
2018         }
2019       }
2020     }
2021   pool_stop_uid = ltorg_uids[0];
2022 }
2023
2024 /* Return true if INSN is a 'ltorg' insn.  */
2025
2026 int 
2027 s390_stop_dump_lit_p (insn)
2028     rtx insn;
2029 {
2030   rtx body=PATTERN (insn);
2031   if (GET_CODE (body) == PARALLEL
2032       && GET_CODE (XVECEXP (body, 0, 0)) == SET
2033       && GET_CODE (XVECEXP (body, 0, 1)) == USE
2034       && GET_CODE (XEXP ((XVECEXP (body, 0, 1)),0)) == CONST_INT
2035       && GET_CODE (SET_DEST (XVECEXP (body, 0, 0))) == REG
2036       && REGNO (SET_DEST (XVECEXP (body, 0, 0))) == BASE_REGISTER
2037       && SET_SRC (XVECEXP (body, 0, 0)) == pc_rtx) {
2038     return 1;
2039   }
2040   else
2041     return 0;   
2042 }
2043
2044 /* Output literal pool chunk to be used for insns
2045    between insn ACT_INSN and the insn with UID STOP.  */
2046
2047 void
2048 s390_dump_literal_pool (act_insn, stop)
2049      rtx act_insn;
2050      rtx stop;
2051 {
2052   s390_pool_start_insn = act_insn;
2053   pool_stop_uid = INTVAL (stop);
2054   s390_pool_count++;
2055   output_constant_pool (current_function_name, current_function_decl);
2056   function_section (current_function_decl);
2057 }
2058
2059
2060 #ifdef DWARF2_DEBUGGING_INFO
2061 extern char *dwarf2out_cfi_label PARAMS ((void));
2062 #endif
2063
2064 /* Flag set in prologue, used in epilog to know
2065    if stack is allocated or not.  */
2066 static int leaf_function_flag;
2067
2068 /* Symbol references needed by the profile code;
2069    set up by the function prologue routine if necessary.  */
2070 rtx s390_profile[10];
2071
2072 /* Number of elements of current constant pool.  */
2073 int s390_nr_constants;
2074
2075 /* Return true if floating point registers need to be saved.  */
2076
2077 static int 
2078 save_fprs_p ()
2079 {
2080   int i;
2081   if (!TARGET_64BIT)
2082     return 0;
2083   for (i=24; i<=31; i++) 
2084     {
2085       if (regs_ever_live[i] == 1)
2086         return 1;
2087     }
2088   return 0;
2089 }
2090
2091 /* Return true if urrent function is a leaf function, 
2092    without automatics, alloca or vararg stuff.  */
2093
2094 static int
2095 cur_is_leaf_function ()
2096 {
2097   int lsize =  get_frame_size () + current_function_outgoing_args_size
2098     + save_fprs_p () * 64;
2099
2100   if (leaf_function_p () && ((lsize) == 0) &&
2101       ! (current_function_calls_alloca) &&
2102       ! (current_function_stdarg) && ! (current_function_varargs))
2103     return 1;
2104   return 0;
2105 }
2106
2107 /* Return offset between argument pointer and frame pointer 
2108    initially after prologue.  */
2109
2110 int 
2111 s390_arg_frame_offset ()
2112 {
2113   int lsize =  get_frame_size () + current_function_outgoing_args_size
2114     + save_fprs_p () * 64;
2115
2116   if (cur_is_leaf_function ())
2117     return STACK_POINTER_OFFSET;
2118   else
2119     return 2*STACK_POINTER_OFFSET + lsize;
2120 }
2121
2122 /* Output code to stdio stream FILE to save floating point 
2123    registers on current stack, at offset OFFSET to the frame
2124    pointer register FP.  */
2125
2126 static int 
2127 save_fprs (file, offset, fp)
2128      FILE *file;
2129      long offset;
2130      int fp;
2131 {
2132   int i;
2133
2134   if (!TARGET_64BIT)
2135     return 0;
2136
2137   for (i=24; i<=31; i++) 
2138     {
2139       if (regs_ever_live[i] == 1)
2140         {
2141           fprintf (file, "\tstd\t%s,%ld(%s)\n", reg_names[i], 
2142                    (i-24) * 8 + offset, reg_names[fp]); 
2143         }
2144     }
2145
2146   return 1;
2147 }
2148
2149 /* Output code to stdio stream FILE to restore floating point 
2150    registers from current stack, at offset OFFSET to the frame
2151    pointer register FP.  */
2152
2153 static int 
2154 restore_fprs (file, offset, fp)
2155      FILE *file;
2156      long offset;
2157      int fp;
2158 {
2159   int i;
2160
2161   if (!TARGET_64BIT)
2162     return 0;
2163
2164   if (!save_fprs_p ())
2165     return 0;
2166
2167   if (offset < 0) 
2168     {
2169       fp = 1;
2170       offset = 0;
2171       fprintf (file, "\tlgr\t%s,%s\n", reg_names[fp], 
2172                reg_names[STACK_POINTER_REGNUM]); 
2173       fprintf (file, "\taghi\t%s,-64\n", reg_names[fp]); 
2174     }
2175
2176   for (i=24; i<=31; i++) 
2177     {
2178       if (regs_ever_live[i] == 1)
2179         {
2180           fprintf (file, "\tld\t%s,%ld(%s)\n", reg_names[i], 
2181                    (i-24) * 8 + offset, reg_names[fp]); 
2182         }
2183     }
2184
2185   return 1;
2186 }
2187
2188 /* Output main constant pool to stdio stream FILE.  */ 
2189
2190 static void
2191 s390_output_constant_pool (file)
2192      FILE *file;
2193 {
2194   /* Output constant pool.  */
2195   if (s390_nr_constants || regs_ever_live[BASE_REGISTER])
2196     {
2197       s390_pool_count = 0;
2198       if (TARGET_64BIT)
2199         {
2200           fprintf (file, "\tlarl\t%s,.LT%X_%X\n", reg_names[BASE_REGISTER],
2201                    s390_function_count, s390_pool_count);
2202           readonly_data_section ();
2203           ASM_OUTPUT_ALIGN (file, floor_log2 (3));
2204         }
2205       else
2206         {
2207           fprintf (file, "\tbras\t%s,.LTN%X_%X\n", reg_names[BASE_REGISTER],
2208                    s390_function_count, s390_pool_count);
2209         }
2210       fprintf (file, ".LT%X_%X:\n", s390_function_count, s390_pool_count);
2211       output_constant_pool (current_function_name, current_function_decl);
2212       fprintf (file, ".LTN%X_%X:\n", s390_function_count,
2213                s390_pool_count);
2214       if (TARGET_64BIT)
2215         function_section (current_function_decl);
2216       
2217       regs_ever_live[BASE_REGISTER] = 1;
2218     }
2219 }
2220
2221 /* Add constant CTX to the constant pool at a late time 
2222    (after the initial pass to count the number of constants
2223    was already done).  Returns the resulting constant 
2224    pool reference.  */
2225
2226 static rtx
2227 s390_force_const_mem_late (cst)
2228      rtx cst;
2229 {
2230   cst = force_const_mem (Pmode, cst);
2231
2232   s390_nr_constants++;
2233   regs_ever_live[BASE_REGISTER] = 1;
2234
2235   emit_insn_before (gen_rtx (USE, Pmode, cst), get_insns ());
2236
2237   return cst;
2238 }
2239
2240 /* Add a reference to the symbol NAME to the constant pool.
2241    FUNC specifies whether NAME refers to a function, while
2242    GLOBAL specifies whether NAME is a global symbol.  Depending
2243    on these flags, the appopriate PLT or GOT references are
2244    generated.  Returns the constant pool reference.  */
2245
2246 static rtx
2247 s390_force_const_mem_symbol (name, func, global)
2248      const char *name;
2249      int func;
2250      int global;
2251 {
2252   rtx symbol;
2253
2254   if (TARGET_64BIT)
2255     abort ();
2256
2257   symbol = gen_rtx (SYMBOL_REF, Pmode, name);
2258   SYMBOL_REF_FLAG (symbol) = !global;
2259
2260   if (flag_pic)
2261     {
2262       if (global)
2263         {
2264           current_function_uses_pic_offset_table = 1;
2265           symbol = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, symbol), func? 114 : 112);
2266           symbol = gen_rtx_CONST (VOIDmode, symbol);
2267         }
2268       else
2269         {
2270           symbol = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, symbol), 100);
2271           symbol = gen_rtx_CONST (VOIDmode, symbol);
2272         }
2273     }
2274
2275   return s390_force_const_mem_late (symbol);
2276 }
2277
2278 /* Output the function prologue assembly code to the 
2279    stdio stream FILE.  The local frame size is passed
2280    in LSIZE.  */
2281
2282 void
2283 s390_function_prologue (file, lsize)
2284      FILE *file;
2285      HOST_WIDE_INT lsize;
2286 {
2287   extern int profile_label_no;
2288   int i, j;
2289   long frame_size;
2290   rtx stack_label = 0, got_label = 0;
2291   char *l;
2292   char b64[2] = " ";
2293   b64[0] = TARGET_64BIT ? 'g' : '\0';
2294
2295   /* Check for too large size of local variables */
2296
2297   if (lsize > 0x7fff0000)
2298     fatal_error ("Total size of local variables exceeds architecture limit.");
2299
2300   /* Profile code (-p, -a, -ax needs some literals).  */
2301
2302   if (profile_block_flag && !TARGET_64BIT)
2303     {
2304       s390_profile[0] = s390_force_const_mem_symbol ("__bb_init_func", 1, 1);
2305       s390_profile[1] = s390_force_const_mem_symbol ("__bb_init_trace_func", 1, 1);
2306       s390_profile[2] = s390_force_const_mem_symbol ("__bb_trace_func", 1, 1);
2307       s390_profile[3] = s390_force_const_mem_symbol ("__bb_trace_ret", 1, 1);
2308       s390_profile[5] = s390_force_const_mem_symbol ("__bb", 0, 1);
2309       s390_profile[6] = s390_force_const_mem_symbol (".LPBX0", 0, 0);
2310       s390_profile[7] = s390_force_const_mem_symbol (".LPBX2", 0, 0);
2311     }
2312
2313   if (profile_flag && !TARGET_64BIT)
2314     {
2315       static char label[128];
2316       sprintf (label, "%sP%d", LPREFIX, profile_label_no);
2317
2318       s390_profile[4] = s390_force_const_mem_symbol ("_mcount", 1, 1);
2319       s390_profile[9] = s390_force_const_mem_symbol (label, 0, 0);
2320     }
2321
2322   if (get_pool_size () > S390_POOL_MAX)
2323     s390_final_chunkify (1);
2324   else
2325     s390_final_chunkify (0);
2326
2327   if (current_function_uses_pic_offset_table)
2328     regs_ever_live[12] = 1;
2329
2330   if (!TARGET_64BIT && current_function_uses_pic_offset_table)
2331     {
2332       got_label = s390_force_const_mem_symbol ("_GLOBAL_OFFSET_TABLE_", 0, 0);
2333     }
2334
2335   if ((frame_size = 
2336        STARTING_FRAME_OFFSET + lsize + save_fprs_p () * 64) > 0x7fff)
2337     {
2338       stack_label = s390_force_const_mem_late (GEN_INT (frame_size));
2339     }
2340
2341   if (!optimize)
2342     {
2343       /* Stupid register allocation is stupid ...
2344          It does not always recognize the base register is used. */
2345       
2346       regs_ever_live[BASE_REGISTER] = 1;
2347     }
2348
2349  if (cur_is_leaf_function ())
2350    {
2351       leaf_function_flag = 1;
2352       fprintf (file, "%s\tleaf function\n", ASM_COMMENT_START);
2353       fprintf (file, "%s\thas varargs             %d\n", ASM_COMMENT_START,
2354                current_function_stdarg);
2355       fprintf (file, "%s\tincoming args (stack)   %d\n", ASM_COMMENT_START,
2356                current_function_args_size);
2357       fprintf (file, "%s\tfunction length         %d\n", ASM_COMMENT_START,
2358                insn_current_address);
2359       fprintf (file, "%s\tregister live           ", ASM_COMMENT_START);
2360       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2361         fprintf (file, "%d", regs_ever_live[i]);
2362       fputc   ('\n',file);
2363       
2364       /* Save gprs 6 - 15 and fprs 4 and 6.  */
2365       for (i = 6; i < 13 && (regs_ever_live[i] == 0); i++);
2366
2367       if (s390_nr_constants || regs_ever_live[13] || i != 13)
2368         {
2369           fprintf (file, "\tstm%s\t%s,%s,%d(%s)\n", 
2370                          b64, reg_names[i], reg_names[13],
2371                          i * UNITS_PER_WORD,
2372                          reg_names[STACK_POINTER_REGNUM]);
2373 #ifdef INCOMING_RETURN_ADDR_RTX
2374           if (dwarf2out_do_frame ())
2375             {
2376               l = dwarf2out_cfi_label ();
2377               dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, 
2378                                  STACK_POINTER_OFFSET);
2379               for (j = i; j <= 14; j++)
2380                 dwarf2out_reg_save (l, j, (TARGET_64BIT ? (j-20) : (j-24))
2381                                     * UNITS_PER_WORD);
2382               if (regs_ever_live[18])
2383                 dwarf2out_reg_save (l, 18, -16);
2384               if (regs_ever_live[19])
2385                 dwarf2out_reg_save (l, 19, -8);
2386             }
2387 #endif
2388         }
2389
2390       s390_output_constant_pool (file);
2391
2392       /* Save fprs.  */
2393
2394       if (!TARGET_64BIT)
2395         {
2396           if (regs_ever_live[18])
2397             fprintf (file, "\tstd\t4,80(%s)\n", reg_names[STACK_POINTER_REGNUM]);
2398           if (regs_ever_live[19])
2399             fprintf (file, "\tstd\t6,88(%s)\n", reg_names[STACK_POINTER_REGNUM]);
2400         }
2401     }
2402   else
2403     {                           /* No leaf function.  */
2404       fprintf (file, "%s\tleaf function           %d\n", ASM_COMMENT_START,
2405                leaf_function_p ());
2406       fprintf (file, "%s\tautomatics              %d\n", ASM_COMMENT_START,
2407                (int)lsize);
2408       fprintf (file, "%s\toutgoing args           %d\n", ASM_COMMENT_START,
2409                current_function_outgoing_args_size);
2410       fprintf (file, "%s\tneed frame pointer      %d\n", ASM_COMMENT_START,
2411                frame_pointer_needed);
2412       fprintf (file, "%s\tcall alloca             %d\n", ASM_COMMENT_START,
2413                current_function_calls_alloca);
2414       fprintf (file, "%s\thas varargs             %d\n", ASM_COMMENT_START,
2415                current_function_stdarg || current_function_varargs);
2416       fprintf (file, "%s\tincoming args (stack)   %d\n", ASM_COMMENT_START,
2417                current_function_args_size);
2418       fprintf (file, "%s\tfunction length         %d\n", ASM_COMMENT_START,
2419                insn_current_address);
2420       fprintf (file, "%s\tregister live           ", ASM_COMMENT_START);
2421       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2422         fprintf (file, "%d", regs_ever_live[i]);
2423       fputc   ('\n',file);
2424
2425       /* Save gprs 6 - 15 and fprs 4 and 6.  */
2426       
2427       if (current_function_stdarg || current_function_varargs)
2428         {
2429           i = 2;
2430         }
2431       else
2432         {
2433           for (i = 6; i < 13 && (regs_ever_live[i] == 0); i++);
2434         }
2435
2436       fprintf (file, "\tstm%s\t%s,%s,%d(%s)\n", 
2437                      b64, reg_names[i], reg_names[15], i * UNITS_PER_WORD,
2438                      reg_names[STACK_POINTER_REGNUM]);
2439
2440 #ifdef INCOMING_RETURN_ADDR_RTX
2441       if (dwarf2out_do_frame ())
2442         {
2443           l = dwarf2out_cfi_label ();
2444           dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, STACK_POINTER_OFFSET);
2445           for (j = i; j <= 15; j++)
2446             dwarf2out_reg_save (l, j, (TARGET_64BIT ? (j-20) : (j-24)) *
2447                                 UNITS_PER_WORD);
2448           if (regs_ever_live[18])
2449             dwarf2out_reg_save (l, 18, -16);
2450           if (regs_ever_live[19])
2451             dwarf2out_reg_save (l, 19, -8);
2452         }
2453 #endif
2454
2455       s390_output_constant_pool (file);
2456
2457       /* Save fprs.  */
2458
2459       if (current_function_stdarg || current_function_varargs)
2460         {
2461           fprintf (file, "\tstd\t%s,%d(%s)\n", 
2462                    reg_names[16],
2463                    STACK_POINTER_OFFSET-32,
2464                    reg_names[STACK_POINTER_REGNUM]);
2465           fprintf (file, "\tstd\t%s,%d(%s)\n",
2466                    reg_names[17],
2467                    STACK_POINTER_OFFSET-24,
2468                    reg_names[STACK_POINTER_REGNUM]);
2469           if (TARGET_64BIT)
2470             {
2471               fprintf (file, "\tstd\t%s,%d(%s)\n", 
2472                        reg_names[18],
2473                        STACK_POINTER_OFFSET-16,
2474                        reg_names[STACK_POINTER_REGNUM]);
2475               fprintf (file, "\tstd\t%s,%d(%s)\n", 
2476                        reg_names[19],
2477                        STACK_POINTER_OFFSET-8,
2478                        reg_names[STACK_POINTER_REGNUM]);
2479             }
2480         }
2481       if (!TARGET_64BIT)
2482         {
2483           if (regs_ever_live[18])
2484             fprintf (file, "\tstd\t%s,%d(%s)\n", 
2485                      reg_names[18],
2486                      STACK_POINTER_OFFSET-16,
2487                      reg_names[STACK_POINTER_REGNUM]);
2488           if (regs_ever_live[19])
2489             fprintf (file, "\tstd\t%s,%d(%s)\n",
2490                      reg_names[19],
2491                      STACK_POINTER_OFFSET-8,
2492                      reg_names[STACK_POINTER_REGNUM]);
2493         }
2494
2495       
2496       if (save_fprs_p () && frame_size > 4095) 
2497         {
2498           int fp = 1;
2499           fprintf (file, "\tlgr\t%s,%s\n", reg_names[fp], 
2500                    reg_names[STACK_POINTER_REGNUM]); 
2501           fprintf (file, "\taghi\t%s,-64\n", reg_names[fp]);
2502           save_fprs (file, 0, fp);
2503         }
2504
2505       /* Decrement stack.  */
2506
2507       if (TARGET_BACKCHAIN || (STARTING_FRAME_OFFSET +
2508                                lsize + STACK_POINTER_OFFSET > 4095
2509                                || frame_pointer_needed
2510                                || current_function_calls_alloca))
2511         {
2512
2513           fprintf (file, "\tl%sr\t%s,%s\n", b64, 
2514                          reg_names[1], reg_names[STACK_POINTER_REGNUM]);
2515         }
2516
2517       if (stack_label)
2518         {
2519           rtx operands[2];
2520
2521           operands[0] = stack_pointer_rtx;
2522           operands[1] = stack_label;
2523           if (TARGET_64BIT)
2524             output_asm_insn ("sg\t%0,%1", operands);
2525           else
2526             output_asm_insn ("s\t%0,%1", operands);
2527         }
2528       else
2529         {
2530           fprintf (file, "\ta%shi\t%s,-%ld\n",b64, 
2531                    reg_names[STACK_POINTER_REGNUM], frame_size);
2532         }
2533 #ifdef INCOMING_RETURN_ADDR_RTX
2534       if (dwarf2out_do_frame ())
2535         {
2536           if (frame_pointer_needed)
2537             dwarf2out_def_cfa ("", HARD_FRAME_POINTER_REGNUM,
2538                                STACK_POINTER_OFFSET+frame_size);
2539           else
2540             dwarf2out_def_cfa ("", STACK_POINTER_REGNUM,
2541                                STACK_POINTER_OFFSET+frame_size);
2542         }
2543 #endif
2544
2545
2546       /* Generate backchain.  */
2547
2548       if (TARGET_BACKCHAIN || (STARTING_FRAME_OFFSET + 
2549                                lsize + STACK_POINTER_OFFSET > 4095
2550                                || frame_pointer_needed
2551                                || current_function_calls_alloca))
2552         {
2553           fprintf (file, "\tst%s\t%s,0(%s)\n", 
2554                          b64, reg_names[1], reg_names[STACK_POINTER_REGNUM]);
2555         }
2556     }
2557
2558   if (frame_pointer_needed)
2559     {
2560       fprintf (file, "\tl%sr\t%s,%s\n", b64, 
2561                      reg_names[FRAME_POINTER_REGNUM], 
2562                      reg_names[STACK_POINTER_REGNUM]);
2563     }
2564
2565   /* Load GOT if used and emit use insn that optimizer does not
2566      erase literal pool entry.  */
2567
2568   if (current_function_uses_pic_offset_table)
2569     {
2570       rtx operands[3];
2571       if (TARGET_64BIT)
2572         {
2573           fprintf (file, "\tlarl\t%s,_GLOBAL_OFFSET_TABLE_\n",
2574                          reg_names[PIC_OFFSET_TABLE_REGNUM]);
2575         }
2576       else
2577         {
2578           operands[0] = gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM);
2579           operands[1] = got_label;
2580           operands[2] = gen_rtx (REG, Pmode, BASE_REGISTER);
2581           output_asm_insn ("l\t%0,%1\n\tar\t%0,%2", operands);
2582         }
2583     }
2584   /* Save FPRs below save area.  */
2585
2586   if (frame_size <= 4095)
2587     save_fprs (file, frame_size - 64, STACK_POINTER_REGNUM);
2588
2589   return;
2590 }
2591
2592 /* Output the function epilogue assembly code to the 
2593    stdio stream FILE.  The local frame size is passed
2594    in LSIZE.  */
2595
2596 void
2597 s390_function_epilogue (file, lsize)
2598      FILE *file;
2599      HOST_WIDE_INT lsize;
2600 {
2601 /* Register is call clobbered and not used for eh or return.  */
2602 #define FREE_REG 4
2603
2604   int i;
2605   long frame_size;
2606   int return_reg = RETURN_REGNUM;
2607   int fp, offset;
2608   char b64[2] = " ";
2609
2610   b64[0] = TARGET_64BIT ? 'g' : '\0';
2611   frame_size = STARTING_FRAME_OFFSET + lsize + save_fprs_p () * 64;
2612   
2613   if (current_function_uses_pic_offset_table)
2614     regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2615   
2616   if (leaf_function_flag)
2617     {
2618       for (i = 6; i < 13 && (regs_ever_live[i] == 0); i++);
2619
2620       if (s390_nr_constants || regs_ever_live[13] || i != 13)
2621         {
2622             fprintf (file, "\tlm%s\t%s,%s,%d(%s)\n", b64, 
2623                      reg_names[i], reg_names[13],
2624                      UNITS_PER_WORD * i,
2625                      reg_names[STACK_POINTER_REGNUM]);
2626         }
2627       if (!TARGET_64BIT)
2628         {
2629           if (regs_ever_live[18])
2630             fprintf (file, "\tld\t%s,%d(%s)\n", 
2631                      reg_names[18],
2632                      STACK_POINTER_OFFSET-16,
2633                      reg_names[STACK_POINTER_REGNUM]);
2634           if (regs_ever_live[19])
2635             fprintf (file, "\tld\t%s,%d(%s)\n",
2636                      reg_names[19],
2637                      STACK_POINTER_OFFSET-8,
2638                      reg_names[STACK_POINTER_REGNUM]);
2639         }
2640     }
2641   else
2642     {
2643       for (i = 6; i < 13 && (regs_ever_live[i] == 0); i++);
2644
2645       if (frame_size + STACK_POINTER_OFFSET > 4095)    
2646         {
2647           offset = 0;
2648           fp = STACK_POINTER_REGNUM;
2649         }
2650       else if (frame_pointer_needed || current_function_calls_alloca)
2651         {
2652           offset = frame_size;
2653           fp = FRAME_POINTER_REGNUM;
2654         }
2655       else
2656         {
2657           offset = frame_size;
2658           fp = STACK_POINTER_REGNUM;
2659         }
2660
2661       /* Restore from offset below save area.  */
2662
2663       if (offset == 0)
2664         fprintf (file, "\tl%s\t%s,0(%s)\n", b64, 
2665                        reg_names[fp], reg_names[fp]);
2666       restore_fprs (file, offset-64, fp);
2667       return_reg = FREE_REG;
2668       fprintf (file, "\tl%s\t%s,%d(%s)\n", b64, reg_names[return_reg], 
2669                UNITS_PER_WORD*RETURN_REGNUM+offset, reg_names[fp]);
2670       if (!TARGET_64BIT)
2671         {
2672           if (regs_ever_live[18])
2673             fprintf (file, "\tld\t%s,%d(%s)\n", 
2674                      reg_names[18],
2675                      offset+STACK_POINTER_OFFSET-16, reg_names[fp]);
2676           if (regs_ever_live[19])
2677             fprintf (file, "\tld\t%s,%d(%s)\n",
2678                      reg_names[19],
2679                      offset+STACK_POINTER_OFFSET-8, reg_names[fp]);
2680         }
2681       fprintf (file, "\tlm%s\t%s,%s,%d(%s)\n", b64, 
2682                      reg_names[i], reg_names[15],
2683                      (UNITS_PER_WORD * i) + offset, reg_names[fp]);
2684     }
2685   
2686   fprintf (file, "\tbr\t%s\n", reg_names[return_reg]);
2687
2688   current_function_uses_pic_offset_table = 0;
2689   leaf_function_flag = 0;
2690   s390_pool_start_insn = NULL_RTX;
2691   s390_pool_count = -1;
2692   s390_function_count++;
2693   return;
2694 }
2695
2696
2697 /* Return the size in bytes of a function argument of 
2698    type TYPE and/or mode MODE.  At least one of TYPE or
2699    MODE must be specified.  */
2700
2701 static int
2702 s390_function_arg_size (mode, type)
2703      enum machine_mode mode;
2704      tree type;
2705 {
2706   if (type)
2707     return int_size_in_bytes (type);
2708
2709   /* No type info available for some library calls ... */
2710   if (mode != BLKmode)
2711     return GET_MODE_SIZE (mode);
2712
2713   /* If we have neither type nor mode, abort */
2714   abort ();
2715 }
2716
2717 /* Return 1 if a function argument of type TYPE and mode MODE
2718    is to be passed by reference.  The ABI specifies that only
2719    structures of size 1, 2, 4, or 8 bytes are passed by value,
2720    all other structures (and complex numbers) are passed by
2721    reference.  */
2722
2723 int
2724 s390_function_arg_pass_by_reference (mode, type)
2725      enum machine_mode mode;
2726      tree type;
2727 {
2728   int size = s390_function_arg_size (mode, type);
2729
2730   if (type)
2731     {
2732       if (AGGREGATE_TYPE_P (type) &&
2733           size != 1 && size != 2 && size != 4 && size != 8)
2734         return 1;
2735
2736       if (TREE_CODE (type) == COMPLEX_TYPE)
2737         return 1;
2738     }
2739   return 0;
2740
2741 }
2742
2743 /* Update the data in CUM to advance over an argument of mode MODE and
2744    data type TYPE.  (TYPE is null for libcalls where that information
2745    may not be available.).  The boolean NAMED specifies whether the
2746    argument is a named argument (as opposed to an unnamed argument
2747    matching an ellipsis).  */
2748
2749 void
2750 s390_function_arg_advance (cum, mode, type, named)
2751      CUMULATIVE_ARGS *cum;
2752      enum machine_mode mode;
2753      tree type;
2754      int named ATTRIBUTE_UNUSED;
2755 {
2756   if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
2757     {
2758       cum->fprs++;
2759     }
2760   else if (s390_function_arg_pass_by_reference (mode, type))
2761     {
2762       cum->gprs += 1;
2763     }
2764   else
2765     {
2766       int size = s390_function_arg_size (mode, type);
2767       cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
2768     }
2769 }
2770
2771 /* Define where to put the arguments to a function.
2772    Value is zero to push the argument on the stack,
2773    or a hard register in which to store the argument.
2774
2775    MODE is the argument's machine mode.
2776    TYPE is the data type of the argument (as a tree).
2777     This is null for libcalls where that information may
2778     not be available.
2779    CUM is a variable of type CUMULATIVE_ARGS which gives info about
2780     the preceding args and about the function being called.
2781    NAMED is nonzero if this argument is a named parameter
2782     (otherwise it is an extra parameter matching an ellipsis).  
2783
2784    On S/390, we use general purpose registers 2 through 6 to
2785    pass integer, pointer, and certain structure arguments, and
2786    floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
2787    to pass floating point arguments.  All remaining arguments
2788    are pushed to the stack.  */
2789
2790 rtx
2791 s390_function_arg (cum, mode, type, named)
2792      CUMULATIVE_ARGS *cum;
2793      enum machine_mode mode;
2794      tree type;
2795      int named ATTRIBUTE_UNUSED;
2796 {
2797   if (s390_function_arg_pass_by_reference (mode, type))
2798       return 0;
2799
2800   if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
2801     {
2802       if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
2803         return 0;
2804       else
2805         return gen_rtx (REG, mode, cum->fprs + 16);
2806     }
2807   else
2808     {
2809       int size = s390_function_arg_size (mode, type);
2810       int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
2811
2812       if (cum->gprs + n_gprs > 5)
2813         return 0;
2814       else
2815         return gen_rtx (REG, mode, cum->gprs + 2);
2816     }
2817 }
2818
2819
2820 /* Create and return the va_list datatype.
2821
2822    On S/390, va_list is an array type equivalent to
2823
2824       typedef struct __va_list_tag
2825         {
2826             long __gpr;
2827             long __fpr;
2828             void *__overflow_arg_area;
2829             void *__reg_save_area;
2830             
2831         } va_list[1];
2832
2833    where __gpr and __fpr hold the number of general purpose
2834    or floating point arguments used up to now, respectively,
2835    __overflow_arg_area points to the stack location of the 
2836    next argument passed on the stack, and __reg_save_area
2837    always points to the start of the register area in the
2838    call frame of the current function.  The function prologue
2839    saves all registers used for argument passing into this
2840    area if the function uses variable arguments.  */
2841
2842 tree
2843 s390_build_va_list ()
2844 {
2845   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
2846
2847   record = make_lang_type (RECORD_TYPE);
2848
2849   type_decl =
2850     build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
2851
2852   f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"), 
2853                       long_integer_type_node);
2854   f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"), 
2855                       long_integer_type_node);
2856   f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
2857                       ptr_type_node);
2858   f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
2859                       ptr_type_node);
2860
2861   DECL_FIELD_CONTEXT (f_gpr) = record;
2862   DECL_FIELD_CONTEXT (f_fpr) = record;
2863   DECL_FIELD_CONTEXT (f_ovf) = record;
2864   DECL_FIELD_CONTEXT (f_sav) = record;
2865
2866   TREE_CHAIN (record) = type_decl;
2867   TYPE_NAME (record) = type_decl;
2868   TYPE_FIELDS (record) = f_gpr;
2869   TREE_CHAIN (f_gpr) = f_fpr;
2870   TREE_CHAIN (f_fpr) = f_ovf;
2871   TREE_CHAIN (f_ovf) = f_sav;
2872
2873   layout_type (record);
2874
2875   /* The correct type is an array type of one element.  */
2876   return build_array_type (record, build_index_type (size_zero_node));
2877 }
2878
2879 /* Implement va_start by filling the va_list structure VALIST.
2880    STDARG_P is true if implementing __builtin_stdarg_va_start,
2881    false if implementing __builtin_varargs_va_start.  NEXTARG
2882    points to the first anonymous stack argument.
2883
2884    The following global variables are used to initalize
2885    the va_list structure:
2886
2887      current_function_args_info:
2888        holds number of gprs and fprs used for named arguments.
2889      current_function_arg_offset_rtx:
2890        holds the offset of the first anonymous stack argument
2891        (relative to the virtual arg pointer).  */
2892
2893 void
2894 s390_va_start (stdarg_p, valist, nextarg)
2895      int stdarg_p;
2896      tree valist;
2897      rtx nextarg ATTRIBUTE_UNUSED;
2898 {
2899   HOST_WIDE_INT n_gpr, n_fpr;
2900   int off;
2901   tree f_gpr, f_fpr, f_ovf, f_sav;
2902   tree gpr, fpr, ovf, sav, t;
2903
2904   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
2905   f_fpr = TREE_CHAIN (f_gpr);
2906   f_ovf = TREE_CHAIN (f_fpr);
2907   f_sav = TREE_CHAIN (f_ovf);
2908
2909   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
2910   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
2911   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
2912   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
2913   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
2914
2915   /* Count number of gp and fp argument registers used.  */
2916
2917   n_gpr = current_function_args_info.gprs;
2918   n_fpr = current_function_args_info.fprs;
2919
2920   t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
2921   TREE_SIDE_EFFECTS (t) = 1;
2922   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2923
2924   t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
2925   TREE_SIDE_EFFECTS (t) = 1;
2926   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2927
2928   /* Find the overflow area.  */
2929   t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
2930
2931   off = INTVAL (current_function_arg_offset_rtx);
2932   off = off < 0 ? 0 : off;
2933   if (! stdarg_p)
2934     off = off > 0 ? off - UNITS_PER_WORD : off;
2935   if (TARGET_DEBUG_ARG)
2936     fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
2937              (int)n_gpr, (int)n_fpr, off);
2938
2939   t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
2940
2941   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
2942   TREE_SIDE_EFFECTS (t) = 1;
2943   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2944
2945   /* Find the register save area.  */
2946   t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
2947   t = build (PLUS_EXPR, TREE_TYPE (sav), t,
2948              build_int_2 (-STACK_POINTER_OFFSET, -1));
2949   t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
2950   TREE_SIDE_EFFECTS (t) = 1;
2951   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2952 }
2953
2954 /* Implement va_arg by updating the va_list structure 
2955    VALIST as required to retrieve an argument of type
2956    TYPE, and returning that argument. 
2957    
2958    Generates code equivalent to:
2959    
2960    if (integral value) {
2961      if (size  <= 4 && args.gpr < 5 ||
2962          size  > 4 && args.gpr < 4 ) 
2963        ret = args.reg_save_area[args.gpr+8]
2964      else
2965        ret = *args.overflow_arg_area++;
2966    } else if (float value) {
2967      if (args.fgpr < 2)
2968        ret = args.reg_save_area[args.fpr+64]
2969      else
2970        ret = *args.overflow_arg_area++;
2971    } else if (aggregate value) {
2972      if (args.gpr < 5)
2973        ret = *args.reg_save_area[args.gpr]
2974      else
2975        ret = **args.overflow_arg_area++;
2976    } */
2977
2978 rtx
2979 s390_va_arg (valist, type)
2980      tree valist;
2981      tree type;
2982 {
2983   tree f_gpr, f_fpr, f_ovf, f_sav;
2984   tree gpr, fpr, ovf, sav, reg, t, u;
2985   int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
2986   rtx lab_false, lab_over, addr_rtx, r;
2987
2988   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
2989   f_fpr = TREE_CHAIN (f_gpr);
2990   f_ovf = TREE_CHAIN (f_fpr);
2991   f_sav = TREE_CHAIN (f_ovf);
2992
2993   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
2994   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
2995   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
2996   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
2997   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
2998
2999   size = int_size_in_bytes (type);
3000
3001   if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
3002     {
3003       if (TARGET_DEBUG_ARG)
3004         {
3005           fprintf (stderr, "va_arg: aggregate type");
3006           debug_tree (type);
3007         }
3008
3009       /* Aggregates are passed by reference.  */
3010       indirect_p = 1;
3011       reg = gpr;
3012       n_reg = 1;
3013       sav_ofs = 2 * UNITS_PER_WORD;
3014       sav_scale = UNITS_PER_WORD;
3015       size = UNITS_PER_WORD;
3016       max_reg = 4;
3017     }
3018   else if (FLOAT_TYPE_P (type) && ! TARGET_SOFT_FLOAT)
3019     {
3020       if (TARGET_DEBUG_ARG)
3021         {
3022           fprintf (stderr, "va_arg: float type");
3023           debug_tree (type);
3024         }
3025
3026       /* FP args go in FP registers, if present.  */
3027       indirect_p = 0;
3028       reg = fpr;
3029       n_reg = 1;
3030       sav_ofs = 16 * UNITS_PER_WORD;
3031       sav_scale = 8;
3032       /* TARGET_64BIT has up to 4 parameter in fprs */
3033       max_reg = TARGET_64BIT ? 3 : 1;
3034     }
3035   else
3036     {
3037       if (TARGET_DEBUG_ARG)
3038         {
3039           fprintf (stderr, "va_arg: other type");
3040           debug_tree (type);
3041         }
3042
3043       /* Otherwise into GP registers.  */
3044       indirect_p = 0;
3045       reg = gpr;
3046       n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3047       sav_ofs = 2 * UNITS_PER_WORD;
3048       if (TARGET_64BIT)
3049         sav_ofs += TYPE_MODE (type) == SImode ? 4 : 
3050                    TYPE_MODE (type) == HImode ? 6 : 
3051                    TYPE_MODE (type) == QImode ? 7 : 0;
3052       else
3053         sav_ofs += TYPE_MODE (type) == HImode ? 2 : 
3054                    TYPE_MODE (type) == QImode ? 3 : 0;
3055
3056       sav_scale = UNITS_PER_WORD;
3057       if (n_reg > 1)
3058         max_reg = 3;
3059       else
3060         max_reg = 4;
3061     }
3062
3063   /* Pull the value out of the saved registers ...  */
3064
3065   lab_false = gen_label_rtx ();
3066   lab_over = gen_label_rtx ();
3067   addr_rtx = gen_reg_rtx (Pmode);
3068
3069   emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
3070                            GEN_INT (max_reg),
3071                            GT, const1_rtx, Pmode, 0, 1, lab_false);
3072
3073   if (sav_ofs)
3074     t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3075   else
3076     t = sav;
3077
3078   u = build (MULT_EXPR, long_integer_type_node,
3079              reg, build_int_2 (sav_scale, 0));
3080   TREE_SIDE_EFFECTS (u) = 1;
3081
3082   t = build (PLUS_EXPR, ptr_type_node, t, u);
3083   TREE_SIDE_EFFECTS (t) = 1;
3084
3085   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3086   if (r != addr_rtx)
3087     emit_move_insn (addr_rtx, r);
3088
3089
3090   emit_jump_insn (gen_jump (lab_over));
3091   emit_barrier ();
3092   emit_label (lab_false);
3093
3094   /* ... Otherwise out of the overflow area.  */
3095
3096   t = save_expr (ovf);
3097
3098
3099   /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated.  */
3100   if (size < UNITS_PER_WORD)
3101     {
3102       t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
3103       t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3104       TREE_SIDE_EFFECTS (t) = 1;
3105       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3106
3107       t = save_expr (ovf);
3108     }
3109
3110   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3111   if (r != addr_rtx)
3112     emit_move_insn (addr_rtx, r);
3113
3114   t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3115   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3116   TREE_SIDE_EFFECTS (t) = 1;
3117   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3118
3119   emit_label (lab_over);
3120
3121   /* If less than max_regs a registers are retrieved out 
3122      of register save area, increment.  */
3123
3124   u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg, 
3125              build_int_2 (n_reg, 0));
3126   TREE_SIDE_EFFECTS (u) = 1;
3127   expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3128
3129   if (indirect_p)
3130     {
3131       r = gen_rtx_MEM (Pmode, addr_rtx);
3132       MEM_ALIAS_SET (r) = get_varargs_alias_set ();
3133       emit_move_insn (addr_rtx, r);
3134     }
3135
3136
3137   return addr_rtx;
3138 }
3139
3140
3141 /* Output assembly code for the trampoline template to
3142    stdio stream FILE.
3143
3144    On S/390, we use gpr 1 internally in the trampoline code;
3145    gpr 0 is used to hold the static chain.  */
3146
3147 void
3148 s390_trampoline_template (file)
3149      FILE *file;
3150 {
3151   if (TARGET_64BIT)
3152     {
3153       fprintf (file, "larl\t%s,0f\n", reg_names[1]);
3154       fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
3155       fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
3156       fprintf (file, "br\t%s\n", reg_names[1]);
3157       fprintf (file, "0:\t.quad\t0\n");
3158       fprintf (file, ".quad\t0\n");
3159     }
3160   else
3161     {
3162       fprintf (file, "basr\t%s,0\n", reg_names[1]);
3163       fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
3164       fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
3165       fprintf (file, "br\t%s\n", reg_names[1]);
3166       fprintf (file, ".long\t0\n");
3167       fprintf (file, ".long\t0\n");
3168     }
3169 }
3170
3171 /* Emit RTL insns to initialize the variable parts of a trampoline.
3172    FNADDR is an RTX for the address of the function's pure code.
3173    CXT is an RTX for the static chain value for the function.  */
3174
3175 void
3176 s390_initialize_trampoline (addr, fnaddr, cxt)
3177      rtx addr;
3178      rtx fnaddr;
3179      rtx cxt;
3180 {
3181   emit_move_insn (gen_rtx 
3182                   (MEM, Pmode,
3183                    memory_address (Pmode, 
3184                    plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
3185   emit_move_insn (gen_rtx
3186                   (MEM, Pmode,
3187                    memory_address (Pmode, 
3188                    plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
3189 }