OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [s390/] [s390.c] - Blame information for rev 38

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Subroutines used for code generation on IBM S/390 and zSeries
2
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4
   Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5
                  Ulrich Weigand (uweigand@de.ibm.com).
6
 
7
This file is part of GCC.
8
 
9
GCC is free software; you can redistribute it and/or modify it under
10
the terms of the GNU General Public License as published by the Free
11
Software Foundation; either version 3, or (at your option) any later
12
version.
13
 
14
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15
WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17
for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with GCC; see the file COPYING3.  If not see
21
<http://www.gnu.org/licenses/>.  */
22
 
23
#include "config.h"
24
#include "system.h"
25
#include "coretypes.h"
26
#include "tm.h"
27
#include "rtl.h"
28
#include "tree.h"
29
#include "tm_p.h"
30
#include "regs.h"
31
#include "hard-reg-set.h"
32
#include "real.h"
33
#include "insn-config.h"
34
#include "conditions.h"
35
#include "output.h"
36
#include "insn-attr.h"
37
#include "flags.h"
38
#include "except.h"
39
#include "function.h"
40
#include "recog.h"
41
#include "expr.h"
42
#include "reload.h"
43
#include "toplev.h"
44
#include "basic-block.h"
45
#include "integrate.h"
46
#include "ggc.h"
47
#include "target.h"
48
#include "target-def.h"
49
#include "debug.h"
50
#include "langhooks.h"
51
#include "optabs.h"
52
#include "tree-gimple.h"
53
 
54
 
55
/* Define the specific costs for a given cpu.  */
56
 
57
struct processor_costs
58
{
59
  /* multiplication */
60
  const int m;        /* cost of an M instruction.  */
61
  const int mghi;     /* cost of an MGHI instruction.  */
62
  const int mh;       /* cost of an MH instruction.  */
63
  const int mhi;      /* cost of an MHI instruction.  */
64
  const int ml;       /* cost of an ML instruction.  */
65
  const int mr;       /* cost of an MR instruction.  */
66
  const int ms;       /* cost of an MS instruction.  */
67
  const int msg;      /* cost of an MSG instruction.  */
68
  const int msgf;     /* cost of an MSGF instruction.  */
69
  const int msgfr;    /* cost of an MSGFR instruction.  */
70
  const int msgr;     /* cost of an MSGR instruction.  */
71
  const int msr;      /* cost of an MSR instruction.  */
72
  const int mult_df;  /* cost of multiplication in DFmode.  */
73
  const int mxbr;
74
  /* square root */
75
  const int sqxbr;    /* cost of square root in TFmode.  */
76
  const int sqdbr;    /* cost of square root in DFmode.  */
77
  const int sqebr;    /* cost of square root in SFmode.  */
78
  /* multiply and add */
79
  const int madbr;    /* cost of multiply and add in DFmode.  */
80
  const int maebr;    /* cost of multiply and add in SFmode.  */
81
  /* division */
82
  const int dxbr;
83
  const int dxr;
84
  const int ddbr;
85
  const int ddr;
86
  const int debr;
87
  const int der;
88
  const int dlgr;
89
  const int dlr;
90
  const int dr;
91
  const int dsgfr;
92
  const int dsgr;
93
};
94
 
95
const struct processor_costs *s390_cost;
96
 
97
static const
98
struct processor_costs z900_cost =
99
{
100
  COSTS_N_INSNS (5),     /* M     */
101
  COSTS_N_INSNS (10),    /* MGHI  */
102
  COSTS_N_INSNS (5),     /* MH    */
103
  COSTS_N_INSNS (4),     /* MHI   */
104
  COSTS_N_INSNS (5),     /* ML    */
105
  COSTS_N_INSNS (5),     /* MR    */
106
  COSTS_N_INSNS (4),     /* MS    */
107
  COSTS_N_INSNS (15),    /* MSG   */
108
  COSTS_N_INSNS (7),     /* MSGF  */
109
  COSTS_N_INSNS (7),     /* MSGFR */
110
  COSTS_N_INSNS (10),    /* MSGR  */
111
  COSTS_N_INSNS (4),     /* MSR   */
112
  COSTS_N_INSNS (7),     /* multiplication in DFmode */
113
  COSTS_N_INSNS (13),    /* MXBR */
114
  COSTS_N_INSNS (136),   /* SQXBR */
115
  COSTS_N_INSNS (44),    /* SQDBR */
116
  COSTS_N_INSNS (35),    /* SQEBR */
117
  COSTS_N_INSNS (18),    /* MADBR */
118
  COSTS_N_INSNS (13),    /* MAEBR */
119
  COSTS_N_INSNS (134),   /* DXBR */
120
  COSTS_N_INSNS (135),   /* DXR */
121
  COSTS_N_INSNS (30),    /* DDBR */
122
  COSTS_N_INSNS (30),    /* DDR  */
123
  COSTS_N_INSNS (27),    /* DEBR */
124
  COSTS_N_INSNS (26),    /* DER  */
125
  COSTS_N_INSNS (220),   /* DLGR */
126
  COSTS_N_INSNS (34),    /* DLR */
127
  COSTS_N_INSNS (34),    /* DR */
128
  COSTS_N_INSNS (32),    /* DSGFR */
129
  COSTS_N_INSNS (32),    /* DSGR */
130
};
131
 
132
static const
133
struct processor_costs z990_cost =
134
{
135
  COSTS_N_INSNS (4),     /* M     */
136
  COSTS_N_INSNS (2),     /* MGHI  */
137
  COSTS_N_INSNS (2),     /* MH    */
138
  COSTS_N_INSNS (2),     /* MHI   */
139
  COSTS_N_INSNS (4),     /* ML    */
140
  COSTS_N_INSNS (4),     /* MR    */
141
  COSTS_N_INSNS (5),     /* MS    */
142
  COSTS_N_INSNS (6),     /* MSG   */
143
  COSTS_N_INSNS (4),     /* MSGF  */
144
  COSTS_N_INSNS (4),     /* MSGFR */
145
  COSTS_N_INSNS (4),     /* MSGR  */
146
  COSTS_N_INSNS (4),     /* MSR   */
147
  COSTS_N_INSNS (1),     /* multiplication in DFmode */
148
  COSTS_N_INSNS (28),    /* MXBR */
149
  COSTS_N_INSNS (130),   /* SQXBR */
150
  COSTS_N_INSNS (66),    /* SQDBR */
151
  COSTS_N_INSNS (38),    /* SQEBR */
152
  COSTS_N_INSNS (1),     /* MADBR */
153
  COSTS_N_INSNS (1),     /* MAEBR */
154
  COSTS_N_INSNS (60),    /* DXBR */
155
  COSTS_N_INSNS (72),    /* DXR */
156
  COSTS_N_INSNS (40),    /* DDBR */
157
  COSTS_N_INSNS (44),    /* DDR  */
158
  COSTS_N_INSNS (26),    /* DDBR */
159
  COSTS_N_INSNS (28),    /* DER  */
160
  COSTS_N_INSNS (176),   /* DLGR */
161
  COSTS_N_INSNS (31),    /* DLR */
162
  COSTS_N_INSNS (31),    /* DR */
163
  COSTS_N_INSNS (31),    /* DSGFR */
164
  COSTS_N_INSNS (31),    /* DSGR */
165
};
166
 
167
static const
168
struct processor_costs z9_109_cost =
169
{
170
  COSTS_N_INSNS (4),     /* M     */
171
  COSTS_N_INSNS (2),     /* MGHI  */
172
  COSTS_N_INSNS (2),     /* MH    */
173
  COSTS_N_INSNS (2),     /* MHI   */
174
  COSTS_N_INSNS (4),     /* ML    */
175
  COSTS_N_INSNS (4),     /* MR    */
176
  COSTS_N_INSNS (5),     /* MS    */
177
  COSTS_N_INSNS (6),     /* MSG   */
178
  COSTS_N_INSNS (4),     /* MSGF  */
179
  COSTS_N_INSNS (4),     /* MSGFR */
180
  COSTS_N_INSNS (4),     /* MSGR  */
181
  COSTS_N_INSNS (4),     /* MSR   */
182
  COSTS_N_INSNS (1),     /* multiplication in DFmode */
183
  COSTS_N_INSNS (28),    /* MXBR */
184
  COSTS_N_INSNS (130),   /* SQXBR */
185
  COSTS_N_INSNS (66),    /* SQDBR */
186
  COSTS_N_INSNS (38),    /* SQEBR */
187
  COSTS_N_INSNS (1),     /* MADBR */
188
  COSTS_N_INSNS (1),     /* MAEBR */
189
  COSTS_N_INSNS (60),    /* DXBR */
190
  COSTS_N_INSNS (72),    /* DXR */
191
  COSTS_N_INSNS (40),    /* DDBR */
192
  COSTS_N_INSNS (37),    /* DDR  */
193
  COSTS_N_INSNS (26),    /* DDBR */
194
  COSTS_N_INSNS (28),    /* DER  */
195
  COSTS_N_INSNS (30),    /* DLGR */
196
  COSTS_N_INSNS (23),    /* DLR */
197
  COSTS_N_INSNS (23),    /* DR */
198
  COSTS_N_INSNS (24),    /* DSGFR */
199
  COSTS_N_INSNS (24),    /* DSGR */
200
};
201
 
202
extern int reload_completed;
203
 
204
/* Save information from a "cmpxx" operation until the branch or scc is
205
   emitted.  */
206
rtx s390_compare_op0, s390_compare_op1;
207
 
208
/* Save the result of a compare_and_swap  until the branch or scc is
209
   emitted.  */
210
rtx s390_compare_emitted = NULL_RTX;
211
 
212
/* Structure used to hold the components of a S/390 memory
213
   address.  A legitimate address on S/390 is of the general
214
   form
215
          base + index + displacement
216
   where any of the components is optional.
217
 
218
   base and index are registers of the class ADDR_REGS,
219
   displacement is an unsigned 12-bit immediate constant.  */
220
 
221
struct s390_address
222
{
223
  rtx base;
224
  rtx indx;
225
  rtx disp;
226
  bool pointer;
227
  bool literal_pool;
228
};
229
 
230
/* Which cpu are we tuning for.  */
231
enum processor_type s390_tune = PROCESSOR_max;
232
enum processor_flags s390_tune_flags;
233
/* Which instruction set architecture to use.  */
234
enum processor_type s390_arch;
235
enum processor_flags s390_arch_flags;
236
 
237
HOST_WIDE_INT s390_warn_framesize = 0;
238
HOST_WIDE_INT s390_stack_size = 0;
239
HOST_WIDE_INT s390_stack_guard = 0;
240
 
241
/* The following structure is embedded in the machine
242
   specific part of struct function.  */
243
 
244
struct s390_frame_layout GTY (())
245
{
246
  /* Offset within stack frame.  */
247
  HOST_WIDE_INT gprs_offset;
248
  HOST_WIDE_INT f0_offset;
249
  HOST_WIDE_INT f4_offset;
250
  HOST_WIDE_INT f8_offset;
251
  HOST_WIDE_INT backchain_offset;
252
 
253
  /* Number of first and last gpr where slots in the register
254
     save area are reserved for.  */
255
  int first_save_gpr_slot;
256
  int last_save_gpr_slot;
257
 
258
  /* Number of first and last gpr to be saved, restored.  */
259
  int first_save_gpr;
260
  int first_restore_gpr;
261
  int last_save_gpr;
262
  int last_restore_gpr;
263
 
264
  /* Bits standing for floating point registers. Set, if the
265
     respective register has to be saved. Starting with reg 16 (f0)
266
     at the rightmost bit.
267
     Bit 15 -  8  7  6  5  4  3  2  1  0
268
     fpr 15 -  8  7  5  3  1  6  4  2  0
269
     reg 31 - 24 23 22 21 20 19 18 17 16  */
270
  unsigned int fpr_bitmap;
271
 
272
  /* Number of floating point registers f8-f15 which must be saved.  */
273
  int high_fprs;
274
 
275
  /* Set if return address needs to be saved.
276
     This flag is set by s390_return_addr_rtx if it could not use
277
     the initial value of r14 and therefore depends on r14 saved
278
     to the stack.  */
279
  bool save_return_addr_p;
280
 
281
  /* Size of stack frame.  */
282
  HOST_WIDE_INT frame_size;
283
};
284
 
285
/* Define the structure for the machine field in struct function.  */
286
 
287
struct machine_function GTY(())
288
{
289
  struct s390_frame_layout frame_layout;
290
 
291
  /* Literal pool base register.  */
292
  rtx base_reg;
293
 
294
  /* True if we may need to perform branch splitting.  */
295
  bool split_branches_pending_p;
296
 
297
  /* True during final stage of literal pool processing.  */
298
  bool decomposed_literal_pool_addresses_ok_p;
299
 
300
  /* Some local-dynamic TLS symbol name.  */
301
  const char *some_ld_name;
302
 
303
  bool has_landing_pad_p;
304
};
305
 
306
/* Few accessor macros for struct cfun->machine->s390_frame_layout.  */
307
 
308
#define cfun_frame_layout (cfun->machine->frame_layout)
309
#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
310
#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot -           \
311
  cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
312
#define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |=    \
313
  (1 << (BITNUM)))
314
#define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap &    \
315
  (1 << (BITNUM))))
316
 
317
/* Number of GPRs and FPRs used for argument passing.  */
318
#define GP_ARG_NUM_REG 5
319
#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
320
 
321
/* A couple of shortcuts.  */
322
#define CONST_OK_FOR_J(x) \
323
        CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
324
#define CONST_OK_FOR_K(x) \
325
        CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
326
#define CONST_OK_FOR_Os(x) \
327
        CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
328
#define CONST_OK_FOR_Op(x) \
329
        CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
330
#define CONST_OK_FOR_On(x) \
331
        CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
332
 
333
#define REGNO_PAIR_OK(REGNO, MODE)                               \
334
  (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
335
 
336
/* Return true if the back end supports mode MODE.  */
337
static bool
338
s390_scalar_mode_supported_p (enum machine_mode mode)
339
{
340
  if (DECIMAL_FLOAT_MODE_P (mode))
341
    return true;
342
  else
343
    return default_scalar_mode_supported_p (mode);
344
}
345
 
346
/* Set the has_landing_pad_p flag in struct machine_function to VALUE.  */
347
 
348
void
349
s390_set_has_landing_pad_p (bool value)
350
{
351
  cfun->machine->has_landing_pad_p = value;
352
}
353
 
354
/* If two condition code modes are compatible, return a condition code
355
   mode which is compatible with both.  Otherwise, return
356
   VOIDmode.  */
357
 
358
static enum machine_mode
359
s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
360
{
361
  if (m1 == m2)
362
    return m1;
363
 
364
  switch (m1)
365
    {
366
    case CCZmode:
367
      if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
368
          || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
369
        return m2;
370
      return VOIDmode;
371
 
372
    case CCSmode:
373
    case CCUmode:
374
    case CCTmode:
375
    case CCSRmode:
376
    case CCURmode:
377
    case CCZ1mode:
378
      if (m2 == CCZmode)
379
        return m1;
380
 
381
      return VOIDmode;
382
 
383
    default:
384
      return VOIDmode;
385
    }
386
  return VOIDmode;
387
}
388
 
389
/* Return true if SET either doesn't set the CC register, or else
390
   the source and destination have matching CC modes and that
391
   CC mode is at least as constrained as REQ_MODE.  */
392
 
393
static bool
394
s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
395
{
396
  enum machine_mode set_mode;
397
 
398
  gcc_assert (GET_CODE (set) == SET);
399
 
400
  if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
401
    return 1;
402
 
403
  set_mode = GET_MODE (SET_DEST (set));
404
  switch (set_mode)
405
    {
406
    case CCSmode:
407
    case CCSRmode:
408
    case CCUmode:
409
    case CCURmode:
410
    case CCLmode:
411
    case CCL1mode:
412
    case CCL2mode:
413
    case CCL3mode:
414
    case CCT1mode:
415
    case CCT2mode:
416
    case CCT3mode:
417
      if (req_mode != set_mode)
418
        return 0;
419
      break;
420
 
421
    case CCZmode:
422
      if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
423
          && req_mode != CCSRmode && req_mode != CCURmode)
424
        return 0;
425
      break;
426
 
427
    case CCAPmode:
428
    case CCANmode:
429
      if (req_mode != CCAmode)
430
        return 0;
431
      break;
432
 
433
    default:
434
      gcc_unreachable ();
435
    }
436
 
437
  return (GET_MODE (SET_SRC (set)) == set_mode);
438
}
439
 
440
/* Return true if every SET in INSN that sets the CC register
441
   has source and destination with matching CC modes and that
442
   CC mode is at least as constrained as REQ_MODE.
443
   If REQ_MODE is VOIDmode, always return false.  */
444
 
445
bool
446
s390_match_ccmode (rtx insn, enum machine_mode req_mode)
447
{
448
  int i;
449
 
450
  /* s390_tm_ccmode returns VOIDmode to indicate failure.  */
451
  if (req_mode == VOIDmode)
452
    return false;
453
 
454
  if (GET_CODE (PATTERN (insn)) == SET)
455
    return s390_match_ccmode_set (PATTERN (insn), req_mode);
456
 
457
  if (GET_CODE (PATTERN (insn)) == PARALLEL)
458
      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
459
        {
460
          rtx set = XVECEXP (PATTERN (insn), 0, i);
461
          if (GET_CODE (set) == SET)
462
            if (!s390_match_ccmode_set (set, req_mode))
463
              return false;
464
        }
465
 
466
  return true;
467
}
468
 
469
/* If a test-under-mask instruction can be used to implement
470
   (compare (and ... OP1) OP2), return the CC mode required
471
   to do that.  Otherwise, return VOIDmode.
472
   MIXED is true if the instruction can distinguish between
473
   CC1 and CC2 for mixed selected bits (TMxx), it is false
474
   if the instruction cannot (TM).  */
475
 
476
enum machine_mode
477
s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
478
{
479
  int bit0, bit1;
480
 
481
  /* ??? Fixme: should work on CONST_DOUBLE as well.  */
482
  if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
483
    return VOIDmode;
484
 
485
  /* Selected bits all zero: CC0.
486
     e.g.: int a; if ((a & (16 + 128)) == 0) */
487
  if (INTVAL (op2) == 0)
488
    return CCTmode;
489
 
490
  /* Selected bits all one: CC3.
491
     e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
492
  if (INTVAL (op2) == INTVAL (op1))
493
    return CCT3mode;
494
 
495
  /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
496
     int a;
497
     if ((a & (16 + 128)) == 16)         -> CCT1
498
     if ((a & (16 + 128)) == 128)        -> CCT2  */
499
  if (mixed)
500
    {
501
      bit1 = exact_log2 (INTVAL (op2));
502
      bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
503
      if (bit0 != -1 && bit1 != -1)
504
        return bit0 > bit1 ? CCT1mode : CCT2mode;
505
    }
506
 
507
  return VOIDmode;
508
}
509
 
510
/* Given a comparison code OP (EQ, NE, etc.) and the operands
511
   OP0 and OP1 of a COMPARE, return the mode to be used for the
512
   comparison.  */
513
 
514
enum machine_mode
515
s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
516
{
517
  switch (code)
518
    {
519
      case EQ:
520
      case NE:
521
        if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
522
            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
523
          return CCAPmode;
524
        if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
525
            && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
526
          return CCAPmode;
527
        if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
528
             || GET_CODE (op1) == NEG)
529
            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
530
          return CCLmode;
531
 
532
        if (GET_CODE (op0) == AND)
533
          {
534
            /* Check whether we can potentially do it via TM.  */
535
            enum machine_mode ccmode;
536
            ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
537
            if (ccmode != VOIDmode)
538
              {
539
                /* Relax CCTmode to CCZmode to allow fall-back to AND
540
                   if that turns out to be beneficial.  */
541
                return ccmode == CCTmode ? CCZmode : ccmode;
542
              }
543
          }
544
 
545
        if (register_operand (op0, HImode)
546
            && GET_CODE (op1) == CONST_INT
547
            && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
548
          return CCT3mode;
549
        if (register_operand (op0, QImode)
550
            && GET_CODE (op1) == CONST_INT
551
            && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
552
          return CCT3mode;
553
 
554
        return CCZmode;
555
 
556
      case LE:
557
      case LT:
558
      case GE:
559
      case GT:
560
        /* The only overflow condition of NEG and ABS happens when
561
           -INT_MAX is used as parameter, which stays negative. So
562
           we have an overflow from a positive value to a negative.
563
           Using CCAP mode the resulting cc can be used for comparisons.  */
564
        if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
565
            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
566
          return CCAPmode;
567
 
568
        /* If constants are involved in an add instruction it is possible to use
569
           the resulting cc for comparisons with zero. Knowing the sign of the
570
           constant the overflow behavior gets predictable. e.g.:
571
             int a, b; if ((b = a + c) > 0)
572
           with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP  */
573
        if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
574
            && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
575
          {
576
            if (INTVAL (XEXP((op0), 1)) < 0)
577
              return CCANmode;
578
            else
579
              return CCAPmode;
580
          }
581
        /* Fall through.  */
582
      case UNORDERED:
583
      case ORDERED:
584
      case UNEQ:
585
      case UNLE:
586
      case UNLT:
587
      case UNGE:
588
      case UNGT:
589
      case LTGT:
590
        if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
591
            && GET_CODE (op1) != CONST_INT)
592
          return CCSRmode;
593
        return CCSmode;
594
 
595
      case LTU:
596
      case GEU:
597
        if (GET_CODE (op0) == PLUS
598
            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
599
          return CCL1mode;
600
 
601
        if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
602
            && GET_CODE (op1) != CONST_INT)
603
          return CCURmode;
604
        return CCUmode;
605
 
606
      case LEU:
607
      case GTU:
608
        if (GET_CODE (op0) == MINUS
609
            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
610
          return CCL2mode;
611
 
612
        if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
613
            && GET_CODE (op1) != CONST_INT)
614
          return CCURmode;
615
        return CCUmode;
616
 
617
      default:
618
        gcc_unreachable ();
619
    }
620
}
621
 
622
/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
623
   that we can implement more efficiently.  */
624
 
625
void
626
s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
627
{
628
  /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
629
  if ((*code == EQ || *code == NE)
630
      && *op1 == const0_rtx
631
      && GET_CODE (*op0) == ZERO_EXTRACT
632
      && GET_CODE (XEXP (*op0, 1)) == CONST_INT
633
      && GET_CODE (XEXP (*op0, 2)) == CONST_INT
634
      && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
635
    {
636
      rtx inner = XEXP (*op0, 0);
637
      HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
638
      HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
639
      HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
640
 
641
      if (len > 0 && len < modesize
642
          && pos >= 0 && pos + len <= modesize
643
          && modesize <= HOST_BITS_PER_WIDE_INT)
644
        {
645
          unsigned HOST_WIDE_INT block;
646
          block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
647
          block <<= modesize - pos - len;
648
 
649
          *op0 = gen_rtx_AND (GET_MODE (inner), inner,
650
                              gen_int_mode (block, GET_MODE (inner)));
651
        }
652
    }
653
 
654
  /* Narrow AND of memory against immediate to enable TM.  */
655
  if ((*code == EQ || *code == NE)
656
      && *op1 == const0_rtx
657
      && GET_CODE (*op0) == AND
658
      && GET_CODE (XEXP (*op0, 1)) == CONST_INT
659
      && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
660
    {
661
      rtx inner = XEXP (*op0, 0);
662
      rtx mask = XEXP (*op0, 1);
663
 
664
      /* Ignore paradoxical SUBREGs if all extra bits are masked out.  */
665
      if (GET_CODE (inner) == SUBREG
666
          && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
667
          && (GET_MODE_SIZE (GET_MODE (inner))
668
              >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
669
          && ((INTVAL (mask)
670
               & GET_MODE_MASK (GET_MODE (inner))
671
               & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
672
              == 0))
673
        inner = SUBREG_REG (inner);
674
 
675
      /* Do not change volatile MEMs.  */
676
      if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
677
        {
678
          int part = s390_single_part (XEXP (*op0, 1),
679
                                       GET_MODE (inner), QImode, 0);
680
          if (part >= 0)
681
            {
682
              mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
683
              inner = adjust_address_nv (inner, QImode, part);
684
              *op0 = gen_rtx_AND (QImode, inner, mask);
685
            }
686
        }
687
    }
688
 
689
  /* Narrow comparisons against 0xffff to HImode if possible.  */
690
  if ((*code == EQ || *code == NE)
691
      && GET_CODE (*op1) == CONST_INT
692
      && INTVAL (*op1) == 0xffff
693
      && SCALAR_INT_MODE_P (GET_MODE (*op0))
694
      && (nonzero_bits (*op0, GET_MODE (*op0))
695
          & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
696
    {
697
      *op0 = gen_lowpart (HImode, *op0);
698
      *op1 = constm1_rtx;
699
    }
700
 
701
 
702
  /* Remove redundant UNSPEC_CMPINT conversions if possible.  */
703
  if (GET_CODE (*op0) == UNSPEC
704
      && XINT (*op0, 1) == UNSPEC_CMPINT
705
      && XVECLEN (*op0, 0) == 1
706
      && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
707
      && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
708
      && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
709
      && *op1 == const0_rtx)
710
    {
711
      enum rtx_code new_code = UNKNOWN;
712
      switch (*code)
713
        {
714
          case EQ: new_code = EQ;  break;
715
          case NE: new_code = NE;  break;
716
          case LT: new_code = GTU; break;
717
          case GT: new_code = LTU; break;
718
          case LE: new_code = GEU; break;
719
          case GE: new_code = LEU; break;
720
          default: break;
721
        }
722
 
723
      if (new_code != UNKNOWN)
724
        {
725
          *op0 = XVECEXP (*op0, 0, 0);
726
          *code = new_code;
727
        }
728
    }
729
 
730
  /* Simplify cascaded EQ, NE with const0_rtx.  */
731
  if ((*code == NE || *code == EQ)
732
      && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
733
      && GET_MODE (*op0) == SImode
734
      && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
735
      && REG_P (XEXP (*op0, 0))
736
      && XEXP (*op0, 1) == const0_rtx
737
      && *op1 == const0_rtx)
738
    {
739
      if ((*code == EQ && GET_CODE (*op0) == NE)
740
          || (*code == NE && GET_CODE (*op0) == EQ))
741
        *code = EQ;
742
      else
743
        *code = NE;
744
      *op0 = XEXP (*op0, 0);
745
    }
746
 
747
  /* Prefer register over memory as first operand.  */
748
  if (MEM_P (*op0) && REG_P (*op1))
749
    {
750
      rtx tem = *op0; *op0 = *op1; *op1 = tem;
751
      *code = swap_condition (*code);
752
    }
753
}
754
 
755
/* Emit a compare instruction suitable to implement the comparison
756
   OP0 CODE OP1.  Return the correct condition RTL to be placed in
757
   the IF_THEN_ELSE of the conditional branch testing the result.  */
758
 
759
rtx
760
s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
761
{
762
  enum machine_mode mode = s390_select_ccmode (code, op0, op1);
763
  rtx ret = NULL_RTX;
764
 
765
  /* Do not output a redundant compare instruction if a compare_and_swap
766
     pattern already computed the result and the machine modes are compatible.  */
767
  if (s390_compare_emitted
768
      && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted), mode)
769
          == GET_MODE (s390_compare_emitted)))
770
    ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
771
  else
772
    {
773
      rtx cc = gen_rtx_REG (mode, CC_REGNUM);
774
 
775
      emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
776
      ret = gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
777
    }
778
  s390_compare_emitted = NULL_RTX;
779
  return ret;
780
}
781
 
782
/* Emit a SImode compare and swap instruction setting MEM to NEW if OLD
783
   matches CMP.
784
   Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
785
   conditional branch testing the result.  */
786
 
787
static rtx
788
s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem, rtx cmp, rtx new)
789
{
790
  rtx ret;
791
 
792
  emit_insn (gen_sync_compare_and_swap_ccsi (old, mem, cmp, new));
793
  ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
794
 
795
  s390_compare_emitted = NULL_RTX;
796
 
797
  return ret;
798
}
799
 
800
/* Emit a jump instruction to TARGET.  If COND is NULL_RTX, emit an
801
   unconditional jump, else a conditional jump under condition COND.  */
802
 
803
void
804
s390_emit_jump (rtx target, rtx cond)
805
{
806
  rtx insn;
807
 
808
  target = gen_rtx_LABEL_REF (VOIDmode, target);
809
  if (cond)
810
    target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
811
 
812
  insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
813
  emit_jump_insn (insn);
814
}
815
 
816
/* Return branch condition mask to implement a branch
817
   specified by CODE.  Return -1 for invalid comparisons.  */
818
 
819
int
820
s390_branch_condition_mask (rtx code)
821
{
822
  const int CC0 = 1 << 3;
823
  const int CC1 = 1 << 2;
824
  const int CC2 = 1 << 1;
825
  const int CC3 = 1 << 0;
826
 
827
  gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
828
  gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
829
  gcc_assert (XEXP (code, 1) == const0_rtx);
830
 
831
  switch (GET_MODE (XEXP (code, 0)))
832
    {
833
    case CCZmode:
834
    case CCZ1mode:
835
      switch (GET_CODE (code))
836
        {
837
        case EQ:        return CC0;
838
        case NE:        return CC1 | CC2 | CC3;
839
        default:        return -1;
840
        }
841
      break;
842
 
843
    case CCT1mode:
844
      switch (GET_CODE (code))
845
        {
846
        case EQ:        return CC1;
847
        case NE:        return CC0 | CC2 | CC3;
848
        default:        return -1;
849
        }
850
      break;
851
 
852
    case CCT2mode:
853
      switch (GET_CODE (code))
854
        {
855
        case EQ:        return CC2;
856
        case NE:        return CC0 | CC1 | CC3;
857
        default:        return -1;
858
        }
859
      break;
860
 
861
    case CCT3mode:
862
      switch (GET_CODE (code))
863
        {
864
        case EQ:        return CC3;
865
        case NE:        return CC0 | CC1 | CC2;
866
        default:        return -1;
867
        }
868
      break;
869
 
870
    case CCLmode:
871
      switch (GET_CODE (code))
872
        {
873
        case EQ:        return CC0 | CC2;
874
        case NE:        return CC1 | CC3;
875
        default:        return -1;
876
        }
877
      break;
878
 
879
    case CCL1mode:
880
      switch (GET_CODE (code))
881
        {
882
        case LTU:       return CC2 | CC3;  /* carry */
883
        case GEU:       return CC0 | CC1;  /* no carry */
884
        default:        return -1;
885
        }
886
      break;
887
 
888
    case CCL2mode:
889
      switch (GET_CODE (code))
890
        {
891
        case GTU:       return CC0 | CC1;  /* borrow */
892
        case LEU:       return CC2 | CC3;  /* no borrow */
893
        default:        return -1;
894
        }
895
      break;
896
 
897
    case CCL3mode:
898
      switch (GET_CODE (code))
899
        {
900
        case EQ:        return CC0 | CC2;
901
        case NE:        return CC1 | CC3;
902
        case LTU:       return CC1;
903
        case GTU:       return CC3;
904
        case LEU:       return CC1 | CC2;
905
        case GEU:       return CC2 | CC3;
906
        default:        return -1;
907
        }
908
 
909
    case CCUmode:
910
      switch (GET_CODE (code))
911
        {
912
        case EQ:        return CC0;
913
        case NE:        return CC1 | CC2 | CC3;
914
        case LTU:       return CC1;
915
        case GTU:       return CC2;
916
        case LEU:       return CC0 | CC1;
917
        case GEU:       return CC0 | CC2;
918
        default:        return -1;
919
        }
920
      break;
921
 
922
    case CCURmode:
923
      switch (GET_CODE (code))
924
        {
925
        case EQ:        return CC0;
926
        case NE:        return CC2 | CC1 | CC3;
927
        case LTU:       return CC2;
928
        case GTU:       return CC1;
929
        case LEU:       return CC0 | CC2;
930
        case GEU:       return CC0 | CC1;
931
        default:        return -1;
932
        }
933
      break;
934
 
935
    case CCAPmode:
936
      switch (GET_CODE (code))
937
        {
938
        case EQ:        return CC0;
939
        case NE:        return CC1 | CC2 | CC3;
940
        case LT:        return CC1 | CC3;
941
        case GT:        return CC2;
942
        case LE:        return CC0 | CC1 | CC3;
943
        case GE:        return CC0 | CC2;
944
        default:        return -1;
945
        }
946
      break;
947
 
948
    case CCANmode:
949
      switch (GET_CODE (code))
950
        {
951
        case EQ:        return CC0;
952
        case NE:        return CC1 | CC2 | CC3;
953
        case LT:        return CC1;
954
        case GT:        return CC2 | CC3;
955
        case LE:        return CC0 | CC1;
956
        case GE:        return CC0 | CC2 | CC3;
957
        default:        return -1;
958
        }
959
      break;
960
 
961
    case CCSmode:
962
      switch (GET_CODE (code))
963
        {
964
        case EQ:        return CC0;
965
        case NE:        return CC1 | CC2 | CC3;
966
        case LT:        return CC1;
967
        case GT:        return CC2;
968
        case LE:        return CC0 | CC1;
969
        case GE:        return CC0 | CC2;
970
        case UNORDERED: return CC3;
971
        case ORDERED:   return CC0 | CC1 | CC2;
972
        case UNEQ:      return CC0 | CC3;
973
        case UNLT:      return CC1 | CC3;
974
        case UNGT:      return CC2 | CC3;
975
        case UNLE:      return CC0 | CC1 | CC3;
976
        case UNGE:      return CC0 | CC2 | CC3;
977
        case LTGT:      return CC1 | CC2;
978
        default:        return -1;
979
        }
980
      break;
981
 
982
    case CCSRmode:
983
      switch (GET_CODE (code))
984
        {
985
        case EQ:        return CC0;
986
        case NE:        return CC2 | CC1 | CC3;
987
        case LT:        return CC2;
988
        case GT:        return CC1;
989
        case LE:        return CC0 | CC2;
990
        case GE:        return CC0 | CC1;
991
        case UNORDERED: return CC3;
992
        case ORDERED:   return CC0 | CC2 | CC1;
993
        case UNEQ:      return CC0 | CC3;
994
        case UNLT:      return CC2 | CC3;
995
        case UNGT:      return CC1 | CC3;
996
        case UNLE:      return CC0 | CC2 | CC3;
997
        case UNGE:      return CC0 | CC1 | CC3;
998
        case LTGT:      return CC2 | CC1;
999
        default:        return -1;
1000
        }
1001
      break;
1002
 
1003
    default:
1004
      return -1;
1005
    }
1006
}
1007
 
1008
/* If INV is false, return assembler mnemonic string to implement
1009
   a branch specified by CODE.  If INV is true, return mnemonic
1010
   for the corresponding inverted branch.  */
1011
 
1012
static const char *
1013
s390_branch_condition_mnemonic (rtx code, int inv)
1014
{
1015
  static const char *const mnemonic[16] =
1016
    {
1017
      NULL, "o", "h", "nle",
1018
      "l", "nhe", "lh", "ne",
1019
      "e", "nlh", "he", "nl",
1020
      "le", "nh", "no", NULL
1021
    };
1022
 
1023
  int mask = s390_branch_condition_mask (code);
1024
  gcc_assert (mask >= 0);
1025
 
1026
  if (inv)
1027
    mask ^= 15;
1028
 
1029
  gcc_assert (mask >= 1 && mask <= 14);
1030
 
1031
  return mnemonic[mask];
1032
}
1033
 
1034
/* Return the part of op which has a value different from def.
1035
   The size of the part is determined by mode.
1036
   Use this function only if you already know that op really
1037
   contains such a part.  */
1038
 
1039
unsigned HOST_WIDE_INT
1040
s390_extract_part (rtx op, enum machine_mode mode, int def)
1041
{
1042
  unsigned HOST_WIDE_INT value = 0;
1043
  int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
1044
  int part_bits = GET_MODE_BITSIZE (mode);
1045
  unsigned HOST_WIDE_INT part_mask
1046
    = ((unsigned HOST_WIDE_INT)1 << part_bits) - 1;
1047
  int i;
1048
 
1049
  for (i = 0; i < max_parts; i++)
1050
    {
1051
      if (i == 0)
1052
        value = (unsigned HOST_WIDE_INT) INTVAL (op);
1053
      else
1054
        value >>= part_bits;
1055
 
1056
      if ((value & part_mask) != (def & part_mask))
1057
        return value & part_mask;
1058
    }
1059
 
1060
  gcc_unreachable ();
1061
}
1062
 
1063
/* If OP is an integer constant of mode MODE with exactly one
1064
   part of mode PART_MODE unequal to DEF, return the number of that
1065
   part. Otherwise, return -1.  */
1066
 
1067
int
1068
s390_single_part (rtx op,
1069
                  enum machine_mode mode,
1070
                  enum machine_mode part_mode,
1071
                  int def)
1072
{
1073
  unsigned HOST_WIDE_INT value = 0;
1074
  int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1075
  unsigned HOST_WIDE_INT part_mask
1076
    = ((unsigned HOST_WIDE_INT)1 << GET_MODE_BITSIZE (part_mode)) - 1;
1077
  int i, part = -1;
1078
 
1079
  if (GET_CODE (op) != CONST_INT)
1080
    return -1;
1081
 
1082
  for (i = 0; i < n_parts; i++)
1083
    {
1084
      if (i == 0)
1085
        value = (unsigned HOST_WIDE_INT) INTVAL (op);
1086
      else
1087
        value >>= GET_MODE_BITSIZE (part_mode);
1088
 
1089
      if ((value & part_mask) != (def & part_mask))
1090
        {
1091
          if (part != -1)
1092
            return -1;
1093
          else
1094
            part = i;
1095
        }
1096
    }
1097
  return part == -1 ? -1 : n_parts - 1 - part;
1098
}
1099
 
1100
/* Check whether we can (and want to) split a double-word
1101
   move in mode MODE from SRC to DST into two single-word
1102
   moves, moving the subword FIRST_SUBWORD first.  */
1103
 
1104
bool
1105
s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1106
{
1107
  /* Floating point registers cannot be split.  */
1108
  if (FP_REG_P (src) || FP_REG_P (dst))
1109
    return false;
1110
 
1111
  /* We don't need to split if operands are directly accessible.  */
1112
  if (s_operand (src, mode) || s_operand (dst, mode))
1113
    return false;
1114
 
1115
  /* Non-offsettable memory references cannot be split.  */
1116
  if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1117
      || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1118
    return false;
1119
 
1120
  /* Moving the first subword must not clobber a register
1121
     needed to move the second subword.  */
1122
  if (register_operand (dst, mode))
1123
    {
1124
      rtx subreg = operand_subword (dst, first_subword, 0, mode);
1125
      if (reg_overlap_mentioned_p (subreg, src))
1126
        return false;
1127
    }
1128
 
1129
  return true;
1130
}
1131
 
1132
/* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1133
   and [MEM2, MEM2 + SIZE] do overlap and false
1134
   otherwise.  */
1135
 
1136
bool
1137
s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
1138
{
1139
  rtx addr1, addr2, addr_delta;
1140
  HOST_WIDE_INT delta;
1141
 
1142
  if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1143
    return true;
1144
 
1145
  if (size == 0)
1146
    return false;
1147
 
1148
  addr1 = XEXP (mem1, 0);
1149
  addr2 = XEXP (mem2, 0);
1150
 
1151
  addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1152
 
1153
  /* This overlapping check is used by peepholes merging memory block operations.
1154
     Overlapping operations would otherwise be recognized by the S/390 hardware
1155
     and would fall back to a slower implementation. Allowing overlapping
1156
     operations would lead to slow code but not to wrong code. Therefore we are
1157
     somewhat optimistic if we cannot prove that the memory blocks are
1158
     overlapping.
1159
     That's why we return false here although this may accept operations on
1160
     overlapping memory areas.  */
1161
  if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
1162
    return false;
1163
 
1164
  delta = INTVAL (addr_delta);
1165
 
1166
  if (delta == 0
1167
      || (delta > 0 && delta < size)
1168
      || (delta < 0 && -delta < size))
1169
    return true;
1170
 
1171
  return false;
1172
}
1173
 
1174
/* Check whether the address of memory reference MEM2 equals exactly
1175
   the address of memory reference MEM1 plus DELTA.  Return true if
1176
   we can prove this to be the case, false otherwise.  */
1177
 
1178
bool
1179
s390_offset_p (rtx mem1, rtx mem2, rtx delta)
1180
{
1181
  rtx addr1, addr2, addr_delta;
1182
 
1183
  if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1184
    return false;
1185
 
1186
  addr1 = XEXP (mem1, 0);
1187
  addr2 = XEXP (mem2, 0);
1188
 
1189
  addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1190
  if (!addr_delta || !rtx_equal_p (addr_delta, delta))
1191
    return false;
1192
 
1193
  return true;
1194
}
1195
 
1196
/* Expand logical operator CODE in mode MODE with operands OPERANDS.  */
1197
 
1198
void
1199
s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1200
                              rtx *operands)
1201
{
1202
  enum machine_mode wmode = mode;
1203
  rtx dst = operands[0];
1204
  rtx src1 = operands[1];
1205
  rtx src2 = operands[2];
1206
  rtx op, clob, tem;
1207
 
1208
  /* If we cannot handle the operation directly, use a temp register.  */
1209
  if (!s390_logical_operator_ok_p (operands))
1210
    dst = gen_reg_rtx (mode);
1211
 
1212
  /* QImode and HImode patterns make sense only if we have a destination
1213
     in memory.  Otherwise perform the operation in SImode.  */
1214
  if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1215
    wmode = SImode;
1216
 
1217
  /* Widen operands if required.  */
1218
  if (mode != wmode)
1219
    {
1220
      if (GET_CODE (dst) == SUBREG
1221
          && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1222
        dst = tem;
1223
      else if (REG_P (dst))
1224
        dst = gen_rtx_SUBREG (wmode, dst, 0);
1225
      else
1226
        dst = gen_reg_rtx (wmode);
1227
 
1228
      if (GET_CODE (src1) == SUBREG
1229
          && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1230
        src1 = tem;
1231
      else if (GET_MODE (src1) != VOIDmode)
1232
        src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1233
 
1234
      if (GET_CODE (src2) == SUBREG
1235
          && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1236
        src2 = tem;
1237
      else if (GET_MODE (src2) != VOIDmode)
1238
        src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1239
    }
1240
 
1241
  /* Emit the instruction.  */
1242
  op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1243
  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1244
  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1245
 
1246
  /* Fix up the destination if needed.  */
1247
  if (dst != operands[0])
1248
    emit_move_insn (operands[0], gen_lowpart (mode, dst));
1249
}
1250
 
1251
/* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR).  */
1252
 
1253
bool
1254
s390_logical_operator_ok_p (rtx *operands)
1255
{
1256
  /* If the destination operand is in memory, it needs to coincide
1257
     with one of the source operands.  After reload, it has to be
1258
     the first source operand.  */
1259
  if (GET_CODE (operands[0]) == MEM)
1260
    return rtx_equal_p (operands[0], operands[1])
1261
           || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1262
 
1263
  return true;
1264
}
1265
 
1266
/* Narrow logical operation CODE of memory operand MEMOP with immediate
1267
   operand IMMOP to switch from SS to SI type instructions.  */
1268
 
1269
void
1270
s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1271
{
1272
  int def = code == AND ? -1 : 0;
1273
  HOST_WIDE_INT mask;
1274
  int part;
1275
 
1276
  gcc_assert (GET_CODE (*memop) == MEM);
1277
  gcc_assert (!MEM_VOLATILE_P (*memop));
1278
 
1279
  mask = s390_extract_part (*immop, QImode, def);
1280
  part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1281
  gcc_assert (part >= 0);
1282
 
1283
  *memop = adjust_address (*memop, QImode, part);
1284
  *immop = gen_int_mode (mask, QImode);
1285
}
1286
 
1287
 
1288
/* How to allocate a 'struct machine_function'.  */
1289
 
1290
static struct machine_function *
1291
s390_init_machine_status (void)
1292
{
1293
  return ggc_alloc_cleared (sizeof (struct machine_function));
1294
}
1295
 
1296
/* Change optimizations to be performed, depending on the
1297
   optimization level.
1298
 
1299
   LEVEL is the optimization level specified; 2 if `-O2' is
1300
   specified, 1 if `-O' is specified, and 0 if neither is specified.
1301
 
1302
   SIZE is nonzero if `-Os' is specified and zero otherwise.  */
1303
 
1304
void
1305
optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1306
{
1307
  /* ??? There are apparently still problems with -fcaller-saves.  */
1308
  flag_caller_saves = 0;
1309
 
1310
  /* By default, always emit DWARF-2 unwind info.  This allows debugging
1311
     without maintaining a stack frame back-chain.  */
1312
  flag_asynchronous_unwind_tables = 1;
1313
 
1314
  /* Use MVCLE instructions to decrease code size if requested.  */
1315
  if (size != 0)
1316
    target_flags |= MASK_MVCLE;
1317
}
1318
 
1319
/* Return true if ARG is the name of a processor.  Set *TYPE and *FLAGS
1320
   to the associated processor_type and processor_flags if so.  */
1321
 
1322
static bool
1323
s390_handle_arch_option (const char *arg,
1324
                         enum processor_type *type,
1325
                         enum processor_flags *flags)
1326
{
1327
  static struct pta
1328
    {
1329
      const char *const name;           /* processor name or nickname.  */
1330
      const enum processor_type processor;
1331
      const enum processor_flags flags;
1332
    }
1333
  const processor_alias_table[] =
1334
    {
1335
      {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1336
      {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1337
      {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1338
      {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1339
                                    | PF_LONG_DISPLACEMENT},
1340
      {"z9-109", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH
1341
                                       | PF_LONG_DISPLACEMENT | PF_EXTIMM},
1342
    };
1343
  size_t i;
1344
 
1345
  for (i = 0; i < ARRAY_SIZE (processor_alias_table); i++)
1346
    if (strcmp (arg, processor_alias_table[i].name) == 0)
1347
      {
1348
        *type = processor_alias_table[i].processor;
1349
        *flags = processor_alias_table[i].flags;
1350
        return true;
1351
      }
1352
  return false;
1353
}
1354
 
1355
/* Implement TARGET_HANDLE_OPTION.  */
1356
 
1357
static bool
1358
s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1359
{
1360
  switch (code)
1361
    {
1362
    case OPT_march_:
1363
      return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
1364
 
1365
    case OPT_mstack_guard_:
1366
      if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_guard) != 1)
1367
        return false;
1368
      if (exact_log2 (s390_stack_guard) == -1)
1369
        error ("stack guard value must be an exact power of 2");
1370
      return true;
1371
 
1372
    case OPT_mstack_size_:
1373
      if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_size) != 1)
1374
        return false;
1375
      if (exact_log2 (s390_stack_size) == -1)
1376
        error ("stack size must be an exact power of 2");
1377
      return true;
1378
 
1379
    case OPT_mtune_:
1380
      return s390_handle_arch_option (arg, &s390_tune, &s390_tune_flags);
1381
 
1382
    case OPT_mwarn_framesize_:
1383
      return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_warn_framesize) == 1;
1384
 
1385
    default:
1386
      return true;
1387
    }
1388
}
1389
 
1390
void
1391
override_options (void)
1392
{
1393
  /* Set up function hooks.  */
1394
  init_machine_status = s390_init_machine_status;
1395
 
1396
  /* Architecture mode defaults according to ABI.  */
1397
  if (!(target_flags_explicit & MASK_ZARCH))
1398
    {
1399
      if (TARGET_64BIT)
1400
        target_flags |= MASK_ZARCH;
1401
      else
1402
        target_flags &= ~MASK_ZARCH;
1403
    }
1404
 
1405
  /* Determine processor architectural level.  */
1406
  if (!s390_arch_string)
1407
    {
1408
      s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1409
      s390_handle_arch_option (s390_arch_string, &s390_arch, &s390_arch_flags);
1410
    }
1411
 
1412
  /* Determine processor to tune for.  */
1413
  if (s390_tune == PROCESSOR_max)
1414
    {
1415
      s390_tune = s390_arch;
1416
      s390_tune_flags = s390_arch_flags;
1417
    }
1418
 
1419
  /* Sanity checks.  */
1420
  if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1421
    error ("z/Architecture mode not supported on %s", s390_arch_string);
1422
  if (TARGET_64BIT && !TARGET_ZARCH)
1423
    error ("64-bit ABI not supported in ESA/390 mode");
1424
 
1425
  /* Set processor cost function.  */
1426
  if (s390_tune == PROCESSOR_2094_Z9_109)
1427
    s390_cost = &z9_109_cost;
1428
  else if (s390_tune == PROCESSOR_2084_Z990)
1429
    s390_cost = &z990_cost;
1430
  else
1431
    s390_cost = &z900_cost;
1432
 
1433
  if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1434
    error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1435
           "in combination");
1436
 
1437
  if (s390_stack_size)
1438
    {
1439
      if (!s390_stack_guard)
1440
        error ("-mstack-size implies use of -mstack-guard");
1441
      else if (s390_stack_guard >= s390_stack_size)
1442
        error ("stack size must be greater than the stack guard value");
1443
      else if (s390_stack_size > 1 << 16)
1444
        error ("stack size must not be greater than 64k");
1445
    }
1446
  else if (s390_stack_guard)
1447
    error ("-mstack-guard implies use of -mstack-size");
1448
 
1449
#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1450
  if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
1451
    target_flags |= MASK_LONG_DOUBLE_128;
1452
#endif
1453
}
1454
 
1455
/* Map for smallest class containing reg regno.  */
1456
 
1457
const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1458
{ GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1459
  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1460
  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1461
  ADDR_REGS,    ADDR_REGS, ADDR_REGS, ADDR_REGS,
1462
  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1463
  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1464
  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1465
  FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
1466
  ADDR_REGS,    CC_REGS,   ADDR_REGS, ADDR_REGS,
1467
  ACCESS_REGS,  ACCESS_REGS
1468
};
1469
 
1470
/* Return attribute type of insn.  */
1471
 
1472
static enum attr_type
1473
s390_safe_attr_type (rtx insn)
1474
{
1475
  if (recog_memoized (insn) >= 0)
1476
    return get_attr_type (insn);
1477
  else
1478
    return TYPE_NONE;
1479
}
1480
 
1481
/* Return true if DISP is a valid short displacement.  */
1482
 
1483
static bool
1484
s390_short_displacement (rtx disp)
1485
{
1486
  /* No displacement is OK.  */
1487
  if (!disp)
1488
    return true;
1489
 
1490
  /* Integer displacement in range.  */
1491
  if (GET_CODE (disp) == CONST_INT)
1492
    return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1493
 
1494
  /* GOT offset is not OK, the GOT can be large.  */
1495
  if (GET_CODE (disp) == CONST
1496
      && GET_CODE (XEXP (disp, 0)) == UNSPEC
1497
      && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1498
          || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1499
    return false;
1500
 
1501
  /* All other symbolic constants are literal pool references,
1502
     which are OK as the literal pool must be small.  */
1503
  if (GET_CODE (disp) == CONST)
1504
    return true;
1505
 
1506
  return false;
1507
}
1508
 
1509
/* Decompose a RTL expression ADDR for a memory address into
1510
   its components, returned in OUT.
1511
 
1512
   Returns false if ADDR is not a valid memory address, true
1513
   otherwise.  If OUT is NULL, don't return the components,
1514
   but check for validity only.
1515
 
1516
   Note: Only addresses in canonical form are recognized.
1517
   LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1518
   canonical form so that they will be recognized.  */
1519
 
1520
static int
1521
s390_decompose_address (rtx addr, struct s390_address *out)
1522
{
1523
  HOST_WIDE_INT offset = 0;
1524
  rtx base = NULL_RTX;
1525
  rtx indx = NULL_RTX;
1526
  rtx disp = NULL_RTX;
1527
  rtx orig_disp;
1528
  bool pointer = false;
1529
  bool base_ptr = false;
1530
  bool indx_ptr = false;
1531
  bool literal_pool = false;
1532
 
1533
  /* We may need to substitute the literal pool base register into the address
1534
     below.  However, at this point we do not know which register is going to
1535
     be used as base, so we substitute the arg pointer register.  This is going
1536
     to be treated as holding a pointer below -- it shouldn't be used for any
1537
     other purpose.  */
1538
  rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
1539
 
1540
  /* Decompose address into base + index + displacement.  */
1541
 
1542
  if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1543
    base = addr;
1544
 
1545
  else if (GET_CODE (addr) == PLUS)
1546
    {
1547
      rtx op0 = XEXP (addr, 0);
1548
      rtx op1 = XEXP (addr, 1);
1549
      enum rtx_code code0 = GET_CODE (op0);
1550
      enum rtx_code code1 = GET_CODE (op1);
1551
 
1552
      if (code0 == REG || code0 == UNSPEC)
1553
        {
1554
          if (code1 == REG || code1 == UNSPEC)
1555
            {
1556
              indx = op0;       /* index + base */
1557
              base = op1;
1558
            }
1559
 
1560
          else
1561
            {
1562
              base = op0;       /* base + displacement */
1563
              disp = op1;
1564
            }
1565
        }
1566
 
1567
      else if (code0 == PLUS)
1568
        {
1569
          indx = XEXP (op0, 0);  /* index + base + disp */
1570
          base = XEXP (op0, 1);
1571
          disp = op1;
1572
        }
1573
 
1574
      else
1575
        {
1576
          return false;
1577
        }
1578
    }
1579
 
1580
  else
1581
    disp = addr;                /* displacement */
1582
 
1583
  /* Extract integer part of displacement.  */
1584
  orig_disp = disp;
1585
  if (disp)
1586
    {
1587
      if (GET_CODE (disp) == CONST_INT)
1588
        {
1589
          offset = INTVAL (disp);
1590
          disp = NULL_RTX;
1591
        }
1592
      else if (GET_CODE (disp) == CONST
1593
               && GET_CODE (XEXP (disp, 0)) == PLUS
1594
               && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1595
        {
1596
          offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1597
          disp = XEXP (XEXP (disp, 0), 0);
1598
        }
1599
    }
1600
 
1601
  /* Strip off CONST here to avoid special case tests later.  */
1602
  if (disp && GET_CODE (disp) == CONST)
1603
    disp = XEXP (disp, 0);
1604
 
1605
  /* We can convert literal pool addresses to
1606
     displacements by basing them off the base register.  */
1607
  if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
1608
    {
1609
      /* Either base or index must be free to hold the base register.  */
1610
      if (!base)
1611
        base = fake_pool_base, literal_pool = true;
1612
      else if (!indx)
1613
        indx = fake_pool_base, literal_pool = true;
1614
      else
1615
        return false;
1616
 
1617
      /* Mark up the displacement.  */
1618
      disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
1619
                             UNSPEC_LTREL_OFFSET);
1620
    }
1621
 
1622
  /* Validate base register.  */
1623
  if (base)
1624
    {
1625
      if (GET_CODE (base) == UNSPEC)
1626
        switch (XINT (base, 1))
1627
          {
1628
          case UNSPEC_LTREF:
1629
            if (!disp)
1630
              disp = gen_rtx_UNSPEC (Pmode,
1631
                                     gen_rtvec (1, XVECEXP (base, 0, 0)),
1632
                                     UNSPEC_LTREL_OFFSET);
1633
            else
1634
              return false;
1635
 
1636
            base = XVECEXP (base, 0, 1);
1637
            break;
1638
 
1639
          case UNSPEC_LTREL_BASE:
1640
            if (XVECLEN (base, 0) == 1)
1641
              base = fake_pool_base, literal_pool = true;
1642
            else
1643
              base = XVECEXP (base, 0, 1);
1644
            break;
1645
 
1646
          default:
1647
            return false;
1648
          }
1649
 
1650
      if (!REG_P (base)
1651
          || (GET_MODE (base) != SImode
1652
              && GET_MODE (base) != Pmode))
1653
        return false;
1654
 
1655
      if (REGNO (base) == STACK_POINTER_REGNUM
1656
          || REGNO (base) == FRAME_POINTER_REGNUM
1657
          || ((reload_completed || reload_in_progress)
1658
              && frame_pointer_needed
1659
              && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1660
          || REGNO (base) == ARG_POINTER_REGNUM
1661
          || (flag_pic
1662
              && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1663
        pointer = base_ptr = true;
1664
 
1665
      if ((reload_completed || reload_in_progress)
1666
          && base == cfun->machine->base_reg)
1667
        pointer = base_ptr = literal_pool = true;
1668
    }
1669
 
1670
  /* Validate index register.  */
1671
  if (indx)
1672
    {
1673
      if (GET_CODE (indx) == UNSPEC)
1674
        switch (XINT (indx, 1))
1675
          {
1676
          case UNSPEC_LTREF:
1677
            if (!disp)
1678
              disp = gen_rtx_UNSPEC (Pmode,
1679
                                     gen_rtvec (1, XVECEXP (indx, 0, 0)),
1680
                                     UNSPEC_LTREL_OFFSET);
1681
            else
1682
              return false;
1683
 
1684
            indx = XVECEXP (indx, 0, 1);
1685
            break;
1686
 
1687
          case UNSPEC_LTREL_BASE:
1688
            if (XVECLEN (indx, 0) == 1)
1689
              indx = fake_pool_base, literal_pool = true;
1690
            else
1691
              indx = XVECEXP (indx, 0, 1);
1692
            break;
1693
 
1694
          default:
1695
            return false;
1696
          }
1697
 
1698
      if (!REG_P (indx)
1699
          || (GET_MODE (indx) != SImode
1700
              && GET_MODE (indx) != Pmode))
1701
        return false;
1702
 
1703
      if (REGNO (indx) == STACK_POINTER_REGNUM
1704
          || REGNO (indx) == FRAME_POINTER_REGNUM
1705
          || ((reload_completed || reload_in_progress)
1706
              && frame_pointer_needed
1707
              && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1708
          || REGNO (indx) == ARG_POINTER_REGNUM
1709
          || (flag_pic
1710
              && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1711
        pointer = indx_ptr = true;
1712
 
1713
      if ((reload_completed || reload_in_progress)
1714
          && indx == cfun->machine->base_reg)
1715
        pointer = indx_ptr = literal_pool = true;
1716
    }
1717
 
1718
  /* Prefer to use pointer as base, not index.  */
1719
  if (base && indx && !base_ptr
1720
      && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
1721
    {
1722
      rtx tmp = base;
1723
      base = indx;
1724
      indx = tmp;
1725
    }
1726
 
1727
  /* Validate displacement.  */
1728
  if (!disp)
1729
    {
1730
      /* If virtual registers are involved, the displacement will change later
1731
         anyway as the virtual registers get eliminated.  This could make a
1732
         valid displacement invalid, but it is more likely to make an invalid
1733
         displacement valid, because we sometimes access the register save area
1734
         via negative offsets to one of those registers.
1735
         Thus we don't check the displacement for validity here.  If after
1736
         elimination the displacement turns out to be invalid after all,
1737
         this is fixed up by reload in any case.  */
1738
      if (base != arg_pointer_rtx
1739
          && indx != arg_pointer_rtx
1740
          && base != return_address_pointer_rtx
1741
          && indx != return_address_pointer_rtx
1742
          && base != frame_pointer_rtx
1743
          && indx != frame_pointer_rtx
1744
          && base != virtual_stack_vars_rtx
1745
          && indx != virtual_stack_vars_rtx)
1746
        if (!DISP_IN_RANGE (offset))
1747
          return false;
1748
    }
1749
  else
1750
    {
1751
      /* All the special cases are pointers.  */
1752
      pointer = true;
1753
 
1754
      /* In the small-PIC case, the linker converts @GOT
1755
         and @GOTNTPOFF offsets to possible displacements.  */
1756
      if (GET_CODE (disp) == UNSPEC
1757
          && (XINT (disp, 1) == UNSPEC_GOT
1758
              || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
1759
          && flag_pic == 1)
1760
        {
1761
          ;
1762
        }
1763
 
1764
      /* Accept chunkified literal pool symbol references.  */
1765
      else if (cfun && cfun->machine
1766
               && cfun->machine->decomposed_literal_pool_addresses_ok_p
1767
               && GET_CODE (disp) == MINUS
1768
               && GET_CODE (XEXP (disp, 0)) == LABEL_REF
1769
               && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
1770
        {
1771
          ;
1772
        }
1773
 
1774
      /* Accept literal pool references.  */
1775
      else if (GET_CODE (disp) == UNSPEC
1776
               && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
1777
        {
1778
          orig_disp = gen_rtx_CONST (Pmode, disp);
1779
          if (offset)
1780
            {
1781
              /* If we have an offset, make sure it does not
1782
                 exceed the size of the constant pool entry.  */
1783
              rtx sym = XVECEXP (disp, 0, 0);
1784
              if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
1785
                return false;
1786
 
1787
              orig_disp = plus_constant (orig_disp, offset);
1788
            }
1789
        }
1790
 
1791
      else
1792
        return false;
1793
    }
1794
 
1795
  if (!base && !indx)
1796
    pointer = true;
1797
 
1798
  if (out)
1799
    {
1800
      out->base = base;
1801
      out->indx = indx;
1802
      out->disp = orig_disp;
1803
      out->pointer = pointer;
1804
      out->literal_pool = literal_pool;
1805
    }
1806
 
1807
  return true;
1808
}
1809
 
1810
/* Decompose a RTL expression OP for a shift count into its components,
1811
   and return the base register in BASE and the offset in OFFSET.
1812
 
1813
   Return true if OP is a valid shift count, false if not.  */
1814
 
1815
bool
1816
s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
1817
{
1818
  HOST_WIDE_INT off = 0;
1819
 
1820
  /* We can have an integer constant, an address register,
1821
     or a sum of the two.  */
1822
  if (GET_CODE (op) == CONST_INT)
1823
    {
1824
      off = INTVAL (op);
1825
      op = NULL_RTX;
1826
    }
1827
  if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1828
    {
1829
      off = INTVAL (XEXP (op, 1));
1830
      op = XEXP (op, 0);
1831
    }
1832
  while (op && GET_CODE (op) == SUBREG)
1833
    op = SUBREG_REG (op);
1834
 
1835
  if (op && GET_CODE (op) != REG)
1836
    return false;
1837
 
1838
  if (offset)
1839
    *offset = off;
1840
  if (base)
1841
    *base = op;
1842
 
1843
   return true;
1844
}
1845
 
1846
 
1847
/* Return true if CODE is a valid address without index.  */
1848
 
1849
bool
1850
s390_legitimate_address_without_index_p (rtx op)
1851
{
1852
  struct s390_address addr;
1853
 
1854
  if (!s390_decompose_address (XEXP (op, 0), &addr))
1855
    return false;
1856
  if (addr.indx)
1857
    return false;
1858
 
1859
  return true;
1860
}
1861
 
1862
 
1863
/* Evaluates constraint strings described by the regular expression
1864
   ([A|B](Q|R|S|T))|U|W and returns 1 if OP is a valid operand for the
1865
   constraint given in STR, or 0 else.  */
1866
 
1867
int
1868
s390_mem_constraint (const char *str, rtx op)
1869
{
1870
  struct s390_address addr;
1871
  char c = str[0];
1872
 
1873
  /* Check for offsettable variants of memory constraints.  */
1874
  if (c == 'A')
1875
    {
1876
      /* Only accept non-volatile MEMs.  */
1877
      if (!MEM_P (op) || MEM_VOLATILE_P (op))
1878
        return 0;
1879
 
1880
      if ((reload_completed || reload_in_progress)
1881
          ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
1882
        return 0;
1883
 
1884
      c = str[1];
1885
    }
1886
 
1887
  /* Check for non-literal-pool variants of memory constraints.  */
1888
  else if (c == 'B')
1889
    {
1890
      if (GET_CODE (op) != MEM)
1891
        return 0;
1892
      if (!s390_decompose_address (XEXP (op, 0), &addr))
1893
        return 0;
1894
      if (addr.literal_pool)
1895
        return 0;
1896
 
1897
      c = str[1];
1898
    }
1899
 
1900
  switch (c)
1901
    {
1902
    case 'Q':
1903
      if (GET_CODE (op) != MEM)
1904
        return 0;
1905
      if (!s390_decompose_address (XEXP (op, 0), &addr))
1906
        return 0;
1907
      if (addr.indx)
1908
        return 0;
1909
 
1910
      if (TARGET_LONG_DISPLACEMENT)
1911
        {
1912
          if (!s390_short_displacement (addr.disp))
1913
            return 0;
1914
        }
1915
      break;
1916
 
1917
    case 'R':
1918
      if (GET_CODE (op) != MEM)
1919
        return 0;
1920
 
1921
      if (TARGET_LONG_DISPLACEMENT)
1922
        {
1923
          if (!s390_decompose_address (XEXP (op, 0), &addr))
1924
            return 0;
1925
          if (!s390_short_displacement (addr.disp))
1926
            return 0;
1927
        }
1928
      break;
1929
 
1930
    case 'S':
1931
      if (!TARGET_LONG_DISPLACEMENT)
1932
        return 0;
1933
      if (GET_CODE (op) != MEM)
1934
        return 0;
1935
      if (!s390_decompose_address (XEXP (op, 0), &addr))
1936
        return 0;
1937
      if (addr.indx)
1938
        return 0;
1939
      if (s390_short_displacement (addr.disp))
1940
        return 0;
1941
      break;
1942
 
1943
    case 'T':
1944
      if (!TARGET_LONG_DISPLACEMENT)
1945
        return 0;
1946
      if (GET_CODE (op) != MEM)
1947
        return 0;
1948
      /* Any invalid address here will be fixed up by reload,
1949
         so accept it for the most generic constraint.  */
1950
      if (s390_decompose_address (XEXP (op, 0), &addr)
1951
          && s390_short_displacement (addr.disp))
1952
        return 0;
1953
      break;
1954
 
1955
    case 'U':
1956
      if (TARGET_LONG_DISPLACEMENT)
1957
        {
1958
          if (!s390_decompose_address (op, &addr))
1959
            return 0;
1960
          if (!s390_short_displacement (addr.disp))
1961
            return 0;
1962
        }
1963
      break;
1964
 
1965
    case 'W':
1966
      if (!TARGET_LONG_DISPLACEMENT)
1967
        return 0;
1968
      /* Any invalid address here will be fixed up by reload,
1969
         so accept it for the most generic constraint.  */
1970
      if (s390_decompose_address (op, &addr)
1971
          && s390_short_displacement (addr.disp))
1972
        return 0;
1973
      break;
1974
 
1975
    case 'Y':
1976
      /* Simply check for the basic form of a shift count.  Reload will
1977
         take care of making sure we have a proper base register.  */
1978
      if (!s390_decompose_shift_count (op, NULL, NULL))
1979
        return 0;
1980
      break;
1981
 
1982
    default:
1983
      return 0;
1984
    }
1985
 
1986
  return 1;
1987
}
1988
 
1989
 
1990
 
1991
/* Evaluates constraint strings starting with letter O.  Input
1992
   parameter C is the second letter following the "O" in the constraint
1993
   string. Returns 1 if VALUE meets the respective constraint and 0
1994
   otherwise.  */
1995
 
1996
int
1997
s390_O_constraint_str (const char c, HOST_WIDE_INT value)
1998
{
1999
  if (!TARGET_EXTIMM)
2000
    return 0;
2001
 
2002
  switch (c)
2003
    {
2004
    case 's':
2005
      return trunc_int_for_mode (value, SImode) == value;
2006
 
2007
    case 'p':
2008
      return value == 0
2009
        || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
2010
 
2011
    case 'n':
2012
      return value == -1
2013
        || s390_single_part (GEN_INT (value), DImode, SImode, -1) == 1;
2014
 
2015
    default:
2016
      gcc_unreachable ();
2017
    }
2018
}
2019
 
2020
 
2021
/* Evaluates constraint strings starting with letter N.  Parameter STR
2022
   contains the letters following letter "N" in the constraint string.
2023
   Returns true if VALUE matches the constraint.  */
2024
 
2025
int
2026
s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
2027
{
2028
  enum machine_mode mode, part_mode;
2029
  int def;
2030
  int part, part_goal;
2031
 
2032
 
2033
  if (str[0] == 'x')
2034
    part_goal = -1;
2035
  else
2036
    part_goal = str[0] - '0';
2037
 
2038
  switch (str[1])
2039
    {
2040
    case 'Q':
2041
      part_mode = QImode;
2042
      break;
2043
    case 'H':
2044
      part_mode = HImode;
2045
      break;
2046
    case 'S':
2047
      part_mode = SImode;
2048
      break;
2049
    default:
2050
      return 0;
2051
    }
2052
 
2053
  switch (str[2])
2054
    {
2055
    case 'H':
2056
      mode = HImode;
2057
      break;
2058
    case 'S':
2059
      mode = SImode;
2060
      break;
2061
    case 'D':
2062
      mode = DImode;
2063
      break;
2064
    default:
2065
      return 0;
2066
    }
2067
 
2068
  switch (str[3])
2069
    {
2070
    case '0':
2071
      def = 0;
2072
      break;
2073
    case 'F':
2074
      def = -1;
2075
      break;
2076
    default:
2077
      return 0;
2078
    }
2079
 
2080
  if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
2081
    return 0;
2082
 
2083
  part = s390_single_part (GEN_INT (value), mode, part_mode, def);
2084
  if (part < 0)
2085
    return 0;
2086
  if (part_goal != -1 && part_goal != part)
2087
    return 0;
2088
 
2089
  return 1;
2090
}
2091
 
2092
 
2093
/* Returns true if the input parameter VALUE is a float zero.  */
2094
 
2095
int
2096
s390_float_const_zero_p (rtx value)
2097
{
2098
  return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
2099
          && value == CONST0_RTX (GET_MODE (value)));
2100
}
2101
 
2102
 
2103
/* Compute a (partial) cost for rtx X.  Return true if the complete
2104
   cost has been computed, and false if subexpressions should be
2105
   scanned.  In either case, *TOTAL contains the cost result.
2106
   CODE contains GET_CODE (x), OUTER_CODE contains the code
2107
   of the superexpression of x.  */
2108
 
2109
static bool
2110
s390_rtx_costs (rtx x, int code, int outer_code, int *total)
2111
{
2112
  switch (code)
2113
    {
2114
    case CONST:
2115
    case CONST_INT:
2116
    case LABEL_REF:
2117
    case SYMBOL_REF:
2118
    case CONST_DOUBLE:
2119
    case MEM:
2120
      *total = 0;
2121
      return true;
2122
 
2123
    case ASHIFT:
2124
    case ASHIFTRT:
2125
    case LSHIFTRT:
2126
    case ROTATE:
2127
    case ROTATERT:
2128
    case AND:
2129
    case IOR:
2130
    case XOR:
2131
    case NEG:
2132
    case NOT:
2133
      *total = COSTS_N_INSNS (1);
2134
      return false;
2135
 
2136
    case PLUS:
2137
    case MINUS:
2138
      /* Check for multiply and add.  */
2139
      if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2140
          && GET_CODE (XEXP (x, 0)) == MULT
2141
          && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD)
2142
        {
2143
          /* This is the multiply and add case.  */
2144
          if (GET_MODE (x) == DFmode)
2145
            *total = s390_cost->madbr;
2146
          else
2147
            *total = s390_cost->maebr;
2148
          *total += rtx_cost (XEXP (XEXP (x, 0), 0), MULT)
2149
            + rtx_cost (XEXP (XEXP (x, 0), 1), MULT)
2150
            + rtx_cost (XEXP (x, 1), code);
2151
          return true;  /* Do not do an additional recursive descent.  */
2152
        }
2153
      *total = COSTS_N_INSNS (1);
2154
      return false;
2155
 
2156
    case MULT:
2157
      switch (GET_MODE (x))
2158
        {
2159
        case SImode:
2160
          {
2161
            rtx left = XEXP (x, 0);
2162
            rtx right = XEXP (x, 1);
2163
            if (GET_CODE (right) == CONST_INT
2164
                && CONST_OK_FOR_K (INTVAL (right)))
2165
              *total = s390_cost->mhi;
2166
            else if (GET_CODE (left) == SIGN_EXTEND)
2167
              *total = s390_cost->mh;
2168
            else
2169
              *total = s390_cost->ms;  /* msr, ms, msy */
2170
            break;
2171
          }
2172
        case DImode:
2173
          {
2174
            rtx left = XEXP (x, 0);
2175
            rtx right = XEXP (x, 1);
2176
            if (TARGET_64BIT)
2177
              {
2178
                if (GET_CODE (right) == CONST_INT
2179
                    && CONST_OK_FOR_K (INTVAL (right)))
2180
                  *total = s390_cost->mghi;
2181
                else if (GET_CODE (left) == SIGN_EXTEND)
2182
                  *total = s390_cost->msgf;
2183
                else
2184
                  *total = s390_cost->msg;  /* msgr, msg */
2185
              }
2186
            else /* TARGET_31BIT */
2187
              {
2188
                if (GET_CODE (left) == SIGN_EXTEND
2189
                    && GET_CODE (right) == SIGN_EXTEND)
2190
                  /* mulsidi case: mr, m */
2191
                  *total = s390_cost->m;
2192
                else if (GET_CODE (left) == ZERO_EXTEND
2193
                         && GET_CODE (right) == ZERO_EXTEND
2194
                         && TARGET_CPU_ZARCH)
2195
                  /* umulsidi case: ml, mlr */
2196
                  *total = s390_cost->ml;
2197
                else
2198
                  /* Complex calculation is required.  */
2199
                  *total = COSTS_N_INSNS (40);
2200
              }
2201
            break;
2202
          }
2203
        case SFmode:
2204
        case DFmode:
2205
          *total = s390_cost->mult_df;
2206
          break;
2207
        case TFmode:
2208
          *total = s390_cost->mxbr;
2209
          break;
2210
        default:
2211
          return false;
2212
        }
2213
      return false;
2214
 
2215
    case UDIV:
2216
    case UMOD:
2217
      if (GET_MODE (x) == TImode)              /* 128 bit division */
2218
        *total = s390_cost->dlgr;
2219
      else if (GET_MODE (x) == DImode)
2220
        {
2221
          rtx right = XEXP (x, 1);
2222
          if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2223
            *total = s390_cost->dlr;
2224
          else                                 /* 64 by 64 bit division */
2225
            *total = s390_cost->dlgr;
2226
        }
2227
      else if (GET_MODE (x) == SImode)         /* 32 bit division */
2228
        *total = s390_cost->dlr;
2229
      return false;
2230
 
2231
    case DIV:
2232
    case MOD:
2233
      if (GET_MODE (x) == DImode)
2234
        {
2235
          rtx right = XEXP (x, 1);
2236
          if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2237
            if (TARGET_64BIT)
2238
              *total = s390_cost->dsgfr;
2239
            else
2240
              *total = s390_cost->dr;
2241
          else                                 /* 64 by 64 bit division */
2242
            *total = s390_cost->dsgr;
2243
        }
2244
      else if (GET_MODE (x) == SImode)         /* 32 bit division */
2245
        *total = s390_cost->dlr;
2246
      else if (GET_MODE (x) == SFmode)
2247
        {
2248
          if (TARGET_IEEE_FLOAT)
2249
            *total = s390_cost->debr;
2250
          else /* TARGET_IBM_FLOAT */
2251
            *total = s390_cost->der;
2252
        }
2253
      else if (GET_MODE (x) == DFmode)
2254
        {
2255
          if (TARGET_IEEE_FLOAT)
2256
            *total = s390_cost->ddbr;
2257
          else /* TARGET_IBM_FLOAT */
2258
            *total = s390_cost->ddr;
2259
        }
2260
      else if (GET_MODE (x) == TFmode)
2261
        {
2262
          if (TARGET_IEEE_FLOAT)
2263
            *total = s390_cost->dxbr;
2264
          else /* TARGET_IBM_FLOAT */
2265
            *total = s390_cost->dxr;
2266
        }
2267
      return false;
2268
 
2269
    case SQRT:
2270
      if (GET_MODE (x) == SFmode)
2271
        *total = s390_cost->sqebr;
2272
      else if (GET_MODE (x) == DFmode)
2273
        *total = s390_cost->sqdbr;
2274
      else /* TFmode */
2275
        *total = s390_cost->sqxbr;
2276
      return false;
2277
 
2278
    case SIGN_EXTEND:
2279
    case ZERO_EXTEND:
2280
      if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2281
          || outer_code == PLUS || outer_code == MINUS
2282
          || outer_code == COMPARE)
2283
        *total = 0;
2284
      return false;
2285
 
2286
    case COMPARE:
2287
      *total = COSTS_N_INSNS (1);
2288
      if (GET_CODE (XEXP (x, 0)) == AND
2289
          && GET_CODE (XEXP (x, 1)) == CONST_INT
2290
          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2291
        {
2292
          rtx op0 = XEXP (XEXP (x, 0), 0);
2293
          rtx op1 = XEXP (XEXP (x, 0), 1);
2294
          rtx op2 = XEXP (x, 1);
2295
 
2296
          if (memory_operand (op0, GET_MODE (op0))
2297
              && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
2298
            return true;
2299
          if (register_operand (op0, GET_MODE (op0))
2300
              && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2301
            return true;
2302
        }
2303
      return false;
2304
 
2305
    default:
2306
      return false;
2307
    }
2308
}
2309
 
2310
/* Return the cost of an address rtx ADDR.  */
2311
 
2312
static int
2313
s390_address_cost (rtx addr)
2314
{
2315
  struct s390_address ad;
2316
  if (!s390_decompose_address (addr, &ad))
2317
    return 1000;
2318
 
2319
  return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2320
}
2321
 
2322
/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2323
   otherwise return 0.  */
2324
 
2325
int
2326
tls_symbolic_operand (rtx op)
2327
{
2328
  if (GET_CODE (op) != SYMBOL_REF)
2329
    return 0;
2330
  return SYMBOL_REF_TLS_MODEL (op);
2331
}
2332
 
2333
/* Split DImode access register reference REG (on 64-bit) into its constituent
2334
   low and high parts, and store them into LO and HI.  Note that gen_lowpart/
2335
   gen_highpart cannot be used as they assume all registers are word-sized,
2336
   while our access registers have only half that size.  */
2337
 
2338
void
2339
s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2340
{
2341
  gcc_assert (TARGET_64BIT);
2342
  gcc_assert (ACCESS_REG_P (reg));
2343
  gcc_assert (GET_MODE (reg) == DImode);
2344
  gcc_assert (!(REGNO (reg) & 1));
2345
 
2346
  *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2347
  *hi = gen_rtx_REG (SImode, REGNO (reg));
2348
}
2349
 
2350
/* Return true if OP contains a symbol reference */
2351
 
2352
bool
2353
symbolic_reference_mentioned_p (rtx op)
2354
{
2355
  const char *fmt;
2356
  int i;
2357
 
2358
  if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2359
    return 1;
2360
 
2361
  fmt = GET_RTX_FORMAT (GET_CODE (op));
2362
  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2363
    {
2364
      if (fmt[i] == 'E')
2365
        {
2366
          int j;
2367
 
2368
          for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2369
            if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2370
              return 1;
2371
        }
2372
 
2373
      else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2374
        return 1;
2375
    }
2376
 
2377
  return 0;
2378
}
2379
 
2380
/* Return true if OP contains a reference to a thread-local symbol.  */
2381
 
2382
bool
2383
tls_symbolic_reference_mentioned_p (rtx op)
2384
{
2385
  const char *fmt;
2386
  int i;
2387
 
2388
  if (GET_CODE (op) == SYMBOL_REF)
2389
    return tls_symbolic_operand (op);
2390
 
2391
  fmt = GET_RTX_FORMAT (GET_CODE (op));
2392
  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2393
    {
2394
      if (fmt[i] == 'E')
2395
        {
2396
          int j;
2397
 
2398
          for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2399
            if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2400
              return true;
2401
        }
2402
 
2403
      else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2404
        return true;
2405
    }
2406
 
2407
  return false;
2408
}
2409
 
2410
 
2411
/* Return true if OP is a legitimate general operand when
2412
   generating PIC code.  It is given that flag_pic is on
2413
   and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
2414
 
2415
int
2416
legitimate_pic_operand_p (rtx op)
2417
{
2418
  /* Accept all non-symbolic constants.  */
2419
  if (!SYMBOLIC_CONST (op))
2420
    return 1;
2421
 
2422
  /* Reject everything else; must be handled
2423
     via emit_symbolic_move.  */
2424
  return 0;
2425
}
2426
 
2427
/* Returns true if the constant value OP is a legitimate general operand.
2428
   It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
2429
 
2430
int
2431
legitimate_constant_p (rtx op)
2432
{
2433
  /* Accept all non-symbolic constants.  */
2434
  if (!SYMBOLIC_CONST (op))
2435
    return 1;
2436
 
2437
  /* Accept immediate LARL operands.  */
2438
  if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2439
    return 1;
2440
 
2441
  /* Thread-local symbols are never legal constants.  This is
2442
     so that emit_call knows that computing such addresses
2443
     might require a function call.  */
2444
  if (TLS_SYMBOLIC_CONST (op))
2445
    return 0;
2446
 
2447
  /* In the PIC case, symbolic constants must *not* be
2448
     forced into the literal pool.  We accept them here,
2449
     so that they will be handled by emit_symbolic_move.  */
2450
  if (flag_pic)
2451
    return 1;
2452
 
2453
  /* All remaining non-PIC symbolic constants are
2454
     forced into the literal pool.  */
2455
  return 0;
2456
}
2457
 
2458
/* Determine if it's legal to put X into the constant pool.  This
2459
   is not possible if X contains the address of a symbol that is
2460
   not constant (TLS) or not known at final link time (PIC).  */
2461
 
2462
static bool
2463
s390_cannot_force_const_mem (rtx x)
2464
{
2465
  switch (GET_CODE (x))
2466
    {
2467
    case CONST_INT:
2468
    case CONST_DOUBLE:
2469
      /* Accept all non-symbolic constants.  */
2470
      return false;
2471
 
2472
    case LABEL_REF:
2473
      /* Labels are OK iff we are non-PIC.  */
2474
      return flag_pic != 0;
2475
 
2476
    case SYMBOL_REF:
2477
      /* 'Naked' TLS symbol references are never OK,
2478
         non-TLS symbols are OK iff we are non-PIC.  */
2479
      if (tls_symbolic_operand (x))
2480
        return true;
2481
      else
2482
        return flag_pic != 0;
2483
 
2484
    case CONST:
2485
      return s390_cannot_force_const_mem (XEXP (x, 0));
2486
    case PLUS:
2487
    case MINUS:
2488
      return s390_cannot_force_const_mem (XEXP (x, 0))
2489
             || s390_cannot_force_const_mem (XEXP (x, 1));
2490
 
2491
    case UNSPEC:
2492
      switch (XINT (x, 1))
2493
        {
2494
        /* Only lt-relative or GOT-relative UNSPECs are OK.  */
2495
        case UNSPEC_LTREL_OFFSET:
2496
        case UNSPEC_GOT:
2497
        case UNSPEC_GOTOFF:
2498
        case UNSPEC_PLTOFF:
2499
        case UNSPEC_TLSGD:
2500
        case UNSPEC_TLSLDM:
2501
        case UNSPEC_NTPOFF:
2502
        case UNSPEC_DTPOFF:
2503
        case UNSPEC_GOTNTPOFF:
2504
        case UNSPEC_INDNTPOFF:
2505
          return false;
2506
 
2507
        /* If the literal pool shares the code section, be put
2508
           execute template placeholders into the pool as well.  */
2509
        case UNSPEC_INSN:
2510
          return TARGET_CPU_ZARCH;
2511
 
2512
        default:
2513
          return true;
2514
        }
2515
      break;
2516
 
2517
    default:
2518
      gcc_unreachable ();
2519
    }
2520
}
2521
 
2522
/* Returns true if the constant value OP is a legitimate general
2523
   operand during and after reload.  The difference to
2524
   legitimate_constant_p is that this function will not accept
2525
   a constant that would need to be forced to the literal pool
2526
   before it can be used as operand.  */
2527
 
2528
bool
2529
legitimate_reload_constant_p (rtx op)
2530
{
2531
  /* Accept la(y) operands.  */
2532
  if (GET_CODE (op) == CONST_INT
2533
      && DISP_IN_RANGE (INTVAL (op)))
2534
    return true;
2535
 
2536
  /* Accept l(g)hi/l(g)fi operands.  */
2537
  if (GET_CODE (op) == CONST_INT
2538
      && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
2539
    return true;
2540
 
2541
  /* Accept lliXX operands.  */
2542
  if (TARGET_ZARCH
2543
      && GET_CODE (op) == CONST_INT
2544
      && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2545
      && s390_single_part (op, word_mode, HImode, 0) >= 0)
2546
  return true;
2547
 
2548
  if (TARGET_EXTIMM
2549
      && GET_CODE (op) == CONST_INT
2550
      && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2551
      && s390_single_part (op, word_mode, SImode, 0) >= 0)
2552
    return true;
2553
 
2554
  /* Accept larl operands.  */
2555
  if (TARGET_CPU_ZARCH
2556
      && larl_operand (op, VOIDmode))
2557
    return true;
2558
 
2559
  /* Accept lzXX operands.  */
2560
  if (GET_CODE (op) == CONST_DOUBLE
2561
      && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', "G"))
2562
    return true;
2563
 
2564
  /* Accept double-word operands that can be split.  */
2565
  if (GET_CODE (op) == CONST_INT
2566
      && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op))
2567
    {
2568
      enum machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
2569
      rtx hi = operand_subword (op, 0, 0, dword_mode);
2570
      rtx lo = operand_subword (op, 1, 0, dword_mode);
2571
      return legitimate_reload_constant_p (hi)
2572
             && legitimate_reload_constant_p (lo);
2573
    }
2574
 
2575
  /* Everything else cannot be handled without reload.  */
2576
  return false;
2577
}
2578
 
2579
/* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2580
   return the class of reg to actually use.  */
2581
 
2582
enum reg_class
2583
s390_preferred_reload_class (rtx op, enum reg_class class)
2584
{
2585
  switch (GET_CODE (op))
2586
    {
2587
      /* Constants we cannot reload must be forced into the
2588
         literal pool.  */
2589
 
2590
      case CONST_DOUBLE:
2591
      case CONST_INT:
2592
        if (legitimate_reload_constant_p (op))
2593
          return class;
2594
        else
2595
          return NO_REGS;
2596
 
2597
      /* If a symbolic constant or a PLUS is reloaded,
2598
         it is most likely being used as an address, so
2599
         prefer ADDR_REGS.  If 'class' is not a superset
2600
         of ADDR_REGS, e.g. FP_REGS, reject this reload.  */
2601
      case PLUS:
2602
      case LABEL_REF:
2603
      case SYMBOL_REF:
2604
      case CONST:
2605
        if (reg_class_subset_p (ADDR_REGS, class))
2606
          return ADDR_REGS;
2607
        else
2608
          return NO_REGS;
2609
 
2610
      default:
2611
        break;
2612
    }
2613
 
2614
  return class;
2615
}
2616
 
2617
/* Return the register class of a scratch register needed to
2618
   load IN into a register of class CLASS in MODE.
2619
 
2620
   We need a temporary when loading a PLUS expression which
2621
   is not a legitimate operand of the LOAD ADDRESS instruction.  */
2622
 
2623
enum reg_class
2624
s390_secondary_input_reload_class (enum reg_class class,
2625
                                   enum machine_mode mode, rtx in)
2626
{
2627
  if (s390_plus_operand (in, mode))
2628
    return ADDR_REGS;
2629
 
2630
  if (reg_classes_intersect_p (FP_REGS, class)
2631
      && mode == TFmode
2632
      && GET_CODE (in) == MEM
2633
      && GET_CODE (XEXP (in, 0)) == PLUS
2634
      && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT
2635
      && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1))
2636
                         + GET_MODE_SIZE (mode) - 1))
2637
    return ADDR_REGS;
2638
 
2639
  if (reg_classes_intersect_p (CC_REGS, class))
2640
    return GENERAL_REGS;
2641
 
2642
  return NO_REGS;
2643
}
2644
 
2645
/* Return the register class of a scratch register needed to
2646
   store a register of class CLASS in MODE into OUT:
2647
 
2648
   We need a temporary when storing a double-word to a
2649
   non-offsettable memory address.  */
2650
 
2651
enum reg_class
2652
s390_secondary_output_reload_class (enum reg_class class,
2653
                                    enum machine_mode mode, rtx out)
2654
{
2655
  if ((TARGET_64BIT ? (mode == TImode || mode == TFmode)
2656
                    : (mode == DImode || mode == DFmode))
2657
      && reg_classes_intersect_p (GENERAL_REGS, class)
2658
      && GET_CODE (out) == MEM
2659
      && GET_CODE (XEXP (out, 0)) == PLUS
2660
      && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS
2661
      && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2662
      && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2663
                         + GET_MODE_SIZE (mode) - 1))
2664
    return ADDR_REGS;
2665
 
2666
  if (reg_classes_intersect_p (FP_REGS, class)
2667
      && mode == TFmode
2668
      && GET_CODE (out) == MEM
2669
      && GET_CODE (XEXP (out, 0)) == PLUS
2670
      && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2671
      && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2672
                         + GET_MODE_SIZE (mode) - 1))
2673
    return ADDR_REGS;
2674
 
2675
  if (reg_classes_intersect_p (CC_REGS, class))
2676
    return GENERAL_REGS;
2677
 
2678
  return NO_REGS;
2679
}
2680
 
2681
/* Generate code to load SRC, which is PLUS that is not a
2682
   legitimate operand for the LA instruction, into TARGET.
2683
   SCRATCH may be used as scratch register.  */
2684
 
2685
void
2686
s390_expand_plus_operand (rtx target, rtx src,
2687
                          rtx scratch)
2688
{
2689
  rtx sum1, sum2;
2690
  struct s390_address ad;
2691
 
2692
  /* src must be a PLUS; get its two operands.  */
2693
  gcc_assert (GET_CODE (src) == PLUS);
2694
  gcc_assert (GET_MODE (src) == Pmode);
2695
 
2696
  /* Check if any of the two operands is already scheduled
2697
     for replacement by reload.  This can happen e.g. when
2698
     float registers occur in an address.  */
2699
  sum1 = find_replacement (&XEXP (src, 0));
2700
  sum2 = find_replacement (&XEXP (src, 1));
2701
  src = gen_rtx_PLUS (Pmode, sum1, sum2);
2702
 
2703
  /* If the address is already strictly valid, there's nothing to do.  */
2704
  if (!s390_decompose_address (src, &ad)
2705
      || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2706
      || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
2707
    {
2708
      /* Otherwise, one of the operands cannot be an address register;
2709
         we reload its value into the scratch register.  */
2710
      if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2711
        {
2712
          emit_move_insn (scratch, sum1);
2713
          sum1 = scratch;
2714
        }
2715
      if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2716
        {
2717
          emit_move_insn (scratch, sum2);
2718
          sum2 = scratch;
2719
        }
2720
 
2721
      /* According to the way these invalid addresses are generated
2722
         in reload.c, it should never happen (at least on s390) that
2723
         *neither* of the PLUS components, after find_replacements
2724
         was applied, is an address register.  */
2725
      if (sum1 == scratch && sum2 == scratch)
2726
        {
2727
          debug_rtx (src);
2728
          gcc_unreachable ();
2729
        }
2730
 
2731
      src = gen_rtx_PLUS (Pmode, sum1, sum2);
2732
    }
2733
 
2734
  /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
2735
     is only ever performed on addresses, so we can mark the
2736
     sum as legitimate for LA in any case.  */
2737
  s390_load_address (target, src);
2738
}
2739
 
2740
 
2741
/* Return true if ADDR is a valid memory address.
2742
   STRICT specifies whether strict register checking applies.  */
2743
 
2744
bool
2745
legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2746
                      rtx addr, int strict)
2747
{
2748
  struct s390_address ad;
2749
  if (!s390_decompose_address (addr, &ad))
2750
    return false;
2751
 
2752
  if (strict)
2753
    {
2754
      if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2755
        return false;
2756
 
2757
      if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
2758
        return false;
2759
    }
2760
  else
2761
    {
2762
      if (ad.base
2763
          && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
2764
               || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
2765
        return false;
2766
 
2767
      if (ad.indx
2768
          && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
2769
               || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
2770
          return false;
2771
    }
2772
  return true;
2773
}
2774
 
2775
/* Return true if OP is a valid operand for the LA instruction.
2776
   In 31-bit, we need to prove that the result is used as an
2777
   address, as LA performs only a 31-bit addition.  */
2778
 
2779
bool
2780
legitimate_la_operand_p (rtx op)
2781
{
2782
  struct s390_address addr;
2783
  if (!s390_decompose_address (op, &addr))
2784
    return false;
2785
 
2786
  return (TARGET_64BIT || addr.pointer);
2787
}
2788
 
2789
/* Return true if it is valid *and* preferable to use LA to
2790
   compute the sum of OP1 and OP2.  */
2791
 
2792
bool
2793
preferred_la_operand_p (rtx op1, rtx op2)
2794
{
2795
  struct s390_address addr;
2796
 
2797
  if (op2 != const0_rtx)
2798
    op1 = gen_rtx_PLUS (Pmode, op1, op2);
2799
 
2800
  if (!s390_decompose_address (op1, &addr))
2801
    return false;
2802
  if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
2803
    return false;
2804
  if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
2805
    return false;
2806
 
2807
  if (!TARGET_64BIT && !addr.pointer)
2808
    return false;
2809
 
2810
  if (addr.pointer)
2811
    return true;
2812
 
2813
  if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2814
      || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2815
    return true;
2816
 
2817
  return false;
2818
}
2819
 
2820
/* Emit a forced load-address operation to load SRC into DST.
2821
   This will use the LOAD ADDRESS instruction even in situations
2822
   where legitimate_la_operand_p (SRC) returns false.  */
2823
 
2824
void
2825
s390_load_address (rtx dst, rtx src)
2826
{
2827
  if (TARGET_64BIT)
2828
    emit_move_insn (dst, src);
2829
  else
2830
    emit_insn (gen_force_la_31 (dst, src));
2831
}
2832
 
2833
/* Return a legitimate reference for ORIG (an address) using the
2834
   register REG.  If REG is 0, a new pseudo is generated.
2835
 
2836
   There are two types of references that must be handled:
2837
 
2838
   1. Global data references must load the address from the GOT, via
2839
      the PIC reg.  An insn is emitted to do this load, and the reg is
2840
      returned.
2841
 
2842
   2. Static data references, constant pool addresses, and code labels
2843
      compute the address as an offset from the GOT, whose base is in
2844
      the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
2845
      differentiate them from global data objects.  The returned
2846
      address is the PIC reg + an unspec constant.
2847
 
2848
   GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2849
   reg also appears in the address.  */
2850
 
2851
rtx
2852
legitimize_pic_address (rtx orig, rtx reg)
2853
{
2854
  rtx addr = orig;
2855
  rtx new = orig;
2856
  rtx base;
2857
 
2858
  gcc_assert (!TLS_SYMBOLIC_CONST (addr));
2859
 
2860
  if (GET_CODE (addr) == LABEL_REF
2861
      || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2862
    {
2863
      /* This is a local symbol.  */
2864
      if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2865
        {
2866
          /* Access local symbols PC-relative via LARL.
2867
             This is the same as in the non-PIC case, so it is
2868
             handled automatically ...  */
2869
        }
2870
      else
2871
        {
2872
          /* Access local symbols relative to the GOT.  */
2873
 
2874
          rtx temp = reg? reg : gen_reg_rtx (Pmode);
2875
 
2876
          if (reload_in_progress || reload_completed)
2877
            regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2878
 
2879
          addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2880
          addr = gen_rtx_CONST (Pmode, addr);
2881
          addr = force_const_mem (Pmode, addr);
2882
          emit_move_insn (temp, addr);
2883
 
2884
          new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2885
          if (reg != 0)
2886
            {
2887
              s390_load_address (reg, new);
2888
              new = reg;
2889
            }
2890
        }
2891
    }
2892
  else if (GET_CODE (addr) == SYMBOL_REF)
2893
    {
2894
      if (reg == 0)
2895
        reg = gen_reg_rtx (Pmode);
2896
 
2897
      if (flag_pic == 1)
2898
        {
2899
          /* Assume GOT offset < 4k.  This is handled the same way
2900
             in both 31- and 64-bit code (@GOT).  */
2901
 
2902
          if (reload_in_progress || reload_completed)
2903
            regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2904
 
2905
          new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2906
          new = gen_rtx_CONST (Pmode, new);
2907
          new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2908
          new = gen_const_mem (Pmode, new);
2909
          emit_move_insn (reg, new);
2910
          new = reg;
2911
        }
2912
      else if (TARGET_CPU_ZARCH)
2913
        {
2914
          /* If the GOT offset might be >= 4k, we determine the position
2915
             of the GOT entry via a PC-relative LARL (@GOTENT).  */
2916
 
2917
          rtx temp = gen_reg_rtx (Pmode);
2918
 
2919
          new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2920
          new = gen_rtx_CONST (Pmode, new);
2921
          emit_move_insn (temp, new);
2922
 
2923
          new = gen_const_mem (Pmode, temp);
2924
          emit_move_insn (reg, new);
2925
          new = reg;
2926
        }
2927
      else
2928
        {
2929
          /* If the GOT offset might be >= 4k, we have to load it
2930
             from the literal pool (@GOT).  */
2931
 
2932
          rtx temp = gen_reg_rtx (Pmode);
2933
 
2934
          if (reload_in_progress || reload_completed)
2935
            regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2936
 
2937
          addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2938
          addr = gen_rtx_CONST (Pmode, addr);
2939
          addr = force_const_mem (Pmode, addr);
2940
          emit_move_insn (temp, addr);
2941
 
2942
          new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2943
          new = gen_const_mem (Pmode, new);
2944
          emit_move_insn (reg, new);
2945
          new = reg;
2946
        }
2947
    }
2948
  else
2949
    {
2950
      if (GET_CODE (addr) == CONST)
2951
        {
2952
          addr = XEXP (addr, 0);
2953
          if (GET_CODE (addr) == UNSPEC)
2954
            {
2955
              gcc_assert (XVECLEN (addr, 0) == 1);
2956
              switch (XINT (addr, 1))
2957
                {
2958
                  /* If someone moved a GOT-relative UNSPEC
2959
                     out of the literal pool, force them back in.  */
2960
                  case UNSPEC_GOTOFF:
2961
                  case UNSPEC_PLTOFF:
2962
                    new = force_const_mem (Pmode, orig);
2963
                    break;
2964
 
2965
                  /* @GOT is OK as is if small.  */
2966
                  case UNSPEC_GOT:
2967
                    if (flag_pic == 2)
2968
                      new = force_const_mem (Pmode, orig);
2969
                    break;
2970
 
2971
                  /* @GOTENT is OK as is.  */
2972
                  case UNSPEC_GOTENT:
2973
                    break;
2974
 
2975
                  /* @PLT is OK as is on 64-bit, must be converted to
2976
                     GOT-relative @PLTOFF on 31-bit.  */
2977
                  case UNSPEC_PLT:
2978
                    if (!TARGET_CPU_ZARCH)
2979
                      {
2980
                        rtx temp = reg? reg : gen_reg_rtx (Pmode);
2981
 
2982
                        if (reload_in_progress || reload_completed)
2983
                          regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2984
 
2985
                        addr = XVECEXP (addr, 0, 0);
2986
                        addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2987
                                               UNSPEC_PLTOFF);
2988
                        addr = gen_rtx_CONST (Pmode, addr);
2989
                        addr = force_const_mem (Pmode, addr);
2990
                        emit_move_insn (temp, addr);
2991
 
2992
                        new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2993
                        if (reg != 0)
2994
                          {
2995
                            s390_load_address (reg, new);
2996
                            new = reg;
2997
                          }
2998
                      }
2999
                    break;
3000
 
3001
                  /* Everything else cannot happen.  */
3002
                  default:
3003
                    gcc_unreachable ();
3004
                }
3005
            }
3006
          else
3007
            gcc_assert (GET_CODE (addr) == PLUS);
3008
        }
3009
      if (GET_CODE (addr) == PLUS)
3010
        {
3011
          rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
3012
 
3013
          gcc_assert (!TLS_SYMBOLIC_CONST (op0));
3014
          gcc_assert (!TLS_SYMBOLIC_CONST (op1));
3015
 
3016
          /* Check first to see if this is a constant offset
3017
             from a local symbol reference.  */
3018
          if ((GET_CODE (op0) == LABEL_REF
3019
                || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
3020
              && GET_CODE (op1) == CONST_INT)
3021
            {
3022
              if (TARGET_CPU_ZARCH
3023
                  && larl_operand (op0, VOIDmode)
3024
                  && INTVAL (op1) < (HOST_WIDE_INT)1 << 31
3025
                  && INTVAL (op1) >= -((HOST_WIDE_INT)1 << 31))
3026
                {
3027
                  if (INTVAL (op1) & 1)
3028
                    {
3029
                      /* LARL can't handle odd offsets, so emit a
3030
                         pair of LARL and LA.  */
3031
                      rtx temp = reg? reg : gen_reg_rtx (Pmode);
3032
 
3033
                      if (!DISP_IN_RANGE (INTVAL (op1)))
3034
                        {
3035
                          HOST_WIDE_INT even = INTVAL (op1) - 1;
3036
                          op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
3037
                          op0 = gen_rtx_CONST (Pmode, op0);
3038
                          op1 = const1_rtx;
3039
                        }
3040
 
3041
                      emit_move_insn (temp, op0);
3042
                      new = gen_rtx_PLUS (Pmode, temp, op1);
3043
 
3044
                      if (reg != 0)
3045
                        {
3046
                          s390_load_address (reg, new);
3047
                          new = reg;
3048
                        }
3049
                    }
3050
                  else
3051
                    {
3052
                      /* If the offset is even, we can just use LARL.
3053
                         This will happen automatically.  */
3054
                    }
3055
                }
3056
              else
3057
                {
3058
                  /* Access local symbols relative to the GOT.  */
3059
 
3060
                  rtx temp = reg? reg : gen_reg_rtx (Pmode);
3061
 
3062
                  if (reload_in_progress || reload_completed)
3063
                    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3064
 
3065
                  addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
3066
                                         UNSPEC_GOTOFF);
3067
                  addr = gen_rtx_PLUS (Pmode, addr, op1);
3068
                  addr = gen_rtx_CONST (Pmode, addr);
3069
                  addr = force_const_mem (Pmode, addr);
3070
                  emit_move_insn (temp, addr);
3071
 
3072
                  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3073
                  if (reg != 0)
3074
                    {
3075
                      s390_load_address (reg, new);
3076
                      new = reg;
3077
                    }
3078
                }
3079
            }
3080
 
3081
          /* Now, check whether it is a GOT relative symbol plus offset
3082
             that was pulled out of the literal pool.  Force it back in.  */
3083
 
3084
          else if (GET_CODE (op0) == UNSPEC
3085
                   && GET_CODE (op1) == CONST_INT
3086
                   && XINT (op0, 1) == UNSPEC_GOTOFF)
3087
            {
3088
              gcc_assert (XVECLEN (op0, 0) == 1);
3089
 
3090
              new = force_const_mem (Pmode, orig);
3091
            }
3092
 
3093
          /* Otherwise, compute the sum.  */
3094
          else
3095
            {
3096
              base = legitimize_pic_address (XEXP (addr, 0), reg);
3097
              new  = legitimize_pic_address (XEXP (addr, 1),
3098
                                             base == reg ? NULL_RTX : reg);
3099
              if (GET_CODE (new) == CONST_INT)
3100
                new = plus_constant (base, INTVAL (new));
3101
              else
3102
                {
3103
                  if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
3104
                    {
3105
                      base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
3106
                      new = XEXP (new, 1);
3107
                    }
3108
                  new = gen_rtx_PLUS (Pmode, base, new);
3109
                }
3110
 
3111
              if (GET_CODE (new) == CONST)
3112
                new = XEXP (new, 0);
3113
              new = force_operand (new, 0);
3114
            }
3115
        }
3116
    }
3117
  return new;
3118
}
3119
 
3120
/* Load the thread pointer into a register.  */
3121
 
3122
rtx
3123
s390_get_thread_pointer (void)
3124
{
3125
  rtx tp = gen_reg_rtx (Pmode);
3126
 
3127
  emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
3128
  mark_reg_pointer (tp, BITS_PER_WORD);
3129
 
3130
  return tp;
3131
}
3132
 
3133
/* Emit a tls call insn. The call target is the SYMBOL_REF stored
3134
   in s390_tls_symbol which always refers to __tls_get_offset.
3135
   The returned offset is written to RESULT_REG and an USE rtx is
3136
   generated for TLS_CALL.  */
3137
 
3138
static GTY(()) rtx s390_tls_symbol;
3139
 
3140
static void
3141
s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3142
{
3143
  rtx insn;
3144
 
3145
  gcc_assert (flag_pic);
3146
 
3147
  if (!s390_tls_symbol)
3148
    s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
3149
 
3150
  insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
3151
                         gen_rtx_REG (Pmode, RETURN_REGNUM));
3152
 
3153
  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
3154
  CONST_OR_PURE_CALL_P (insn) = 1;
3155
}
3156
 
3157
/* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
3158
   this (thread-local) address.  REG may be used as temporary.  */
3159
 
3160
static rtx
3161
legitimize_tls_address (rtx addr, rtx reg)
3162
{
3163
  rtx new, tls_call, temp, base, r2, insn;
3164
 
3165
  if (GET_CODE (addr) == SYMBOL_REF)
3166
    switch (tls_symbolic_operand (addr))
3167
      {
3168
      case TLS_MODEL_GLOBAL_DYNAMIC:
3169
        start_sequence ();
3170
        r2 = gen_rtx_REG (Pmode, 2);
3171
        tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
3172
        new = gen_rtx_CONST (Pmode, tls_call);
3173
        new = force_const_mem (Pmode, new);
3174
        emit_move_insn (r2, new);
3175
        s390_emit_tls_call_insn (r2, tls_call);
3176
        insn = get_insns ();
3177
        end_sequence ();
3178
 
3179
        new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3180
        temp = gen_reg_rtx (Pmode);
3181
        emit_libcall_block (insn, temp, r2, new);
3182
 
3183
        new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3184
        if (reg != 0)
3185
          {
3186
            s390_load_address (reg, new);
3187
            new = reg;
3188
          }
3189
        break;
3190
 
3191
      case TLS_MODEL_LOCAL_DYNAMIC:
3192
        start_sequence ();
3193
        r2 = gen_rtx_REG (Pmode, 2);
3194
        tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
3195
        new = gen_rtx_CONST (Pmode, tls_call);
3196
        new = force_const_mem (Pmode, new);
3197
        emit_move_insn (r2, new);
3198
        s390_emit_tls_call_insn (r2, tls_call);
3199
        insn = get_insns ();
3200
        end_sequence ();
3201
 
3202
        new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
3203
        temp = gen_reg_rtx (Pmode);
3204
        emit_libcall_block (insn, temp, r2, new);
3205
 
3206
        new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3207
        base = gen_reg_rtx (Pmode);
3208
        s390_load_address (base, new);
3209
 
3210
        new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
3211
        new = gen_rtx_CONST (Pmode, new);
3212
        new = force_const_mem (Pmode, new);
3213
        temp = gen_reg_rtx (Pmode);
3214
        emit_move_insn (temp, new);
3215
 
3216
        new = gen_rtx_PLUS (Pmode, base, temp);
3217
        if (reg != 0)
3218
          {
3219
            s390_load_address (reg, new);
3220
            new = reg;
3221
          }
3222
        break;
3223
 
3224
      case TLS_MODEL_INITIAL_EXEC:
3225
        if (flag_pic == 1)
3226
          {
3227
            /* Assume GOT offset < 4k.  This is handled the same way
3228
               in both 31- and 64-bit code.  */
3229
 
3230
            if (reload_in_progress || reload_completed)
3231
              regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3232
 
3233
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3234
            new = gen_rtx_CONST (Pmode, new);
3235
            new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3236
            new = gen_const_mem (Pmode, new);
3237
            temp = gen_reg_rtx (Pmode);
3238
            emit_move_insn (temp, new);
3239
          }
3240
        else if (TARGET_CPU_ZARCH)
3241
          {
3242
            /* If the GOT offset might be >= 4k, we determine the position
3243
               of the GOT entry via a PC-relative LARL.  */
3244
 
3245
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3246
            new = gen_rtx_CONST (Pmode, new);
3247
            temp = gen_reg_rtx (Pmode);
3248
            emit_move_insn (temp, new);
3249
 
3250
            new = gen_const_mem (Pmode, temp);
3251
            temp = gen_reg_rtx (Pmode);
3252
            emit_move_insn (temp, new);
3253
          }
3254
        else if (flag_pic)
3255
          {
3256
            /* If the GOT offset might be >= 4k, we have to load it
3257
               from the literal pool.  */
3258
 
3259
            if (reload_in_progress || reload_completed)
3260
              regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3261
 
3262
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3263
            new = gen_rtx_CONST (Pmode, new);
3264
            new = force_const_mem (Pmode, new);
3265
            temp = gen_reg_rtx (Pmode);
3266
            emit_move_insn (temp, new);
3267
 
3268
            new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3269
            new = gen_const_mem (Pmode, new);
3270
 
3271
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3272
            temp = gen_reg_rtx (Pmode);
3273
            emit_insn (gen_rtx_SET (Pmode, temp, new));
3274
          }
3275
        else
3276
          {
3277
            /* In position-dependent code, load the absolute address of
3278
               the GOT entry from the literal pool.  */
3279
 
3280
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3281
            new = gen_rtx_CONST (Pmode, new);
3282
            new = force_const_mem (Pmode, new);
3283
            temp = gen_reg_rtx (Pmode);
3284
            emit_move_insn (temp, new);
3285
 
3286
            new = temp;
3287
            new = gen_const_mem (Pmode, new);
3288
            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3289
            temp = gen_reg_rtx (Pmode);
3290
            emit_insn (gen_rtx_SET (Pmode, temp, new));
3291
          }
3292
 
3293
        new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3294
        if (reg != 0)
3295
          {
3296
            s390_load_address (reg, new);
3297
            new = reg;
3298
          }
3299
        break;
3300
 
3301
      case TLS_MODEL_LOCAL_EXEC:
3302
        new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3303
        new = gen_rtx_CONST (Pmode, new);
3304
        new = force_const_mem (Pmode, new);
3305
        temp = gen_reg_rtx (Pmode);
3306
        emit_move_insn (temp, new);
3307
 
3308
        new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3309
        if (reg != 0)
3310
          {
3311
            s390_load_address (reg, new);
3312
            new = reg;
3313
          }
3314
        break;
3315
 
3316
      default:
3317
        gcc_unreachable ();
3318
      }
3319
 
3320
  else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3321
    {
3322
      switch (XINT (XEXP (addr, 0), 1))
3323
        {
3324
        case UNSPEC_INDNTPOFF:
3325
          gcc_assert (TARGET_CPU_ZARCH);
3326
          new = addr;
3327
          break;
3328
 
3329
        default:
3330
          gcc_unreachable ();
3331
        }
3332
    }
3333
 
3334
  else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3335
           && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3336
    {
3337
      new = XEXP (XEXP (addr, 0), 0);
3338
      if (GET_CODE (new) != SYMBOL_REF)
3339
        new = gen_rtx_CONST (Pmode, new);
3340
 
3341
      new = legitimize_tls_address (new, reg);
3342
      new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
3343
      new = force_operand (new, 0);
3344
    }
3345
 
3346
  else
3347
    gcc_unreachable ();  /* for now ... */
3348
 
3349
  return new;
3350
}
3351
 
3352
/* Emit insns to move operands[1] into operands[0].  */
3353
 
3354
void
3355
emit_symbolic_move (rtx *operands)
3356
{
3357
  rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3358
 
3359
  if (GET_CODE (operands[0]) == MEM)
3360
    operands[1] = force_reg (Pmode, operands[1]);
3361
  else if (TLS_SYMBOLIC_CONST (operands[1]))
3362
    operands[1] = legitimize_tls_address (operands[1], temp);
3363
  else if (flag_pic)
3364
    operands[1] = legitimize_pic_address (operands[1], temp);
3365
}
3366
 
3367
/* Try machine-dependent ways of modifying an illegitimate address X
3368
   to be legitimate.  If we find one, return the new, valid address.
3369
 
3370
   OLDX is the address as it was before break_out_memory_refs was called.
3371
   In some cases it is useful to look at this to decide what needs to be done.
3372
 
3373
   MODE is the mode of the operand pointed to by X.
3374
 
3375
   When -fpic is used, special handling is needed for symbolic references.
3376
   See comments by legitimize_pic_address for details.  */
3377
 
3378
rtx
3379
legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3380
                    enum machine_mode mode ATTRIBUTE_UNUSED)
3381
{
3382
  rtx constant_term = const0_rtx;
3383
 
3384
  if (TLS_SYMBOLIC_CONST (x))
3385
    {
3386
      x = legitimize_tls_address (x, 0);
3387
 
3388
      if (legitimate_address_p (mode, x, FALSE))
3389
        return x;
3390
    }
3391
  else if (GET_CODE (x) == PLUS
3392
           && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
3393
               || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
3394
    {
3395
      return x;
3396
    }
3397
  else if (flag_pic)
3398
    {
3399
      if (SYMBOLIC_CONST (x)
3400
          || (GET_CODE (x) == PLUS
3401
              && (SYMBOLIC_CONST (XEXP (x, 0))
3402
                  || SYMBOLIC_CONST (XEXP (x, 1)))))
3403
          x = legitimize_pic_address (x, 0);
3404
 
3405
      if (legitimate_address_p (mode, x, FALSE))
3406
        return x;
3407
    }
3408
 
3409
  x = eliminate_constant_term (x, &constant_term);
3410
 
3411
  /* Optimize loading of large displacements by splitting them
3412
     into the multiple of 4K and the rest; this allows the
3413
     former to be CSE'd if possible.
3414
 
3415
     Don't do this if the displacement is added to a register
3416
     pointing into the stack frame, as the offsets will
3417
     change later anyway.  */
3418
 
3419
  if (GET_CODE (constant_term) == CONST_INT
3420
      && !TARGET_LONG_DISPLACEMENT
3421
      && !DISP_IN_RANGE (INTVAL (constant_term))
3422
      && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3423
    {
3424
      HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3425
      HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3426
 
3427
      rtx temp = gen_reg_rtx (Pmode);
3428
      rtx val  = force_operand (GEN_INT (upper), temp);
3429
      if (val != temp)
3430
        emit_move_insn (temp, val);
3431
 
3432
      x = gen_rtx_PLUS (Pmode, x, temp);
3433
      constant_term = GEN_INT (lower);
3434
    }
3435
 
3436
  if (GET_CODE (x) == PLUS)
3437
    {
3438
      if (GET_CODE (XEXP (x, 0)) == REG)
3439
        {
3440
          rtx temp = gen_reg_rtx (Pmode);
3441
          rtx val  = force_operand (XEXP (x, 1), temp);
3442
          if (val != temp)
3443
            emit_move_insn (temp, val);
3444
 
3445
          x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3446
        }
3447
 
3448
      else if (GET_CODE (XEXP (x, 1)) == REG)
3449
        {
3450
          rtx temp = gen_reg_rtx (Pmode);
3451
          rtx val  = force_operand (XEXP (x, 0), temp);
3452
          if (val != temp)
3453
            emit_move_insn (temp, val);
3454
 
3455
          x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3456
        }
3457
    }
3458
 
3459
  if (constant_term != const0_rtx)
3460
    x = gen_rtx_PLUS (Pmode, x, constant_term);
3461
 
3462
  return x;
3463
}
3464
 
3465
/* Try a machine-dependent way of reloading an illegitimate address AD
3466
   operand.  If we find one, push the reload and and return the new address.
3467
 
3468
   MODE is the mode of the enclosing MEM.  OPNUM is the operand number
3469
   and TYPE is the reload type of the current reload.  */
3470
 
3471
rtx
3472
legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3473
                           int opnum, int type)
3474
{
3475
  if (!optimize || TARGET_LONG_DISPLACEMENT)
3476
    return NULL_RTX;
3477
 
3478
  if (GET_CODE (ad) == PLUS)
3479
    {
3480
      rtx tem = simplify_binary_operation (PLUS, Pmode,
3481
                                           XEXP (ad, 0), XEXP (ad, 1));
3482
      if (tem)
3483
        ad = tem;
3484
    }
3485
 
3486
  if (GET_CODE (ad) == PLUS
3487
      && GET_CODE (XEXP (ad, 0)) == REG
3488
      && GET_CODE (XEXP (ad, 1)) == CONST_INT
3489
      && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3490
    {
3491
      HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3492
      HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3493
      rtx cst, tem, new;
3494
 
3495
      cst = GEN_INT (upper);
3496
      if (!legitimate_reload_constant_p (cst))
3497
        cst = force_const_mem (Pmode, cst);
3498
 
3499
      tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3500
      new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3501
 
3502
      push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3503
                   BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3504
                   opnum, (enum reload_type) type);
3505
      return new;
3506
    }
3507
 
3508
  return NULL_RTX;
3509
}
3510
 
3511
/* Emit code to move LEN bytes from DST to SRC.  */
3512
 
3513
void
3514
s390_expand_movmem (rtx dst, rtx src, rtx len)
3515
{
3516
  if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3517
    {
3518
      if (INTVAL (len) > 0)
3519
        emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3520
    }
3521
 
3522
  else if (TARGET_MVCLE)
3523
    {
3524
      emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3525
    }
3526
 
3527
  else
3528
    {
3529
      rtx dst_addr, src_addr, count, blocks, temp;
3530
      rtx loop_start_label = gen_label_rtx ();
3531
      rtx loop_end_label = gen_label_rtx ();
3532
      rtx end_label = gen_label_rtx ();
3533
      enum machine_mode mode;
3534
 
3535
      mode = GET_MODE (len);
3536
      if (mode == VOIDmode)
3537
        mode = Pmode;
3538
 
3539
      dst_addr = gen_reg_rtx (Pmode);
3540
      src_addr = gen_reg_rtx (Pmode);
3541
      count = gen_reg_rtx (mode);
3542
      blocks = gen_reg_rtx (mode);
3543
 
3544
      convert_move (count, len, 1);
3545
      emit_cmp_and_jump_insns (count, const0_rtx,
3546
                               EQ, NULL_RTX, mode, 1, end_label);
3547
 
3548
      emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3549
      emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3550
      dst = change_address (dst, VOIDmode, dst_addr);
3551
      src = change_address (src, VOIDmode, src_addr);
3552
 
3553
      temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3554
      if (temp != count)
3555
        emit_move_insn (count, temp);
3556
 
3557
      temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3558
      if (temp != blocks)
3559
        emit_move_insn (blocks, temp);
3560
 
3561
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3562
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3563
 
3564
      emit_label (loop_start_label);
3565
 
3566
      emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3567
      s390_load_address (dst_addr,
3568
                         gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3569
      s390_load_address (src_addr,
3570
                         gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3571
 
3572
      temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3573
      if (temp != blocks)
3574
        emit_move_insn (blocks, temp);
3575
 
3576
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3577
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3578
 
3579
      emit_jump (loop_start_label);
3580
      emit_label (loop_end_label);
3581
 
3582
      emit_insn (gen_movmem_short (dst, src,
3583
                                   convert_to_mode (Pmode, count, 1)));
3584
      emit_label (end_label);
3585
    }
3586
}
3587
 
3588
/* Emit code to set LEN bytes at DST to VAL.
3589
   Make use of clrmem if VAL is zero.  */
3590
 
3591
void
3592
s390_expand_setmem (rtx dst, rtx len, rtx val)
3593
{
3594
  if (GET_CODE (len) == CONST_INT && INTVAL (len) == 0)
3595
    return;
3596
 
3597
  gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
3598
 
3599
  if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
3600
    {
3601
      if (val == const0_rtx && INTVAL (len) <= 256)
3602
        emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3603
      else
3604
        {
3605
          /* Initialize memory by storing the first byte.  */
3606
          emit_move_insn (adjust_address (dst, QImode, 0), val);
3607
 
3608
          if (INTVAL (len) > 1)
3609
            {
3610
              /* Initiate 1 byte overlap move.
3611
                 The first byte of DST is propagated through DSTP1.
3612
                 Prepare a movmem for:  DST+1 = DST (length = LEN - 1).
3613
                 DST is set to size 1 so the rest of the memory location
3614
                 does not count as source operand.  */
3615
              rtx dstp1 = adjust_address (dst, VOIDmode, 1);
3616
              set_mem_size (dst, const1_rtx);
3617
 
3618
              emit_insn (gen_movmem_short (dstp1, dst,
3619
                                           GEN_INT (INTVAL (len) - 2)));
3620
            }
3621
        }
3622
    }
3623
 
3624
  else if (TARGET_MVCLE)
3625
    {
3626
      val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
3627
      emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
3628
    }
3629
 
3630
  else
3631
    {
3632
      rtx dst_addr, src_addr, count, blocks, temp, dstp1 = NULL_RTX;
3633
      rtx loop_start_label = gen_label_rtx ();
3634
      rtx loop_end_label = gen_label_rtx ();
3635
      rtx end_label = gen_label_rtx ();
3636
      enum machine_mode mode;
3637
 
3638
      mode = GET_MODE (len);
3639
      if (mode == VOIDmode)
3640
        mode = Pmode;
3641
 
3642
      dst_addr = gen_reg_rtx (Pmode);
3643
      src_addr = gen_reg_rtx (Pmode);
3644
      count = gen_reg_rtx (mode);
3645
      blocks = gen_reg_rtx (mode);
3646
 
3647
      convert_move (count, len, 1);
3648
      emit_cmp_and_jump_insns (count, const0_rtx,
3649
                               EQ, NULL_RTX, mode, 1, end_label);
3650
 
3651
      emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3652
      dst = change_address (dst, VOIDmode, dst_addr);
3653
 
3654
      if (val == const0_rtx)
3655
        temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3656
      else
3657
        {
3658
          dstp1 = adjust_address (dst, VOIDmode, 1);
3659
          set_mem_size (dst, const1_rtx);
3660
 
3661
          /* Initialize memory by storing the first byte.  */
3662
          emit_move_insn (adjust_address (dst, QImode, 0), val);
3663
 
3664
          /* If count is 1 we are done.  */
3665
          emit_cmp_and_jump_insns (count, const1_rtx,
3666
                                   EQ, NULL_RTX, mode, 1, end_label);
3667
 
3668
          temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1, 0);
3669
        }
3670
      if (temp != count)
3671
        emit_move_insn (count, temp);
3672
 
3673
      temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3674
      if (temp != blocks)
3675
        emit_move_insn (blocks, temp);
3676
 
3677
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3678
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3679
 
3680
      emit_label (loop_start_label);
3681
 
3682
      if (val == const0_rtx)
3683
        emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3684
      else
3685
        emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255)));
3686
      s390_load_address (dst_addr,
3687
                         gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3688
 
3689
      temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3690
      if (temp != blocks)
3691
        emit_move_insn (blocks, temp);
3692
 
3693
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3694
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3695
 
3696
      emit_jump (loop_start_label);
3697
      emit_label (loop_end_label);
3698
 
3699
      if (val == const0_rtx)
3700
        emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3701
      else
3702
        emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1)));
3703
      emit_label (end_label);
3704
    }
3705
}
3706
 
3707
/* Emit code to compare LEN bytes at OP0 with those at OP1,
3708
   and return the result in TARGET.  */
3709
 
3710
void
3711
s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3712
{
3713
  rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
3714
  rtx tmp;
3715
 
3716
  /* As the result of CMPINT is inverted compared to what we need,
3717
     we have to swap the operands.  */
3718
  tmp = op0; op0 = op1; op1 = tmp;
3719
 
3720
  if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3721
    {
3722
      if (INTVAL (len) > 0)
3723
        {
3724
          emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3725
          emit_insn (gen_cmpint (target, ccreg));
3726
        }
3727
      else
3728
        emit_move_insn (target, const0_rtx);
3729
    }
3730
  else if (TARGET_MVCLE)
3731
    {
3732
      emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3733
      emit_insn (gen_cmpint (target, ccreg));
3734
    }
3735
  else
3736
    {
3737
      rtx addr0, addr1, count, blocks, temp;
3738
      rtx loop_start_label = gen_label_rtx ();
3739
      rtx loop_end_label = gen_label_rtx ();
3740
      rtx end_label = gen_label_rtx ();
3741
      enum machine_mode mode;
3742
 
3743
      mode = GET_MODE (len);
3744
      if (mode == VOIDmode)
3745
        mode = Pmode;
3746
 
3747
      addr0 = gen_reg_rtx (Pmode);
3748
      addr1 = gen_reg_rtx (Pmode);
3749
      count = gen_reg_rtx (mode);
3750
      blocks = gen_reg_rtx (mode);
3751
 
3752
      convert_move (count, len, 1);
3753
      emit_cmp_and_jump_insns (count, const0_rtx,
3754
                               EQ, NULL_RTX, mode, 1, end_label);
3755
 
3756
      emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3757
      emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3758
      op0 = change_address (op0, VOIDmode, addr0);
3759
      op1 = change_address (op1, VOIDmode, addr1);
3760
 
3761
      temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3762
      if (temp != count)
3763
        emit_move_insn (count, temp);
3764
 
3765
      temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1, 0);
3766
      if (temp != blocks)
3767
        emit_move_insn (blocks, temp);
3768
 
3769
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3770
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3771
 
3772
      emit_label (loop_start_label);
3773
 
3774
      emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3775
      temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3776
      temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3777
                        gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3778
      temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3779
      emit_jump_insn (temp);
3780
 
3781
      s390_load_address (addr0,
3782
                         gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3783
      s390_load_address (addr1,
3784
                         gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3785
 
3786
      temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3787
      if (temp != blocks)
3788
        emit_move_insn (blocks, temp);
3789
 
3790
      emit_cmp_and_jump_insns (blocks, const0_rtx,
3791
                               EQ, NULL_RTX, mode, 1, loop_end_label);
3792
 
3793
      emit_jump (loop_start_label);
3794
      emit_label (loop_end_label);
3795
 
3796
      emit_insn (gen_cmpmem_short (op0, op1,
3797
                                   convert_to_mode (Pmode, count, 1)));
3798
      emit_label (end_label);
3799
 
3800
      emit_insn (gen_cmpint (target, ccreg));
3801
    }
3802
}
3803
 
3804
 
3805
/* Expand conditional increment or decrement using alc/slb instructions.
3806
   Should generate code setting DST to either SRC or SRC + INCREMENT,
3807
   depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3808
   Returns true if successful, false otherwise.
3809
 
3810
   That makes it possible to implement some if-constructs without jumps e.g.:
3811
   (borrow = CC0 | CC1 and carry = CC2 | CC3)
3812
   unsigned int a, b, c;
3813
   if (a < b)  c++; -> CCU  b > a  -> CC2;    c += carry;
3814
   if (a < b)  c--; -> CCL3 a - b  -> borrow; c -= borrow;
3815
   if (a <= b) c++; -> CCL3 b - a  -> borrow; c += carry;
3816
   if (a <= b) c--; -> CCU  a <= b -> borrow; c -= borrow;
3817
 
3818
   Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3819
   if (a == b) c++; -> CCL3 a ^= b; 0 - a  -> borrow;    c += carry;
3820
   if (a == b) c--; -> CCU  a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3821
   if (a != b) c++; -> CCU  a ^= b; a > 0  -> CC2;       c += carry;
3822
   if (a != b) c--; -> CCL3 a ^= b; 0 - a  -> borrow;    c -= borrow; */
3823
 
3824
bool
3825
s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3826
                   rtx dst, rtx src, rtx increment)
3827
{
3828
  enum machine_mode cmp_mode;
3829
  enum machine_mode cc_mode;
3830
  rtx op_res;
3831
  rtx insn;
3832
  rtvec p;
3833
  int ret;
3834
 
3835
  if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3836
      && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3837
    cmp_mode = SImode;
3838
  else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3839
           && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3840
    cmp_mode = DImode;
3841
  else
3842
    return false;
3843
 
3844
  /* Try ADD LOGICAL WITH CARRY.  */
3845
  if (increment == const1_rtx)
3846
    {
3847
      /* Determine CC mode to use.  */
3848
      if (cmp_code == EQ || cmp_code == NE)
3849
        {
3850
          if (cmp_op1 != const0_rtx)
3851
            {
3852
              cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3853
                                             NULL_RTX, 0, OPTAB_WIDEN);
3854
              cmp_op1 = const0_rtx;
3855
            }
3856
 
3857
          cmp_code = cmp_code == EQ ? LEU : GTU;
3858
        }
3859
 
3860
      if (cmp_code == LTU || cmp_code == LEU)
3861
        {
3862
          rtx tem = cmp_op0;
3863
          cmp_op0 = cmp_op1;
3864
          cmp_op1 = tem;
3865
          cmp_code = swap_condition (cmp_code);
3866
        }
3867
 
3868
      switch (cmp_code)
3869
        {
3870
          case GTU:
3871
            cc_mode = CCUmode;
3872
            break;
3873
 
3874
          case GEU:
3875
            cc_mode = CCL3mode;
3876
            break;
3877
 
3878
          default:
3879
            return false;
3880
        }
3881
 
3882
      /* Emit comparison instruction pattern. */
3883
      if (!register_operand (cmp_op0, cmp_mode))
3884
        cmp_op0 = force_reg (cmp_mode, cmp_op0);
3885
 
3886
      insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3887
                          gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3888
      /* We use insn_invalid_p here to add clobbers if required.  */
3889
      ret = insn_invalid_p (emit_insn (insn));
3890
      gcc_assert (!ret);
3891
 
3892
      /* Emit ALC instruction pattern.  */
3893
      op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3894
                               gen_rtx_REG (cc_mode, CC_REGNUM),
3895
                               const0_rtx);
3896
 
3897
      if (src != const0_rtx)
3898
        {
3899
          if (!register_operand (src, GET_MODE (dst)))
3900
            src = force_reg (GET_MODE (dst), src);
3901
 
3902
          src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3903
          op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3904
        }
3905
 
3906
      p = rtvec_alloc (2);
3907
      RTVEC_ELT (p, 0) =
3908
        gen_rtx_SET (VOIDmode, dst, op_res);
3909
      RTVEC_ELT (p, 1) =
3910
        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3911
      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3912
 
3913
      return true;
3914
    }
3915
 
3916
  /* Try SUBTRACT LOGICAL WITH BORROW.  */
3917
  if (increment == constm1_rtx)
3918
    {
3919
      /* Determine CC mode to use.  */
3920
      if (cmp_code == EQ || cmp_code == NE)
3921
        {
3922
          if (cmp_op1 != const0_rtx)
3923
            {
3924
              cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3925
                                             NULL_RTX, 0, OPTAB_WIDEN);
3926
              cmp_op1 = const0_rtx;
3927
            }
3928
 
3929
          cmp_code = cmp_code == EQ ? LEU : GTU;
3930
        }
3931
 
3932
      if (cmp_code == GTU || cmp_code == GEU)
3933
        {
3934
          rtx tem = cmp_op0;
3935
          cmp_op0 = cmp_op1;
3936
          cmp_op1 = tem;
3937
          cmp_code = swap_condition (cmp_code);
3938
        }
3939
 
3940
      switch (cmp_code)
3941
        {
3942
          case LEU:
3943
            cc_mode = CCUmode;
3944
            break;
3945
 
3946
          case LTU:
3947
            cc_mode = CCL3mode;
3948
            break;
3949
 
3950
          default:
3951
            return false;
3952
        }
3953
 
3954
      /* Emit comparison instruction pattern. */
3955
      if (!register_operand (cmp_op0, cmp_mode))
3956
        cmp_op0 = force_reg (cmp_mode, cmp_op0);
3957
 
3958
      insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3959
                          gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3960
      /* We use insn_invalid_p here to add clobbers if required.  */
3961
      ret = insn_invalid_p (emit_insn (insn));
3962
      gcc_assert (!ret);
3963
 
3964
      /* Emit SLB instruction pattern.  */
3965
      if (!register_operand (src, GET_MODE (dst)))
3966
        src = force_reg (GET_MODE (dst), src);
3967
 
3968
      op_res = gen_rtx_MINUS (GET_MODE (dst),
3969
                              gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3970
                              gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3971
                                              gen_rtx_REG (cc_mode, CC_REGNUM),
3972
                                              const0_rtx));
3973
      p = rtvec_alloc (2);
3974
      RTVEC_ELT (p, 0) =
3975
        gen_rtx_SET (VOIDmode, dst, op_res);
3976
      RTVEC_ELT (p, 1) =
3977
        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3978
      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3979
 
3980
      return true;
3981
    }
3982
 
3983
  return false;
3984
}
3985
 
3986
/* Expand code for the insv template. Return true if successful, false else.  */
3987
 
3988
bool
3989
s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
3990
{
3991
  int bitsize = INTVAL (op1);
3992
  int bitpos = INTVAL (op2);
3993
 
3994
  /* We need byte alignment.  */
3995
  if (bitsize % BITS_PER_UNIT)
3996
    return false;
3997
 
3998
  if (bitpos == 0
3999
      && memory_operand (dest, VOIDmode)
4000
      && (register_operand (src, word_mode)
4001
          || const_int_operand (src, VOIDmode)))
4002
    {
4003
      /* Emit standard pattern if possible.  */
4004
      enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT);
4005
      if (GET_MODE_BITSIZE (mode) == bitsize)
4006
        emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src));
4007
 
4008
      /* (set (ze (mem)) (const_int)).  */
4009
      else if (const_int_operand (src, VOIDmode))
4010
        {
4011
          int size = bitsize / BITS_PER_UNIT;
4012
          rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode,
4013
                                        GET_MODE_SIZE (word_mode) - size);
4014
 
4015
          dest = adjust_address (dest, BLKmode, 0);
4016
          set_mem_size (dest, GEN_INT (size));
4017
          s390_expand_movmem (dest, src_mem, GEN_INT (size));
4018
        }
4019
 
4020
      /* (set (ze (mem)) (reg)).  */
4021
      else if (register_operand (src, word_mode))
4022
        {
4023
          if (bitsize <= GET_MODE_BITSIZE (SImode))
4024
            emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
4025
                                                  const0_rtx), src);
4026
          else
4027
            {
4028
              /* Emit st,stcmh sequence.  */
4029
              int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode);
4030
              int size = stcmh_width / BITS_PER_UNIT;
4031
 
4032
              emit_move_insn (adjust_address (dest, SImode, size),
4033
                              gen_lowpart (SImode, src));
4034
              set_mem_size (dest, GEN_INT (size));
4035
              emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT
4036
                                                    (stcmh_width), const0_rtx),
4037
                              gen_rtx_LSHIFTRT (word_mode, src, GEN_INT
4038
                                                (GET_MODE_BITSIZE (SImode))));
4039
            }
4040
        }
4041
      else
4042
        return false;
4043
 
4044
      return true;
4045
    }
4046
 
4047
  /* (set (ze (reg)) (const_int)).  */
4048
  if (TARGET_ZARCH
4049
      && register_operand (dest, word_mode)
4050
      && (bitpos % 16) == 0
4051
      && (bitsize % 16) == 0
4052
      && const_int_operand (src, VOIDmode))
4053
    {
4054
      HOST_WIDE_INT val = INTVAL (src);
4055
      int regpos = bitpos + bitsize;
4056
 
4057
      while (regpos > bitpos)
4058
        {
4059
          enum machine_mode putmode;
4060
          int putsize;
4061
 
4062
          if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
4063
            putmode = SImode;
4064
          else
4065
            putmode = HImode;
4066
 
4067
          putsize = GET_MODE_BITSIZE (putmode);
4068
          regpos -= putsize;
4069
          emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4070
                                                GEN_INT (putsize),
4071
                                                GEN_INT (regpos)),
4072
                          gen_int_mode (val, putmode));
4073
          val >>= putsize;
4074
        }
4075
      gcc_assert (regpos == bitpos);
4076
      return true;
4077
    }
4078
 
4079
  return false;
4080
}
4081
 
4082
/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4083
   register that holds VAL of mode MODE shifted by COUNT bits.  */
4084
 
4085
static inline rtx
4086
s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
4087
{
4088
  val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
4089
                             NULL_RTX, 1, OPTAB_DIRECT);
4090
  return expand_simple_binop (SImode, ASHIFT, val, count,
4091
                              NULL_RTX, 1, OPTAB_DIRECT);
4092
}
4093
 
4094
/* Structure to hold the initial parameters for a compare_and_swap operation
4095
   in HImode and QImode.  */
4096
 
4097
struct alignment_context
4098
{
4099
  rtx memsi;      /* SI aligned memory location.  */
4100
  rtx shift;      /* Bit offset with regard to lsb.  */
4101
  rtx modemask;   /* Mask of the HQImode shifted by SHIFT bits.  */
4102
  rtx modemaski;  /* ~modemask */
4103
  bool aligned;   /* True if memory is aligned, false else.  */
4104
};
4105
 
4106
/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4107
   structure AC for transparent simplifying, if the memory alignment is known
4108
   to be at least 32bit.  MEM is the memory location for the actual operation
4109
   and MODE its mode.  */
4110
 
4111
static void
4112
init_alignment_context (struct alignment_context *ac, rtx mem,
4113
                        enum machine_mode mode)
4114
{
4115
  ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
4116
  ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
4117
 
4118
  if (ac->aligned)
4119
    ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned.  */
4120
  else
4121
    {
4122
      /* Alignment is unknown.  */
4123
      rtx byteoffset, addr, align;
4124
 
4125
      /* Force the address into a register.  */
4126
      addr = force_reg (Pmode, XEXP (mem, 0));
4127
 
4128
      /* Align it to SImode.  */
4129
      align = expand_simple_binop (Pmode, AND, addr,
4130
                                   GEN_INT (-GET_MODE_SIZE (SImode)),
4131
                                   NULL_RTX, 1, OPTAB_DIRECT);
4132
      /* Generate MEM.  */
4133
      ac->memsi = gen_rtx_MEM (SImode, align);
4134
      MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
4135
      set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
4136
      set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
4137
 
4138
      /* Calculate shiftcount.  */
4139
      byteoffset = expand_simple_binop (Pmode, AND, addr,
4140
                                        GEN_INT (GET_MODE_SIZE (SImode) - 1),
4141
                                        NULL_RTX, 1, OPTAB_DIRECT);
4142
      /* As we already have some offset, evaluate the remaining distance.  */
4143
      ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
4144
                                      NULL_RTX, 1, OPTAB_DIRECT);
4145
 
4146
    }
4147
  /* Shift is the byte count, but we need the bitcount.  */
4148
  ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
4149
                                  NULL_RTX, 1, OPTAB_DIRECT);
4150
  /* Calculate masks.  */
4151
  ac->modemask = expand_simple_binop (SImode, ASHIFT,
4152
                                     GEN_INT (GET_MODE_MASK (mode)), ac->shift,
4153
                                     NULL_RTX, 1, OPTAB_DIRECT);
4154
  ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
4155
}
4156
 
4157
/* Expand an atomic compare and swap operation for HImode and QImode.  MEM is
4158
   the memory location, CMP the old value to compare MEM with and NEW the value
4159
   to set if CMP == MEM.
4160
   CMP is never in memory for compare_and_swap_cc because
4161
   expand_bool_compare_and_swap puts it into a register for later compare.  */
4162
 
4163
void
4164
s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx new)
4165
{
4166
  struct alignment_context ac;
4167
  rtx cmpv, newv, val, resv, cc;
4168
  rtx res = gen_reg_rtx (SImode);
4169
  rtx csloop = gen_label_rtx ();
4170
  rtx csend = gen_label_rtx ();
4171
 
4172
  gcc_assert (register_operand (target, VOIDmode));
4173
  gcc_assert (MEM_P (mem));
4174
 
4175
  init_alignment_context (&ac, mem, mode);
4176
 
4177
  /* Shift the values to the correct bit positions.  */
4178
  if (!(ac.aligned && MEM_P (cmp)))
4179
    cmp = s390_expand_mask_and_shift (cmp, mode, ac.shift);
4180
  if (!(ac.aligned && MEM_P (new)))
4181
    new = s390_expand_mask_and_shift (new, mode, ac.shift);
4182
 
4183
  /* Load full word.  Subsequent loads are performed by CS.  */
4184
  val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
4185
                             NULL_RTX, 1, OPTAB_DIRECT);
4186
 
4187
  /* Start CS loop.  */
4188
  emit_label (csloop);
4189
  /* val = "<mem>00..0<mem>"
4190
   * cmp = "00..0<cmp>00..0"
4191
   * new = "00..0<new>00..0"
4192
   */
4193
 
4194
  /* Patch cmp and new with val at correct position.  */
4195
  if (ac.aligned && MEM_P (cmp))
4196
    {
4197
      cmpv = force_reg (SImode, val);
4198
      store_bit_field (cmpv, GET_MODE_BITSIZE (mode), 0, SImode, cmp);
4199
    }
4200
  else
4201
    cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
4202
                                                   NULL_RTX, 1, OPTAB_DIRECT));
4203
  if (ac.aligned && MEM_P (new))
4204
    {
4205
      newv = force_reg (SImode, val);
4206
      store_bit_field (newv, GET_MODE_BITSIZE (mode), 0, SImode, new);
4207
    }
4208
  else
4209
    newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new, val,
4210
                                                   NULL_RTX, 1, OPTAB_DIRECT));
4211
 
4212
  /* Jump to end if we're done (likely?).  */
4213
  s390_emit_jump (csend, s390_emit_compare_and_swap (EQ, res, ac.memsi,
4214
                                                     cmpv, newv));
4215
 
4216
  /* Check for changes outside mode.  */
4217
  resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
4218
                              NULL_RTX, 1, OPTAB_DIRECT);
4219
  cc = s390_emit_compare (NE, resv, val);
4220
  emit_move_insn (val, resv);
4221
  /* Loop internal if so.  */
4222
  s390_emit_jump (csloop, cc);
4223
 
4224
  emit_label (csend);
4225
 
4226
  /* Return the correct part of the bitfield.  */
4227
  convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
4228
                                             NULL_RTX, 1, OPTAB_DIRECT), 1);
4229
}
4230
 
4231
/* Expand an atomic operation CODE of mode MODE.  MEM is the memory location
4232
   and VAL the value to play with.  If AFTER is true then store the the value
4233
   MEM holds after the operation, if AFTER is false then store the value MEM
4234
   holds before the operation.  If TARGET is zero then discard that value, else
4235
   store it to TARGET.  */
4236
 
4237
void
4238
s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
4239
                    rtx target, rtx mem, rtx val, bool after)
4240
{
4241
  struct alignment_context ac;
4242
  rtx cmp;
4243
  rtx new = gen_reg_rtx (SImode);
4244
  rtx orig = gen_reg_rtx (SImode);
4245
  rtx csloop = gen_label_rtx ();
4246
 
4247
  gcc_assert (!target || register_operand (target, VOIDmode));
4248
  gcc_assert (MEM_P (mem));
4249
 
4250
  init_alignment_context (&ac, mem, mode);
4251
 
4252
  /* Shift val to the correct bit positions.
4253
     Preserve "icm", but prevent "ex icm".  */
4254
  if (!(ac.aligned && code == SET && MEM_P (val)))
4255
    val = s390_expand_mask_and_shift (val, mode, ac.shift);
4256
 
4257
  /* Further preparation insns.  */
4258
  if (code == PLUS || code == MINUS)
4259
    emit_move_insn (orig, val);
4260
  else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
4261
    val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
4262
                               NULL_RTX, 1, OPTAB_DIRECT);
4263
 
4264
  /* Load full word.  Subsequent loads are performed by CS.  */
4265
  cmp = force_reg (SImode, ac.memsi);
4266
 
4267
  /* Start CS loop.  */
4268
  emit_label (csloop);
4269
  emit_move_insn (new, cmp);
4270
 
4271
  /* Patch new with val at correct position.  */
4272
  switch (code)
4273
    {
4274
    case PLUS:
4275
    case MINUS:
4276
      val = expand_simple_binop (SImode, code, new, orig,
4277
                                 NULL_RTX, 1, OPTAB_DIRECT);
4278
      val = expand_simple_binop (SImode, AND, val, ac.modemask,
4279
                                 NULL_RTX, 1, OPTAB_DIRECT);
4280
      /* FALLTHRU */
4281
    case SET:
4282
      if (ac.aligned && MEM_P (val))
4283
        store_bit_field (new, GET_MODE_BITSIZE (mode), 0, SImode, val);
4284
      else
4285
        {
4286
          new = expand_simple_binop (SImode, AND, new, ac.modemaski,
4287
                                     NULL_RTX, 1, OPTAB_DIRECT);
4288
          new = expand_simple_binop (SImode, IOR, new, val,
4289
                                     NULL_RTX, 1, OPTAB_DIRECT);
4290
        }
4291
      break;
4292
    case AND:
4293
    case IOR:
4294
    case XOR:
4295
      new = expand_simple_binop (SImode, code, new, val,
4296
                                 NULL_RTX, 1, OPTAB_DIRECT);
4297
      break;
4298
    case MULT: /* NAND */
4299
      new = expand_simple_binop (SImode, XOR, new, ac.modemask,
4300
                                 NULL_RTX, 1, OPTAB_DIRECT);
4301
      new = expand_simple_binop (SImode, AND, new, val,
4302
                                 NULL_RTX, 1, OPTAB_DIRECT);
4303
      break;
4304
    default:
4305
      gcc_unreachable ();
4306
    }
4307
 
4308
  s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
4309
                                                      ac.memsi, cmp, new));
4310
 
4311
  /* Return the correct part of the bitfield.  */
4312
  if (target)
4313
    convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
4314
                                               after ? new : cmp, ac.shift,
4315
                                               NULL_RTX, 1, OPTAB_DIRECT), 1);
4316
}
4317
 
4318
/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4319
   We need to emit DTP-relative relocations.  */
4320
 
4321
static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
4322
 
4323
static void
4324
s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
4325
{
4326
  switch (size)
4327
    {
4328
    case 4:
4329
      fputs ("\t.long\t", file);
4330
      break;
4331
    case 8:
4332
      fputs ("\t.quad\t", file);
4333
      break;
4334
    default:
4335
      gcc_unreachable ();
4336
    }
4337
  output_addr_const (file, x);
4338
  fputs ("@DTPOFF", file);
4339
}
4340
 
4341
#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4342
/* Implement TARGET_MANGLE_FUNDAMENTAL_TYPE.  */
4343
 
4344
static const char *
4345
s390_mangle_fundamental_type (tree type)
4346
{
4347
  if (TYPE_MAIN_VARIANT (type) == long_double_type_node
4348
      && TARGET_LONG_DOUBLE_128)
4349
    return "g";
4350
 
4351
  /* For all other types, use normal C++ mangling.  */
4352
  return NULL;
4353
}
4354
#endif
4355
 
4356
/* In the name of slightly smaller debug output, and to cater to
4357
   general assembler lossage, recognize various UNSPEC sequences
4358
   and turn them back into a direct symbol reference.  */
4359
 
4360
static rtx
4361
s390_delegitimize_address (rtx orig_x)
4362
{
4363
  rtx x = orig_x, y;
4364
 
4365
  if (GET_CODE (x) != MEM)
4366
    return orig_x;
4367
 
4368
  x = XEXP (x, 0);
4369
  if (GET_CODE (x) == PLUS
4370
      && GET_CODE (XEXP (x, 1)) == CONST
4371
      && GET_CODE (XEXP (x, 0)) == REG
4372
      && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
4373
    {
4374
      y = XEXP (XEXP (x, 1), 0);
4375
      if (GET_CODE (y) == UNSPEC
4376
          && XINT (y, 1) == UNSPEC_GOT)
4377
        return XVECEXP (y, 0, 0);
4378
      return orig_x;
4379
    }
4380
 
4381
  if (GET_CODE (x) == CONST)
4382
    {
4383
      y = XEXP (x, 0);
4384
      if (GET_CODE (y) == UNSPEC
4385
          && XINT (y, 1) == UNSPEC_GOTENT)
4386
        return XVECEXP (y, 0, 0);
4387
      return orig_x;
4388
    }
4389
 
4390
  return orig_x;
4391
}
4392
 
4393
/* Output operand OP to stdio stream FILE.
4394
   OP is an address (register + offset) which is not used to address data;
4395
   instead the rightmost bits are interpreted as the value.  */
4396
 
4397
static void
4398
print_shift_count_operand (FILE *file, rtx op)
4399
{
4400
  HOST_WIDE_INT offset;
4401
  rtx base;
4402
 
4403
  /* Extract base register and offset.  */
4404
  if (!s390_decompose_shift_count (op, &base, &offset))
4405
    gcc_unreachable ();
4406
 
4407
  /* Sanity check.  */
4408
  if (base)
4409
    {
4410
      gcc_assert (GET_CODE (base) == REG);
4411
      gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
4412
      gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
4413
    }
4414
 
4415
  /* Offsets are constricted to twelve bits.  */
4416
  fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
4417
  if (base)
4418
    fprintf (file, "(%s)", reg_names[REGNO (base)]);
4419
}
4420
 
4421
/* See 'get_some_local_dynamic_name'.  */
4422
 
4423
static int
4424
get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4425
{
4426
  rtx x = *px;
4427
 
4428
  if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
4429
    {
4430
      x = get_pool_constant (x);
4431
      return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
4432
    }
4433
 
4434
  if (GET_CODE (x) == SYMBOL_REF
4435
      && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
4436
    {
4437
      cfun->machine->some_ld_name = XSTR (x, 0);
4438
      return 1;
4439
    }
4440
 
4441
  return 0;
4442
}
4443
 
4444
/* Locate some local-dynamic symbol still in use by this function
4445
   so that we can print its name in local-dynamic base patterns.  */
4446
 
4447
static const char *
4448
get_some_local_dynamic_name (void)
4449
{
4450
  rtx insn;
4451
 
4452
  if (cfun->machine->some_ld_name)
4453
    return cfun->machine->some_ld_name;
4454
 
4455
  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4456
    if (INSN_P (insn)
4457
        && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4458
      return cfun->machine->some_ld_name;
4459
 
4460
  gcc_unreachable ();
4461
}
4462
 
4463
/* Output machine-dependent UNSPECs occurring in address constant X
4464
   in assembler syntax to stdio stream FILE.  Returns true if the
4465
   constant X could be recognized, false otherwise.  */
4466
 
4467
bool
4468
s390_output_addr_const_extra (FILE *file, rtx x)
4469
{
4470
  if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
4471
    switch (XINT (x, 1))
4472
      {
4473
      case UNSPEC_GOTENT:
4474
        output_addr_const (file, XVECEXP (x, 0, 0));
4475
        fprintf (file, "@GOTENT");
4476
        return true;
4477
      case UNSPEC_GOT:
4478
        output_addr_const (file, XVECEXP (x, 0, 0));
4479
        fprintf (file, "@GOT");
4480
        return true;
4481
      case UNSPEC_GOTOFF:
4482
        output_addr_const (file, XVECEXP (x, 0, 0));
4483
        fprintf (file, "@GOTOFF");
4484
        return true;
4485
      case UNSPEC_PLT:
4486
        output_addr_const (file, XVECEXP (x, 0, 0));
4487
        fprintf (file, "@PLT");
4488
        return true;
4489
      case UNSPEC_PLTOFF:
4490
        output_addr_const (file, XVECEXP (x, 0, 0));
4491
        fprintf (file, "@PLTOFF");
4492
        return true;
4493
      case UNSPEC_TLSGD:
4494
        output_addr_const (file, XVECEXP (x, 0, 0));
4495
        fprintf (file, "@TLSGD");
4496
        return true;
4497
      case UNSPEC_TLSLDM:
4498
        assemble_name (file, get_some_local_dynamic_name ());
4499
        fprintf (file, "@TLSLDM");
4500
        return true;
4501
      case UNSPEC_DTPOFF:
4502
        output_addr_const (file, XVECEXP (x, 0, 0));
4503
        fprintf (file, "@DTPOFF");
4504
        return true;
4505
      case UNSPEC_NTPOFF:
4506
        output_addr_const (file, XVECEXP (x, 0, 0));
4507
        fprintf (file, "@NTPOFF");
4508
        return true;
4509
      case UNSPEC_GOTNTPOFF:
4510
        output_addr_const (file, XVECEXP (x, 0, 0));
4511
        fprintf (file, "@GOTNTPOFF");
4512
        return true;
4513
      case UNSPEC_INDNTPOFF:
4514
        output_addr_const (file, XVECEXP (x, 0, 0));
4515
        fprintf (file, "@INDNTPOFF");
4516
        return true;
4517
      }
4518
 
4519
  return false;
4520
}
4521
 
4522
/* Output address operand ADDR in assembler syntax to
4523
   stdio stream FILE.  */
4524
 
4525
void
4526
print_operand_address (FILE *file, rtx addr)
4527
{
4528
  struct s390_address ad;
4529
 
4530
  if (!s390_decompose_address (addr, &ad)
4531
      || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4532
      || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
4533
    output_operand_lossage ("cannot decompose address");
4534
 
4535
  if (ad.disp)
4536
    output_addr_const (file, ad.disp);
4537
  else
4538
    fprintf (file, "0");
4539
 
4540
  if (ad.base && ad.indx)
4541
    fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
4542
                              reg_names[REGNO (ad.base)]);
4543
  else if (ad.base)
4544
    fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4545
}
4546
 
4547
/* Output operand X in assembler syntax to stdio stream FILE.
4548
   CODE specified the format flag.  The following format flags
4549
   are recognized:
4550
 
4551
    'C': print opcode suffix for branch condition.
4552
    'D': print opcode suffix for inverse branch condition.
4553
    'J': print tls_load/tls_gdcall/tls_ldcall suffix
4554
    'G': print the size of the operand in bytes.
4555
    'O': print only the displacement of a memory reference.
4556
    'R': print only the base register of a memory reference.
4557
    'S': print S-type memory reference (base+displacement).
4558
    'N': print the second word of a DImode operand.
4559
    'M': print the second word of a TImode operand.
4560
    'Y': print shift count operand.
4561
 
4562
    'b': print integer X as if it's an unsigned byte.
4563
    'x': print integer X as if it's an unsigned halfword.
4564
    'h': print integer X as if it's a signed halfword.
4565
    'i': print the first nonzero HImode part of X.
4566
    'j': print the first HImode part unequal to -1 of X.
4567
    'k': print the first nonzero SImode part of X.
4568
    'm': print the first SImode part unequal to -1 of X.
4569
    'o': print integer X as if it's an unsigned 32bit word.  */
4570
 
4571
void
4572
print_operand (FILE *file, rtx x, int code)
4573
{
4574
  switch (code)
4575
    {
4576
    case 'C':
4577
      fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4578
      return;
4579
 
4580
    case 'D':
4581
      fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4582
      return;
4583
 
4584
    case 'J':
4585
      if (GET_CODE (x) == SYMBOL_REF)
4586
        {
4587
          fprintf (file, "%s", ":tls_load:");
4588
          output_addr_const (file, x);
4589
        }
4590
      else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
4591
        {
4592
          fprintf (file, "%s", ":tls_gdcall:");
4593
          output_addr_const (file, XVECEXP (x, 0, 0));
4594
        }
4595
      else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
4596
        {
4597
          fprintf (file, "%s", ":tls_ldcall:");
4598
          assemble_name (file, get_some_local_dynamic_name ());
4599
        }
4600
      else
4601
        gcc_unreachable ();
4602
      return;
4603
 
4604
    case 'G':
4605
      fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
4606
      return;
4607
 
4608
    case 'O':
4609
      {
4610
        struct s390_address ad;
4611
        int ret;
4612
 
4613
        gcc_assert (GET_CODE (x) == MEM);
4614
        ret = s390_decompose_address (XEXP (x, 0), &ad);
4615
        gcc_assert (ret);
4616
        gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4617
        gcc_assert (!ad.indx);
4618
 
4619
        if (ad.disp)
4620
          output_addr_const (file, ad.disp);
4621
        else
4622
          fprintf (file, "0");
4623
      }
4624
      return;
4625
 
4626
    case 'R':
4627
      {
4628
        struct s390_address ad;
4629
        int ret;
4630
 
4631
        gcc_assert (GET_CODE (x) == MEM);
4632
        ret = s390_decompose_address (XEXP (x, 0), &ad);
4633
        gcc_assert (ret);
4634
        gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4635
        gcc_assert (!ad.indx);
4636
 
4637
        if (ad.base)
4638
          fprintf (file, "%s", reg_names[REGNO (ad.base)]);
4639
        else
4640
          fprintf (file, "0");
4641
      }
4642
      return;
4643
 
4644
    case 'S':
4645
      {
4646
        struct s390_address ad;
4647
        int ret;
4648
 
4649
        gcc_assert (GET_CODE (x) == MEM);
4650
        ret = s390_decompose_address (XEXP (x, 0), &ad);
4651
        gcc_assert (ret);
4652
        gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4653
        gcc_assert (!ad.indx);
4654
 
4655
        if (ad.disp)
4656
          output_addr_const (file, ad.disp);
4657
        else
4658
          fprintf (file, "0");
4659
 
4660
        if (ad.base)
4661
          fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4662
      }
4663
      return;
4664
 
4665
    case 'N':
4666
      if (GET_CODE (x) == REG)
4667
        x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4668
      else if (GET_CODE (x) == MEM)
4669
        x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
4670
      else
4671
        gcc_unreachable ();
4672
      break;
4673
 
4674
    case 'M':
4675
      if (GET_CODE (x) == REG)
4676
        x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4677
      else if (GET_CODE (x) == MEM)
4678
        x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
4679
      else
4680
        gcc_unreachable ();
4681
      break;
4682
 
4683
    case 'Y':
4684
      print_shift_count_operand (file, x);
4685
      return;
4686
    }
4687
 
4688
  switch (GET_CODE (x))
4689
    {
4690
    case REG:
4691
      fprintf (file, "%s", reg_names[REGNO (x)]);
4692
      break;
4693
 
4694
    case MEM:
4695
      output_address (XEXP (x, 0));
4696
      break;
4697
 
4698
    case CONST:
4699
    case CODE_LABEL:
4700
    case LABEL_REF:
4701
    case SYMBOL_REF:
4702
      output_addr_const (file, x);
4703
      break;
4704
 
4705
    case CONST_INT:
4706
      if (code == 'b')
4707
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
4708
      else if (code == 'x')
4709
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
4710
      else if (code == 'h')
4711
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
4712
      else if (code == 'i')
4713
        fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4714
                 s390_extract_part (x, HImode, 0));
4715
      else if (code == 'j')
4716
        fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4717
                 s390_extract_part (x, HImode, -1));
4718
      else if (code == 'k')
4719
        fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4720
                 s390_extract_part (x, SImode, 0));
4721
      else if (code == 'm')
4722
        fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4723
                 s390_extract_part (x, SImode, -1));
4724
      else if (code == 'o')
4725
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff);
4726
      else
4727
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4728
      break;
4729
 
4730
    case CONST_DOUBLE:
4731
      gcc_assert (GET_MODE (x) == VOIDmode);
4732
      if (code == 'b')
4733
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
4734
      else if (code == 'x')
4735
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
4736
      else if (code == 'h')
4737
        fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
4738
      else
4739
        gcc_unreachable ();
4740
      break;
4741
 
4742
    default:
4743
      fatal_insn ("UNKNOWN in print_operand !?", x);
4744
      break;
4745
    }
4746
}
4747
 
4748
/* Target hook for assembling integer objects.  We need to define it
4749
   here to work a round a bug in some versions of GAS, which couldn't
4750
   handle values smaller than INT_MIN when printed in decimal.  */
4751
 
4752
static bool
4753
s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
4754
{
4755
  if (size == 8 && aligned_p
4756
      && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
4757
    {
4758
      fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
4759
               INTVAL (x));
4760
      return true;
4761
    }
4762
  return default_assemble_integer (x, size, aligned_p);
4763
}
4764
 
4765
/* Returns true if register REGNO is used  for forming
4766
   a memory address in expression X.  */
4767
 
4768
static bool
4769
reg_used_in_mem_p (int regno, rtx x)
4770
{
4771
  enum rtx_code code = GET_CODE (x);
4772
  int i, j;
4773
  const char *fmt;
4774
 
4775
  if (code == MEM)
4776
    {
4777
      if (refers_to_regno_p (regno, regno+1,
4778
                             XEXP (x, 0), 0))
4779
        return true;
4780
    }
4781
  else if (code == SET
4782
           && GET_CODE (SET_DEST (x)) == PC)
4783
    {
4784
      if (refers_to_regno_p (regno, regno+1,
4785
                             SET_SRC (x), 0))
4786
        return true;
4787
    }
4788
 
4789
  fmt = GET_RTX_FORMAT (code);
4790
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4791
    {
4792
      if (fmt[i] == 'e'
4793
          && reg_used_in_mem_p (regno, XEXP (x, i)))
4794
        return true;
4795
 
4796
      else if (fmt[i] == 'E')
4797
        for (j = 0; j < XVECLEN (x, i); j++)
4798
          if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4799
            return true;
4800
    }
4801
  return false;
4802
}
4803
 
4804
/* Returns true if expression DEP_RTX sets an address register
4805
   used by instruction INSN to address memory.  */
4806
 
4807
static bool
4808
addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4809
{
4810
  rtx target, pat;
4811
 
4812
  if (GET_CODE (dep_rtx) == INSN)
4813
      dep_rtx = PATTERN (dep_rtx);
4814
 
4815
  if (GET_CODE (dep_rtx) == SET)
4816
    {
4817
      target = SET_DEST (dep_rtx);
4818
      if (GET_CODE (target) == STRICT_LOW_PART)
4819
        target = XEXP (target, 0);
4820
      while (GET_CODE (target) == SUBREG)
4821
        target = SUBREG_REG (target);
4822
 
4823
      if (GET_CODE (target) == REG)
4824
        {
4825
          int regno = REGNO (target);
4826
 
4827
          if (s390_safe_attr_type (insn) == TYPE_LA)
4828
            {
4829
              pat = PATTERN (insn);
4830
              if (GET_CODE (pat) == PARALLEL)
4831
                {
4832
                  gcc_assert (XVECLEN (pat, 0) == 2);
4833
                  pat = XVECEXP (pat, 0, 0);
4834
                }
4835
              gcc_assert (GET_CODE (pat) == SET);
4836
              return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4837
            }
4838
          else if (get_attr_atype (insn) == ATYPE_AGEN)
4839
            return reg_used_in_mem_p (regno, PATTERN (insn));
4840
        }
4841
    }
4842
  return false;
4843
}
4844
 
4845
/* Return 1, if dep_insn sets register used in insn in the agen unit.  */
4846
 
4847
int
4848
s390_agen_dep_p (rtx dep_insn, rtx insn)
4849
{
4850
  rtx dep_rtx = PATTERN (dep_insn);
4851
  int i;
4852
 
4853
  if (GET_CODE (dep_rtx) == SET
4854
      && addr_generation_dependency_p (dep_rtx, insn))
4855
    return 1;
4856
  else if (GET_CODE (dep_rtx) == PARALLEL)
4857
    {
4858
      for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4859
        {
4860
          if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4861
            return 1;
4862
        }
4863
    }
4864
  return 0;
4865
}
4866
 
4867
/* A C statement (sans semicolon) to update the integer scheduling priority
4868
   INSN_PRIORITY (INSN).  Increase the priority to execute the INSN earlier,
4869
   reduce the priority to execute INSN later.  Do not define this macro if
4870
   you do not need to adjust the scheduling priorities of insns.
4871
 
4872
   A STD instruction should be scheduled earlier,
4873
   in order to use the bypass.  */
4874
 
4875
static int
4876
s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4877
{
4878
  if (! INSN_P (insn))
4879
    return priority;
4880
 
4881
  if (s390_tune != PROCESSOR_2084_Z990
4882
      && s390_tune != PROCESSOR_2094_Z9_109)
4883
    return priority;
4884
 
4885
  switch (s390_safe_attr_type (insn))
4886
    {
4887
      case TYPE_FSTOREDF:
4888
      case TYPE_FSTORESF:
4889
        priority = priority << 3;
4890
        break;
4891
      case TYPE_STORE:
4892
      case TYPE_STM:
4893
        priority = priority << 1;
4894
        break;
4895
      default:
4896
        break;
4897
    }
4898
  return priority;
4899
}
4900
 
4901
/* The number of instructions that can be issued per cycle.  */
4902
 
4903
static int
4904
s390_issue_rate (void)
4905
{
4906
  if (s390_tune == PROCESSOR_2084_Z990
4907
      || s390_tune == PROCESSOR_2094_Z9_109)
4908
    return 3;
4909
  return 1;
4910
}
4911
 
4912
static int
4913
s390_first_cycle_multipass_dfa_lookahead (void)
4914
{
4915
  return 4;
4916
}
4917
 
4918
 
4919
/* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4920
   Fix up MEMs as required.  */
4921
 
4922
static void
4923
annotate_constant_pool_refs (rtx *x)
4924
{
4925
  int i, j;
4926
  const char *fmt;
4927
 
4928
  gcc_assert (GET_CODE (*x) != SYMBOL_REF
4929
              || !CONSTANT_POOL_ADDRESS_P (*x));
4930
 
4931
  /* Literal pool references can only occur inside a MEM ...  */
4932
  if (GET_CODE (*x) == MEM)
4933
    {
4934
      rtx memref = XEXP (*x, 0);
4935
 
4936
      if (GET_CODE (memref) == SYMBOL_REF
4937
          && CONSTANT_POOL_ADDRESS_P (memref))
4938
        {
4939
          rtx base = cfun->machine->base_reg;
4940
          rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4941
                                     UNSPEC_LTREF);
4942
 
4943
          *x = replace_equiv_address (*x, addr);
4944
          return;
4945
        }
4946
 
4947
      if (GET_CODE (memref) == CONST
4948
          && GET_CODE (XEXP (memref, 0)) == PLUS
4949
          && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4950
          && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4951
          && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4952
        {
4953
          HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4954
          rtx sym = XEXP (XEXP (memref, 0), 0);
4955
          rtx base = cfun->machine->base_reg;
4956
          rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4957
                                     UNSPEC_LTREF);
4958
 
4959
          *x = replace_equiv_address (*x, plus_constant (addr, off));
4960
          return;
4961
        }
4962
    }
4963
 
4964
  /* ... or a load-address type pattern.  */
4965
  if (GET_CODE (*x) == SET)
4966
    {
4967
      rtx addrref = SET_SRC (*x);
4968
 
4969
      if (GET_CODE (addrref) == SYMBOL_REF
4970
          && CONSTANT_POOL_ADDRESS_P (addrref))
4971
        {
4972
          rtx base = cfun->machine->base_reg;
4973
          rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4974
                                     UNSPEC_LTREF);
4975
 
4976
          SET_SRC (*x) = addr;
4977
          return;
4978
        }
4979
 
4980
      if (GET_CODE (addrref) == CONST
4981
          && GET_CODE (XEXP (addrref, 0)) == PLUS
4982
          && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4983
          && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4984
          && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4985
        {
4986
          HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4987
          rtx sym = XEXP (XEXP (addrref, 0), 0);
4988
          rtx base = cfun->machine->base_reg;
4989
          rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4990
                                     UNSPEC_LTREF);
4991
 
4992
          SET_SRC (*x) = plus_constant (addr, off);
4993
          return;
4994
        }
4995
    }
4996
 
4997
  /* Annotate LTREL_BASE as well.  */
4998
  if (GET_CODE (*x) == UNSPEC
4999
      && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5000
    {
5001
      rtx base = cfun->machine->base_reg;
5002
      *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
5003
                                  UNSPEC_LTREL_BASE);
5004
      return;
5005
    }
5006
 
5007
  fmt = GET_RTX_FORMAT (GET_CODE (*x));
5008
  for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5009
    {
5010
      if (fmt[i] == 'e')
5011
        {
5012
          annotate_constant_pool_refs (&XEXP (*x, i));
5013
        }
5014
      else if (fmt[i] == 'E')
5015
        {
5016
          for (j = 0; j < XVECLEN (*x, i); j++)
5017
            annotate_constant_pool_refs (&XVECEXP (*x, i, j));
5018
        }
5019
    }
5020
}
5021
 
5022
/* Split all branches that exceed the maximum distance.
5023
   Returns true if this created a new literal pool entry.  */
5024
 
5025
static int
5026
s390_split_branches (void)
5027
{
5028
  rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5029
  int new_literal = 0, ret;
5030
  rtx insn, pat, tmp, target;
5031
  rtx *label;
5032
 
5033
  /* We need correct insn addresses.  */
5034
 
5035
  shorten_branches (get_insns ());
5036
 
5037
  /* Find all branches that exceed 64KB, and split them.  */
5038
 
5039
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5040
    {
5041
      if (GET_CODE (insn) != JUMP_INSN)
5042
        continue;
5043
 
5044
      pat = PATTERN (insn);
5045
      if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5046
        pat = XVECEXP (pat, 0, 0);
5047
      if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
5048
        continue;
5049
 
5050
      if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
5051
        {
5052
          label = &SET_SRC (pat);
5053
        }
5054
      else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
5055
        {
5056
          if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
5057
            label = &XEXP (SET_SRC (pat), 1);
5058
          else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
5059
            label = &XEXP (SET_SRC (pat), 2);
5060
          else
5061
            continue;
5062
        }
5063
      else
5064
        continue;
5065
 
5066
      if (get_attr_length (insn) <= 4)
5067
        continue;
5068
 
5069
      /* We are going to use the return register as scratch register,
5070
         make sure it will be saved/restored by the prologue/epilogue.  */
5071
      cfun_frame_layout.save_return_addr_p = 1;
5072
 
5073
      if (!flag_pic)
5074
        {
5075
          new_literal = 1;
5076
          tmp = force_const_mem (Pmode, *label);
5077
          tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
5078
          INSN_ADDRESSES_NEW (tmp, -1);
5079
          annotate_constant_pool_refs (&PATTERN (tmp));
5080
 
5081
          target = temp_reg;
5082
        }
5083
      else
5084
        {
5085
          new_literal = 1;
5086
          target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
5087
                                   UNSPEC_LTREL_OFFSET);
5088
          target = gen_rtx_CONST (Pmode, target);
5089
          target = force_const_mem (Pmode, target);
5090
          tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
5091
          INSN_ADDRESSES_NEW (tmp, -1);
5092
          annotate_constant_pool_refs (&PATTERN (tmp));
5093
 
5094
          target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
5095
                                                        cfun->machine->base_reg),
5096
                                   UNSPEC_LTREL_BASE);
5097
          target = gen_rtx_PLUS (Pmode, temp_reg, target);
5098
        }
5099
 
5100
      ret = validate_change (insn, label, target, 0);
5101
      gcc_assert (ret);
5102
    }
5103
 
5104
  return new_literal;
5105
}
5106
 
5107
 
5108
/* Find an annotated literal pool symbol referenced in RTX X,
5109
   and store it at REF.  Will abort if X contains references to
5110
   more than one such pool symbol; multiple references to the same
5111
   symbol are allowed, however.
5112
 
5113
   The rtx pointed to by REF must be initialized to NULL_RTX
5114
   by the caller before calling this routine.  */
5115
 
5116
static void
5117
find_constant_pool_ref (rtx x, rtx *ref)
5118
{
5119
  int i, j;
5120
  const char *fmt;
5121
 
5122
  /* Ignore LTREL_BASE references.  */
5123
  if (GET_CODE (x) == UNSPEC
5124
      && XINT (x, 1) == UNSPEC_LTREL_BASE)
5125
    return;
5126
  /* Likewise POOL_ENTRY insns.  */
5127
  if (GET_CODE (x) == UNSPEC_VOLATILE
5128
      && XINT (x, 1) == UNSPECV_POOL_ENTRY)
5129
    return;
5130
 
5131
  gcc_assert (GET_CODE (x) != SYMBOL_REF
5132
              || !CONSTANT_POOL_ADDRESS_P (x));
5133
 
5134
  if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
5135
    {
5136
      rtx sym = XVECEXP (x, 0, 0);
5137
      gcc_assert (GET_CODE (sym) == SYMBOL_REF
5138
                  && CONSTANT_POOL_ADDRESS_P (sym));
5139
 
5140
      if (*ref == NULL_RTX)
5141
        *ref = sym;
5142
      else
5143
        gcc_assert (*ref == sym);
5144
 
5145
      return;
5146
    }
5147
 
5148
  fmt = GET_RTX_FORMAT (GET_CODE (x));
5149
  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5150
    {
5151
      if (fmt[i] == 'e')
5152
        {
5153
          find_constant_pool_ref (XEXP (x, i), ref);
5154
        }
5155
      else if (fmt[i] == 'E')
5156
        {
5157
          for (j = 0; j < XVECLEN (x, i); j++)
5158
            find_constant_pool_ref (XVECEXP (x, i, j), ref);
5159
        }
5160
    }
5161
}
5162
 
5163
/* Replace every reference to the annotated literal pool
5164
   symbol REF in X by its base plus OFFSET.  */
5165
 
5166
static void
5167
replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
5168
{
5169
  int i, j;
5170
  const char *fmt;
5171
 
5172
  gcc_assert (*x != ref);
5173
 
5174
  if (GET_CODE (*x) == UNSPEC
5175
      && XINT (*x, 1) == UNSPEC_LTREF
5176
      && XVECEXP (*x, 0, 0) == ref)
5177
    {
5178
      *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
5179
      return;
5180
    }
5181
 
5182
  if (GET_CODE (*x) == PLUS
5183
      && GET_CODE (XEXP (*x, 1)) == CONST_INT
5184
      && GET_CODE (XEXP (*x, 0)) == UNSPEC
5185
      && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
5186
      && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
5187
    {
5188
      rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
5189
      *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
5190
      return;
5191
    }
5192
 
5193
  fmt = GET_RTX_FORMAT (GET_CODE (*x));
5194
  for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5195
    {
5196
      if (fmt[i] == 'e')
5197
        {
5198
          replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
5199
        }
5200
      else if (fmt[i] == 'E')
5201
        {
5202
          for (j = 0; j < XVECLEN (*x, i); j++)
5203
            replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
5204
        }
5205
    }
5206
}
5207
 
5208
/* Check whether X contains an UNSPEC_LTREL_BASE.
5209
   Return its constant pool symbol if found, NULL_RTX otherwise.  */
5210
 
5211
static rtx
5212
find_ltrel_base (rtx x)
5213
{
5214
  int i, j;
5215
  const char *fmt;
5216
 
5217
  if (GET_CODE (x) == UNSPEC
5218
      && XINT (x, 1) == UNSPEC_LTREL_BASE)
5219
    return XVECEXP (x, 0, 0);
5220
 
5221
  fmt = GET_RTX_FORMAT (GET_CODE (x));
5222
  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5223
    {
5224
      if (fmt[i] == 'e')
5225
        {
5226
          rtx fnd = find_ltrel_base (XEXP (x, i));
5227
          if (fnd)
5228
            return fnd;
5229
        }
5230
      else if (fmt[i] == 'E')
5231
        {
5232
          for (j = 0; j < XVECLEN (x, i); j++)
5233
            {
5234
              rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
5235
              if (fnd)
5236
                return fnd;
5237
            }
5238
        }
5239
    }
5240
 
5241
  return NULL_RTX;
5242
}
5243
 
5244
/* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base.  */
5245
 
5246
static void
5247
replace_ltrel_base (rtx *x)
5248
{
5249
  int i, j;
5250
  const char *fmt;
5251
 
5252
  if (GET_CODE (*x) == UNSPEC
5253
      && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5254
    {
5255
      *x = XVECEXP (*x, 0, 1);
5256
      return;
5257
    }
5258
 
5259
  fmt = GET_RTX_FORMAT (GET_CODE (*x));
5260
  for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5261
    {
5262
      if (fmt[i] == 'e')
5263
        {
5264
          replace_ltrel_base (&XEXP (*x, i));
5265
        }
5266
      else if (fmt[i] == 'E')
5267
        {
5268
          for (j = 0; j < XVECLEN (*x, i); j++)
5269
            replace_ltrel_base (&XVECEXP (*x, i, j));
5270
        }
5271
    }
5272
}
5273
 
5274
 
5275
/* We keep a list of constants which we have to add to internal
5276
   constant tables in the middle of large functions.  */
5277
 
5278
#define NR_C_MODES 11
5279
enum machine_mode constant_modes[NR_C_MODES] =
5280
{
5281
  TFmode, TImode, TDmode,
5282
  DFmode, DImode, DDmode,
5283
  SFmode, SImode, SDmode,
5284
  HImode,
5285
  QImode
5286
};
5287
 
5288
struct constant
5289
{
5290
  struct constant *next;
5291
  rtx value;
5292
  rtx label;
5293
};
5294
 
5295
struct constant_pool
5296
{
5297
  struct constant_pool *next;
5298
  rtx first_insn;
5299
  rtx pool_insn;
5300
  bitmap insns;
5301
 
5302
  struct constant *constants[NR_C_MODES];
5303
  struct constant *execute;
5304
  rtx label;
5305
  int size;
5306
};
5307
 
5308
/* Allocate new constant_pool structure.  */
5309
 
5310
static struct constant_pool *
5311
s390_alloc_pool (void)
5312
{
5313
  struct constant_pool *pool;
5314
  int i;
5315
 
5316
  pool = (struct constant_pool *) xmalloc (sizeof *pool);
5317
  pool->next = NULL;
5318
  for (i = 0; i < NR_C_MODES; i++)
5319
    pool->constants[i] = NULL;
5320
 
5321
  pool->execute = NULL;
5322
  pool->label = gen_label_rtx ();
5323
  pool->first_insn = NULL_RTX;
5324
  pool->pool_insn = NULL_RTX;
5325
  pool->insns = BITMAP_ALLOC (NULL);
5326
  pool->size = 0;
5327
 
5328
  return pool;
5329
}
5330
 
5331
/* Create new constant pool covering instructions starting at INSN
5332
   and chain it to the end of POOL_LIST.  */
5333
 
5334
static struct constant_pool *
5335
s390_start_pool (struct constant_pool **pool_list, rtx insn)
5336
{
5337
  struct constant_pool *pool, **prev;
5338
 
5339
  pool = s390_alloc_pool ();
5340
  pool->first_insn = insn;
5341
 
5342
  for (prev = pool_list; *prev; prev = &(*prev)->next)
5343
    ;
5344
  *prev = pool;
5345
 
5346
  return pool;
5347
}
5348
 
5349
/* End range of instructions covered by POOL at INSN and emit
5350
   placeholder insn representing the pool.  */
5351
 
5352
static void
5353
s390_end_pool (struct constant_pool *pool, rtx insn)
5354
{
5355
  rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
5356
 
5357
  if (!insn)
5358
    insn = get_last_insn ();
5359
 
5360
  pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
5361
  INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5362
}
5363
 
5364
/* Add INSN to the list of insns covered by POOL.  */
5365
 
5366
static void
5367
s390_add_pool_insn (struct constant_pool *pool, rtx insn)
5368
{
5369
  bitmap_set_bit (pool->insns, INSN_UID (insn));
5370
}
5371
 
5372
/* Return pool out of POOL_LIST that covers INSN.  */
5373
 
5374
static struct constant_pool *
5375
s390_find_pool (struct constant_pool *pool_list, rtx insn)
5376
{
5377
  struct constant_pool *pool;
5378
 
5379
  for (pool = pool_list; pool; pool = pool->next)
5380
    if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
5381
      break;
5382
 
5383
  return pool;
5384
}
5385
 
5386
/* Add constant VAL of mode MODE to the constant pool POOL.  */
5387
 
5388
static void
5389
s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
5390
{
5391
  struct constant *c;
5392
  int i;
5393
 
5394
  for (i = 0; i < NR_C_MODES; i++)
5395
    if (constant_modes[i] == mode)
5396
      break;
5397
  gcc_assert (i != NR_C_MODES);
5398
 
5399
  for (c = pool->constants[i]; c != NULL; c = c->next)
5400
    if (rtx_equal_p (val, c->value))
5401
      break;
5402
 
5403
  if (c == NULL)
5404
    {
5405
      c = (struct constant *) xmalloc (sizeof *c);
5406
      c->value = val;
5407
      c->label = gen_label_rtx ();
5408
      c->next = pool->constants[i];
5409
      pool->constants[i] = c;
5410
      pool->size += GET_MODE_SIZE (mode);
5411
    }
5412
}
5413
 
5414
/* Find constant VAL of mode MODE in the constant pool POOL.
5415
   Return an RTX describing the distance from the start of
5416
   the pool to the location of the new constant.  */
5417
 
5418
static rtx
5419
s390_find_constant (struct constant_pool *pool, rtx val,
5420
                    enum machine_mode mode)
5421
{
5422
  struct constant *c;
5423
  rtx offset;
5424
  int i;
5425
 
5426
  for (i = 0; i < NR_C_MODES; i++)
5427
    if (constant_modes[i] == mode)
5428
      break;
5429
  gcc_assert (i != NR_C_MODES);
5430
 
5431
  for (c = pool->constants[i]; c != NULL; c = c->next)
5432
    if (rtx_equal_p (val, c->value))
5433
      break;
5434
 
5435
  gcc_assert (c);
5436
 
5437
  offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5438
                                 gen_rtx_LABEL_REF (Pmode, pool->label));
5439
  offset = gen_rtx_CONST (Pmode, offset);
5440
  return offset;
5441
}
5442
 
5443
/* Check whether INSN is an execute.  Return the label_ref to its
5444
   execute target template if so, NULL_RTX otherwise.  */
5445
 
5446
static rtx
5447
s390_execute_label (rtx insn)
5448
{
5449
  if (GET_CODE (insn) == INSN
5450
      && GET_CODE (PATTERN (insn)) == PARALLEL
5451
      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
5452
      && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
5453
    return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
5454
 
5455
  return NULL_RTX;
5456
}
5457
 
5458
/* Add execute target for INSN to the constant pool POOL.  */
5459
 
5460
static void
5461
s390_add_execute (struct constant_pool *pool, rtx insn)
5462
{
5463
  struct constant *c;
5464
 
5465
  for (c = pool->execute; c != NULL; c = c->next)
5466
    if (INSN_UID (insn) == INSN_UID (c->value))
5467
      break;
5468
 
5469
  if (c == NULL)
5470
    {
5471
      c = (struct constant *) xmalloc (sizeof *c);
5472
      c->value = insn;
5473
      c->label = gen_label_rtx ();
5474
      c->next = pool->execute;
5475
      pool->execute = c;
5476
      pool->size += 6;
5477
    }
5478
}
5479
 
5480
/* Find execute target for INSN in the constant pool POOL.
5481
   Return an RTX describing the distance from the start of
5482
   the pool to the location of the execute target.  */
5483
 
5484
static rtx
5485
s390_find_execute (struct constant_pool *pool, rtx insn)
5486
{
5487
  struct constant *c;
5488
  rtx offset;
5489
 
5490
  for (c = pool->execute; c != NULL; c = c->next)
5491
    if (INSN_UID (insn) == INSN_UID (c->value))
5492
      break;
5493
 
5494
  gcc_assert (c);
5495
 
5496
  offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5497
                                 gen_rtx_LABEL_REF (Pmode, pool->label));
5498
  offset = gen_rtx_CONST (Pmode, offset);
5499
  return offset;
5500
}
5501
 
5502
/* For an execute INSN, extract the execute target template.  */
5503
 
5504
static rtx
5505
s390_execute_target (rtx insn)
5506
{
5507
  rtx pattern = PATTERN (insn);
5508
  gcc_assert (s390_execute_label (insn));
5509
 
5510
  if (XVECLEN (pattern, 0) == 2)
5511
    {
5512
      pattern = copy_rtx (XVECEXP (pattern, 0, 1));
5513
    }
5514
  else
5515
    {
5516
      rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
5517
      int i;
5518
 
5519
      for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
5520
        RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
5521
 
5522
      pattern = gen_rtx_PARALLEL (VOIDmode, vec);
5523
    }
5524
 
5525
  return pattern;
5526
}
5527
 
5528
/* Indicate that INSN cannot be duplicated.  This is the case for
5529
   execute insns that carry a unique label.  */
5530
 
5531
static bool
5532
s390_cannot_copy_insn_p (rtx insn)
5533
{
5534
  rtx label = s390_execute_label (insn);
5535
  return label && label != const0_rtx;
5536
}
5537
 
5538
/* Dump out the constants in POOL.  If REMOTE_LABEL is true,
5539
   do not emit the pool base label.  */
5540
 
5541
static void
5542
s390_dump_pool (struct constant_pool *pool, bool remote_label)
5543
{
5544
  struct constant *c;
5545
  rtx insn = pool->pool_insn;
5546
  int i;
5547
 
5548
  /* Switch to rodata section.  */
5549
  if (TARGET_CPU_ZARCH)
5550
    {
5551
      insn = emit_insn_after (gen_pool_section_start (), insn);
5552
      INSN_ADDRESSES_NEW (insn, -1);
5553
    }
5554
 
5555
  /* Ensure minimum pool alignment.  */
5556
  if (TARGET_CPU_ZARCH)
5557
    insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
5558
  else
5559
    insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
5560
  INSN_ADDRESSES_NEW (insn, -1);
5561
 
5562
  /* Emit pool base label.  */
5563
  if (!remote_label)
5564
    {
5565
      insn = emit_label_after (pool->label, insn);
5566
      INSN_ADDRESSES_NEW (insn, -1);
5567
    }
5568
 
5569
  /* Dump constants in descending alignment requirement order,
5570
     ensuring proper alignment for every constant.  */
5571
  for (i = 0; i < NR_C_MODES; i++)
5572
    for (c = pool->constants[i]; c; c = c->next)
5573
      {
5574
        /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references.  */
5575
        rtx value = c->value;
5576
        if (GET_CODE (value) == CONST
5577
            && GET_CODE (XEXP (value, 0)) == UNSPEC
5578
            && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
5579
            && XVECLEN (XEXP (value, 0), 0) == 1)
5580
          {
5581
            value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
5582
                                   gen_rtx_LABEL_REF (VOIDmode, pool->label));
5583
            value = gen_rtx_CONST (VOIDmode, value);
5584
          }
5585
 
5586
        insn = emit_label_after (c->label, insn);
5587
        INSN_ADDRESSES_NEW (insn, -1);
5588
 
5589
        value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
5590
                                         gen_rtvec (1, value),
5591
                                         UNSPECV_POOL_ENTRY);
5592
        insn = emit_insn_after (value, insn);
5593
        INSN_ADDRESSES_NEW (insn, -1);
5594
      }
5595
 
5596
  /* Ensure minimum alignment for instructions.  */
5597
  insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
5598
  INSN_ADDRESSES_NEW (insn, -1);
5599
 
5600
  /* Output in-pool execute template insns.  */
5601
  for (c = pool->execute; c; c = c->next)
5602
    {
5603
      insn = emit_label_after (c->label, insn);
5604
      INSN_ADDRESSES_NEW (insn, -1);
5605
 
5606
      insn = emit_insn_after (s390_execute_target (c->value), insn);
5607
      INSN_ADDRESSES_NEW (insn, -1);
5608
    }
5609
 
5610
  /* Switch back to previous section.  */
5611
  if (TARGET_CPU_ZARCH)
5612
    {
5613
      insn = emit_insn_after (gen_pool_section_end (), insn);
5614
      INSN_ADDRESSES_NEW (insn, -1);
5615
    }
5616
 
5617
  insn = emit_barrier_after (insn);
5618
  INSN_ADDRESSES_NEW (insn, -1);
5619
 
5620
  /* Remove placeholder insn.  */
5621
  remove_insn (pool->pool_insn);
5622
}
5623
 
5624
/* Free all memory used by POOL.  */
5625
 
5626
static void
5627
s390_free_pool (struct constant_pool *pool)
5628
{
5629
  struct constant *c, *next;
5630
  int i;
5631
 
5632
  for (i = 0; i < NR_C_MODES; i++)
5633
    for (c = pool->constants[i]; c; c = next)
5634
      {
5635
        next = c->next;
5636
        free (c);
5637
      }
5638
 
5639
  for (c = pool->execute; c; c = next)
5640
    {
5641
      next = c->next;
5642
      free (c);
5643
    }
5644
 
5645
  BITMAP_FREE (pool->insns);
5646
  free (pool);
5647
}
5648
 
5649
 
5650
/* Collect main literal pool.  Return NULL on overflow.  */
5651
 
5652
static struct constant_pool *
5653
s390_mainpool_start (void)
5654
{
5655
  struct constant_pool *pool;
5656
  rtx insn;
5657
 
5658
  pool = s390_alloc_pool ();
5659
 
5660
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5661
    {
5662
      if (GET_CODE (insn) == INSN
5663
          && GET_CODE (PATTERN (insn)) == SET
5664
          && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
5665
          && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
5666
        {
5667
          gcc_assert (!pool->pool_insn);
5668
          pool->pool_insn = insn;
5669
        }
5670
 
5671
      if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5672
        {
5673
          s390_add_execute (pool, insn);
5674
        }
5675
      else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5676
        {
5677
          rtx pool_ref = NULL_RTX;
5678
          find_constant_pool_ref (PATTERN (insn), &pool_ref);
5679
          if (pool_ref)
5680
            {
5681
              rtx constant = get_pool_constant (pool_ref);
5682
              enum machine_mode mode = get_pool_mode (pool_ref);
5683
              s390_add_constant (pool, constant, mode);
5684
            }
5685
        }
5686
    }
5687
 
5688
  gcc_assert (pool->pool_insn || pool->size == 0);
5689
 
5690
  if (pool->size >= 4096)
5691
    {
5692
      /* We're going to chunkify the pool, so remove the main
5693
         pool placeholder insn.  */
5694
      remove_insn (pool->pool_insn);
5695
 
5696
      s390_free_pool (pool);
5697
      pool = NULL;
5698
    }
5699
 
5700
  return pool;
5701
}
5702
 
5703
/* POOL holds the main literal pool as collected by s390_mainpool_start.
5704
   Modify the current function to output the pool constants as well as
5705
   the pool register setup instruction.  */
5706
 
5707
static void
5708
s390_mainpool_finish (struct constant_pool *pool)
5709
{
5710
  rtx base_reg = cfun->machine->base_reg;
5711
  rtx insn;
5712
 
5713
  /* If the pool is empty, we're done.  */
5714
  if (pool->size == 0)
5715
    {
5716
      /* We don't actually need a base register after all.  */
5717
      cfun->machine->base_reg = NULL_RTX;
5718
 
5719
      if (pool->pool_insn)
5720
        remove_insn (pool->pool_insn);
5721
      s390_free_pool (pool);
5722
      return;
5723
    }
5724
 
5725
  /* We need correct insn addresses.  */
5726
  shorten_branches (get_insns ());
5727
 
5728
  /* On zSeries, we use a LARL to load the pool register.  The pool is
5729
     located in the .rodata section, so we emit it after the function.  */
5730
  if (TARGET_CPU_ZARCH)
5731
    {
5732
      insn = gen_main_base_64 (base_reg, pool->label);
5733
      insn = emit_insn_after (insn, pool->pool_insn);
5734
      INSN_ADDRESSES_NEW (insn, -1);
5735
      remove_insn (pool->pool_insn);
5736
 
5737
      insn = get_last_insn ();
5738
      pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5739
      INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5740
 
5741
      s390_dump_pool (pool, 0);
5742
    }
5743
 
5744
  /* On S/390, if the total size of the function's code plus literal pool
5745
     does not exceed 4096 bytes, we use BASR to set up a function base
5746
     pointer, and emit the literal pool at the end of the function.  */
5747
  else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5748
           + pool->size + 8 /* alignment slop */ < 4096)
5749
    {
5750
      insn = gen_main_base_31_small (base_reg, pool->label);
5751
      insn = emit_insn_after (insn, pool->pool_insn);
5752
      INSN_ADDRESSES_NEW (insn, -1);
5753
      remove_insn (pool->pool_insn);
5754
 
5755
      insn = emit_label_after (pool->label, insn);
5756
      INSN_ADDRESSES_NEW (insn, -1);
5757
 
5758
      insn = get_last_insn ();
5759
      pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5760
      INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5761
 
5762
      s390_dump_pool (pool, 1);
5763
    }
5764
 
5765
  /* Otherwise, we emit an inline literal pool and use BASR to branch
5766
     over it, setting up the pool register at the same time.  */
5767
  else
5768
    {
5769
      rtx pool_end = gen_label_rtx ();
5770
 
5771
      insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
5772
      insn = emit_insn_after (insn, pool->pool_insn);
5773
      INSN_ADDRESSES_NEW (insn, -1);
5774
      remove_insn (pool->pool_insn);
5775
 
5776
      insn = emit_label_after (pool->label, insn);
5777
      INSN_ADDRESSES_NEW (insn, -1);
5778
 
5779
      pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5780
      INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5781
 
5782
      insn = emit_label_after (pool_end, pool->pool_insn);
5783
      INSN_ADDRESSES_NEW (insn, -1);
5784
 
5785
      s390_dump_pool (pool, 1);
5786
    }
5787
 
5788
 
5789
  /* Replace all literal pool references.  */
5790
 
5791
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5792
    {
5793
      if (INSN_P (insn))
5794
        replace_ltrel_base (&PATTERN (insn));
5795
 
5796
      if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5797
        {
5798
          rtx addr, pool_ref = NULL_RTX;
5799
          find_constant_pool_ref (PATTERN (insn), &pool_ref);
5800
          if (pool_ref)
5801
            {
5802
              if (s390_execute_label (insn))
5803
                addr = s390_find_execute (pool, insn);
5804
              else
5805
                addr = s390_find_constant (pool, get_pool_constant (pool_ref),
5806
                                                 get_pool_mode (pool_ref));
5807
 
5808
              replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5809
              INSN_CODE (insn) = -1;
5810
            }
5811
        }
5812
    }
5813
 
5814
 
5815
  /* Free the pool.  */
5816
  s390_free_pool (pool);
5817
}
5818
 
5819
/* POOL holds the main literal pool as collected by s390_mainpool_start.
5820
   We have decided we cannot use this pool, so revert all changes
5821
   to the current function that were done by s390_mainpool_start.  */
5822
static void
5823
s390_mainpool_cancel (struct constant_pool *pool)
5824
{
5825
  /* We didn't actually change the instruction stream, so simply
5826
     free the pool memory.  */
5827
  s390_free_pool (pool);
5828
}
5829
 
5830
 
5831
/* Chunkify the literal pool.  */
5832
 
5833
#define S390_POOL_CHUNK_MIN     0xc00
5834
#define S390_POOL_CHUNK_MAX     0xe00
5835
 
5836
static struct constant_pool *
5837
s390_chunkify_start (void)
5838
{
5839
  struct constant_pool *curr_pool = NULL, *pool_list = NULL;
5840
  int extra_size = 0;
5841
  bitmap far_labels;
5842
  rtx pending_ltrel = NULL_RTX;
5843
  rtx insn;
5844
 
5845
  rtx (*gen_reload_base) (rtx, rtx) =
5846
    TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
5847
 
5848
 
5849
  /* We need correct insn addresses.  */
5850
 
5851
  shorten_branches (get_insns ());
5852
 
5853
  /* Scan all insns and move literals to pool chunks.  */
5854
 
5855
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5856
    {
5857
      /* Check for pending LTREL_BASE.  */
5858
      if (INSN_P (insn))
5859
        {
5860
          rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5861
          if (ltrel_base)
5862
            {
5863
              gcc_assert (ltrel_base == pending_ltrel);
5864
              pending_ltrel = NULL_RTX;
5865
            }
5866
        }
5867
 
5868
      if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5869
        {
5870
          if (!curr_pool)
5871
            curr_pool = s390_start_pool (&pool_list, insn);
5872
 
5873
          s390_add_execute (curr_pool, insn);
5874
          s390_add_pool_insn (curr_pool, insn);
5875
        }
5876
      else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5877
        {
5878
          rtx pool_ref = NULL_RTX;
5879
          find_constant_pool_ref (PATTERN (insn), &pool_ref);
5880
          if (pool_ref)
5881
            {
5882
              rtx constant = get_pool_constant (pool_ref);
5883
              enum machine_mode mode = get_pool_mode (pool_ref);
5884
 
5885
              if (!curr_pool)
5886
                curr_pool = s390_start_pool (&pool_list, insn);
5887
 
5888
              s390_add_constant (curr_pool, constant, mode);
5889
              s390_add_pool_insn (curr_pool, insn);
5890
 
5891
              /* Don't split the pool chunk between a LTREL_OFFSET load
5892
                 and the corresponding LTREL_BASE.  */
5893
              if (GET_CODE (constant) == CONST
5894
                  && GET_CODE (XEXP (constant, 0)) == UNSPEC
5895
                  && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5896
                {
5897
                  gcc_assert (!pending_ltrel);
5898
                  pending_ltrel = pool_ref;
5899
                }
5900
            }
5901
        }
5902
 
5903
      if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5904
        {
5905
          if (curr_pool)
5906
            s390_add_pool_insn (curr_pool, insn);
5907
          /* An LTREL_BASE must follow within the same basic block.  */
5908
          gcc_assert (!pending_ltrel);
5909
        }
5910
 
5911
      if (!curr_pool
5912
          || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5913
          || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5914
        continue;
5915
 
5916
      if (TARGET_CPU_ZARCH)
5917
        {
5918
          if (curr_pool->size < S390_POOL_CHUNK_MAX)
5919
            continue;
5920
 
5921
          s390_end_pool (curr_pool, NULL_RTX);
5922
          curr_pool = NULL;
5923
        }
5924
      else
5925
        {
5926
          int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5927
                           - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5928
                         + extra_size;
5929
 
5930
          /* We will later have to insert base register reload insns.
5931
             Those will have an effect on code size, which we need to
5932
             consider here.  This calculation makes rather pessimistic
5933
             worst-case assumptions.  */
5934
          if (GET_CODE (insn) == CODE_LABEL)
5935
            extra_size += 6;
5936
 
5937
          if (chunk_size < S390_POOL_CHUNK_MIN
5938
              && curr_pool->size < S390_POOL_CHUNK_MIN)
5939
            continue;
5940
 
5941
          /* Pool chunks can only be inserted after BARRIERs ...  */
5942
          if (GET_CODE (insn) == BARRIER)
5943
            {
5944
              s390_end_pool (curr_pool, insn);
5945
              curr_pool = NULL;
5946
              extra_size = 0;
5947
            }
5948
 
5949
          /* ... so if we don't find one in time, create one.  */
5950
          else if ((chunk_size > S390_POOL_CHUNK_MAX
5951
                   || curr_pool->size > S390_POOL_CHUNK_MAX))
5952
            {
5953
              rtx label, jump, barrier;
5954
 
5955
              /* We can insert the barrier only after a 'real' insn.  */
5956
              if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5957
                continue;
5958
              if (get_attr_length (insn) == 0)
5959
                continue;
5960
 
5961
              /* Don't separate LTREL_BASE from the corresponding
5962
                 LTREL_OFFSET load.  */
5963
              if (pending_ltrel)
5964
                continue;
5965
 
5966
              label = gen_label_rtx ();
5967
              jump = emit_jump_insn_after (gen_jump (label), insn);
5968
              barrier = emit_barrier_after (jump);
5969
              insn = emit_label_after (label, barrier);
5970
              JUMP_LABEL (jump) = label;
5971
              LABEL_NUSES (label) = 1;
5972
 
5973
              INSN_ADDRESSES_NEW (jump, -1);
5974
              INSN_ADDRESSES_NEW (barrier, -1);
5975
              INSN_ADDRESSES_NEW (insn, -1);
5976
 
5977
              s390_end_pool (curr_pool, barrier);
5978
              curr_pool = NULL;
5979
              extra_size = 0;
5980
            }
5981
        }
5982
    }
5983
 
5984
  if (curr_pool)
5985
    s390_end_pool (curr_pool, NULL_RTX);
5986
  gcc_assert (!pending_ltrel);
5987
 
5988
  /* Find all labels that are branched into
5989
     from an insn belonging to a different chunk.  */
5990
 
5991
  far_labels = BITMAP_ALLOC (NULL);
5992
 
5993
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5994
    {
5995
      /* Labels marked with LABEL_PRESERVE_P can be target
5996
         of non-local jumps, so we have to mark them.
5997
         The same holds for named labels.
5998
 
5999
         Don't do that, however, if it is the label before
6000
         a jump table.  */
6001
 
6002
      if (GET_CODE (insn) == CODE_LABEL
6003
          && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
6004
        {
6005
          rtx vec_insn = next_real_insn (insn);
6006
          rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6007
                        PATTERN (vec_insn) : NULL_RTX;
6008
          if (!vec_pat
6009
              || !(GET_CODE (vec_pat) == ADDR_VEC
6010
                   || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6011
            bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
6012
        }
6013
 
6014
      /* If we have a direct jump (conditional or unconditional)
6015
         or a casesi jump, check all potential targets.  */
6016
      else if (GET_CODE (insn) == JUMP_INSN)
6017
        {
6018
          rtx pat = PATTERN (insn);
6019
          if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
6020
            pat = XVECEXP (pat, 0, 0);
6021
 
6022
          if (GET_CODE (pat) == SET)
6023
            {
6024
              rtx label = JUMP_LABEL (insn);
6025
              if (label)
6026
                {
6027
                  if (s390_find_pool (pool_list, label)
6028
                      != s390_find_pool (pool_list, insn))
6029
                    bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6030
                }
6031
            }
6032
          else if (GET_CODE (pat) == PARALLEL
6033
                   && XVECLEN (pat, 0) == 2
6034
                   && GET_CODE (XVECEXP (pat, 0, 0)) == SET
6035
                   && GET_CODE (XVECEXP (pat, 0, 1)) == USE
6036
                   && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
6037
            {
6038
              /* Find the jump table used by this casesi jump.  */
6039
              rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
6040
              rtx vec_insn = next_real_insn (vec_label);
6041
              rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6042
                            PATTERN (vec_insn) : NULL_RTX;
6043
              if (vec_pat
6044
                  && (GET_CODE (vec_pat) == ADDR_VEC
6045
                      || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6046
                {
6047
                  int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
6048
 
6049
                  for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
6050
                    {
6051
                      rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
6052
 
6053
                      if (s390_find_pool (pool_list, label)
6054
                          != s390_find_pool (pool_list, insn))
6055
                        bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6056
                    }
6057
                }
6058
            }
6059
        }
6060
    }
6061
 
6062
  /* Insert base register reload insns before every pool.  */
6063
 
6064
  for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6065
    {
6066
      rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6067
                                      curr_pool->label);
6068
      rtx insn = curr_pool->first_insn;
6069
      INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
6070
    }
6071
 
6072
  /* Insert base register reload insns at every far label.  */
6073
 
6074
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6075
    if (GET_CODE (insn) == CODE_LABEL
6076
        && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
6077
      {
6078
        struct constant_pool *pool = s390_find_pool (pool_list, insn);
6079
        if (pool)
6080
          {
6081
            rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6082
                                            pool->label);
6083
            INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
6084
          }
6085
      }
6086
 
6087
 
6088
  BITMAP_FREE (far_labels);
6089
 
6090
 
6091
  /* Recompute insn addresses.  */
6092
 
6093
  init_insn_lengths ();
6094
  shorten_branches (get_insns ());
6095
 
6096
  return pool_list;
6097
}
6098
 
6099
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6100
   After we have decided to use this list, finish implementing
6101
   all changes to the current function as required.  */
6102
 
6103
static void
6104
s390_chunkify_finish (struct constant_pool *pool_list)
6105
{
6106
  struct constant_pool *curr_pool = NULL;
6107
  rtx insn;
6108
 
6109
 
6110
  /* Replace all literal pool references.  */
6111
 
6112
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6113
    {
6114
      if (INSN_P (insn))
6115
        replace_ltrel_base (&PATTERN (insn));
6116
 
6117
      curr_pool = s390_find_pool (pool_list, insn);
6118
      if (!curr_pool)
6119
        continue;
6120
 
6121
      if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6122
        {
6123
          rtx addr, pool_ref = NULL_RTX;
6124
          find_constant_pool_ref (PATTERN (insn), &pool_ref);
6125
          if (pool_ref)
6126
            {
6127
              if (s390_execute_label (insn))
6128
                addr = s390_find_execute (curr_pool, insn);
6129
              else
6130
                addr = s390_find_constant (curr_pool,
6131
                                           get_pool_constant (pool_ref),
6132
                                           get_pool_mode (pool_ref));
6133
 
6134
              replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
6135
              INSN_CODE (insn) = -1;
6136
            }
6137
        }
6138
    }
6139
 
6140
  /* Dump out all literal pools.  */
6141
 
6142
  for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6143
    s390_dump_pool (curr_pool, 0);
6144
 
6145
  /* Free pool list.  */
6146
 
6147
  while (pool_list)
6148
    {
6149
      struct constant_pool *next = pool_list->next;
6150
      s390_free_pool (pool_list);
6151
      pool_list = next;
6152
    }
6153
}
6154
 
6155
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6156
   We have decided we cannot use this list, so revert all changes
6157
   to the current function that were done by s390_chunkify_start.  */
6158
 
6159
static void
6160
s390_chunkify_cancel (struct constant_pool *pool_list)
6161
{
6162
  struct constant_pool *curr_pool = NULL;
6163
  rtx insn;
6164
 
6165
  /* Remove all pool placeholder insns.  */
6166
 
6167
  for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6168
    {
6169
      /* Did we insert an extra barrier?  Remove it.  */
6170
      rtx barrier = PREV_INSN (curr_pool->pool_insn);
6171
      rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
6172
      rtx label = NEXT_INSN (curr_pool->pool_insn);
6173
 
6174
      if (jump && GET_CODE (jump) == JUMP_INSN
6175
          && barrier && GET_CODE (barrier) == BARRIER
6176
          && label && GET_CODE (label) == CODE_LABEL
6177
          && GET_CODE (PATTERN (jump)) == SET
6178
          && SET_DEST (PATTERN (jump)) == pc_rtx
6179
          && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
6180
          && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
6181
        {
6182
          remove_insn (jump);
6183
          remove_insn (barrier);
6184
          remove_insn (label);
6185
        }
6186
 
6187
      remove_insn (curr_pool->pool_insn);
6188
    }
6189
 
6190
  /* Remove all base register reload insns.  */
6191
 
6192
  for (insn = get_insns (); insn; )
6193
    {
6194
      rtx next_insn = NEXT_INSN (insn);
6195
 
6196
      if (GET_CODE (insn) == INSN
6197
          && GET_CODE (PATTERN (insn)) == SET
6198
          && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
6199
          && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
6200
        remove_insn (insn);
6201
 
6202
      insn = next_insn;
6203
    }
6204
 
6205
  /* Free pool list.  */
6206
 
6207
  while (pool_list)
6208
    {
6209
      struct constant_pool *next = pool_list->next;
6210
      s390_free_pool (pool_list);
6211
      pool_list = next;
6212
    }
6213
}
6214
 
6215
 
6216
/* Output the constant pool entry EXP in mode MODE with alignment ALIGN.  */
6217
 
6218
void
6219
s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
6220
{
6221
  REAL_VALUE_TYPE r;
6222
 
6223
  switch (GET_MODE_CLASS (mode))
6224
    {
6225
    case MODE_FLOAT:
6226
    case MODE_DECIMAL_FLOAT:
6227
      gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
6228
 
6229
      REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
6230
      assemble_real (r, mode, align);
6231
      break;
6232
 
6233
    case MODE_INT:
6234
      assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
6235
      break;
6236
 
6237
    default:
6238
      gcc_unreachable ();
6239
    }
6240
}
6241
 
6242
 
6243
/* Return an RTL expression representing the value of the return address
6244
   for the frame COUNT steps up from the current frame.  FRAME is the
6245
   frame pointer of that frame.  */
6246
 
6247
rtx
6248
s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
6249
{
6250
  int offset;
6251
  rtx addr;
6252
 
6253
  /* Without backchain, we fail for all but the current frame.  */
6254
 
6255
  if (!TARGET_BACKCHAIN && count > 0)
6256
    return NULL_RTX;
6257
 
6258
  /* For the current frame, we need to make sure the initial
6259
     value of RETURN_REGNUM is actually saved.  */
6260
 
6261
  if (count == 0)
6262
    {
6263
      /* On non-z architectures branch splitting could overwrite r14.  */
6264
      if (TARGET_CPU_ZARCH)
6265
        return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
6266
      else
6267
        {
6268
          cfun_frame_layout.save_return_addr_p = true;
6269
          return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
6270
        }
6271
    }
6272
 
6273
  if (TARGET_PACKED_STACK)
6274
    offset = -2 * UNITS_PER_WORD;
6275
  else
6276
    offset = RETURN_REGNUM * UNITS_PER_WORD;
6277
 
6278
  addr = plus_constant (frame, offset);
6279
  addr = memory_address (Pmode, addr);
6280
  return gen_rtx_MEM (Pmode, addr);
6281
}
6282
 
6283
/* Return an RTL expression representing the back chain stored in
6284
   the current stack frame.  */
6285
 
6286
rtx
6287
s390_back_chain_rtx (void)
6288
{
6289
  rtx chain;
6290
 
6291
  gcc_assert (TARGET_BACKCHAIN);
6292
 
6293
  if (TARGET_PACKED_STACK)
6294
    chain = plus_constant (stack_pointer_rtx,
6295
                           STACK_POINTER_OFFSET - UNITS_PER_WORD);
6296
  else
6297
    chain = stack_pointer_rtx;
6298
 
6299
  chain = gen_rtx_MEM (Pmode, chain);
6300
  return chain;
6301
}
6302
 
6303
/* Find first call clobbered register unused in a function.
6304
   This could be used as base register in a leaf function
6305
   or for holding the return address before epilogue.  */
6306
 
6307
static int
6308
find_unused_clobbered_reg (void)
6309
{
6310
  int i;
6311
  for (i = 0; i < 6; i++)
6312
    if (!regs_ever_live[i])
6313
      return i;
6314
  return 0;
6315
}
6316
 
6317
 
6318
/* Helper function for s390_regs_ever_clobbered.  Sets the fields in DATA for all
6319
   clobbered hard regs in SETREG.  */
6320
 
6321
static void
6322
s390_reg_clobbered_rtx (rtx setreg, rtx set_insn ATTRIBUTE_UNUSED, void *data)
6323
{
6324
  int *regs_ever_clobbered = (int *)data;
6325
  unsigned int i, regno;
6326
  enum machine_mode mode = GET_MODE (setreg);
6327
 
6328
  if (GET_CODE (setreg) == SUBREG)
6329
    {
6330
      rtx inner = SUBREG_REG (setreg);
6331
      if (!GENERAL_REG_P (inner))
6332
        return;
6333
      regno = subreg_regno (setreg);
6334
    }
6335
  else if (GENERAL_REG_P (setreg))
6336
    regno = REGNO (setreg);
6337
  else
6338
    return;
6339
 
6340
  for (i = regno;
6341
       i < regno + HARD_REGNO_NREGS (regno, mode);
6342
       i++)
6343
    regs_ever_clobbered[i] = 1;
6344
}
6345
 
6346
/* Walks through all basic blocks of the current function looking
6347
   for clobbered hard regs using s390_reg_clobbered_rtx.  The fields
6348
   of the passed integer array REGS_EVER_CLOBBERED are set to one for
6349
   each of those regs.  */
6350
 
6351
static void
6352
s390_regs_ever_clobbered (int *regs_ever_clobbered)
6353
{
6354
  basic_block cur_bb;
6355
  rtx cur_insn;
6356
  unsigned int i;
6357
 
6358
  memset (regs_ever_clobbered, 0, 16 * sizeof (int));
6359
 
6360
  /* For non-leaf functions we have to consider all call clobbered regs to be
6361
     clobbered.  */
6362
  if (!current_function_is_leaf)
6363
    {
6364
      for (i = 0; i < 16; i++)
6365
        regs_ever_clobbered[i] = call_really_used_regs[i];
6366
    }
6367
 
6368
  /* Make the "magic" eh_return registers live if necessary.  For regs_ever_live
6369
     this work is done by liveness analysis (mark_regs_live_at_end).
6370
     Special care is needed for functions containing landing pads.  Landing pads
6371
     may use the eh registers, but the code which sets these registers is not
6372
     contained in that function.  Hence s390_regs_ever_clobbered is not able to
6373
     deal with this automatically.  */
6374
  if (current_function_calls_eh_return || cfun->machine->has_landing_pad_p)
6375
    for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
6376
      if (current_function_calls_eh_return
6377
          || (cfun->machine->has_landing_pad_p
6378
              && regs_ever_live [EH_RETURN_DATA_REGNO (i)]))
6379
        regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
6380
 
6381
  /* For nonlocal gotos all call-saved registers have to be saved.
6382
     This flag is also set for the unwinding code in libgcc.
6383
     See expand_builtin_unwind_init.  For regs_ever_live this is done by
6384
     reload.  */
6385
  if (current_function_has_nonlocal_label)
6386
    for (i = 0; i < 16; i++)
6387
      if (!call_really_used_regs[i])
6388
        regs_ever_clobbered[i] = 1;
6389
 
6390
  FOR_EACH_BB (cur_bb)
6391
    {
6392
      FOR_BB_INSNS (cur_bb, cur_insn)
6393
        {
6394
          if (INSN_P (cur_insn))
6395
            note_stores (PATTERN (cur_insn),
6396
                         s390_reg_clobbered_rtx,
6397
                         regs_ever_clobbered);
6398
        }
6399
    }
6400
}
6401
 
6402
/* Determine the frame area which actually has to be accessed
6403
   in the function epilogue. The values are stored at the
6404
   given pointers AREA_BOTTOM (address of the lowest used stack
6405
   address) and AREA_TOP (address of the first item which does
6406
   not belong to the stack frame).  */
6407
 
6408
static void
6409
s390_frame_area (int *area_bottom, int *area_top)
6410
{
6411
  int b, t;
6412
  int i;
6413
 
6414
  b = INT_MAX;
6415
  t = INT_MIN;
6416
 
6417
  if (cfun_frame_layout.first_restore_gpr != -1)
6418
    {
6419
      b = (cfun_frame_layout.gprs_offset
6420
           + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
6421
      t = b + (cfun_frame_layout.last_restore_gpr
6422
               - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
6423
    }
6424
 
6425
  if (TARGET_64BIT && cfun_save_high_fprs_p)
6426
    {
6427
      b = MIN (b, cfun_frame_layout.f8_offset);
6428
      t = MAX (t, (cfun_frame_layout.f8_offset
6429
                   + cfun_frame_layout.high_fprs * 8));
6430
    }
6431
 
6432
  if (!TARGET_64BIT)
6433
    for (i = 2; i < 4; i++)
6434
      if (cfun_fpr_bit_p (i))
6435
        {
6436
          b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
6437
          t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
6438
        }
6439
 
6440
  *area_bottom = b;
6441
  *area_top = t;
6442
}
6443
 
6444
/* Fill cfun->machine with info about register usage of current function.
6445
   Return in CLOBBERED_REGS which GPRs are currently considered set.  */
6446
 
6447
static void
6448
s390_register_info (int clobbered_regs[])
6449
{
6450
  int i, j;
6451
 
6452
  /* fprs 8 - 15 are call saved for 64 Bit ABI.  */
6453
  cfun_frame_layout.fpr_bitmap = 0;
6454
  cfun_frame_layout.high_fprs = 0;
6455
  if (TARGET_64BIT)
6456
    for (i = 24; i < 32; i++)
6457
      if (regs_ever_live[i] && !global_regs[i])
6458
        {
6459
          cfun_set_fpr_bit (i - 16);
6460
          cfun_frame_layout.high_fprs++;
6461
        }
6462
 
6463
  /* Find first and last gpr to be saved.  We trust regs_ever_live
6464
     data, except that we don't save and restore global registers.
6465
 
6466
     Also, all registers with special meaning to the compiler need
6467
     to be handled extra.  */
6468
 
6469
  s390_regs_ever_clobbered (clobbered_regs);
6470
 
6471
  for (i = 0; i < 16; i++)
6472
    clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i];
6473
 
6474
  if (frame_pointer_needed)
6475
    clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
6476
 
6477
  if (flag_pic)
6478
    clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
6479
      |= regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
6480
 
6481
  clobbered_regs[BASE_REGNUM]
6482
    |= (cfun->machine->base_reg
6483
        && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
6484
 
6485
  clobbered_regs[RETURN_REGNUM]
6486
    |= (!current_function_is_leaf
6487
        || TARGET_TPF_PROFILING
6488
        || cfun->machine->split_branches_pending_p
6489
        || cfun_frame_layout.save_return_addr_p
6490
        || current_function_calls_eh_return
6491
        || current_function_stdarg);
6492
 
6493
  clobbered_regs[STACK_POINTER_REGNUM]
6494
    |= (!current_function_is_leaf
6495
        || TARGET_TPF_PROFILING
6496
        || cfun_save_high_fprs_p
6497
        || get_frame_size () > 0
6498
        || current_function_calls_alloca
6499
        || current_function_stdarg);
6500
 
6501
  for (i = 6; i < 16; i++)
6502
    if (regs_ever_live[i] || clobbered_regs[i])
6503
      break;
6504
  for (j = 15; j > i; j--)
6505
    if (regs_ever_live[j] || clobbered_regs[j])
6506
      break;
6507
 
6508
  if (i == 16)
6509
    {
6510
      /* Nothing to save/restore.  */
6511
      cfun_frame_layout.first_save_gpr_slot = -1;
6512
      cfun_frame_layout.last_save_gpr_slot = -1;
6513
      cfun_frame_layout.first_save_gpr = -1;
6514
      cfun_frame_layout.first_restore_gpr = -1;
6515
      cfun_frame_layout.last_save_gpr = -1;
6516
      cfun_frame_layout.last_restore_gpr = -1;
6517
    }
6518
  else
6519
    {
6520
      /* Save slots for gprs from i to j.  */
6521
      cfun_frame_layout.first_save_gpr_slot = i;
6522
      cfun_frame_layout.last_save_gpr_slot = j;
6523
 
6524
      for (i = cfun_frame_layout.first_save_gpr_slot;
6525
           i < cfun_frame_layout.last_save_gpr_slot + 1;
6526
           i++)
6527
        if (clobbered_regs[i])
6528
          break;
6529
 
6530
      for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
6531
        if (clobbered_regs[j])
6532
          break;
6533
 
6534
      if (i == cfun_frame_layout.last_save_gpr_slot + 1)
6535
        {
6536
          /* Nothing to save/restore.  */
6537
          cfun_frame_layout.first_save_gpr = -1;
6538
          cfun_frame_layout.first_restore_gpr = -1;
6539
          cfun_frame_layout.last_save_gpr = -1;
6540
          cfun_frame_layout.last_restore_gpr = -1;
6541
        }
6542
      else
6543
        {
6544
          /* Save / Restore from gpr i to j.  */
6545
          cfun_frame_layout.first_save_gpr = i;
6546
          cfun_frame_layout.first_restore_gpr = i;
6547
          cfun_frame_layout.last_save_gpr = j;
6548
          cfun_frame_layout.last_restore_gpr = j;
6549
        }
6550
    }
6551
 
6552
  if (current_function_stdarg)
6553
    {
6554
      /* Varargs functions need to save gprs 2 to 6.  */
6555
      if (cfun->va_list_gpr_size
6556
          && current_function_args_info.gprs < GP_ARG_NUM_REG)
6557
        {
6558
          int min_gpr = current_function_args_info.gprs;
6559
          int max_gpr = min_gpr + cfun->va_list_gpr_size;
6560
          if (max_gpr > GP_ARG_NUM_REG)
6561
            max_gpr = GP_ARG_NUM_REG;
6562
 
6563
          if (cfun_frame_layout.first_save_gpr == -1
6564
              || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
6565
            {
6566
              cfun_frame_layout.first_save_gpr = 2 + min_gpr;
6567
              cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
6568
            }
6569
 
6570
          if (cfun_frame_layout.last_save_gpr == -1
6571
              || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
6572
            {
6573
              cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
6574
              cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
6575
            }
6576
        }
6577
 
6578
      /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved.  */
6579
      if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
6580
          && current_function_args_info.fprs < FP_ARG_NUM_REG)
6581
        {
6582
          int min_fpr = current_function_args_info.fprs;
6583
          int max_fpr = min_fpr + cfun->va_list_fpr_size;
6584
          if (max_fpr > FP_ARG_NUM_REG)
6585
            max_fpr = FP_ARG_NUM_REG;
6586
 
6587
          /* ??? This is currently required to ensure proper location
6588
             of the fpr save slots within the va_list save area.  */
6589
          if (TARGET_PACKED_STACK)
6590
            min_fpr = 0;
6591
 
6592
          for (i = min_fpr; i < max_fpr; i++)
6593
            cfun_set_fpr_bit (i);
6594
        }
6595
    }
6596
 
6597
  if (!TARGET_64BIT)
6598
    for (i = 2; i < 4; i++)
6599
      if (regs_ever_live[i + 16] && !global_regs[i + 16])
6600
        cfun_set_fpr_bit (i);
6601
}
6602
 
6603
/* Fill cfun->machine with info about frame of current function.  */
6604
 
6605
static void
6606
s390_frame_info (void)
6607
{
6608
  int i;
6609
 
6610
  cfun_frame_layout.frame_size = get_frame_size ();
6611
  if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
6612
    fatal_error ("total size of local variables exceeds architecture limit");
6613
 
6614
  if (!TARGET_PACKED_STACK)
6615
    {
6616
      cfun_frame_layout.backchain_offset = 0;
6617
      cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
6618
      cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
6619
      cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
6620
      cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
6621
                                       * UNITS_PER_WORD);
6622
    }
6623
  else if (TARGET_BACKCHAIN) /* kernel stack layout */
6624
    {
6625
      cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
6626
                                            - UNITS_PER_WORD);
6627
      cfun_frame_layout.gprs_offset
6628
        = (cfun_frame_layout.backchain_offset
6629
           - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
6630
           * UNITS_PER_WORD);
6631
 
6632
      if (TARGET_64BIT)
6633
        {
6634
          cfun_frame_layout.f4_offset
6635
            = (cfun_frame_layout.gprs_offset
6636
               - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6637
 
6638
          cfun_frame_layout.f0_offset
6639
            = (cfun_frame_layout.f4_offset
6640
               - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6641
        }
6642
      else
6643
        {
6644
          /* On 31 bit we have to care about alignment of the
6645
             floating point regs to provide fastest access.  */
6646
          cfun_frame_layout.f0_offset
6647
            = ((cfun_frame_layout.gprs_offset
6648
                & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
6649
               - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6650
 
6651
          cfun_frame_layout.f4_offset
6652
            = (cfun_frame_layout.f0_offset
6653
               - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6654
        }
6655
    }
6656
  else /* no backchain */
6657
    {
6658
      cfun_frame_layout.f4_offset
6659
        = (STACK_POINTER_OFFSET
6660
           - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6661
 
6662
      cfun_frame_layout.f0_offset
6663
        = (cfun_frame_layout.f4_offset
6664
           - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6665
 
6666
      cfun_frame_layout.gprs_offset
6667
        = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
6668
    }
6669
 
6670
  if (current_function_is_leaf
6671
      && !TARGET_TPF_PROFILING
6672
      && cfun_frame_layout.frame_size == 0
6673
      && !cfun_save_high_fprs_p
6674
      && !current_function_calls_alloca
6675
      && !current_function_stdarg)
6676
    return;
6677
 
6678
  if (!TARGET_PACKED_STACK)
6679
    cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
6680
                                     + current_function_outgoing_args_size
6681
                                     + cfun_frame_layout.high_fprs * 8);
6682
  else
6683
    {
6684
      if (TARGET_BACKCHAIN)
6685
        cfun_frame_layout.frame_size += UNITS_PER_WORD;
6686
 
6687
      /* No alignment trouble here because f8-f15 are only saved under
6688
         64 bit.  */
6689
      cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
6690
                                               cfun_frame_layout.f4_offset),
6691
                                          cfun_frame_layout.gprs_offset)
6692
                                     - cfun_frame_layout.high_fprs * 8);
6693
 
6694
      cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
6695
 
6696
      for (i = 0; i < 8; i++)
6697
        if (cfun_fpr_bit_p (i))
6698
          cfun_frame_layout.frame_size += 8;
6699
 
6700
      cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
6701
 
6702
      /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6703
         the frame size to sustain 8 byte alignment of stack frames.  */
6704
      cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
6705
                                       STACK_BOUNDARY / BITS_PER_UNIT - 1)
6706
                                      & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
6707
 
6708
      cfun_frame_layout.frame_size += current_function_outgoing_args_size;
6709
    }
6710
}
6711
 
6712
/* Generate frame layout.  Fills in register and frame data for the current
6713
   function in cfun->machine.  This routine can be called multiple times;
6714
   it will re-do the complete frame layout every time.  */
6715
 
6716
static void
6717
s390_init_frame_layout (void)
6718
{
6719
  HOST_WIDE_INT frame_size;
6720
  int base_used;
6721
  int clobbered_regs[16];
6722
 
6723
  /* On S/390 machines, we may need to perform branch splitting, which
6724
     will require both base and return address register.  We have no
6725
     choice but to assume we're going to need them until right at the
6726
     end of the machine dependent reorg phase.  */
6727
  if (!TARGET_CPU_ZARCH)
6728
    cfun->machine->split_branches_pending_p = true;
6729
 
6730
  do
6731
    {
6732
      frame_size = cfun_frame_layout.frame_size;
6733
 
6734
      /* Try to predict whether we'll need the base register.  */
6735
      base_used = cfun->machine->split_branches_pending_p
6736
                  || current_function_uses_const_pool
6737
                  || (!DISP_IN_RANGE (frame_size)
6738
                      && !CONST_OK_FOR_K (frame_size));
6739
 
6740
      /* Decide which register to use as literal pool base.  In small
6741
         leaf functions, try to use an unused call-clobbered register
6742
         as base register to avoid save/restore overhead.  */
6743
      if (!base_used)
6744
        cfun->machine->base_reg = NULL_RTX;
6745
      else if (current_function_is_leaf && !regs_ever_live[5])
6746
        cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
6747
      else
6748
        cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6749
 
6750
      s390_register_info (clobbered_regs);
6751
      s390_frame_info ();
6752
    }
6753
  while (frame_size != cfun_frame_layout.frame_size);
6754
}
6755
 
6756
/* Update frame layout.  Recompute actual register save data based on
6757
   current info and update regs_ever_live for the special registers.
6758
   May be called multiple times, but may never cause *more* registers
6759
   to be saved than s390_init_frame_layout allocated room for.  */
6760
 
6761
static void
6762
s390_update_frame_layout (void)
6763
{
6764
  int clobbered_regs[16];
6765
 
6766
  s390_register_info (clobbered_regs);
6767
 
6768
  regs_ever_live[BASE_REGNUM] = clobbered_regs[BASE_REGNUM];
6769
  regs_ever_live[RETURN_REGNUM] = clobbered_regs[RETURN_REGNUM];
6770
  regs_ever_live[STACK_POINTER_REGNUM] = clobbered_regs[STACK_POINTER_REGNUM];
6771
 
6772
  if (cfun->machine->base_reg)
6773
    regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
6774
}
6775
 
6776
/* Return true if it is legal to put a value with MODE into REGNO.  */
6777
 
6778
bool
6779
s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
6780
{
6781
  switch (REGNO_REG_CLASS (regno))
6782
    {
6783
    case FP_REGS:
6784
      if (REGNO_PAIR_OK (regno, mode))
6785
        {
6786
          if (mode == SImode || mode == DImode)
6787
            return true;
6788
 
6789
          if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
6790
            return true;
6791
        }
6792
      break;
6793
    case ADDR_REGS:
6794
      if (FRAME_REGNO_P (regno) && mode == Pmode)
6795
        return true;
6796
 
6797
      /* fallthrough */
6798
    case GENERAL_REGS:
6799
      if (REGNO_PAIR_OK (regno, mode))
6800
        {
6801
          if (TARGET_64BIT
6802
              || (mode != TFmode && mode != TCmode && mode != TDmode))
6803
            return true;
6804
        }
6805
      break;
6806
    case CC_REGS:
6807
      if (GET_MODE_CLASS (mode) == MODE_CC)
6808
        return true;
6809
      break;
6810
    case ACCESS_REGS:
6811
      if (REGNO_PAIR_OK (regno, mode))
6812
        {
6813
          if (mode == SImode || mode == Pmode)
6814
            return true;
6815
        }
6816
      break;
6817
    default:
6818
      return false;
6819
    }
6820
 
6821
  return false;
6822
}
6823
 
6824
/* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
6825
 
6826
bool
6827
s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
6828
{
6829
   /* Once we've decided upon a register to use as base register, it must
6830
      no longer be used for any other purpose.  */
6831
  if (cfun->machine->base_reg)
6832
    if (REGNO (cfun->machine->base_reg) == old_reg
6833
        || REGNO (cfun->machine->base_reg) == new_reg)
6834
      return false;
6835
 
6836
  return true;
6837
}
6838
 
6839
/* Maximum number of registers to represent a value of mode MODE
6840
   in a register of class CLASS.  */
6841
 
6842
bool
6843
s390_class_max_nregs (enum reg_class class, enum machine_mode mode)
6844
{
6845
  switch (class)
6846
    {
6847
    case FP_REGS:
6848
      if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6849
        return 2 * ((GET_MODE_SIZE (mode) / 2 + 8 - 1) / 8);
6850
      else
6851
        return (GET_MODE_SIZE (mode) + 8 - 1) / 8;
6852
    case ACCESS_REGS:
6853
      return (GET_MODE_SIZE (mode) + 4 - 1) / 4;
6854
    default:
6855
      break;
6856
    }
6857
  return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6858
}
6859
 
6860
/* Return true if register FROM can be eliminated via register TO.  */
6861
 
6862
bool
6863
s390_can_eliminate (int from, int to)
6864
{
6865
  /* On zSeries machines, we have not marked the base register as fixed.
6866
     Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6867
     If a function requires the base register, we say here that this
6868
     elimination cannot be performed.  This will cause reload to free
6869
     up the base register (as if it were fixed).  On the other hand,
6870
     if the current function does *not* require the base register, we
6871
     say here the elimination succeeds, which in turn allows reload
6872
     to allocate the base register for any other purpose.  */
6873
  if (from == BASE_REGNUM && to == BASE_REGNUM)
6874
    {
6875
      if (TARGET_CPU_ZARCH)
6876
        {
6877
          s390_init_frame_layout ();
6878
          return cfun->machine->base_reg == NULL_RTX;
6879
        }
6880
 
6881
      return false;
6882
    }
6883
 
6884
  /* Everything else must point into the stack frame.  */
6885
  gcc_assert (to == STACK_POINTER_REGNUM
6886
              || to == HARD_FRAME_POINTER_REGNUM);
6887
 
6888
  gcc_assert (from == FRAME_POINTER_REGNUM
6889
              || from == ARG_POINTER_REGNUM
6890
              || from == RETURN_ADDRESS_POINTER_REGNUM);
6891
 
6892
  /* Make sure we actually saved the return address.  */
6893
  if (from == RETURN_ADDRESS_POINTER_REGNUM)
6894
    if (!current_function_calls_eh_return
6895
        && !current_function_stdarg
6896
        && !cfun_frame_layout.save_return_addr_p)
6897
      return false;
6898
 
6899
  return true;
6900
}
6901
 
6902
/* Return offset between register FROM and TO initially after prolog.  */
6903
 
6904
HOST_WIDE_INT
6905
s390_initial_elimination_offset (int from, int to)
6906
{
6907
  HOST_WIDE_INT offset;
6908
  int index;
6909
 
6910
  /* ??? Why are we called for non-eliminable pairs?  */
6911
  if (!s390_can_eliminate (from, to))
6912
    return 0;
6913
 
6914
  switch (from)
6915
    {
6916
    case FRAME_POINTER_REGNUM:
6917
      offset = (get_frame_size()
6918
                + STACK_POINTER_OFFSET
6919
                + current_function_outgoing_args_size);
6920
      break;
6921
 
6922
    case ARG_POINTER_REGNUM:
6923
      s390_init_frame_layout ();
6924
      offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6925
      break;
6926
 
6927
    case RETURN_ADDRESS_POINTER_REGNUM:
6928
      s390_init_frame_layout ();
6929
      index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
6930
      gcc_assert (index >= 0);
6931
      offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
6932
      offset += index * UNITS_PER_WORD;
6933
      break;
6934
 
6935
    case BASE_REGNUM:
6936
      offset = 0;
6937
      break;
6938
 
6939
    default:
6940
      gcc_unreachable ();
6941
    }
6942
 
6943
  return offset;
6944
}
6945
 
6946
/* Emit insn to save fpr REGNUM at offset OFFSET relative
6947
   to register BASE.  Return generated insn.  */
6948
 
6949
static rtx
6950
save_fpr (rtx base, int offset, int regnum)
6951
{
6952
  rtx addr;
6953
  addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6954
 
6955
  if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
6956
    set_mem_alias_set (addr, get_varargs_alias_set ());
6957
  else
6958
    set_mem_alias_set (addr, get_frame_alias_set ());
6959
 
6960
  return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
6961
}
6962
 
6963
/* Emit insn to restore fpr REGNUM from offset OFFSET relative
6964
   to register BASE.  Return generated insn.  */
6965
 
6966
static rtx
6967
restore_fpr (rtx base, int offset, int regnum)
6968
{
6969
  rtx addr;
6970
  addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6971
  set_mem_alias_set (addr, get_frame_alias_set ());
6972
 
6973
  return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
6974
}
6975
 
6976
/* Generate insn to save registers FIRST to LAST into
6977
   the register save area located at offset OFFSET
6978
   relative to register BASE.  */
6979
 
6980
static rtx
6981
save_gprs (rtx base, int offset, int first, int last)
6982
{
6983
  rtx addr, insn, note;
6984
  int i;
6985
 
6986
  addr = plus_constant (base, offset);
6987
  addr = gen_rtx_MEM (Pmode, addr);
6988
 
6989
  set_mem_alias_set (addr, get_frame_alias_set ());
6990
 
6991
  /* Special-case single register.  */
6992
  if (first == last)
6993
    {
6994
      if (TARGET_64BIT)
6995
        insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6996
      else
6997
        insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6998
 
6999
      RTX_FRAME_RELATED_P (insn) = 1;
7000
      return insn;
7001
    }
7002
 
7003
 
7004
  insn = gen_store_multiple (addr,
7005
                             gen_rtx_REG (Pmode, first),
7006
                             GEN_INT (last - first + 1));
7007
 
7008
  if (first <= 6 && current_function_stdarg)
7009
    for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7010
      {
7011
        rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
7012
 
7013
        if (first + i <= 6)
7014
          set_mem_alias_set (mem, get_varargs_alias_set ());
7015
      }
7016
 
7017
  /* We need to set the FRAME_RELATED flag on all SETs
7018
     inside the store-multiple pattern.
7019
 
7020
     However, we must not emit DWARF records for registers 2..5
7021
     if they are stored for use by variable arguments ...
7022
 
7023
     ??? Unfortunately, it is not enough to simply not the
7024
     FRAME_RELATED flags for those SETs, because the first SET
7025
     of the PARALLEL is always treated as if it had the flag
7026
     set, even if it does not.  Therefore we emit a new pattern
7027
     without those registers as REG_FRAME_RELATED_EXPR note.  */
7028
 
7029
  if (first >= 6)
7030
    {
7031
      rtx pat = PATTERN (insn);
7032
 
7033
      for (i = 0; i < XVECLEN (pat, 0); i++)
7034
        if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
7035
          RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
7036
 
7037
      RTX_FRAME_RELATED_P (insn) = 1;
7038
    }
7039
  else if (last >= 6)
7040
    {
7041
      addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
7042
      note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
7043
                                 gen_rtx_REG (Pmode, 6),
7044
                                 GEN_INT (last - 6 + 1));
7045
      note = PATTERN (note);
7046
 
7047
      REG_NOTES (insn) =
7048
        gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7049
                           note, REG_NOTES (insn));
7050
 
7051
      for (i = 0; i < XVECLEN (note, 0); i++)
7052
        if (GET_CODE (XVECEXP (note, 0, i)) == SET)
7053
          RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
7054
 
7055
      RTX_FRAME_RELATED_P (insn) = 1;
7056
    }
7057
 
7058
  return insn;
7059
}
7060
 
7061
/* Generate insn to restore registers FIRST to LAST from
7062
   the register save area located at offset OFFSET
7063
   relative to register BASE.  */
7064
 
7065
static rtx
7066
restore_gprs (rtx base, int offset, int first, int last)
7067
{
7068
  rtx addr, insn;
7069
 
7070
  addr = plus_constant (base, offset);
7071
  addr = gen_rtx_MEM (Pmode, addr);
7072
  set_mem_alias_set (addr, get_frame_alias_set ());
7073
 
7074
  /* Special-case single register.  */
7075
  if (first == last)
7076
    {
7077
      if (TARGET_64BIT)
7078
        insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
7079
      else
7080
        insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
7081
 
7082
      return insn;
7083
    }
7084
 
7085
  insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
7086
                            addr,
7087
                            GEN_INT (last - first + 1));
7088
  return insn;
7089
}
7090
 
7091
/* Return insn sequence to load the GOT register.  */
7092
 
7093
static GTY(()) rtx got_symbol;
7094
rtx
7095
s390_load_got (void)
7096
{
7097
  rtx insns;
7098
 
7099
  if (!got_symbol)
7100
    {
7101
      got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7102
      SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
7103
    }
7104
 
7105
  start_sequence ();
7106
 
7107
  if (TARGET_CPU_ZARCH)
7108
    {
7109
      emit_move_insn (pic_offset_table_rtx, got_symbol);
7110
    }
7111
  else
7112
    {
7113
      rtx offset;
7114
 
7115
      offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
7116
                               UNSPEC_LTREL_OFFSET);
7117
      offset = gen_rtx_CONST (Pmode, offset);
7118
      offset = force_const_mem (Pmode, offset);
7119
 
7120
      emit_move_insn (pic_offset_table_rtx, offset);
7121
 
7122
      offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
7123
                               UNSPEC_LTREL_BASE);
7124
      offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
7125
 
7126
      emit_move_insn (pic_offset_table_rtx, offset);
7127
    }
7128
 
7129
  insns = get_insns ();
7130
  end_sequence ();
7131
  return insns;
7132
}
7133
 
7134
/* Expand the prologue into a bunch of separate insns.  */
7135
 
7136
void
7137
s390_emit_prologue (void)
7138
{
7139
  rtx insn, addr;
7140
  rtx temp_reg;
7141
  int i;
7142
  int offset;
7143
  int next_fpr = 0;
7144
 
7145
  /* Complete frame layout.  */
7146
 
7147
  s390_update_frame_layout ();
7148
 
7149
  /* Annotate all constant pool references to let the scheduler know
7150
     they implicitly use the base register.  */
7151
 
7152
  push_topmost_sequence ();
7153
 
7154
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7155
    if (INSN_P (insn))
7156
      annotate_constant_pool_refs (&PATTERN (insn));
7157
 
7158
  pop_topmost_sequence ();
7159
 
7160
  /* Choose best register to use for temp use within prologue.
7161
     See below for why TPF must use the register 1.  */
7162
 
7163
  if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
7164
      && !current_function_is_leaf
7165
      && !TARGET_TPF_PROFILING)
7166
    temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7167
  else
7168
    temp_reg = gen_rtx_REG (Pmode, 1);
7169
 
7170
  /* Save call saved gprs.  */
7171
  if (cfun_frame_layout.first_save_gpr != -1)
7172
    {
7173
      insn = save_gprs (stack_pointer_rtx,
7174
                        cfun_frame_layout.gprs_offset +
7175
                        UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
7176
                                          - cfun_frame_layout.first_save_gpr_slot),
7177
                        cfun_frame_layout.first_save_gpr,
7178
                        cfun_frame_layout.last_save_gpr);
7179
      emit_insn (insn);
7180
    }
7181
 
7182
  /* Dummy insn to mark literal pool slot.  */
7183
 
7184
  if (cfun->machine->base_reg)
7185
    emit_insn (gen_main_pool (cfun->machine->base_reg));
7186
 
7187
  offset = cfun_frame_layout.f0_offset;
7188
 
7189
  /* Save f0 and f2.  */
7190
  for (i = 0; i < 2; i++)
7191
    {
7192
      if (cfun_fpr_bit_p (i))
7193
        {
7194
          save_fpr (stack_pointer_rtx, offset, i + 16);
7195
          offset += 8;
7196
        }
7197
      else if (!TARGET_PACKED_STACK)
7198
          offset += 8;
7199
    }
7200
 
7201
  /* Save f4 and f6.  */
7202
  offset = cfun_frame_layout.f4_offset;
7203
  for (i = 2; i < 4; i++)
7204
    {
7205
      if (cfun_fpr_bit_p (i))
7206
        {
7207
          insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7208
          offset += 8;
7209
 
7210
          /* If f4 and f6 are call clobbered they are saved due to stdargs and
7211
             therefore are not frame related.  */
7212
          if (!call_really_used_regs[i + 16])
7213
            RTX_FRAME_RELATED_P (insn) = 1;
7214
        }
7215
      else if (!TARGET_PACKED_STACK)
7216
        offset += 8;
7217
    }
7218
 
7219
  if (TARGET_PACKED_STACK
7220
      && cfun_save_high_fprs_p
7221
      && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
7222
    {
7223
      offset = (cfun_frame_layout.f8_offset
7224
                + (cfun_frame_layout.high_fprs - 1) * 8);
7225
 
7226
      for (i = 15; i > 7 && offset >= 0; i--)
7227
        if (cfun_fpr_bit_p (i))
7228
          {
7229
            insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7230
 
7231
            RTX_FRAME_RELATED_P (insn) = 1;
7232
            offset -= 8;
7233
          }
7234
      if (offset >= cfun_frame_layout.f8_offset)
7235
        next_fpr = i + 16;
7236
    }
7237
 
7238
  if (!TARGET_PACKED_STACK)
7239
    next_fpr = cfun_save_high_fprs_p ? 31 : 0;
7240
 
7241
  /* Decrement stack pointer.  */
7242
 
7243
  if (cfun_frame_layout.frame_size > 0)
7244
    {
7245
      rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
7246
 
7247
      if (s390_stack_size)
7248
        {
7249
          HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
7250
                                            & ~(s390_stack_guard - 1));
7251
          rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
7252
                               GEN_INT (stack_check_mask));
7253
 
7254
          if (TARGET_64BIT)
7255
            gen_cmpdi (t, const0_rtx);
7256
          else
7257
            gen_cmpsi (t, const0_rtx);
7258
 
7259
          emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
7260
                                                       gen_rtx_REG (CCmode,
7261
                                                                    CC_REGNUM),
7262
                                                       const0_rtx),
7263
                                           const0_rtx));
7264
        }
7265
 
7266
      if (s390_warn_framesize > 0
7267
          && cfun_frame_layout.frame_size >= s390_warn_framesize)
7268
        warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
7269
                 current_function_name (), cfun_frame_layout.frame_size);
7270
 
7271
      if (s390_warn_dynamicstack_p && cfun->calls_alloca)
7272
        warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7273
 
7274
      /* Save incoming stack pointer into temp reg.  */
7275
      if (TARGET_BACKCHAIN || next_fpr)
7276
        insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
7277
 
7278
      /* Subtract frame size from stack pointer.  */
7279
 
7280
      if (DISP_IN_RANGE (INTVAL (frame_off)))
7281
        {
7282
          insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7283
                              gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7284
                                            frame_off));
7285
          insn = emit_insn (insn);
7286
        }
7287
      else
7288
        {
7289
          if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7290
            frame_off = force_const_mem (Pmode, frame_off);
7291
 
7292
          insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
7293
          annotate_constant_pool_refs (&PATTERN (insn));
7294
        }
7295
 
7296
      RTX_FRAME_RELATED_P (insn) = 1;
7297
      REG_NOTES (insn) =
7298
        gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7299
                           gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7300
                             gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7301
                               GEN_INT (-cfun_frame_layout.frame_size))),
7302
                           REG_NOTES (insn));
7303
 
7304
      /* Set backchain.  */
7305
 
7306
      if (TARGET_BACKCHAIN)
7307
        {
7308
          if (cfun_frame_layout.backchain_offset)
7309
            addr = gen_rtx_MEM (Pmode,
7310
                                plus_constant (stack_pointer_rtx,
7311
                                  cfun_frame_layout.backchain_offset));
7312
          else
7313
            addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
7314
          set_mem_alias_set (addr, get_frame_alias_set ());
7315
          insn = emit_insn (gen_move_insn (addr, temp_reg));
7316
        }
7317
 
7318
      /* If we support asynchronous exceptions (e.g. for Java),
7319
         we need to make sure the backchain pointer is set up
7320
         before any possibly trapping memory access.  */
7321
 
7322
      if (TARGET_BACKCHAIN && flag_non_call_exceptions)
7323
        {
7324
          addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
7325
          emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
7326
        }
7327
    }
7328
 
7329
  /* Save fprs 8 - 15 (64 bit ABI).  */
7330
 
7331
  if (cfun_save_high_fprs_p && next_fpr)
7332
    {
7333
      insn = emit_insn (gen_add2_insn (temp_reg,
7334
                                       GEN_INT (cfun_frame_layout.f8_offset)));
7335
 
7336
      offset = 0;
7337
 
7338
      for (i = 24; i <= next_fpr; i++)
7339
        if (cfun_fpr_bit_p (i - 16))
7340
          {
7341
            rtx addr = plus_constant (stack_pointer_rtx,
7342
                                      cfun_frame_layout.frame_size
7343
                                      + cfun_frame_layout.f8_offset
7344
                                      + offset);
7345
 
7346
            insn = save_fpr (temp_reg, offset, i);
7347
            offset += 8;
7348
            RTX_FRAME_RELATED_P (insn) = 1;
7349
            REG_NOTES (insn) =
7350
              gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7351
                                 gen_rtx_SET (VOIDmode,
7352
                                              gen_rtx_MEM (DFmode, addr),
7353
                                              gen_rtx_REG (DFmode, i)),
7354
                                 REG_NOTES (insn));
7355
          }
7356
    }
7357
 
7358
  /* Set frame pointer, if needed.  */
7359
 
7360
  if (frame_pointer_needed)
7361
    {
7362
      insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
7363
      RTX_FRAME_RELATED_P (insn) = 1;
7364
    }
7365
 
7366
  /* Set up got pointer, if needed.  */
7367
 
7368
  if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
7369
    {
7370
      rtx insns = s390_load_got ();
7371
 
7372
      for (insn = insns; insn; insn = NEXT_INSN (insn))
7373
        {
7374
          annotate_constant_pool_refs (&PATTERN (insn));
7375
 
7376
          REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
7377
                                                REG_NOTES (insn));
7378
        }
7379
 
7380
      emit_insn (insns);
7381
    }
7382
 
7383
  if (TARGET_TPF_PROFILING)
7384
    {
7385
      /* Generate a BAS instruction to serve as a function
7386
         entry intercept to facilitate the use of tracing
7387
         algorithms located at the branch target.  */
7388
      emit_insn (gen_prologue_tpf ());
7389
 
7390
      /* Emit a blockage here so that all code
7391
         lies between the profiling mechanisms.  */
7392
      emit_insn (gen_blockage ());
7393
    }
7394
}
7395
 
7396
/* Expand the epilogue into a bunch of separate insns.  */
7397
 
7398
void
7399
s390_emit_epilogue (bool sibcall)
7400
{
7401
  rtx frame_pointer, return_reg;
7402
  int area_bottom, area_top, offset = 0;
7403
  int next_offset;
7404
  rtvec p;
7405
  int i;
7406
 
7407
  if (TARGET_TPF_PROFILING)
7408
    {
7409
 
7410
      /* Generate a BAS instruction to serve as a function
7411
         entry intercept to facilitate the use of tracing
7412
         algorithms located at the branch target.  */
7413
 
7414
      /* Emit a blockage here so that all code
7415
         lies between the profiling mechanisms.  */
7416
      emit_insn (gen_blockage ());
7417
 
7418
      emit_insn (gen_epilogue_tpf ());
7419
    }
7420
 
7421
  /* Check whether to use frame or stack pointer for restore.  */
7422
 
7423
  frame_pointer = (frame_pointer_needed
7424
                   ? hard_frame_pointer_rtx : stack_pointer_rtx);
7425
 
7426
  s390_frame_area (&area_bottom, &area_top);
7427
 
7428
  /* Check whether we can access the register save area.
7429
     If not, increment the frame pointer as required.  */
7430
 
7431
  if (area_top <= area_bottom)
7432
    {
7433
      /* Nothing to restore.  */
7434
    }
7435
  else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
7436
           && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
7437
    {
7438
      /* Area is in range.  */
7439
      offset = cfun_frame_layout.frame_size;
7440
    }
7441
  else
7442
    {
7443
      rtx insn, frame_off;
7444
 
7445
      offset = area_bottom < 0 ? -area_bottom : 0;
7446
      frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
7447
 
7448
      if (DISP_IN_RANGE (INTVAL (frame_off)))
7449
        {
7450
          insn = gen_rtx_SET (VOIDmode, frame_pointer,
7451
                              gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
7452
          insn = emit_insn (insn);
7453
        }
7454
      else
7455
        {
7456
          if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7457
            frame_off = force_const_mem (Pmode, frame_off);
7458
 
7459
          insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
7460
          annotate_constant_pool_refs (&PATTERN (insn));
7461
        }
7462
    }
7463
 
7464
  /* Restore call saved fprs.  */
7465
 
7466
  if (TARGET_64BIT)
7467
    {
7468
      if (cfun_save_high_fprs_p)
7469
        {
7470
          next_offset = cfun_frame_layout.f8_offset;
7471
          for (i = 24; i < 32; i++)
7472
            {
7473
              if (cfun_fpr_bit_p (i - 16))
7474
                {
7475
                  restore_fpr (frame_pointer,
7476
                               offset + next_offset, i);
7477
                  next_offset += 8;
7478
                }
7479
            }
7480
        }
7481
 
7482
    }
7483
  else
7484
    {
7485
      next_offset = cfun_frame_layout.f4_offset;
7486
      for (i = 18; i < 20; i++)
7487
        {
7488
          if (cfun_fpr_bit_p (i - 16))
7489
            {
7490
              restore_fpr (frame_pointer,
7491
                           offset + next_offset, i);
7492
              next_offset += 8;
7493
            }
7494
          else if (!TARGET_PACKED_STACK)
7495
            next_offset += 8;
7496
        }
7497
 
7498
    }
7499
 
7500
  /* Return register.  */
7501
 
7502
  return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7503
 
7504
  /* Restore call saved gprs.  */
7505
 
7506
  if (cfun_frame_layout.first_restore_gpr != -1)
7507
    {
7508
      rtx insn, addr;
7509
      int i;
7510
 
7511
      /* Check for global register and save them
7512
         to stack location from where they get restored.  */
7513
 
7514
      for (i = cfun_frame_layout.first_restore_gpr;
7515
           i <= cfun_frame_layout.last_restore_gpr;
7516
           i++)
7517
        {
7518
          /* These registers are special and need to be
7519
             restored in any case.  */
7520
          if (i == STACK_POINTER_REGNUM
7521
              || i == RETURN_REGNUM
7522
              || i == BASE_REGNUM
7523
              || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
7524
            continue;
7525
 
7526
          if (global_regs[i])
7527
            {
7528
              addr = plus_constant (frame_pointer,
7529
                                    offset + cfun_frame_layout.gprs_offset
7530
                                    + (i - cfun_frame_layout.first_save_gpr_slot)
7531
                                    * UNITS_PER_WORD);
7532
              addr = gen_rtx_MEM (Pmode, addr);
7533
              set_mem_alias_set (addr, get_frame_alias_set ());
7534
              emit_move_insn (addr, gen_rtx_REG (Pmode, i));
7535
            }
7536
        }
7537
 
7538
      if (! sibcall)
7539
        {
7540
          /* Fetch return address from stack before load multiple,
7541
             this will do good for scheduling.  */
7542
 
7543
          if (cfun_frame_layout.save_return_addr_p
7544
              || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
7545
                  && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
7546
            {
7547
              int return_regnum = find_unused_clobbered_reg();
7548
              if (!return_regnum)
7549
                return_regnum = 4;
7550
              return_reg = gen_rtx_REG (Pmode, return_regnum);
7551
 
7552
              addr = plus_constant (frame_pointer,
7553
                                    offset + cfun_frame_layout.gprs_offset
7554
                                    + (RETURN_REGNUM
7555
                                       - cfun_frame_layout.first_save_gpr_slot)
7556
                                    * UNITS_PER_WORD);
7557
              addr = gen_rtx_MEM (Pmode, addr);
7558
              set_mem_alias_set (addr, get_frame_alias_set ());
7559
              emit_move_insn (return_reg, addr);
7560
            }
7561
        }
7562
 
7563
      insn = restore_gprs (frame_pointer,
7564
                           offset + cfun_frame_layout.gprs_offset
7565
                           + (cfun_frame_layout.first_restore_gpr
7566
                              - cfun_frame_layout.first_save_gpr_slot)
7567
                           * UNITS_PER_WORD,
7568
                           cfun_frame_layout.first_restore_gpr,
7569
                           cfun_frame_layout.last_restore_gpr);
7570
      emit_insn (insn);
7571
    }
7572
 
7573
  if (! sibcall)
7574
    {
7575
 
7576
      /* Return to caller.  */
7577
 
7578
      p = rtvec_alloc (2);
7579
 
7580
      RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
7581
      RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
7582
      emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
7583
    }
7584
}
7585
 
7586
 
7587
/* Return the size in bytes of a function argument of
7588
   type TYPE and/or mode MODE.  At least one of TYPE or
7589
   MODE must be specified.  */
7590
 
7591
static int
7592
s390_function_arg_size (enum machine_mode mode, tree type)
7593
{
7594
  if (type)
7595
    return int_size_in_bytes (type);
7596
 
7597
  /* No type info available for some library calls ...  */
7598
  if (mode != BLKmode)
7599
    return GET_MODE_SIZE (mode);
7600
 
7601
  /* If we have neither type nor mode, abort */
7602
  gcc_unreachable ();
7603
}
7604
 
7605
/* Return true if a function argument of type TYPE and mode MODE
7606
   is to be passed in a floating-point register, if available.  */
7607
 
7608
static bool
7609
s390_function_arg_float (enum machine_mode mode, tree type)
7610
{
7611
  int size = s390_function_arg_size (mode, type);
7612
  if (size > 8)
7613
    return false;
7614
 
7615
  /* Soft-float changes the ABI: no floating-point registers are used.  */
7616
  if (TARGET_SOFT_FLOAT)
7617
    return false;
7618
 
7619
  /* No type info available for some library calls ...  */
7620
  if (!type)
7621
    return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
7622
 
7623
  /* The ABI says that record types with a single member are treated
7624
     just like that member would be.  */
7625
  while (TREE_CODE (type) == RECORD_TYPE)
7626
    {
7627
      tree field, single = NULL_TREE;
7628
 
7629
      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
7630
        {
7631
          if (TREE_CODE (field) != FIELD_DECL)
7632
            continue;
7633
 
7634
          if (single == NULL_TREE)
7635
            single = TREE_TYPE (field);
7636
          else
7637
            return false;
7638
        }
7639
 
7640
      if (single == NULL_TREE)
7641
        return false;
7642
      else
7643
        type = single;
7644
    }
7645
 
7646
  return TREE_CODE (type) == REAL_TYPE;
7647
}
7648
 
7649
/* Return true if a function argument of type TYPE and mode MODE
7650
   is to be passed in an integer register, or a pair of integer
7651
   registers, if available.  */
7652
 
7653
static bool
7654
s390_function_arg_integer (enum machine_mode mode, tree type)
7655
{
7656
  int size = s390_function_arg_size (mode, type);
7657
  if (size > 8)
7658
    return false;
7659
 
7660
  /* No type info available for some library calls ...  */
7661
  if (!type)
7662
    return GET_MODE_CLASS (mode) == MODE_INT
7663
           || (TARGET_SOFT_FLOAT &&  SCALAR_FLOAT_MODE_P (mode));
7664
 
7665
  /* We accept small integral (and similar) types.  */
7666
  if (INTEGRAL_TYPE_P (type)
7667
      || POINTER_TYPE_P (type)
7668
      || TREE_CODE (type) == OFFSET_TYPE
7669
      || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
7670
    return true;
7671
 
7672
  /* We also accept structs of size 1, 2, 4, 8 that are not
7673
     passed in floating-point registers.  */
7674
  if (AGGREGATE_TYPE_P (type)
7675
      && exact_log2 (size) >= 0
7676
      && !s390_function_arg_float (mode, type))
7677
    return true;
7678
 
7679
  return false;
7680
}
7681
 
7682
/* Return 1 if a function argument of type TYPE and mode MODE
7683
   is to be passed by reference.  The ABI specifies that only
7684
   structures of size 1, 2, 4, or 8 bytes are passed by value,
7685
   all other structures (and complex numbers) are passed by
7686
   reference.  */
7687
 
7688
static bool
7689
s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
7690
                        enum machine_mode mode, tree type,
7691
                        bool named ATTRIBUTE_UNUSED)
7692
{
7693
  int size = s390_function_arg_size (mode, type);
7694
  if (size > 8)
7695
    return true;
7696
 
7697
  if (type)
7698
    {
7699
      if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
7700
        return 1;
7701
 
7702
      if (TREE_CODE (type) == COMPLEX_TYPE
7703
          || TREE_CODE (type) == VECTOR_TYPE)
7704
        return 1;
7705
    }
7706
 
7707
  return 0;
7708
}
7709
 
7710
/* Update the data in CUM to advance over an argument of mode MODE and
7711
   data type TYPE.  (TYPE is null for libcalls where that information
7712
   may not be available.).  The boolean NAMED specifies whether the
7713
   argument is a named argument (as opposed to an unnamed argument
7714
   matching an ellipsis).  */
7715
 
7716
void
7717
s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7718
                           tree type, int named ATTRIBUTE_UNUSED)
7719
{
7720
  if (s390_function_arg_float (mode, type))
7721
    {
7722
      cum->fprs += 1;
7723
    }
7724
  else if (s390_function_arg_integer (mode, type))
7725
    {
7726
      int size = s390_function_arg_size (mode, type);
7727
      cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
7728
    }
7729
  else
7730
    gcc_unreachable ();
7731
}
7732
 
7733
/* Define where to put the arguments to a function.
7734
   Value is zero to push the argument on the stack,
7735
   or a hard register in which to store the argument.
7736
 
7737
   MODE is the argument's machine mode.
7738
   TYPE is the data type of the argument (as a tree).
7739
    This is null for libcalls where that information may
7740
    not be available.
7741
   CUM is a variable of type CUMULATIVE_ARGS which gives info about
7742
    the preceding args and about the function being called.
7743
   NAMED is nonzero if this argument is a named parameter
7744
    (otherwise it is an extra parameter matching an ellipsis).
7745
 
7746
   On S/390, we use general purpose registers 2 through 6 to
7747
   pass integer, pointer, and certain structure arguments, and
7748
   floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7749
   to pass floating point arguments.  All remaining arguments
7750
   are pushed to the stack.  */
7751
 
7752
rtx
7753
s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
7754
                   int named ATTRIBUTE_UNUSED)
7755
{
7756
  if (s390_function_arg_float (mode, type))
7757
    {
7758
      if (cum->fprs + 1 > FP_ARG_NUM_REG)
7759
        return 0;
7760
      else
7761
        return gen_rtx_REG (mode, cum->fprs + 16);
7762
    }
7763
  else if (s390_function_arg_integer (mode, type))
7764
    {
7765
      int size = s390_function_arg_size (mode, type);
7766
      int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
7767
 
7768
      if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
7769
        return 0;
7770
      else
7771
        return gen_rtx_REG (mode, cum->gprs + 2);
7772
    }
7773
 
7774
  /* After the real arguments, expand_call calls us once again
7775
     with a void_type_node type.  Whatever we return here is
7776
     passed as operand 2 to the call expanders.
7777
 
7778
     We don't need this feature ...  */
7779
  else if (type == void_type_node)
7780
    return const0_rtx;
7781
 
7782
  gcc_unreachable ();
7783
}
7784
 
7785
/* Return true if return values of type TYPE should be returned
7786
   in a memory buffer whose address is passed by the caller as
7787
   hidden first argument.  */
7788
 
7789
static bool
7790
s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
7791
{
7792
  /* We accept small integral (and similar) types.  */
7793
  if (INTEGRAL_TYPE_P (type)
7794
      || POINTER_TYPE_P (type)
7795
      || TREE_CODE (type) == OFFSET_TYPE
7796
      || TREE_CODE (type) == REAL_TYPE)
7797
    return int_size_in_bytes (type) > 8;
7798
 
7799
  /* Aggregates and similar constructs are always returned
7800
     in memory.  */
7801
  if (AGGREGATE_TYPE_P (type)
7802
      || TREE_CODE (type) == COMPLEX_TYPE
7803
      || TREE_CODE (type) == VECTOR_TYPE)
7804
    return true;
7805
 
7806
  /* ??? We get called on all sorts of random stuff from
7807
     aggregate_value_p.  We can't abort, but it's not clear
7808
     what's safe to return.  Pretend it's a struct I guess.  */
7809
  return true;
7810
}
7811
 
7812
/* Define where to return a (scalar) value of type TYPE.
7813
   If TYPE is null, define where to return a (scalar)
7814
   value of mode MODE from a libcall.  */
7815
 
7816
rtx
7817
s390_function_value (tree type, enum machine_mode mode)
7818
{
7819
  if (type)
7820
    {
7821
      int unsignedp = TYPE_UNSIGNED (type);
7822
      mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
7823
    }
7824
 
7825
  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
7826
  gcc_assert (GET_MODE_SIZE (mode) <= 8);
7827
 
7828
  if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
7829
    return gen_rtx_REG (mode, 16);
7830
  else
7831
    return gen_rtx_REG (mode, 2);
7832
}
7833
 
7834
 
7835
/* Create and return the va_list datatype.
7836
 
7837
   On S/390, va_list is an array type equivalent to
7838
 
7839
      typedef struct __va_list_tag
7840
        {
7841
            long __gpr;
7842
            long __fpr;
7843
            void *__overflow_arg_area;
7844
            void *__reg_save_area;
7845
        } va_list[1];
7846
 
7847
   where __gpr and __fpr hold the number of general purpose
7848
   or floating point arguments used up to now, respectively,
7849
   __overflow_arg_area points to the stack location of the
7850
   next argument passed on the stack, and __reg_save_area
7851
   always points to the start of the register area in the
7852
   call frame of the current function.  The function prologue
7853
   saves all registers used for argument passing into this
7854
   area if the function uses variable arguments.  */
7855
 
7856
static tree
7857
s390_build_builtin_va_list (void)
7858
{
7859
  tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
7860
 
7861
  record = lang_hooks.types.make_type (RECORD_TYPE);
7862
 
7863
  type_decl =
7864
    build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
7865
 
7866
  f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
7867
                      long_integer_type_node);
7868
  f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
7869
                      long_integer_type_node);
7870
  f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
7871
                      ptr_type_node);
7872
  f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
7873
                      ptr_type_node);
7874
 
7875
  va_list_gpr_counter_field = f_gpr;
7876
  va_list_fpr_counter_field = f_fpr;
7877
 
7878
  DECL_FIELD_CONTEXT (f_gpr) = record;
7879
  DECL_FIELD_CONTEXT (f_fpr) = record;
7880
  DECL_FIELD_CONTEXT (f_ovf) = record;
7881
  DECL_FIELD_CONTEXT (f_sav) = record;
7882
 
7883
  TREE_CHAIN (record) = type_decl;
7884
  TYPE_NAME (record) = type_decl;
7885
  TYPE_FIELDS (record) = f_gpr;
7886
  TREE_CHAIN (f_gpr) = f_fpr;
7887
  TREE_CHAIN (f_fpr) = f_ovf;
7888
  TREE_CHAIN (f_ovf) = f_sav;
7889
 
7890
  layout_type (record);
7891
 
7892
  /* The correct type is an array type of one element.  */
7893
  return build_array_type (record, build_index_type (size_zero_node));
7894
}
7895
 
7896
/* Implement va_start by filling the va_list structure VALIST.
7897
   STDARG_P is always true, and ignored.
7898
   NEXTARG points to the first anonymous stack argument.
7899
 
7900
   The following global variables are used to initialize
7901
   the va_list structure:
7902
 
7903
     current_function_args_info:
7904
       holds number of gprs and fprs used for named arguments.
7905
     current_function_arg_offset_rtx:
7906
       holds the offset of the first anonymous stack argument
7907
       (relative to the virtual arg pointer).  */
7908
 
7909
void
7910
s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
7911
{
7912
  HOST_WIDE_INT n_gpr, n_fpr;
7913
  int off;
7914
  tree f_gpr, f_fpr, f_ovf, f_sav;
7915
  tree gpr, fpr, ovf, sav, t;
7916
 
7917
  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7918
  f_fpr = TREE_CHAIN (f_gpr);
7919
  f_ovf = TREE_CHAIN (f_fpr);
7920
  f_sav = TREE_CHAIN (f_ovf);
7921
 
7922
  valist = build_va_arg_indirect_ref (valist);
7923
  gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7924
  fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7925
  ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7926
  sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7927
 
7928
  /* Count number of gp and fp argument registers used.  */
7929
 
7930
  n_gpr = current_function_args_info.gprs;
7931
  n_fpr = current_function_args_info.fprs;
7932
 
7933
  if (cfun->va_list_gpr_size)
7934
    {
7935
      t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
7936
                  build_int_cst (NULL_TREE, n_gpr));
7937
      TREE_SIDE_EFFECTS (t) = 1;
7938
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7939
    }
7940
 
7941
  if (cfun->va_list_fpr_size)
7942
    {
7943
      t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
7944
                  build_int_cst (NULL_TREE, n_fpr));
7945
      TREE_SIDE_EFFECTS (t) = 1;
7946
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7947
    }
7948
 
7949
  /* Find the overflow area.  */
7950
  if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
7951
      || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
7952
    {
7953
      t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
7954
 
7955
      off = INTVAL (current_function_arg_offset_rtx);
7956
      off = off < 0 ? 0 : off;
7957
      if (TARGET_DEBUG_ARG)
7958
        fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7959
                 (int)n_gpr, (int)n_fpr, off);
7960
 
7961
      t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
7962
 
7963
      t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
7964
      TREE_SIDE_EFFECTS (t) = 1;
7965
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7966
    }
7967
 
7968
  /* Find the register save area.  */
7969
  if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
7970
      || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
7971
    {
7972
      t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
7973
      t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
7974
                  build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
7975
 
7976
      t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
7977
      TREE_SIDE_EFFECTS (t) = 1;
7978
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7979
    }
7980
}
7981
 
7982
/* Implement va_arg by updating the va_list structure
7983
   VALIST as required to retrieve an argument of type
7984
   TYPE, and returning that argument.
7985
 
7986
   Generates code equivalent to:
7987
 
7988
   if (integral value) {
7989
     if (size  <= 4 && args.gpr < 5 ||
7990
         size  > 4 && args.gpr < 4 )
7991
       ret = args.reg_save_area[args.gpr+8]
7992
     else
7993
       ret = *args.overflow_arg_area++;
7994
   } else if (float value) {
7995
     if (args.fgpr < 2)
7996
       ret = args.reg_save_area[args.fpr+64]
7997
     else
7998
       ret = *args.overflow_arg_area++;
7999
   } else if (aggregate value) {
8000
     if (args.gpr < 5)
8001
       ret = *args.reg_save_area[args.gpr]
8002
     else
8003
       ret = **args.overflow_arg_area++;
8004
   } */
8005
 
8006
static tree
8007
s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
8008
                      tree *post_p ATTRIBUTE_UNUSED)
8009
{
8010
  tree f_gpr, f_fpr, f_ovf, f_sav;
8011
  tree gpr, fpr, ovf, sav, reg, t, u;
8012
  int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
8013
  tree lab_false, lab_over, addr;
8014
 
8015
  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8016
  f_fpr = TREE_CHAIN (f_gpr);
8017
  f_ovf = TREE_CHAIN (f_fpr);
8018
  f_sav = TREE_CHAIN (f_ovf);
8019
 
8020
  valist = build_va_arg_indirect_ref (valist);
8021
  gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8022
  fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
8023
  ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
8024
  sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
8025
 
8026
  size = int_size_in_bytes (type);
8027
 
8028
  if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8029
    {
8030
      if (TARGET_DEBUG_ARG)
8031
        {
8032
          fprintf (stderr, "va_arg: aggregate type");
8033
          debug_tree (type);
8034
        }
8035
 
8036
      /* Aggregates are passed by reference.  */
8037
      indirect_p = 1;
8038
      reg = gpr;
8039
      n_reg = 1;
8040
 
8041
      /* kernel stack layout on 31 bit: It is assumed here that no padding
8042
         will be added by s390_frame_info because for va_args always an even
8043
         number of gprs has to be saved r15-r2 = 14 regs.  */
8044
      sav_ofs = 2 * UNITS_PER_WORD;
8045
      sav_scale = UNITS_PER_WORD;
8046
      size = UNITS_PER_WORD;
8047
      max_reg = GP_ARG_NUM_REG - n_reg;
8048
    }
8049
  else if (s390_function_arg_float (TYPE_MODE (type), type))
8050
    {
8051
      if (TARGET_DEBUG_ARG)
8052
        {
8053
          fprintf (stderr, "va_arg: float type");
8054
          debug_tree (type);
8055
        }
8056
 
8057
      /* FP args go in FP registers, if present.  */
8058
      indirect_p = 0;
8059
      reg = fpr;
8060
      n_reg = 1;
8061
      sav_ofs = 16 * UNITS_PER_WORD;
8062
      sav_scale = 8;
8063
      max_reg = FP_ARG_NUM_REG - n_reg;
8064
    }
8065
  else
8066
    {
8067
      if (TARGET_DEBUG_ARG)
8068
        {
8069
          fprintf (stderr, "va_arg: other type");
8070
          debug_tree (type);
8071
        }
8072
 
8073
      /* Otherwise into GP registers.  */
8074
      indirect_p = 0;
8075
      reg = gpr;
8076
      n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
8077
 
8078
      /* kernel stack layout on 31 bit: It is assumed here that no padding
8079
         will be added by s390_frame_info because for va_args always an even
8080
         number of gprs has to be saved r15-r2 = 14 regs.  */
8081
      sav_ofs = 2 * UNITS_PER_WORD;
8082
 
8083
      if (size < UNITS_PER_WORD)
8084
        sav_ofs += UNITS_PER_WORD - size;
8085
 
8086
      sav_scale = UNITS_PER_WORD;
8087
      max_reg = GP_ARG_NUM_REG - n_reg;
8088
    }
8089
 
8090
  /* Pull the value out of the saved registers ...  */
8091
 
8092
  lab_false = create_artificial_label ();
8093
  lab_over = create_artificial_label ();
8094
  addr = create_tmp_var (ptr_type_node, "addr");
8095
  DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
8096
 
8097
  t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
8098
  t = build2 (GT_EXPR, boolean_type_node, reg, t);
8099
  u = build1 (GOTO_EXPR, void_type_node, lab_false);
8100
  t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8101
  gimplify_and_add (t, pre_p);
8102
 
8103
  t = build2 (PLUS_EXPR, ptr_type_node, sav,
8104
              fold_convert (ptr_type_node, size_int (sav_ofs)));
8105
  u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
8106
              fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
8107
  t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
8108
 
8109
  t = build2 (MODIFY_EXPR, void_type_node, addr, t);
8110
  gimplify_and_add (t, pre_p);
8111
 
8112
  t = build1 (GOTO_EXPR, void_type_node, lab_over);
8113
  gimplify_and_add (t, pre_p);
8114
 
8115
  t = build1 (LABEL_EXPR, void_type_node, lab_false);
8116
  append_to_statement_list (t, pre_p);
8117
 
8118
 
8119
  /* ... Otherwise out of the overflow area.  */
8120
 
8121
  t = ovf;
8122
  if (size < UNITS_PER_WORD)
8123
    t = build2 (PLUS_EXPR, ptr_type_node, t,
8124
                fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
8125
 
8126
  gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8127
 
8128
  u = build2 (MODIFY_EXPR, void_type_node, addr, t);
8129
  gimplify_and_add (u, pre_p);
8130
 
8131
  t = build2 (PLUS_EXPR, ptr_type_node, t,
8132
              fold_convert (ptr_type_node, size_int (size)));
8133
  t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
8134
  gimplify_and_add (t, pre_p);
8135
 
8136
  t = build1 (LABEL_EXPR, void_type_node, lab_over);
8137
  append_to_statement_list (t, pre_p);
8138
 
8139
 
8140
  /* Increment register save count.  */
8141
 
8142
  u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
8143
              fold_convert (TREE_TYPE (reg), size_int (n_reg)));
8144
  gimplify_and_add (u, pre_p);
8145
 
8146
  if (indirect_p)
8147
    {
8148
      t = build_pointer_type (build_pointer_type (type));
8149
      addr = fold_convert (t, addr);
8150
      addr = build_va_arg_indirect_ref (addr);
8151
    }
8152
  else
8153
    {
8154
      t = build_pointer_type (type);
8155
      addr = fold_convert (t, addr);
8156
    }
8157
 
8158
  return build_va_arg_indirect_ref (addr);
8159
}
8160
 
8161
 
8162
/* Builtins.  */
8163
 
8164
enum s390_builtin
8165
{
8166
  S390_BUILTIN_THREAD_POINTER,
8167
  S390_BUILTIN_SET_THREAD_POINTER,
8168
 
8169
  S390_BUILTIN_max
8170
};
8171
 
8172
static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
8173
  CODE_FOR_get_tp_64,
8174
  CODE_FOR_set_tp_64
8175
};
8176
 
8177
static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
8178
  CODE_FOR_get_tp_31,
8179
  CODE_FOR_set_tp_31
8180
};
8181
 
8182
static void
8183
s390_init_builtins (void)
8184
{
8185
  tree ftype;
8186
 
8187
  ftype = build_function_type (ptr_type_node, void_list_node);
8188
  lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
8189
                               S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
8190
                               NULL, NULL_TREE);
8191
 
8192
  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
8193
  lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
8194
                               S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
8195
                               NULL, NULL_TREE);
8196
}
8197
 
8198
/* Expand an expression EXP that calls a built-in function,
8199
   with result going to TARGET if that's convenient
8200
   (and in mode MODE if that's convenient).
8201
   SUBTARGET may be used as the target for computing one of EXP's operands.
8202
   IGNORE is nonzero if the value is to be ignored.  */
8203
 
8204
static rtx
8205
s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8206
                     enum machine_mode mode ATTRIBUTE_UNUSED,
8207
                     int ignore ATTRIBUTE_UNUSED)
8208
{
8209
#define MAX_ARGS 2
8210
 
8211
  unsigned int const *code_for_builtin =
8212
    TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
8213
 
8214
  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8215
  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8216
  tree arglist = TREE_OPERAND (exp, 1);
8217
  enum insn_code icode;
8218
  rtx op[MAX_ARGS], pat;
8219
  int arity;
8220
  bool nonvoid;
8221
 
8222
  if (fcode >= S390_BUILTIN_max)
8223
    internal_error ("bad builtin fcode");
8224
  icode = code_for_builtin[fcode];
8225
  if (icode == 0)
8226
    internal_error ("bad builtin fcode");
8227
 
8228
  nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
8229
 
8230
  for (arglist = TREE_OPERAND (exp, 1), arity = 0;
8231
       arglist;
8232
       arglist = TREE_CHAIN (arglist), arity++)
8233
    {
8234
      const struct insn_operand_data *insn_op;
8235
 
8236
      tree arg = TREE_VALUE (arglist);
8237
      if (arg == error_mark_node)
8238
        return NULL_RTX;
8239
      if (arity > MAX_ARGS)
8240
        return NULL_RTX;
8241
 
8242
      insn_op = &insn_data[icode].operand[arity + nonvoid];
8243
 
8244
      op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
8245
 
8246
      if (!(*insn_op->predicate) (op[arity], insn_op->mode))
8247
        op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
8248
    }
8249
 
8250
  if (nonvoid)
8251
    {
8252
      enum machine_mode tmode = insn_data[icode].operand[0].mode;
8253
      if (!target
8254
          || GET_MODE (target) != tmode
8255
          || !(*insn_data[icode].operand[0].predicate) (target, tmode))
8256
        target = gen_reg_rtx (tmode);
8257
    }
8258
 
8259
  switch (arity)
8260
    {
8261
    case 0:
8262
      pat = GEN_FCN (icode) (target);
8263
      break;
8264
    case 1:
8265
      if (nonvoid)
8266
        pat = GEN_FCN (icode) (target, op[0]);
8267
      else
8268
        pat = GEN_FCN (icode) (op[0]);
8269
      break;
8270
    case 2:
8271
      pat = GEN_FCN (icode) (target, op[0], op[1]);
8272
      break;
8273
    default:
8274
      gcc_unreachable ();
8275
    }
8276
  if (!pat)
8277
    return NULL_RTX;
8278
  emit_insn (pat);
8279
 
8280
  if (nonvoid)
8281
    return target;
8282
  else
8283
    return const0_rtx;
8284
}
8285
 
8286
 
8287
/* Output assembly code for the trampoline template to
8288
   stdio stream FILE.
8289
 
8290
   On S/390, we use gpr 1 internally in the trampoline code;
8291
   gpr 0 is used to hold the static chain.  */
8292
 
8293
void
8294
s390_trampoline_template (FILE *file)
8295
{
8296
  rtx op[2];
8297
  op[0] = gen_rtx_REG (Pmode, 0);
8298
  op[1] = gen_rtx_REG (Pmode, 1);
8299
 
8300
  if (TARGET_64BIT)
8301
    {
8302
      output_asm_insn ("basr\t%1,0", op);
8303
      output_asm_insn ("lmg\t%0,%1,14(%1)", op);
8304
      output_asm_insn ("br\t%1", op);
8305
      ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
8306
    }
8307
  else
8308
    {
8309
      output_asm_insn ("basr\t%1,0", op);
8310
      output_asm_insn ("lm\t%0,%1,6(%1)", op);
8311
      output_asm_insn ("br\t%1", op);
8312
      ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
8313
    }
8314
}
8315
 
8316
/* Emit RTL insns to initialize the variable parts of a trampoline.
8317
   FNADDR is an RTX for the address of the function's pure code.
8318
   CXT is an RTX for the static chain value for the function.  */
8319
 
8320
void
8321
s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
8322
{
8323
  emit_move_insn (gen_rtx_MEM (Pmode,
8324
                   memory_address (Pmode,
8325
                   plus_constant (addr, (TARGET_64BIT ? 16 : 8)))), cxt);
8326
  emit_move_insn (gen_rtx_MEM (Pmode,
8327
                   memory_address (Pmode,
8328
                   plus_constant (addr, (TARGET_64BIT ? 24 : 12)))), fnaddr);
8329
}
8330
 
8331
/* Return rtx for 64-bit constant formed from the 32-bit subwords
8332
   LOW and HIGH, independent of the host word size.  */
8333
 
8334
rtx
8335
s390_gen_rtx_const_DI (int high, int low)
8336
{
8337
#if HOST_BITS_PER_WIDE_INT >= 64
8338
  HOST_WIDE_INT val;
8339
  val = (HOST_WIDE_INT)high;
8340
  val <<= 32;
8341
  val |= (HOST_WIDE_INT)low;
8342
 
8343
  return GEN_INT (val);
8344
#else
8345
#if HOST_BITS_PER_WIDE_INT >= 32
8346
  return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
8347
#else
8348
  gcc_unreachable ();
8349
#endif
8350
#endif
8351
}
8352
 
8353
/* Output assembler code to FILE to increment profiler label # LABELNO
8354
   for profiling a function entry.  */
8355
 
8356
void
8357
s390_function_profiler (FILE *file, int labelno)
8358
{
8359
  rtx op[7];
8360
 
8361
  char label[128];
8362
  ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
8363
 
8364
  fprintf (file, "# function profiler \n");
8365
 
8366
  op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
8367
  op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
8368
  op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
8369
 
8370
  op[2] = gen_rtx_REG (Pmode, 1);
8371
  op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
8372
  SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
8373
 
8374
  op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
8375
  if (flag_pic)
8376
    {
8377
      op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
8378
      op[4] = gen_rtx_CONST (Pmode, op[4]);
8379
    }
8380
 
8381
  if (TARGET_64BIT)
8382
    {
8383
      output_asm_insn ("stg\t%0,%1", op);
8384
      output_asm_insn ("larl\t%2,%3", op);
8385
      output_asm_insn ("brasl\t%0,%4", op);
8386
      output_asm_insn ("lg\t%0,%1", op);
8387
    }
8388
  else if (!flag_pic)
8389
    {
8390
      op[6] = gen_label_rtx ();
8391
 
8392
      output_asm_insn ("st\t%0,%1", op);
8393
      output_asm_insn ("bras\t%2,%l6", op);
8394
      output_asm_insn (".long\t%4", op);
8395
      output_asm_insn (".long\t%3", op);
8396
      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8397
      output_asm_insn ("l\t%0,0(%2)", op);
8398
      output_asm_insn ("l\t%2,4(%2)", op);
8399
      output_asm_insn ("basr\t%0,%0", op);
8400
      output_asm_insn ("l\t%0,%1", op);
8401
    }
8402
  else
8403
    {
8404
      op[5] = gen_label_rtx ();
8405
      op[6] = gen_label_rtx ();
8406
 
8407
      output_asm_insn ("st\t%0,%1", op);
8408
      output_asm_insn ("bras\t%2,%l6", op);
8409
      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
8410
      output_asm_insn (".long\t%4-%l5", op);
8411
      output_asm_insn (".long\t%3-%l5", op);
8412
      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8413
      output_asm_insn ("lr\t%0,%2", op);
8414
      output_asm_insn ("a\t%0,0(%2)", op);
8415
      output_asm_insn ("a\t%2,4(%2)", op);
8416
      output_asm_insn ("basr\t%0,%0", op);
8417
      output_asm_insn ("l\t%0,%1", op);
8418
    }
8419
}
8420
 
8421
/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8422
   into its SYMBOL_REF_FLAGS.  */
8423
 
8424
static void
8425
s390_encode_section_info (tree decl, rtx rtl, int first)
8426
{
8427
  default_encode_section_info (decl, rtl, first);
8428
 
8429
  /* If a variable has a forced alignment to < 2 bytes, mark it with
8430
     SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand.  */
8431
  if (TREE_CODE (decl) == VAR_DECL
8432
      && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
8433
    SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
8434
}
8435
 
8436
/* Output thunk to FILE that implements a C++ virtual function call (with
8437
   multiple inheritance) to FUNCTION.  The thunk adjusts the this pointer
8438
   by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8439
   stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8440
   relative to the resulting this pointer.  */
8441
 
8442
static void
8443
s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
8444
                      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8445
                      tree function)
8446
{
8447
  rtx op[10];
8448
  int nonlocal = 0;
8449
 
8450
  /* Operand 0 is the target function.  */
8451
  op[0] = XEXP (DECL_RTL (function), 0);
8452
  if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
8453
    {
8454
      nonlocal = 1;
8455
      op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
8456
                              TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
8457
      op[0] = gen_rtx_CONST (Pmode, op[0]);
8458
    }
8459
 
8460
  /* Operand 1 is the 'this' pointer.  */
8461
  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8462
    op[1] = gen_rtx_REG (Pmode, 3);
8463
  else
8464
    op[1] = gen_rtx_REG (Pmode, 2);
8465
 
8466
  /* Operand 2 is the delta.  */
8467
  op[2] = GEN_INT (delta);
8468
 
8469
  /* Operand 3 is the vcall_offset.  */
8470
  op[3] = GEN_INT (vcall_offset);
8471
 
8472
  /* Operand 4 is the temporary register.  */
8473
  op[4] = gen_rtx_REG (Pmode, 1);
8474
 
8475
  /* Operands 5 to 8 can be used as labels.  */
8476
  op[5] = NULL_RTX;
8477
  op[6] = NULL_RTX;
8478
  op[7] = NULL_RTX;
8479
  op[8] = NULL_RTX;
8480
 
8481
  /* Operand 9 can be used for temporary register.  */
8482
  op[9] = NULL_RTX;
8483
 
8484
  /* Generate code.  */
8485
  if (TARGET_64BIT)
8486
    {
8487
      /* Setup literal pool pointer if required.  */
8488
      if ((!DISP_IN_RANGE (delta)
8489
           && !CONST_OK_FOR_K (delta)
8490
           && !CONST_OK_FOR_Os (delta))
8491
          || (!DISP_IN_RANGE (vcall_offset)
8492
              && !CONST_OK_FOR_K (vcall_offset)
8493
              && !CONST_OK_FOR_Os (vcall_offset)))
8494
        {
8495
          op[5] = gen_label_rtx ();
8496
          output_asm_insn ("larl\t%4,%5", op);
8497
        }
8498
 
8499
      /* Add DELTA to this pointer.  */
8500
      if (delta)
8501
        {
8502
          if (CONST_OK_FOR_J (delta))
8503
            output_asm_insn ("la\t%1,%2(%1)", op);
8504
          else if (DISP_IN_RANGE (delta))
8505
            output_asm_insn ("lay\t%1,%2(%1)", op);
8506
          else if (CONST_OK_FOR_K (delta))
8507
            output_asm_insn ("aghi\t%1,%2", op);
8508
          else if (CONST_OK_FOR_Os (delta))
8509
            output_asm_insn ("agfi\t%1,%2", op);
8510
          else
8511
            {
8512
              op[6] = gen_label_rtx ();
8513
              output_asm_insn ("agf\t%1,%6-%5(%4)", op);
8514
            }
8515
        }
8516
 
8517
      /* Perform vcall adjustment.  */
8518
      if (vcall_offset)
8519
        {
8520
          if (DISP_IN_RANGE (vcall_offset))
8521
            {
8522
              output_asm_insn ("lg\t%4,0(%1)", op);
8523
              output_asm_insn ("ag\t%1,%3(%4)", op);
8524
            }
8525
          else if (CONST_OK_FOR_K (vcall_offset))
8526
            {
8527
              output_asm_insn ("lghi\t%4,%3", op);
8528
              output_asm_insn ("ag\t%4,0(%1)", op);
8529
              output_asm_insn ("ag\t%1,0(%4)", op);
8530
            }
8531
          else if (CONST_OK_FOR_Os (vcall_offset))
8532
            {
8533
              output_asm_insn ("lgfi\t%4,%3", op);
8534
              output_asm_insn ("ag\t%4,0(%1)", op);
8535
              output_asm_insn ("ag\t%1,0(%4)", op);
8536
            }
8537
          else
8538
            {
8539
              op[7] = gen_label_rtx ();
8540
              output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
8541
              output_asm_insn ("ag\t%4,0(%1)", op);
8542
              output_asm_insn ("ag\t%1,0(%4)", op);
8543
            }
8544
        }
8545
 
8546
      /* Jump to target.  */
8547
      output_asm_insn ("jg\t%0", op);
8548
 
8549
      /* Output literal pool if required.  */
8550
      if (op[5])
8551
        {
8552
          output_asm_insn (".align\t4", op);
8553
          targetm.asm_out.internal_label (file, "L",
8554
                                          CODE_LABEL_NUMBER (op[5]));
8555
        }
8556
      if (op[6])
8557
        {
8558
          targetm.asm_out.internal_label (file, "L",
8559
                                          CODE_LABEL_NUMBER (op[6]));
8560
          output_asm_insn (".long\t%2", op);
8561
        }
8562
      if (op[7])
8563
        {
8564
          targetm.asm_out.internal_label (file, "L",
8565
                                          CODE_LABEL_NUMBER (op[7]));
8566
          output_asm_insn (".long\t%3", op);
8567
        }
8568
    }
8569
  else
8570
    {
8571
      /* Setup base pointer if required.  */
8572
      if (!vcall_offset
8573
          || (!DISP_IN_RANGE (delta)
8574
              && !CONST_OK_FOR_K (delta)
8575
              && !CONST_OK_FOR_Os (delta))
8576
          || (!DISP_IN_RANGE (delta)
8577
              && !CONST_OK_FOR_K (vcall_offset)
8578
              && !CONST_OK_FOR_Os (vcall_offset)))
8579
        {
8580
          op[5] = gen_label_rtx ();
8581
          output_asm_insn ("basr\t%4,0", op);
8582
          targetm.asm_out.internal_label (file, "L",
8583
                                          CODE_LABEL_NUMBER (op[5]));
8584
        }
8585
 
8586
      /* Add DELTA to this pointer.  */
8587
      if (delta)
8588
        {
8589
          if (CONST_OK_FOR_J (delta))
8590
            output_asm_insn ("la\t%1,%2(%1)", op);
8591
          else if (DISP_IN_RANGE (delta))
8592
            output_asm_insn ("lay\t%1,%2(%1)", op);
8593
          else if (CONST_OK_FOR_K (delta))
8594
            output_asm_insn ("ahi\t%1,%2", op);
8595
          else if (CONST_OK_FOR_Os (delta))
8596
            output_asm_insn ("afi\t%1,%2", op);
8597
          else
8598
            {
8599
              op[6] = gen_label_rtx ();
8600
              output_asm_insn ("a\t%1,%6-%5(%4)", op);
8601
            }
8602
        }
8603
 
8604
      /* Perform vcall adjustment.  */
8605
      if (vcall_offset)
8606
        {
8607
          if (CONST_OK_FOR_J (vcall_offset))
8608
            {
8609
              output_asm_insn ("l\t%4,0(%1)", op);
8610
              output_asm_insn ("a\t%1,%3(%4)", op);
8611
            }
8612
          else if (DISP_IN_RANGE (vcall_offset))
8613
            {
8614
              output_asm_insn ("l\t%4,0(%1)", op);
8615
              output_asm_insn ("ay\t%1,%3(%4)", op);
8616
            }
8617
          else if (CONST_OK_FOR_K (vcall_offset))
8618
            {
8619
              output_asm_insn ("lhi\t%4,%3", op);
8620
              output_asm_insn ("a\t%4,0(%1)", op);
8621
              output_asm_insn ("a\t%1,0(%4)", op);
8622
            }
8623
          else if (CONST_OK_FOR_Os (vcall_offset))
8624
            {
8625
              output_asm_insn ("iilf\t%4,%3", op);
8626
              output_asm_insn ("a\t%4,0(%1)", op);
8627
              output_asm_insn ("a\t%1,0(%4)", op);
8628
            }
8629
          else
8630
            {
8631
              op[7] = gen_label_rtx ();
8632
              output_asm_insn ("l\t%4,%7-%5(%4)", op);
8633
              output_asm_insn ("a\t%4,0(%1)", op);
8634
              output_asm_insn ("a\t%1,0(%4)", op);
8635
            }
8636
 
8637
          /* We had to clobber the base pointer register.
8638
             Re-setup the base pointer (with a different base).  */
8639
          op[5] = gen_label_rtx ();
8640
          output_asm_insn ("basr\t%4,0", op);
8641
          targetm.asm_out.internal_label (file, "L",
8642
                                          CODE_LABEL_NUMBER (op[5]));
8643
        }
8644
 
8645
      /* Jump to target.  */
8646
      op[8] = gen_label_rtx ();
8647
 
8648
      if (!flag_pic)
8649
        output_asm_insn ("l\t%4,%8-%5(%4)", op);
8650
      else if (!nonlocal)
8651
        output_asm_insn ("a\t%4,%8-%5(%4)", op);
8652
      /* We cannot call through .plt, since .plt requires %r12 loaded.  */
8653
      else if (flag_pic == 1)
8654
        {
8655
          output_asm_insn ("a\t%4,%8-%5(%4)", op);
8656
          output_asm_insn ("l\t%4,%0(%4)", op);
8657
        }
8658
      else if (flag_pic == 2)
8659
        {
8660
          op[9] = gen_rtx_REG (Pmode, 0);
8661
          output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
8662
          output_asm_insn ("a\t%4,%8-%5(%4)", op);
8663
          output_asm_insn ("ar\t%4,%9", op);
8664
          output_asm_insn ("l\t%4,0(%4)", op);
8665
        }
8666
 
8667
      output_asm_insn ("br\t%4", op);
8668
 
8669
      /* Output literal pool.  */
8670
      output_asm_insn (".align\t4", op);
8671
 
8672
      if (nonlocal && flag_pic == 2)
8673
        output_asm_insn (".long\t%0", op);
8674
      if (nonlocal)
8675
        {
8676
          op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
8677
          SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
8678
        }
8679
 
8680
      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
8681
      if (!flag_pic)
8682
        output_asm_insn (".long\t%0", op);
8683
      else
8684
        output_asm_insn (".long\t%0-%5", op);
8685
 
8686
      if (op[6])
8687
        {
8688
          targetm.asm_out.internal_label (file, "L",
8689
                                          CODE_LABEL_NUMBER (op[6]));
8690
          output_asm_insn (".long\t%2", op);
8691
        }
8692
      if (op[7])
8693
        {
8694
          targetm.asm_out.internal_label (file, "L",
8695
                                          CODE_LABEL_NUMBER (op[7]));
8696
          output_asm_insn (".long\t%3", op);
8697
        }
8698
    }
8699
}
8700
 
8701
static bool
8702
s390_valid_pointer_mode (enum machine_mode mode)
8703
{
8704
  return (mode == SImode || (TARGET_64BIT && mode == DImode));
8705
}
8706
 
8707
/* Checks whether the given ARGUMENT_LIST would use a caller
8708
   saved register.  This is used to decide whether sibling call
8709
   optimization could be performed on the respective function
8710
   call.  */
8711
 
8712
static bool
8713
s390_call_saved_register_used (tree argument_list)
8714
{
8715
  CUMULATIVE_ARGS cum;
8716
  tree parameter;
8717
  enum machine_mode mode;
8718
  tree type;
8719
  rtx parm_rtx;
8720
  int reg;
8721
 
8722
  INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
8723
 
8724
  while (argument_list)
8725
    {
8726
      parameter = TREE_VALUE (argument_list);
8727
      argument_list = TREE_CHAIN (argument_list);
8728
 
8729
      gcc_assert (parameter);
8730
 
8731
      /* For an undeclared variable passed as parameter we will get
8732
         an ERROR_MARK node here.  */
8733
      if (TREE_CODE (parameter) == ERROR_MARK)
8734
        return true;
8735
 
8736
      type = TREE_TYPE (parameter);
8737
      gcc_assert (type);
8738
 
8739
      mode = TYPE_MODE (type);
8740
      gcc_assert (mode);
8741
 
8742
      if (pass_by_reference (&cum, mode, type, true))
8743
        {
8744
          mode = Pmode;
8745
          type = build_pointer_type (type);
8746
        }
8747
 
8748
       parm_rtx = s390_function_arg (&cum, mode, type, 0);
8749
 
8750
       s390_function_arg_advance (&cum, mode, type, 0);
8751
 
8752
       if (parm_rtx && REG_P (parm_rtx))
8753
         {
8754
           for (reg = 0;
8755
                reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
8756
                reg++)
8757
             if (! call_used_regs[reg + REGNO (parm_rtx)])
8758
               return true;
8759
         }
8760
    }
8761
  return false;
8762
}
8763
 
8764
/* Return true if the given call expression can be
8765
   turned into a sibling call.
8766
   DECL holds the declaration of the function to be called whereas
8767
   EXP is the call expression itself.  */
8768
 
8769
static bool
8770
s390_function_ok_for_sibcall (tree decl, tree exp)
8771
{
8772
  /* The TPF epilogue uses register 1.  */
8773
  if (TARGET_TPF_PROFILING)
8774
    return false;
8775
 
8776
  /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8777
     which would have to be restored before the sibcall.  */
8778
  if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
8779
    return false;
8780
 
8781
  /* Register 6 on s390 is available as an argument register but unfortunately
8782
     "caller saved". This makes functions needing this register for arguments
8783
     not suitable for sibcalls.  */
8784
  if (TREE_OPERAND (exp, 1)
8785
      && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
8786
      return false;
8787
 
8788
  return true;
8789
}
8790
 
8791
/* Return the fixed registers used for condition codes.  */
8792
 
8793
static bool
8794
s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
8795
{
8796
  *p1 = CC_REGNUM;
8797
  *p2 = INVALID_REGNUM;
8798
 
8799
  return true;
8800
}
8801
 
8802
/* This function is used by the call expanders of the machine description.
8803
   It emits the call insn itself together with the necessary operations
8804
   to adjust the target address and returns the emitted insn.
8805
   ADDR_LOCATION is the target address rtx
8806
   TLS_CALL the location of the thread-local symbol
8807
   RESULT_REG the register where the result of the call should be stored
8808
   RETADDR_REG the register where the return address should be stored
8809
               If this parameter is NULL_RTX the call is considered
8810
               to be a sibling call.  */
8811
 
8812
rtx
8813
s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
8814
                rtx retaddr_reg)
8815
{
8816
  bool plt_call = false;
8817
  rtx insn;
8818
  rtx call;
8819
  rtx clobber;
8820
  rtvec vec;
8821
 
8822
  /* Direct function calls need special treatment.  */
8823
  if (GET_CODE (addr_location) == SYMBOL_REF)
8824
    {
8825
      /* When calling a global routine in PIC mode, we must
8826
         replace the symbol itself with the PLT stub.  */
8827
      if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
8828
        {
8829
          addr_location = gen_rtx_UNSPEC (Pmode,
8830
                                          gen_rtvec (1, addr_location),
8831
                                          UNSPEC_PLT);
8832
          addr_location = gen_rtx_CONST (Pmode, addr_location);
8833
          plt_call = true;
8834
        }
8835
 
8836
      /* Unless we can use the bras(l) insn, force the
8837
         routine address into a register.  */
8838
      if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
8839
        {
8840
          if (flag_pic)
8841
            addr_location = legitimize_pic_address (addr_location, 0);
8842
          else
8843
            addr_location = force_reg (Pmode, addr_location);
8844
        }
8845
    }
8846
 
8847
  /* If it is already an indirect call or the code above moved the
8848
     SYMBOL_REF to somewhere else make sure the address can be found in
8849
     register 1.  */
8850
  if (retaddr_reg == NULL_RTX
8851
      && GET_CODE (addr_location) != SYMBOL_REF
8852
      && !plt_call)
8853
    {
8854
      emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
8855
      addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
8856
    }
8857
 
8858
  addr_location = gen_rtx_MEM (QImode, addr_location);
8859
  call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8860
 
8861
  if (result_reg != NULL_RTX)
8862
    call = gen_rtx_SET (VOIDmode, result_reg, call);
8863
 
8864
  if (retaddr_reg != NULL_RTX)
8865
    {
8866
      clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
8867
 
8868
      if (tls_call != NULL_RTX)
8869
        vec = gen_rtvec (3, call, clobber,
8870
                         gen_rtx_USE (VOIDmode, tls_call));
8871
      else
8872
        vec = gen_rtvec (2, call, clobber);
8873
 
8874
      call = gen_rtx_PARALLEL (VOIDmode, vec);
8875
    }
8876
 
8877
  insn = emit_call_insn (call);
8878
 
8879
  /* 31-bit PLT stubs and tls calls use the GOT register implicitly.  */
8880
  if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
8881
    {
8882
      /* s390_function_ok_for_sibcall should
8883
         have denied sibcalls in this case.  */
8884
      gcc_assert (retaddr_reg != NULL_RTX);
8885
 
8886
      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
8887
    }
8888
  return insn;
8889
}
8890
 
8891
/* Implement CONDITIONAL_REGISTER_USAGE.  */
8892
 
8893
void
8894
s390_conditional_register_usage (void)
8895
{
8896
  int i;
8897
 
8898
  if (flag_pic)
8899
    {
8900
      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8901
      call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8902
    }
8903
  if (TARGET_CPU_ZARCH)
8904
    {
8905
      fixed_regs[BASE_REGNUM] = 0;
8906
      call_used_regs[BASE_REGNUM] = 0;
8907
      fixed_regs[RETURN_REGNUM] = 0;
8908
      call_used_regs[RETURN_REGNUM] = 0;
8909
    }
8910
  if (TARGET_64BIT)
8911
    {
8912
      for (i = 24; i < 32; i++)
8913
        call_used_regs[i] = call_really_used_regs[i] = 0;
8914
    }
8915
  else
8916
    {
8917
      for (i = 18; i < 20; i++)
8918
        call_used_regs[i] = call_really_used_regs[i] = 0;
8919
    }
8920
 
8921
  if (TARGET_SOFT_FLOAT)
8922
    {
8923
      for (i = 16; i < 32; i++)
8924
        call_used_regs[i] = fixed_regs[i] = 1;
8925
    }
8926
}
8927
 
8928
/* Corresponding function to eh_return expander.  */
8929
 
8930
static GTY(()) rtx s390_tpf_eh_return_symbol;
8931
void
8932
s390_emit_tpf_eh_return (rtx target)
8933
{
8934
  rtx insn, reg;
8935
 
8936
  if (!s390_tpf_eh_return_symbol)
8937
    s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
8938
 
8939
  reg = gen_rtx_REG (Pmode, 2);
8940
 
8941
  emit_move_insn (reg, target);
8942
  insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
8943
                                     gen_rtx_REG (Pmode, RETURN_REGNUM));
8944
  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
8945
 
8946
  emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
8947
}
8948
 
8949
/* Rework the prologue/epilogue to avoid saving/restoring
8950
   registers unnecessarily.  */
8951
 
8952
static void
8953
s390_optimize_prologue (void)
8954
{
8955
  rtx insn, new_insn, next_insn;
8956
 
8957
  /* Do a final recompute of the frame-related data.  */
8958
 
8959
  s390_update_frame_layout ();
8960
 
8961
  /* If all special registers are in fact used, there's nothing we
8962
     can do, so no point in walking the insn list.  */
8963
 
8964
  if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
8965
      && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
8966
      && (TARGET_CPU_ZARCH
8967
          || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
8968
              && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
8969
    return;
8970
 
8971
  /* Search for prologue/epilogue insns and replace them.  */
8972
 
8973
  for (insn = get_insns (); insn; insn = next_insn)
8974
    {
8975
      int first, last, off;
8976
      rtx set, base, offset;
8977
 
8978
      next_insn = NEXT_INSN (insn);
8979
 
8980
      if (GET_CODE (insn) != INSN)
8981
        continue;
8982
 
8983
      if (GET_CODE (PATTERN (insn)) == PARALLEL
8984
          && store_multiple_operation (PATTERN (insn), VOIDmode))
8985
        {
8986
          set = XVECEXP (PATTERN (insn), 0, 0);
8987
          first = REGNO (SET_SRC (set));
8988
          last = first + XVECLEN (PATTERN (insn), 0) - 1;
8989
          offset = const0_rtx;
8990
          base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
8991
          off = INTVAL (offset);
8992
 
8993
          if (GET_CODE (base) != REG || off < 0)
8994
            continue;
8995
          if (cfun_frame_layout.first_save_gpr != -1
8996
              && (cfun_frame_layout.first_save_gpr < first
8997
                  || cfun_frame_layout.last_save_gpr > last))
8998
            continue;
8999
          if (REGNO (base) != STACK_POINTER_REGNUM
9000
              && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9001
            continue;
9002
          if (first > BASE_REGNUM || last < BASE_REGNUM)
9003
            continue;
9004
 
9005
          if (cfun_frame_layout.first_save_gpr != -1)
9006
            {
9007
              new_insn  = save_gprs (base,
9008
                                     off + (cfun_frame_layout.first_save_gpr
9009
                                            - first) * UNITS_PER_WORD,
9010
                                     cfun_frame_layout.first_save_gpr,
9011
                                     cfun_frame_layout.last_save_gpr);
9012
              new_insn = emit_insn_before (new_insn, insn);
9013
              INSN_ADDRESSES_NEW (new_insn, -1);
9014
            }
9015
 
9016
          remove_insn (insn);
9017
          continue;
9018
        }
9019
 
9020
      if (cfun_frame_layout.first_save_gpr == -1
9021
          && GET_CODE (PATTERN (insn)) == SET
9022
          && GET_CODE (SET_SRC (PATTERN (insn))) == REG
9023
          && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
9024
              || (!TARGET_CPU_ZARCH
9025
                  && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
9026
          && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
9027
        {
9028
          set = PATTERN (insn);
9029
          first = REGNO (SET_SRC (set));
9030
          offset = const0_rtx;
9031
          base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9032
          off = INTVAL (offset);
9033
 
9034
          if (GET_CODE (base) != REG || off < 0)
9035
            continue;
9036
          if (REGNO (base) != STACK_POINTER_REGNUM
9037
              && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9038
            continue;
9039
 
9040
          remove_insn (insn);
9041
          continue;
9042
        }
9043
 
9044
      if (GET_CODE (PATTERN (insn)) == PARALLEL
9045
          && load_multiple_operation (PATTERN (insn), VOIDmode))
9046
        {
9047
          set = XVECEXP (PATTERN (insn), 0, 0);
9048
          first = REGNO (SET_DEST (set));
9049
          last = first + XVECLEN (PATTERN (insn), 0) - 1;
9050
          offset = const0_rtx;
9051
          base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9052
          off = INTVAL (offset);
9053
 
9054
          if (GET_CODE (base) != REG || off < 0)
9055
            continue;
9056
          if (cfun_frame_layout.first_restore_gpr != -1
9057
              && (cfun_frame_layout.first_restore_gpr < first
9058
                  || cfun_frame_layout.last_restore_gpr > last))
9059
            continue;
9060
          if (REGNO (base) != STACK_POINTER_REGNUM
9061
              && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9062
            continue;
9063
          if (first > BASE_REGNUM || last < BASE_REGNUM)
9064
            continue;
9065
 
9066
          if (cfun_frame_layout.first_restore_gpr != -1)
9067
            {
9068
              new_insn = restore_gprs (base,
9069
                                       off + (cfun_frame_layout.first_restore_gpr
9070
                                              - first) * UNITS_PER_WORD,
9071
                                       cfun_frame_layout.first_restore_gpr,
9072
                                       cfun_frame_layout.last_restore_gpr);
9073
              new_insn = emit_insn_before (new_insn, insn);
9074
              INSN_ADDRESSES_NEW (new_insn, -1);
9075
            }
9076
 
9077
          remove_insn (insn);
9078
          continue;
9079
        }
9080
 
9081
      if (cfun_frame_layout.first_restore_gpr == -1
9082
          && GET_CODE (PATTERN (insn)) == SET
9083
          && GET_CODE (SET_DEST (PATTERN (insn))) == REG
9084
          && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
9085
              || (!TARGET_CPU_ZARCH
9086
                  && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
9087
          && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
9088
        {
9089
          set = PATTERN (insn);
9090
          first = REGNO (SET_DEST (set));
9091
          offset = const0_rtx;
9092
          base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9093
          off = INTVAL (offset);
9094
 
9095
          if (GET_CODE (base) != REG || off < 0)
9096
            continue;
9097
          if (REGNO (base) != STACK_POINTER_REGNUM
9098
              && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9099
            continue;
9100
 
9101
          remove_insn (insn);
9102
          continue;
9103
        }
9104
    }
9105
}
9106
 
9107
/* Perform machine-dependent processing.  */
9108
 
9109
static void
9110
s390_reorg (void)
9111
{
9112
  bool pool_overflow = false;
9113
 
9114
  /* Make sure all splits have been performed; splits after
9115
     machine_dependent_reorg might confuse insn length counts.  */
9116
  split_all_insns_noflow ();
9117
 
9118
  /* From here on decomposed literal pool addresses must be accepted.  */
9119
  cfun->machine->decomposed_literal_pool_addresses_ok_p = true;
9120
 
9121
  /* Install the main literal pool and the associated base
9122
     register load insns.
9123
 
9124
     In addition, there are two problematic situations we need
9125
     to correct:
9126
 
9127
     - the literal pool might be > 4096 bytes in size, so that
9128
       some of its elements cannot be directly accessed
9129
 
9130
     - a branch target might be > 64K away from the branch, so that
9131
       it is not possible to use a PC-relative instruction.
9132
 
9133
     To fix those, we split the single literal pool into multiple
9134
     pool chunks, reloading the pool base register at various
9135
     points throughout the function to ensure it always points to
9136
     the pool chunk the following code expects, and / or replace
9137
     PC-relative branches by absolute branches.
9138
 
9139
     However, the two problems are interdependent: splitting the
9140
     literal pool can move a branch further away from its target,
9141
     causing the 64K limit to overflow, and on the other hand,
9142
     replacing a PC-relative branch by an absolute branch means
9143
     we need to put the branch target address into the literal
9144
     pool, possibly causing it to overflow.
9145
 
9146
     So, we loop trying to fix up both problems until we manage
9147
     to satisfy both conditions at the same time.  Note that the
9148
     loop is guaranteed to terminate as every pass of the loop
9149
     strictly decreases the total number of PC-relative branches
9150
     in the function.  (This is not completely true as there
9151
     might be branch-over-pool insns introduced by chunkify_start.
9152
     Those never need to be split however.)  */
9153
 
9154
  for (;;)
9155
    {
9156
      struct constant_pool *pool = NULL;
9157
 
9158
      /* Collect the literal pool.  */
9159
      if (!pool_overflow)
9160
        {
9161
          pool = s390_mainpool_start ();
9162
          if (!pool)
9163
            pool_overflow = true;
9164
        }
9165
 
9166
      /* If literal pool overflowed, start to chunkify it.  */
9167
      if (pool_overflow)
9168
        pool = s390_chunkify_start ();
9169
 
9170
      /* Split out-of-range branches.  If this has created new
9171
         literal pool entries, cancel current chunk list and
9172
         recompute it.  zSeries machines have large branch
9173
         instructions, so we never need to split a branch.  */
9174
      if (!TARGET_CPU_ZARCH && s390_split_branches ())
9175
        {
9176
          if (pool_overflow)
9177
            s390_chunkify_cancel (pool);
9178
          else
9179
            s390_mainpool_cancel (pool);
9180
 
9181
          continue;
9182
        }
9183
 
9184
      /* If we made it up to here, both conditions are satisfied.
9185
         Finish up literal pool related changes.  */
9186
      if (pool_overflow)
9187
        s390_chunkify_finish (pool);
9188
      else
9189
        s390_mainpool_finish (pool);
9190
 
9191
      /* We're done splitting branches.  */
9192
      cfun->machine->split_branches_pending_p = false;
9193
      break;
9194
    }
9195
 
9196
  /* Generate out-of-pool execute target insns.  */
9197
  if (TARGET_CPU_ZARCH)
9198
    {
9199
      rtx insn, label, target;
9200
 
9201
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9202
        {
9203
          label = s390_execute_label (insn);
9204
          if (!label)
9205
            continue;
9206
 
9207
          gcc_assert (label != const0_rtx);
9208
 
9209
          target = emit_label (XEXP (label, 0));
9210
          INSN_ADDRESSES_NEW (target, -1);
9211
 
9212
          target = emit_insn (s390_execute_target (insn));
9213
          INSN_ADDRESSES_NEW (target, -1);
9214
        }
9215
    }
9216
 
9217
  /* Try to optimize prologue and epilogue further.  */
9218
  s390_optimize_prologue ();
9219
}
9220
 
9221
 
9222
/* Initialize GCC target structure.  */
9223
 
9224
#undef  TARGET_ASM_ALIGNED_HI_OP
9225
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9226
#undef  TARGET_ASM_ALIGNED_DI_OP
9227
#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9228
#undef  TARGET_ASM_INTEGER
9229
#define TARGET_ASM_INTEGER s390_assemble_integer
9230
 
9231
#undef  TARGET_ASM_OPEN_PAREN
9232
#define TARGET_ASM_OPEN_PAREN ""
9233
 
9234
#undef  TARGET_ASM_CLOSE_PAREN
9235
#define TARGET_ASM_CLOSE_PAREN ""
9236
 
9237
#undef TARGET_DEFAULT_TARGET_FLAGS
9238
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9239
#undef TARGET_HANDLE_OPTION
9240
#define TARGET_HANDLE_OPTION s390_handle_option
9241
 
9242
#undef  TARGET_ENCODE_SECTION_INFO
9243
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9244
 
9245
#ifdef HAVE_AS_TLS
9246
#undef TARGET_HAVE_TLS
9247
#define TARGET_HAVE_TLS true
9248
#endif
9249
#undef TARGET_CANNOT_FORCE_CONST_MEM
9250
#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9251
 
9252
#undef TARGET_DELEGITIMIZE_ADDRESS
9253
#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9254
 
9255
#undef TARGET_RETURN_IN_MEMORY
9256
#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9257
 
9258
#undef  TARGET_INIT_BUILTINS
9259
#define TARGET_INIT_BUILTINS s390_init_builtins
9260
#undef  TARGET_EXPAND_BUILTIN
9261
#define TARGET_EXPAND_BUILTIN s390_expand_builtin
9262
 
9263
#undef TARGET_ASM_OUTPUT_MI_THUNK
9264
#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9265
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9266
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9267
 
9268
#undef  TARGET_SCHED_ADJUST_PRIORITY
9269
#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9270
#undef TARGET_SCHED_ISSUE_RATE
9271
#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9272
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9273
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9274
 
9275
#undef TARGET_CANNOT_COPY_INSN_P
9276
#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9277
#undef TARGET_RTX_COSTS
9278
#define TARGET_RTX_COSTS s390_rtx_costs
9279
#undef TARGET_ADDRESS_COST
9280
#define TARGET_ADDRESS_COST s390_address_cost
9281
 
9282
#undef TARGET_MACHINE_DEPENDENT_REORG
9283
#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9284
 
9285
#undef TARGET_VALID_POINTER_MODE
9286
#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9287
 
9288
#undef TARGET_BUILD_BUILTIN_VA_LIST
9289
#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9290
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
9291
#define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9292
 
9293
#undef TARGET_PROMOTE_FUNCTION_ARGS
9294
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9295
#undef TARGET_PROMOTE_FUNCTION_RETURN
9296
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9297
#undef TARGET_PASS_BY_REFERENCE
9298
#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9299
 
9300
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
9301
#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9302
 
9303
#undef TARGET_FIXED_CONDITION_CODE_REGS
9304
#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9305
 
9306
#undef TARGET_CC_MODES_COMPATIBLE
9307
#define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9308
 
9309
#undef TARGET_INVALID_WITHIN_DOLOOP
9310
#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9311
 
9312
#ifdef HAVE_AS_TLS
9313
#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9314
#define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9315
#endif
9316
 
9317
#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9318
#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
9319
#define TARGET_MANGLE_FUNDAMENTAL_TYPE s390_mangle_fundamental_type
9320
#endif
9321
 
9322
#undef TARGET_SCALAR_MODE_SUPPORTED_P
9323
#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
9324
 
9325
struct gcc_target targetm = TARGET_INITIALIZER;
9326
 
9327
#include "gt-s390.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.